cdecl in two ways

Reverse Code Engineering 2009. 11. 16. 18:00 posted by jz-


cdecl calling convention은 c에서 주로 쓰는 calling convention으로, 스택을 통해 인자를 전달하며 caller가 stack을 정리하고, return 값은 eax로 전달을 받는 규약입니다.


가장 기본 형태는 아래와 같죠. (visual studio 등)


인자를 2개 넣고 printf를 호출한 뒤, add esp, 0x8을 하는 것을 볼 수 있습니다.


호출한 쪽에서 인자를 몇개 push 했는지 알기 때문에(2개.) add esp, 8을 해줍니다.


(장점은 printf와 같은 가변인자를 멋지게 처리한다는 것인데
calling convention에 대한 설명은 검색해보면 많이 있습니다. ^^)


그런데 gcc는 cdecl시 흥미롭게 인자를 전달합니다.


mov eax, 0x0은 신경쓰지 마세요.
뒤에 add esp, 0x8가 없다고 확인하기 위해 다음 instr 을 스샷에 포함한 것입니다.



위와 같이 push 대신 esp와 esp+(n*4)에 mov 해버립니다.

즉 인자를 전달할 때 esp가 늘어나지 않습니다. 제자리에서 esp 아래쪽에 write를 하는거죠.

이런 방식으로 전달을 하면 cdecl 함수 호출시 스택을 보정해줄 필요가 없습니다.

오히려 stdcall 함수를 호출하면 스택을 sub해줘야 하는 상황이 발생하는데, stdcall 안쓰니까 상관없겠죠.




끗~~