IDA에서 모듈을 분석하다보면 이상한 콜링컨벤션들이 보인다. 특히 객체지향적으로 작성된 프로그램을 분석할 때..
우리가 일반적으로 아는 C 언어 콜링컨벤션은 3개입니다.
__cdecl
__stdcall
__fastcall
이 3개인데 자세한 설명은 아래 블로그에 나와있습니다.
http://blog.naver.com/ljsk139?Redirect=Log&logNo=30143768284
또한 C++에서 사용되는 __thiscall 도 많이 알려져있습니다.
C++ 멤버 함수에서 사용되는 방식이고 이 방식은 변수 인자를 사용하지 않고 레지스터를 사용하는 호출방식이네요.
그 외에도 찾아보니
__cdecl: 씨의 표준호출방식
__pascal: 파스칼 호출방식
__syscall: 이름 그대로 여러가지의 인수를 사용하기 위한 방식
__stdcall: 이름 그대로 표준화한 인수를 사용하는 호출방식
__fastcall: 인수의 전달을 레지스터에 집적한 방식
__watcall: 디폴트로 인수의 전달에 레지스터를 쓰는 방식
__thiscall: 클래스함수에서 인스턴스의 전달만을 레지스터로 최적화한 호출방식
__fortran: 포트란에서 호출가능한 함수의 선언
__interrupt: 호출타입이 인터럽트로써 원거리함수와 유사하지만 스택구조가 다름
__export: 특별히 윈도우즈에 특화된 경우 사용, 16비트인 경우, 엔트리의 진입체킹에 사용
__loadds: 원거리호출에서 프로그램의 데이타를 함수내에서 써야 하는 경우, DGROUP로딩을 자동화
엄청 많네요.. ;;
아무튼 IDA Hex-ray를 사용해 보게되면 다음과 같은 calling convention을 보게됩니다.
__usercall : 스택정리를 caller가 함
__userpurge : 스택정리를 callee가 함
IDA에서 나타내주는 콜링컨벤션인데 두 콜링컨벤션의 차이점은 스택 정리를 caller가 하냐 callee가 하냐의 차이점이 있을 뿐입니다. 두 콜링컨벤션을 사용한 함수 선언 형태는 다음과 같습니다.
int __userpurge sub_100056B0<eax>(int a1<eax>, const void *a2)
첫번째 인자 : eax를 통해 들어옴
두번째 인자 : 스택을 통해 들어옴
리턴 되는 위치 : eax
signed int __usercall sub_10002AA0<eax>(int a1<eax>, int a2<edx>, int a3<ecx>)
첫번째 인자 : eax
두번째 인자 : edx
세번째 인자 : ecx
리턴 되는 위치 : eax
이렇게 중첩도 가능 :D
int **__usercall func16<eax>(int *(__usercall *x)<ebx>(int, long<ecx>, int)<esi>);
함수 포인터 x는 esi 레지스터를 통해 들어옴.
함수 포인터 x의 첫번째 인자 : 스택
함수 포인터 x의 두번째 인자 : ecx
함수 포인터 x의 세번째 인자 : 스택
함수 포인터 x의 리턴 되는 위치 : ebx
func16의 첫번째 인자 : ebx
func16의 리턴 되는 위치 : eax
뭐 이런식입니다.
해석하는데 큰 어려움은 없겠지요.
그래도 너무 Hex-ray만 믿지말고 직접 어셈코드도 분석하면서 판단합니다 ^^
내용이 너무 주저리주저리네요 ㅠㅠ 잘못된 부분있으면 말씀해주세요. 급하게 찾고 올리느라 ㅋㅋ;
'My Study > Reversing' 카테고리의 다른 글
OllyDbg v1.xx Plugin - OllyRename (27) | 2013.03.27 |
---|---|
IceSword ?! 뭐하는 놈? (4) | 2012.11.13 |
바람의나라 가상머신 탐지 우회 (18) | 2012.09.10 |
온라인 알까기 가상머신 탐지 우회 (6) | 2012.09.06 |
VERA ( Reversing tool ) (12) | 2012.07.31 |