Assembly Handle Foundation.
어셈블리 핸드레이 => 어셈블리어를 C언어로 복원시키는 것.
보통 바이너리를 디버거로 실행하면 바이너리에 대한 어셈블리 코드가 나온다.
어셈블리 코드는 경험이 많은 사람이 아니면 파악하기 힘들다.
그래서 보통 IDA를 사용해서 IDA의 강력한 기능 중에 하나인 Hexray 기능을 이용해서 수월하게 진행할 수 있다.
근데 IDA도 완벽하지는 않고, 수작업을 통해 변환된 코드를 수정할 일이 많이 필요하므로,
결국 어셈블리 핸드레이에 익숙해져야 한다.
기본적인 어셈블리 명령어.
Push => 스택에 특정 값을 넣고, esp-4.
Pop => 특정 값에 esp가 가리키는 값을 넣고 esp+4.
nop ==> 아무것도 하지 않는다. 메모리에 빈 공간이 없게 해야 시스템에서 바이너리를 읽을 때 오류가 나지 않는다.
mov a,b ==> b를 a에 복사한다. a=b.
lea a,[b] ==> b의 주소에 있는 값을 a에 복사한다. a=*b.
cmp a,b ==> a와 b를 비교해서 제로 플래그를 세팅해준다.
add a,b ==> a와 b를 더해서 a에 결과를 저장한다. a+=b.
sub a,b ==> a와 b를 빼서 결과를 b에 저장한다. a-=b.
imul a,b ==> a와 b를 곱한 결과를 a에 저장한다. a*=b.
xor a,b ==> a와 b를 xor연산 한 결과를 a에 저장한다.
inc a ==> a값 1증가. a++.
dec a ==> a값 1감소. a--.
je ==> 비교 값이 같을 때(ZF=1)일 때 점프.
jne ==> 비교 값이 다를 때(ZF=0)일 때 점프.
call ==> 해당 프로시저 호출(리턴 값이 스택에 저장됨).
jmp ==> 해당 주소로 점프한다.
위의 명령어 정도는 완벽히 숙지하고 있어야 리버싱을 수월하게 진행할 수 있다.
핸드레이를 하는 과정 자체가 어셈블리 코드를 C언어 등으로 변환하는 작업이기 때문에,
변환 과정에서 코드가 어떤 의미를 하는지에 대한 이해는 필요하다.
Tips.
1-1. ebp와 esp를 통한 값 참조.
컴파일러마다 다르기는 하지만, 일반적으로 스택에서 전달인자 or 변수를 할당할 때
ebp 기준점으로 잡고, 전달인자에 접근하는 경우가 많다.
왜냐하면 ebp는 대게 고정된 위치를 갖기 떄문에, ebp를 통해 ebp 이전에 스택에 들어간 값을 참조하기가 수월하기 때문이다.
반면 esp를 통해서는 지역변수에 접근하는 경우가 많다.
1-2. ebp+8이 첫 번째 전달인자, 따라서 ebp+8보다 큰 값은 함수의 인자를 가리키고 있을 확률이 높다.
1-3. ebp+4는 return address.
2. 값 저장 어셈블리어.
= mov x,y : x=y로 보면 좋다.
= lea x,[y] : mov x,y와 결과가 같다고 보고 해석하면 편하다.
어셈블리어에서 [y]처럼 대괄호가 사용되는 것을 볼 수 있는데,
[]의 의미를 C언어의 포인터처럼 주소가 가리키는 값에 접근하는 방법이라고 보면 좋다.
3.인자의 크기.
= BYTE : 1byte.
= WORD : 2byte.
= DWORD : 4byte.
4.지역변수 할당.
= 지역변수가 얼마나 할당되었는지는 함수 프롤로그 밑의 sub x, esp-x 부분을 보면 된다.
x만큼 지역변수나 함수를 선언했다는 의미이다.
cf)더미값이 포함 되었을 수 있으므로 정확한 크기라고는 말할 수 없다.
5.함수의 호출.
= call x라는 부분은 x라는 함수를 부른다는 의미.
call 부분 바로 위를 보면 PUSH를 통해 esp, esp+4에 접근하는 부분이 보이는데
이 부분은 지역변수로 사용된 변수들을 함수의 전달인자로 넣어주는 부분을 뜻한다.
6.반복문.
for문은 아래와 같은 과정을 통해 진행된다.
6-1 인자 초기화 = mov ebp-0x8,0x0(i=0).
6-2 인자 비교 = cmp dbp-0x8,0x9(i<9).
6-3 반복문의 명령어 실행.
6-4 인자에 대한 연산 수행 => 코드 끝 부분 = add ebp-0x8, 0x1(i++).
7.비교
=strcmp Example.
strcmp의 결과 두 문자열이 일치하면 0을 반환하게 된다.
얻은 값 0값을 토대로 jmp, jne 등의 점프 명령을 수행하기 위해서는 제로 플로그를 세팅해줘야 한다.
이 때 사용하는 명령어 중에는 test라는 명령어가 있다.
test eax, eax를 통해 제로 플래그가 1로 세팅이 되고 나면,
jne 점프문의 경우는 제로플래그가 0일 때 점프하므로,
점프가 실행이 안되고 바로 다음 문장이 실행된다.
'#Tip' 카테고리의 다른 글
Socket Programming Concepts. (0) | 2018.04.09 |
---|---|
GDB simple usage. (0) | 2018.04.09 |
Installing pwntools. (0) | 2018.04.08 |
The Heap: How do use-after-free exploits work? (0) | 2018.04.08 |
About IDA shortcut. (0) | 2018.04.07 |