리버싱 엔지니어링을 할 때 반드시 각 함수의 역할을 파악해야합니다.
함수가 어떻게 생겼고 인자가 몇 개인지 등에 대한 정보를 추출해야합니다.
이제부터 내용을 확인할 수 있는 함수 규약을 알아봅시다.
- _cdecl
- _stdcall
- _fastcall
- _thiscall
확인해야 할 점
: 디스어셈블된 코드를 보고 어떤 콜링 컨벤션(calling convection) 에 해당하는지 파악
-> call 문을 보고 함수의 인자가 몇 개이고 어떤 용도로 쓰이는지를 분석하기 위해
1. _cdecl
위 함수를 돌려서 어셈블리 코드를 확인해봅시다.
_cdecl 는 call , 함수 호출 후 add esp,8 과 같이 함수 밖에서 스택을 보정하는 코드가 등장한다면 _cdecl 방식 함수입니다.해당 스택 크기를 통해 함수 파라미터의 개수까지 확인이 가능합니다. 인자는 4바이트씩 계산돼서 스택을 8바이트까지 쓰기 때문에 파라미터가 2개인 함수라는 걸 파악할 수 있습니다.
- 함수를 호출한 곳에서 스택을 보정
- 파라미터 개수 확인
- 리턴값이 숫자
2. _stdcall
보면 함수가 끝나고 난 후에 스택을 정리하는 부분이 없습니다
그리고 함수 안에서 스택을 정리하게 됩니다.
return 파트를 보면 숫자가 들어갑니다. 그리고 파라미터 갯수도 함수 안에서 파악해주어야합니다.
보통 Win32 API 는 _stdcall 을 사용합니다.
3. _fastcall
보면 edx,ecx 를 사용하는 걸 볼 수 있습니다.
그리고 sum 함수를 보면 sub esp. 0E4h 를 통해서 스택을 확보합니다.
_fastcall은 함수의 파라미터가 2개 이하일 경우, 인자를 push 로 넣지 않고 ecx, edx 레지스터를 이용합니다.
메모리를 이용하는 것보단 레지스터를 사용이 훨씬 빠르게 때문입니다.
그러므로 _fastcall을 사용하는 함수는 파라미터가 2개 미만이거나 빈번히 사용되는 함수에 쓰이는 거죠.
리버싱을 할때 함수 호출 전 ecx,edx 에 값을 넣는 게 보이면 이 함수가 _fastcall 규약의 함수라고 판단할 수 있는거죠.
4. _thiscall
c++ 클래스에서 주로 이용되는 방법이다. 특징은 현재 객체의 포인터를 ecx 로 전달한다. c++ 같은 객체 지향 언어는 하나의 클래스로 여러 개의 객체를 만들 수 있는데 서로 다른 메모리 번지에 존재하게 된다. 클래스 문법을 아는 분들은 'this' 를 사용하시는 걸 아실 겁니다. 바로 ecx 로 전달되는 값이 'this' 입니다. ecx + 4 과 같이요.
'해킹 > 리버싱엔지니어링' 카테고리의 다른 글
Base Relocation Table (0) | 2020.05.01 |
---|---|
실행 압축 (0) | 2020.04.28 |
EAT정리 (0) | 2020.04.25 |
IAT 정리 (0) | 2020.04.25 |
OllyDBG 단축키 (0) | 2020.04.18 |