https://sourceforge.net/p/predef/wiki/Architectures/


gcc에서는 이정도면 될듯하다.

intel계열

#if defined(__i386__)

#if defined(__x86_64__)

arm 계열

32bit

#if defined(__thumb__)

#if defined(__arm__)

64bit

#if defined (__aarch64__)


ida에서 __usercall로 해석되는 함수의 경우는 2~3개 정도의 인자를 불특정 레지스터에 저장하고 사용하기 때문에
C에서 제공하는 calling convention으로 함수를 정의할 수 없었습니다.
(있다면 댓글로 자비좀 베풀어주세요.. )

어쩔 수 없이 naked형태로 후킹 함수를 구현하였습니다.


후킹 대상인 __usercall 함수는 4개의 인자를 사용하고 있습니다.
int __usercall 대상함수(int a1@<edx>, int a2@<esi>, int a3, int a4)
호출 시 레지스터는 유지하고, a3, a4만 push합니다.
호출이 끝나면 push한 만큼 esp를 복원해주고(hook함수 종료 시 mov esp, ebp를 해주니 복원할 필요가 없을듯하나 습관적으로 해주는것이 좋을듯) , 리턴값이 담긴 eax를 백업합니다.
esi와 edx는 __usercall 함수 내부에서 retn전에 pop을 해주기 때문에 따로 백업하지 않아도 됩니다.

이후에 각종 파라미터를 빼내는 함수를 호출하는데, __stdcall로 선언했으므로 따로 스택정리는 하지 않았습니다. 

 pTrampoline는 jmp 다음 명령어를 가리키도록 해주면 됩니다.



다른 컴파일러로 개발할 일 생기면 추가 예정


 

 Visual C

 

GCC 

 

 Bit

32 

64 

32 

64 

 INT 

 4

 LONG

 4

 FLOAT

 4

8

 DOUBLE

 4

8

8

8


멀티 소스로 개발시 LONG형이 문제가 될 수 있다. 특히 long 으로 리턴받는 api사용 시 주의.


8바이트를 쓰고자 한다면, int64_t / __int64_t 로 선언하면 어느 쪽에서도 확실하게 8바이트를 사용할 수 있다.

+ Recent posts