시스템해킹, 리버싱을 시작하기에 앞서, 어셈을 C로 바꾸고 C를 어셈으로 바꿀 수 있는 능력은 정말 중요하다고 생각합니다.
리버싱이든 시스템이든 우리는 어셈블리어를 무조건 마주치고 분석해야하는 입장이기 때문입니다.
(물론 안드로이드 리버싱을 할 때에는 달빅코드로 되어있어서 어셈블리어와는 약간 다른 개념이지만요.)
문제를 많이 풀어보는 것도 좋은데 전 그전에 C언어로 어떤 코드든 컴파일해서 그걸 디버거로 역분석하여
핸드레이로 다시 복원하는 연습을 하셨으면 좋겠다고 생각합니다. 짧게는 한달, 많게는 두달까지요. 이 기준은 여러분이 적당하다고 느낄때까지 입니다. 복원하는 연습을 꾸준히 하다보면 어셈블리어코드가 자연스레 눈에 들어오는데, 그정도면 성공입니다.
예를 들어서,
간단한 코드가 있는데 gdb로 열어보면
이런식으로 열립니다.
mov DWORD PTR [esp+0x18], 0xa
mov DWORD PTR [esp+0x1c], 0x14
에서 mov a, b는 a = b와 같은 의미로 해석하시면 됩니다.
그렇게되면 [esp + 0x18] = 10, [esp + 0x1c] = 20 이 되는데, 편의상 esp + 0x18은 v1, esp + 0x1c는 v2라고 정의합니다.
int v1 = 10;
int v2 = 20;
그리고나선, mov eax, DWORD PTR [esp + 0x1c] 를 연산하는데, 이것은 eax = v2; 가 될 것이고
*어셈블리어에서 eax, ebx, ecx, edx는 일단 값을 넣었다 뺐다 하는 변수 정도로만 알아두시면 됩니다.
mov DWORD PTR [esp+0x4], eax, 이것은 뒤에 나올 add함수의 두번째 인자로 eax(v2)를 넣겠다는 것을 의미합니다.
add(??, v2);
마찬가지로
mov eax, DWORD PTR [esp + 0x18]
eax = v1;
mov DWORD PTR [esp], eax
add(v1, v2);
이 밑에는 mov DWORD PTR [esp + 0x4], eax가 있는데 보통 함수가 실행되고 나면 그 함수의 리턴값은 eax에 들어갑니다. 그러므로 여기서 말하는 eax는 add함수가 됩니다. 그리고 esp + 0x4는 printf함수의 두번째 인자가 되겠죠?
printf("", add(v1, v2));
mov DWORD PTR [esp], 0x8048500
이것은 0x8048500의 주소에 들어있는 값을 printf의 첫번째 인자에 넣습니다.
x/s 0x8048500 명령어를 이용하여 어떤 값이 들어있는지 확인해보면, %d\n 입니다.
printf("%d\n", add(v1, v2));
이런식으로 handray를 차근차근 진행하는 건데, 이것은 기본적인 핸드레이고 더 나아가 구조체와 포인터, 함수포인터를 이용한 바이너리를 역분석하여 핸드레이를 하는게 좋을 것 같습니다.
핸드레이를 할 시에 알아야 할 기본적인 사항을 몇가지 적어봅니다.
제 기준으로 적은 것이므로 다른 생각이 있으신 분은 저에게 말씀해주세요.
*ebp + 8 이상의 값은 함수의 인자를 나타냅니다.
예를 들어, int main(int argc, char *argv[])는 argc = ebp + 0x8, argv[1] = ebp + 0xc, 이렇게 4바이트씩 증가합니다.
*그리고 ebp - 0x8, esp + 0x8 이상의 값은 지역변수입니다. 숫자가 높을수록 가장 먼저 선언된 변수입니다.
*ds:0xXXXXXXXX, ds가 붙은건 전역변수입니다.
*mov x, y는 간단하게 x = y로 생각하시면 편하고 lea x, [y]는 mov x, y와 같다고 보시면 됩니다. ([]는 포인터와 비슷합니다.)
*인자 앞에 BYTE, WORD, DWORD가 붙은건 각각 1, 2, 4 byte를 의미합니다.
*call x는 x라는 함수로 넘어가겠다는 뜻인데 call 위에 보시면 [esp], [esp + 0x4], [esp + 0x8] ...가 보일 겁니다.
이건 각각 함수의 첫번째, 두번째, 세번째 인자를 뜻합니다.
*함수프롤로그 밑에 sub x가 있다는 것은 x만큼 지역변수나 함수를 선언했다는 의미입니다.
*for문의 전형적인 문장은
인자를 초기화하고 (mov ebp - 0x8, 0x0)
인자를 비교하며 (cmp ebp - 0x8, 0x9)
명령어를 쭉 실행하다가 코드의 끝부분에서 인자에 대한 연산을 수행합니다. (add ebp - 0x8, 0x1)
'Let's Study > Hacking Technique' 카테고리의 다른 글
최신 우분투 환경에서 환경변수를 이용한 쉘코드 테스팅 (0) | 2015.10.07 |
---|---|
Alpha-Numeric Shellcode (Ascii Shellcode) (0) | 2015.01.23 |
stack corruption basic (2) | 2014.10.24 |
Assembly-> C Handray(2) (0) | 2014.10.07 |