110901 긁적긁적

system/windows 2011. 9. 1. 17:51
세그먼트 레지스터
- 세그먼트 디스크립터 테이블 인덱스를 보유

그 인덱스를 찾아 세그먼트 디스크립터 테이블을 참조하게 되고
그 세그먼트 디스크립터 테이블에는 세그먼트 메모리가 있음


각 세그먼트 레지스터가 가리키는 세그먼트 디스크립터와 + 가상메모리(os에서 사용자가 지정한 메모리 주소)
- 선형주소가 됨
- 이렇게 사용자가 지정한 메모리 주소로부터 선형 메모리까지 얻어지는 과정을 "세그먼테이션" 이라 칭함


선형주소 + 페이징 기법으로 
- 물리주소가 됨
- 접근하고자 하는 메모리에 대한 세그먼테이션 과정이 끝나면 프로세서는 과정에서 도출된 얻어진 선형 메모리로 부터 
페이징 메커니즘에 의해 물리 메모리 주소를 가지고 오게 됨


가상메모리 - 선형메모리 - 물리메모리

가상메모리는 gdt, ldt 로 선형주소와 매칭
- gdt(global) : 모든 프로그램이 참조할 수 있는 세그먼트 디스크립터들의 모임
- ldt(local) : 멀티테스킹 환경에서 각 테스크 단위로 정의


거기서 나온 선형주소는 페이지 디렉토리와 페이지 테이블을 참조하여 물리주소와 매칭



세그먼트 셀렉터
- index :
세그먼트 디스크립터 테이블에 있는 디스크립터의 배열에서 어떤 것을 선택할 것인지 나타냄
- ti(table indicator) : 
get=0, ldt=1
- rpl(request privilege level) : 요청한 놈에 대한 권한레벨
특권레벨, 예를 들어 커널모드
보호모드는 권한에 따른 제어가 가능한데 바로 rpl, dpl 때문, 이를 비교하여 접근을 제어


하위 3bit가 다른 용도로 사용되므로, index는 01000(8), 10000(16)... 등으로 8씩 증가되는 것처럼 보일것임
디스크립터주소 = gdt주소 + (index*8) 여기서, index에 8을 곱하는 이유는 디스크립터가 8byte이기 때문)


윈도우의 하위 2Gbyte (0 ~ 0x7fffffff) :  유저레벨에서 사용 (어플리케이션이 사용)
윈도우의 상위 2Gbyte (0x80000000 ~ 0xffffffff) : 커널레벨에서 사용



cdecl(C lib)
-아래와 같이 콜러가 스택 정리
00401000    PUSH EBP                        ; add() 시작
00401001    MOV EBP,ESP
00401003    MOV EAX,DWORD PTR SS:[EBP+8]
00401006    ADD EAX,DWORD PTR SS:[EBP+C]
00401009    POP EBP
0040100A    RETN

...

00401010    PUSH EBP                        ; main() 시작
00401011    MOV EBP,ESP
00401013    PUSH 2
00401015    PUSH 1
00401017    CALL callconv.00401000          ; => add() 호출
0040101C    ADD ESP,8                       ; => stack 정리
0040101F    POP EBP                       
00401020    RETN



stdcall(Win32 API)
-아래와 같이 콜리가 스택 정리. 참 착하네
00401000    PUSH EBP                        ; add() 시작
00401001    MOV EBP,ESP
00401003    MOV EAX,DWORD PTR SS:[EBP+8]
00401006    ADD EAX,DWORD PTR SS:[EBP+C]
00401009    POP EBP
0040100A    RETN 8 -- 리턴 + 팝

...

00401010    PUSH EBP                        ; main() 시작
00401011    MOV EBP,ESP
00401013    PUSH 2
00401015    PUSH 1
00401017    CALL callconv.00401000
0040101C    POP EBP
0040101D    RETN


이 함수를 스탠다드콜로 하고 싶다 할땐 아래와 같이 하면 됨
int _stdcall example(int a, int b)


fastcall
기본적으로 stdcall과 같으나, 함수에 전달하는 파라미터 일부(2개 까지)를
스택 메모리가 아닌 레지스터를 이용하여 전달.

예를 들어 파라미터가 4개 일때, 앞의 2개 파라미터는 ecx, edx 를 이용하여 전달

당연히 레지스터를 쓰니 메모리 보다 함수 호출이 빠를 수 밖에..
사실 속도성보다는 편의를 위해 사용.

그러나 ecx, edx 백업 필요 존재 - 다른 값이 쓰여지니까

=====================================
expertprogrammer.tistory.com
rootkit.tistory
reversecore.com
nobless_06.blog.me
 

'system > windows' 카테고리의 다른 글

관리자 권한 실행 - UAC 고려하기  (0) 2012.01.16
Segmentation 시발점 찾다가  (0) 2011.10.31
dll injection 기초  (0) 2010.09.03
win 명령어  (0) 2010.08.05
컬링 컨벤션 세가지(cdecl,stdcall,fastcall)  (0) 2010.07.07
: