공부해요/리버싱_핵심원리

37. x64 프로세서 이야기

yenas0 2024. 12. 18. 05:38
반응형

x64는 x86을 확장시킨 형태

뭐가 추가 변경된걸까..

 

64비트는 메모리 주소가 64비트로 표현됨 ( 64비트의 포인터를 사용한다는 뜻 )

컴구 내용 정리해둔 부분에 있을거같음.. IA기준으로 글 써뒀었나 기억이 안나넴

 

메모리

x64 프로세스 가상 메모리의 실제 크기는 16TB

x86은 4기가임

 

범용 레지스터

개수랑 크기 다 증가함. x64는 R로 시작하고 x86은 E로 시작함 레지스터 이름이.. EAX이런거처럼

하위호환 되려고 하위 비트 레지스터 액세스도 제공함

 

 

 

CALL/JMP Intruction

 

32비트 x86 (절대주소 방식)

FF15 XXXXXXXX 명령어는 4바이트 절대주소(VA)를 사용

CALL DWORD PTR DS:[00405000]처럼 명령어 뒤에 바로 절대 주소

64비트 x64 (상대주소 방식)

FF15 XXXXXXXX 명령어는 4바이트 상대주소(RVA)를 사용

상대주소는 명령어의 위치를 기준으로 계산

명령어 주소 + 상대주소 + 명령어 길이(6)이렇게 계산함

변환된 주소를 통해 해당 메모리의 값(8바이트)을 호출

 

 

함수 호출 규약

64비트에서는 함수 호출 규약이 변형된 fastcall 하나로 통일되었음

처음 4개의 파라미터는 레지스터에 전달되며, 정수형은 RCX, RDX, R8, R9, 실수형은 XMM0~XMM3를 사용

5번째 파라미터부터는 스택을 사용해 전달

레지스터로 전달된 4개의 파라미터에 대해서도 스택에 32바이트의 공간을 예약해 호출 프레임의 일관성을 유지

함수 호출 후 스택 정리는 Caller가 담당하며, 이는 기존 32비트의 cdecl과 fastcall을 결합한 형태

레지스터를 사용함으로써 함수 호출 속도가 빨라지는 장점이 있음

 

스택 & 스택 프레임

64비트가 함수에서 실제 필요한 크기보다 훨신 크게 스택 확보함

 

 

 

실습

Stack32.exe

 

스택프레임 안씀

서브함수 호출 시 스택 사용해서 파라미터 전달함

PUSH 명령어 써서 스택에 입력한 함수 파라미터들을 정리하지 않음 왜냐면 WIN32 API  호출할때 stdall쓰니까 Callee에서 스택 정리함..

API어디갓지..

 

Stack64.exe

변형된 스택 프레임 사용: 코드 시작에서 48h바이트 크기의 스택 할당하고 리턴 직전에 스택 해제함.

PUSH/POP 명령어 거의 사용 안함

왜???

레지스터를 우선 사용하고, 스택 관리 방식이 개선되었기 때문이다

함수 호출 시 파라미터 1~4개는 레지스터(RCX, RDX, R8, R9)를 사용하고, 5번째 이후의 파라미터는 MOV 명령어를 통해 스택에 직접 저장

서브 함수는 Caller(main 함수)가 할당한 스택을 그대로 사용하기 때문에 스택을 새로 할당하거나 정리할 필요가 없다

 

64비트에서는 1~4번 파라미터는 레지스터에 저장되지만, 동시에 스택에 32바이트 공간이 예약된다. 그래서 5번째 파라미터부터는 [rsp+20h] 이후 위치에 저장된다.(예약된 스택부분은 건너 뛰니까..) 

반응형