물마중
[리버스_0x06] [번외] Kris의 Reverse Engineering 강의 되짚어 보기_1 본문
[리버스_0x06] [번외] Kris의 Reverse Engineering 강의 되짚어 보기_1
zweistar2 2011. 1. 18. 01:10편집자: 엔시스
출 처: 보안인닷컴 팀 블로그[http://boanin.tistory.com]
지난 금요일부터 kris의 Reverse Engineering 강의를 듣고 있습니다.
1. 개요
- 강사: Kris Karspersky
- 일시: 2009년 4월 17, 18, 20, 21일
- 장소: SoftForum 빌딩 지하 1층 세미나실
* 작업환경
- System: Windows 2003
XOR EAX, EAX XOR EBX, EBX DEC EBX MOV EAX, SS MOV SS, EAX MOV BX, SS MOV SS, BX CMP EAX, EBX |
between a segment register and a general-purpose register, the 32-bit IA-32 processors do not require
the use of the 16-bit operand-size prefix (a byte with the value 66H) with this instruction, but most
assemblers will insert it… when the processor executes the instruction with a 32-bit general-purpose
register, it assumes the 16 least-significant bits of the general-purpose register are the destination or
source operand the resulting value in 2 high-order bytes of the register is implementation dependent"
foo() { static FILE *f = 0; if (!f) f = fopen(FILE_NAME, "rw"); … fclose(f); return 0; } |
anti-unpacker trick. guess, we dump an image of the running application. static variable f has been
initialized, so the value goes to the dump. ok, we try to run the dumped image. the variable f isn't zero,
thus "f = fopen(FILE_NAME, "rw");" is skipped and the program operates with the old file pointer,
which has no sense, so we get a crash. to fix the problem we have either dump the program _before_
foo() gets control (it might be almost impossible, if foo() is TLS callback), either kill "if (!f)" (it might
be almost impossible if the program has build-in integrity check mechanism). some fair programs, like
notapad.exe also use this trick to reuse the same variables (like Resource ID gets the actual handler).
#include <stdio.h> #define XXL 1024 foo() main() |
00401000 foo proc near 00401000 var_C = dword ptr -0Ch 00401000 var_8 = dword ptr -8 00401000 arg_0 = dword ptr 8 00401000 arg_4 = dword ptr 0Ch 00401000 push ebp 00401001 mov ebp, esp 00401003 sub esp, 0Ch 00401006 mov eax, [ebp+arg_4] 00401009 mov [ebp+var_8], eax 0040100C mov eax, [ebp+arg_0] 0040100F mov [ebp+var_C], eax 00401012 call bar 00401017 add eax, [ebp+var_8] 0040101A add eax, [ebp+var_C] 0040101D mov esp, ebp 0040101F pop ebp 00401020 retn 00401020 foo endp |
@@ 여기서 잠깐! 그렇다면 cdecl, stdcall은 무엇이며, 어떻게 다른가요?
함수호출 방식에는 크게 3가지로 나뉩니다.
문제에서도 언급되었던 cdecl 및 stdcall 그리고 pascal 입니다.우선, 인수를 스택에 집어넣는 방향에 따라 다음과 같이 나뉩니다.
- pascal : 인수를 스택에 저장하는 순서를 왼쪽에서 오른쪽으로 한다.
- cdecl : 인수를 스택에 저장하는 순서를 오른쪽에서 왼쪽으로 한다.
- stdcall : 인수를 스택에 저장하는 순서를 오른쪽에서 왼쪽으로 한다.그리고 스택에 인수를 pop하는 주체에 따라 다음과 같이 나뉩니다.
- pascal : 호출을 당하는 쪽이 스택공간을 삭제한다.
- stdcall : 호출을 당하는 쪽이 스택공간을 삭제한다.
- cdecl : 호출을 하는 쪽이 스택공간을 삭제한다.
이렇게 stdcall은 pascal방식과 cdecl방식을 혼합한 형태를 띄웁니다.
foo(char *p, int len) { char buf[XXL]; if (len > XXL) return -1; memcpy(buf, p, len); … return 0; } |
풀이 4.
'Reverse Engineering > Reversing 이론 설명' 카테고리의 다른 글
[리버스_0x08] Reverse Engineering 中 알고리즘 확인 및 코딩 (0) | 2011.01.18 |
---|---|
[리버스_0x07] [번외] Kris의 Reverse Engineering 강의 되짚어 보기_2 (0) | 2011.01.18 |
[리버스_0x05] Reverse Engineering을 위한 준비운동 (0) | 2011.01.18 |
[리버스_0x04] 함께 공부하는 Reversing_5 (0) | 2011.01.18 |
[리버스_0x03] 함께 공부하는 Reversing_4 (0) | 2011.01.12 |