기본 콘텐츠로 건너뛰기

리버스엔지니어링바이블 02. C 문법과 디스어셈블링

언어에도 패턴이 있듯이 어셈블리에도 패턴이 있다. 긴 어셈블리라도 패턴을 익히면 쉽게 해석할 수 있다.

컴파일러가 자동으로 생성해내는 코드를 필터링 해야한다. 기본적인 예로 함수의 진입점과 종료점에서 나타나는 코드가 있다.

push ebp
mov ebp, esp
진입시

mov esp, ebp
pop ebp
종료시

진입시 push하는 레지스터는 함수내에서 사용하겠다는 의미이다. 기존의 값을 보관하기 위한 과정이다. 종료시에 void 형태의 함수를 제외하고는 eax에 결과값을 넣는다.

함수의 호출 규약에는 4가지가 있다. 어셈블리를 보고 호출 규약을 판단할 수 있다.
1.__cdecl
함수 외부에서 스택을 보정하는 것이 특징이다. 보정의 크기를 통해 변수의 크기를 확인할 수 있다.

2.__stdcall
함수 내부에서 스택을 보정한다. ret x 형태를 가진다. x 크기만큼 스택을 보정하면서 함수를 빠져나온다. Win32API의 방식이다.

3.__fastcall
인자 전달을 스택을 이용하지 않고 ecx와 edx 레지스터를 사용한다. 레지스터를 사용하기 때문에 빠르다. 2개 이하의 인자를 갖는 빈번히 사용되는 함수에 사용하기 적합하다. 함수호출 이전에 ecx, edx에 값을 넣는 형태이면 __fastcall 이다.

4.__thiscall
C++ 클래스에서 사용되는 방법이다. 현재 객체의 포인터를 ecx에 전달한다. 전달된 ecx를 기준으로 오프셋을 더해 멤버함수나 변수를 사용한다. 스택처리 방법은 __stdcall과 동일하다. 다만 클래스에서 사용된다는 특징이 있다.

if문 패턴
비교후 점프 패턴을 띈다.
예. cmp
     jz

반복문
비교후 점프 패턴에 더해 반복적으로 수행하기 위해 다시 돌아오는 코드 카운터를 증가시키는 코드가 있다.
예. label 1 add ~~~
              cmp
              jg
              jmp label1

구조체와 api
스택의 증감을 통해 할당되는 변수나 구조체의 크기를 확인할 수 있다. 함수 호출 이전의 push 과정을 통해 어떠한 인자를 갖는 함수 있지 유추할 수 있다. 디스어셈블러 프로그램을 이용할 경우 어떤 api인지 알려준다.

댓글

이 블로그의 인기 게시물

맥스 어만(Max Ehrmann) - 소망(진정 바라는 것)

진정 바라는 것                                                                       -맥스 어만 소란스럽고 바쁜 일상속에서도  침묵 안에 평화가 있다는 사실을 기억하십시오 포기하지 말고 가능한한 모든 사람들과 잘 지내도록 하십시오 조용하면서도 분명하게 진실을 말하고  어리석고 무지한 사람들의 말에도 귀를 기울이십시오  그들 역시 할 이야기가 있을테니까요  목소리가 크고 공격적인 사람들은 피하십시오  그들은 영혼을 괴롭힙니다 자신을 다른 사람들과 비교하면 자신이 하찮아 보이고  비참한 마음이 들수도 있습니다  더 위대하거나 더 못한 사람들은 언제나...