목차
추천사 = XXVIII
서문 = XXX
1부 기초 리버싱 = 1
1장 리버싱 스토리 = 3
1.1. 리버싱 엔지니어링 = 3
1.2. 리버싱 코드 엔지니어링 = 3
1.2.1. 리버싱(분석) 방법 = 3
1.2.2. Source Code, Hex Code, Assembly Code = 5
1.2.3. 패치와 크랙 = 8
1.3. 리버싱 준비물 = 8
1.3.1. 목표 = 8
1.3.2. 열정 = 9
1.3.3. 구글 = 9
1.4. 리버싱 방해물 = 10
1.4.1. 과욕 = 10
1.4.2. 조급함 = 10
1.5. 리버싱의 묘미 = 10
2장 Hello World! 리버싱 = 13
2.1. Hello World! 프로그램 = 13
2.1.1. 디버거와 어셈블리 언어 = 14
2.2. HelloWorld.exe 디버깅 = 14
2.2.1. 디버깅 목표 = 14
2.2.2. 디버깅 시작 = 15
2.2.3. EP = 16
2.2.4. 40270C 함수 따라가기 = 17
2.2.5. 40104F 점프문 따라가기 = 19
2.2.6. main( ) 함수 찾기 = 20
2.3. 디버거 좀 더 능숙하게 다루기 = 23
2.3.1. 디버거 명령어 = 23
2.3.2. 베이스 캠프 = 24
2.3.3. 베이스 캠프를 설치하는 4가지 방법 = 24
2.4. 원하는 코드를 빨리 찾아내는 4가지 방법 = 28
2.4.1. 코드 실행 방법 = 28
2.4.2. 문자열 검색 방법 = 30
2.4.3. API 검색 방법 (1) - 호출 코드에 BP = 31
2.4.4. API 검색 방법 (2) - API 코드에 직접 BP = 33
2.5. "Hello World!" 문자열 패치 = 37
2.5.1. 패치 = 37
2.5.2. 문자열을 패치하는 두 가지 방법 = 38
2.6. 마무리 = 44
3장 Little Endian 표기법 = 49
3.1. 바이트 오더링 = 49
3.1.1. 리틀 엔디안&빅 엔디안 = 50
3.1.2. OllyDbg에서 리틀 엔디안 확인 = 51
4장 IA-32 Register 기본 설명 = 53
4.1. CPU 레지스터란? = 53
4.1.1. 레지스터에 대해서 알아야 하는 이유 = 53
4.2. IA-32의 레지스터 = 54
4.2.1. Basic program execution registers = 54
4.3. 마무리 = 62
5장 Stack = 63
5.1. 스택 = 63
5.1.1. 스택의 특징 = 63
5.1.2. 스택 동작 예제 = 64
6장 abex' crackme #1 분석 = 67
6.1. abex' crackme #1 = 67
6.1.1. Start debugging = 68
6.1.2. 코드 분석 = 69
6.2. 크랙 = 71
6.3. 스택에 파라미터를 전달하는 방법 = 72
6.4. 마무리 = 73
7장 Stack Frame = 75
7.1. 스택 프레임 = 75
7.2. 실습 예제 - stackframe.exe = 76
7.2.1. StackFrame.cpp = 76
7.2.2. main( ) 함수 시작&스택 프레임 생성 = 78
7.2.3. 로컬 변수 셋팅 = 80
7.2.4. add( ) 함수 파라미터 입력 및 add( ) 함수 호출 = 82
7.2.5. add( ) 함수 시작&스택 프레임 생성 = 83
7.2.6. add( ) 함수의 로컬 변수(x, y) 셋팅 = 84
7.2.7. ADD 연산 = 85
7.2.8. add( ) 함수의 스택 프레임 해제&함수 종료(리턴) = 86
7.2.9. add( ) 함수 파라미터 제거(스택 정리) = 88
7.2.10. printf( ) 함수 호출 = 89
7.2.11. 리턴 값 셋팅 = 89
7.2.12. 스택 프레임 해제&main( ) 함수 종료 = 90
7.3. OllyDbg 옵션 변경 = 91
7.3.1. Disasm 옵션 = 91
7.3.2. Analysis1 옵션 = 92
7.4. 마무리 = 94
8장 abex' crackme #2 = 95
8.1. abex' crackme #2 실행 = 95
8.2. Visual Basic 파일 특징 = 96
8.2.1. VB 전용 엔진 = 96
8.2.2. N(Native) code, P(Pseudo) code = 97
8.2.3. Event Handler = 97
8.2.4. undocumented 구조체 = 97
8.3. Start debugging = 98
8.3.1. 간접호출 = 98
8.3.2. RT_MainStruct 구조체 = 99
8.3.3. ThunRTMain( ) 함수 = 99
8.4. crackme 분석 = 100
8.4.1. 문자열 검색 = 100
8.4.2. 문자열 주소 찾기 = 102
8.4.3. Serial 생성 알고리즘 = 105
8.4.4. 코드 예측하기 = 106
8.4.5. Name 문자열 읽는 코드 = 107
8.4.6. 암호화 루프 = 108
8.4.7. 암호화 방법 = 108
8.5. 마무리 = 111
9장 Process Explorer - 최고의 작업 관리자 = 115
9.1. Process Explorer = 115
9.2. 구체적으로 뭐가 좋은 거죠? = 116
9.3. sysinternals = 117
10장 Calling Convention = 119
10.1. 함수 호출 규약 = 119
10.1.1. cdecl = 120
10.1.2. stdcall = 121
10.1.3. fastcall = 123
11장 Lena's Reversing for Newbies = 125
11.1. 실행 = 125
11.2. 분석 = 126
11.2.1. 목표 (1) - 메시지 박스 제거! = 126
11.2.2. 패치 (1) - 메시지 박스 제거 = 128
11.2.3. 목표 (2) - Registration Code 찾기 = 132
11.3. 마무리 = 134
12장 도대체 리버싱을 어떻게 공부해야 하나요? = 135
12.1. 리버스 엔지니어링 = 135
12.1.1. 모든 공부에는 '목표'가 있어야 합니다. = 13
12.1.2. '긍정적인 마인드'를 가지세요. = 135
12.1.3. '재미'를 느껴야 합니다. = 136
12.1.4. '검색'을 생활화해야 합니다. = 136
12.1.5. 제일 중요한 건 '실천'입니다. = 137
12.1.6. '느긋한 마음'을 가지세요. = 137
2부 PE File Format = 139
13장 PE File Format = 141
13.1. 소개 = 141
13.2. PE File Format = 141
13.2.1. 기본 구조 = 143
13.2.2. VA&RVA = 145
13.3. PE 헤더 = 145
13.3.1. DOS Header = 145
13.3.2. DOS Stub = 147
13.3.3. NT Header = 149
13.3.4. NT Header - File Header = 149
13.3.5. NT Header - Optional Header = 153
13.3.6. 섹션 헤더 = 159
13.4. RVA to RAW = 163
13.5. IAT = 166
13.5.1. DLL = 166
13.5.2. IMAGE_IMPORT_DESCRIPTOR = 169
13.5.3. notepad.exe를 이용한 실습 = 171
13.6. EAT = 177
13.6.1. IMAGE_EXPORT_DIRECTORY = 178
13.6.2. kernel32.dll을 이용한 실습 = 180
13.7. Advanced PE = 184
13.7.1. PEView.exe = 184
13.7.2. Patched PE = 186
13.8. 마무리 = 187
14장 실행 압축 = 193
14.1. 데이터 압축 = 193
14.1.1. 비손실 압축 = 194
14.1.2. 손실 압축 = 194
14.2. 실행 압축 = 194
14.2.1. 패커 = 195
14.2.2. 프로텍터 = 197
14.3. 실행 압축 테스트 = 198
14.3.1. notepad.exe와 notepadupx.exe 파일 비교 = 200
15장 UPX 실행 압축된 notepad 디버깅 = 203
15.1. notepad.exe의 EP Code = 203
15.2. notepad_upx.exe의 EP Code = 204
15.3. UPX 파일 트레이싱 = 205
15.3.1. OllyDbg의 트레이스 명령어 = 206
15.3.2. 루프 #1 = 206
15.3.3. 루프 #2 = 207
15.3.4. 루프 #3 = 209
15.3.5. 루프 #4 = 210
15.4. UPX의 OEP를 빨리 찾는 방법 = 211
15.4.1. POPAD 명령어 이후의 JMP 명령어에 BP 설치 = 212
15.4.2. 스택에 하드웨어 브레이크 포인트(Hardware Break Point) 설치 = 212
15.5. 마무리 = 213
16장 Base Relocation Table = 215
16.1. PE 재배치 = 215
16.1.1. DLL/SYS = 215
16.1.2. EXE = 216
16.2. PE 재배치 발생시 수행되는 작업 = 217
16.3. PE 재배치 동작 원리 = 219
16.3.1. Base Relocation Table = 220
16.3.2. IMAGE_BASE_RELOCATION 구조체 = 221
16.3.3. Base Relocation Table의 해석 방법 = 222
16.3.4. 실습 = 224
17장 실행 파일에서 .reloc 섹션 제거하기 = 227
17.1. .reloc 섹션 = 227
17.2. reloc.exe = 227
17.2.1. .reloc 섹션 헤더 정리 = 228
17.2.2. .reloc 섹션 제거 = 228
17.2.3. IMAGE_FILE_HEADER 수정 = 229
17.2.4. IMAGE_OPTIONAL_HEADER 수정 = 230
17.3. 마무리 = 231
18장 UPack PE 헤더 상세 분석 = 233
18.1. UPack 설명 = 233
18.2. UPack으로 notepad.exe 실행 압축하기 = 234
18.3. Stud_PE 이용 = 236
18.4. PE 헤더 비교 = 237
18.4.1. notepad.exe(원본)의 PE 헤더 = 237
18.4.2. notepad_upack.exe(실행 압축)의 PE 헤더 = 238
18.5. UPack의 PE 헤더 분석 = 239
18.5.1. 헤더 겹쳐쓰기 = 239
18.5.2. IMAGE_FILE_HEADER.SizeOfOptionalHeader = 240
18.5.3. IMAGE_OPTIONAL_HEADER.NumberOfRvaAndSizes = 242
18.5.4. IMAGE_SECTION_HEADER = 245
18.5.5. 섹션 겹쳐쓰기 = 247
18.5.6. RVA to RAW = 249
18.5.7. Import Table(IMAGE_IMPORT_DESCRIPTOR array) = 251
18.5.8. IAT(Import Address Table) = 255
18.6. 마무리 = 257
19장 UPack 디버깅 - OEP 찾기 = 259
19.1. OllyDbg 실행 에러 = 259
19.2. 디코딩 루프 = 261
19.3. IAT 셋팅 = 264
19.4. 마무리 = 265
20장 인라인 패치 실습 = 267
20.1. 인라인 패치 = 267
20.2. 실습 - Patchme = 268
20.3. 디버깅 - 코드 흐름 살펴보기 = 269
20.4. 코드 구조 = 275
20.5. 인라인 패치 실습 = 276
20.5.1. 패치 코드를 어디에 설치할까? = 277
20.5.2. 패치 코드 만들기 = 279
20.5.3. 패치 코드 실행하기 = 281
20.5.4. 결과 확인 = 282
3부 DLL 인젝션 = 285
21장 Windows 메시지 후킹 = 287
21.1. 훅 = 287
21.2. 메시지 훅 = 288
21.3. SetWindowsHookEx( ) = 289
21.4. 키보드 메시지 후킹 실습 = 290
21.4.1. 실습 예제 HookMain.exe = 291
21.4.2. 소스코드 분석 = 294
21.5. 디버깅 실습 = 298
21.5.1. HookMain.exe 디버깅 = 298
21.5.2. Notepad.exe 프로세스내의 KeyHook.dll 디버깅 = 302
21.6. 마무리 = 305
22장 악의적인 목적으로 사용되는 키로거 = 307
22.1. 악성 키로거의 목표 = 307
22.1.1. 온라인 게임 = 307
22.1.2. 인터넷 뱅킹 = 307
22.1.3. 기업 정보 유출 = 308
22.2. 키로거의 종류와 향후 발전 방향 = 308
22.3. 키로거에 대처하는 우리의 자세 = 309
22.4. 개인정보 = 310
23장 DLL Injection = 311
23.1. DLL 인젝션 = 311
23.2. DLL 인젝션 활용 예 = 312
23.2.1. 기능 개선 및 버그 패치 = 313
23.2.2. 메시지 후킹 = 313
23.2.3. API 후킹 = 313
23.2.4. 기타 응용 프로그램 = 313
23.2.5. 악성 코드 = 314
23.3. DLL 인젝션 구현 방법 = 314
23.4. CreateRemoteThread( ) = 315
23.4.1. 실습 예제 myhack.dll = 315
23.4.2. 예제 소스코드 분석 = 320
23.4.3. 디버깅 방법 = 328
23.5. AppInit_DLLs = 331
23.5.1. 예제 소스코드 분석 = 332
23.5.2. 실습 예제 myhack2.dll = 333
23.6. SetWindowsHookEx( ) = 336
23.7. 마무리 = 336
24장 DLL 이젝션 = 339
24.1. DLL 이젝션 동작 원리 = 339
24.2. DLL 이젝션 구현 = 340
24.2.1. 프로세스에 로딩된 DLL 정보 구하기 = 343
24.2.2. 대상 프로세스 핸들 구하기 = 344
24.2.3. FreeLibrary( ) API 주소 구하기 = 344
24.2.4. 대상 프로세스에 스레드를 실행시킴 = 345
24.3. DLL 이젝션 간단 실습 = 345
24.3.1. 파일 복사 및 notepad.exe 실행 = 346
24.3.2. 인젝션 = 347
24.3.3. 이젝션 = 348
25장 PE Patch를 이용한 DLL 로딩 = 349
25.1. 실습 파일 = 349
25.1.1. TextView.exe = 349
25.1.2. TextView_patched.exe = 351
25.2. 소스코드 - myhack3.cpp = 353
25.2.1. DllMain( ) = 353
25.2.2. DownloadURL( ) = 354
25.2.3. DropFile( ) = 356
25.2.4. dummy( ) = 357
25.3. TextView.exe 파일 패치 준비 작업 = 358
25.3.1. 패치 아이디어 = 358
25.3.2. 패치 사전 조사 = 358
25.3.3. IDT 이동 = 361
25.4. TextView.exe 패치 작업 = 364
25.4.1. IMPORT Table의 RVA 값 변경 = 364
25.4.2. BOUND IMPORT TABLE 제거 = 365
25.4.3. 새로운 IDT 생성 = 365
25.4.4. Name, INT, IAT 셋팅 = 367
25.4.5. IAT 섹션의 Characteristics 변경 = 369
25.5. 검증(Test) = 371
25.6. 마무리 = 373
26장 PE Tools = 375
26.1. PE Tools = 375
26.1.1. 프로세스 메모리 덤프 = 377
26.1.2. PE Editor = 379
26.2. 마무리 = 380
쉬어가기 - 리버싱의 참맛 = 380
27장 Code Injection = 383
27.1. Code 인젝션 = 383
27.2. DLL 인젝션 vs Code 인젝션 = 384
27.2.1. 코드 인젝션을 사용하는 이유 = 385
27.3. 실습 예제 = 386
27.3.1. notepad.exe 실행 = 386
27.3.2. CodeInjection.exe 실행 = 387
27.3.3. 메시지 박스 확인 = 388
27.4. CodeInjection.cpp = 388
27.4.1. main( ) = 388
27.4.2. ThreadProc( ) = 389
27.4.3. InjectCode( ) = 393
27.5. Code 인젝션 디버깅 실습 = 396
27.5.1. notepad.exe 디버깅 = 396
27.5.2. OllyDbg 옵션 변경 = 396
27.5.3. CodeInjection.exe 실행 = 397
27.5.4. 스레드 시작 코드 = 398
27.6. 마무리 = 399
28장 어셈블리 언어를 이용한 Code Injection = 401
28.1. 목표 = 401
28.2. 어셈블리 프로그래밍 = 401
28.3. OllyDbg의 Assemble 명령 = 402
28.3.1. ThreadProc( ) 작성 = 404
28.3.2. Save File = 409
28.4. 인젝터 제작 = 410
28.4.1. ThreadProc( ) 함수의 바이너리 코드 얻기 = 410
28.4.2. CodeInjection2.cpp = 412
28.5. 디버깅 실습 = 415
28.5.1. notepad.exe 디버깅 = 415
28.5.2. OllyDbg 옵션 변경 = 415
28.5.3. CodeInjection2.exe 실행 = 416
28.5.4. 스레드 시작 코드 = 417
28.6. 상세 분석 = 418
28.6.1. 스택 프레임 = 418
28.6.2. THREAD_PARAM 구조체 포인터 = 418
28.6.3. "user32.dll" 문자열 = 420
28.6.4. "user32.dll" 문자열 파라미터 입력 = 421
28.6.5. LoadLibraryA("user32.dll") 호출 = 422
28.6.6. "MessageBoxA" 문자열 = 423
28.6.7. GetProcAddress(hMod, "MessageBoxA") 호출 = 424
28.6.8. MessageBoxA( ) 파라미터 입력 1 - MB_OK = 425
28.6.9. MessageBoxA( ) 파라미터 입력 2 - "ReverseCore" = 425
28.6.10. MessageBoxA( ) 파라미터 입력 3 - "www.reversecore.com" = 426
28.6.11. MessageBoxA( ) 파라미터 입력 4 - NULL = 427
28.6.12. MessageBoxA 호출 = 428
28.6.13. ThreadProc( ) 리턴 값 셋팅 = 428
28.6.14. 스택 프레임 해제 및 함수 리턴 = 429
28.7. 마무리 = 429
4부 API 후킹 = 431
29장 API Hooking: 리버싱의 '꽃' = 433
29.1. 후킹 = 433
29.2. API란? = 434
29.3. API 후킹 = 435
29.3.1. 정상 API 호출 = 436
29.3.2. 후킹 API 호출 = 436
29.4. 테크 맵 = 437
29.4.1. Method Object(what) = 438
29.4.2. Location(where) = 438
29.4.3. Technique(How) = 439
29.5. API = 441
30장 메모장 WriteFile( ) 후킹 = 443
30.1. 테크 맵 - 디버그 테크닉 = 443
30.2. 디버거 설명 = 444
30.2.1. 용어 = 444
30.2.2. 디버거 기능 = 444
30.2.3. 디버거 동작 원리 = 444
30.2.4. 디버그 이벤트 = 445
30.3. 작업 순서 = 447
30.4. 실습 = 447
30.5. 동작 원리 = 451
30.5.1. 스택 = 451
30.5.2. 실행 흐름 = 453
30.5.3. 언훅&훅 = 453
30.6. 소스코드 설명 = 454
30.6.1. main( ) = 454
30.6.2. DebugLoop( ) = 455
30.6.3. EXIT_PROCESS_DEBUG_EVENT = 458
30.6.4. CREATE_PROCESS_DEBUG_EVENT - OnCreateProcessDebug Event( ) = 458
30.6.5. EXCEPTION_DEBUG_EVENT - OnExceptionDebugEvent( ) = 460
31장 디버거 이야기 = 469
31.1. OllyDbg = 469
31.2. IDA Pro = 470
31.3. WinDbg = 471
32장 계산기, 한글을 배우다 = 475
32.1. 테크 맵 = 475
32.2. 대상 API 선정 = 476
32.3. IAT 후킹 동작 원리 = 481
32.4. 실습 = 484
32.5. 소스코드 분석 = 486
32.5.1. DllMain( ) = 487
32.5.2. MySetWindowTextW( ) = 4788
32.5.3. hook_iat ( ) = 491
32.6. 인젝션된 DLL의 디버깅 = 496
32.6.1. DllMain( ) = 499
32.6.2. hook_iat ( ) = 500
32.6.3. MySetWindowTextW( ) = 503
32.7. 마무리 = 504
33장 '스텔스' 프로세스 = 507
33.1. 테크 맵 = 507
33.2. API 코드 패치 동작 원리 = 508
33.2.1. 후킹 전 = 508
33.2.2. 후킹 후 = 510
33.3. 프로세스 은폐 = 512
33.3.1. 프로세스 은폐 동작 원리 = 512
33.3.2. 관련 API = 512
33.3.3. 은폐 기법의 문제점 = 513
33.4. 실습 #1(HideProc.exe, stealth.dll) = 515
33.4.1. notepad.exe, procexp.exe, taskmgr.exe 실행 = 515
33.4.2. HideProc.exe 실행 = 515
33.4.3. stealth.dll 인젝션 확인 = 516
33.4.4. notepad.exe 프로세스 은폐 확인 = 516
33.4.5. notepad.exe 프로세스 은폐 해제 = 518
33.5. 소스코드 분석 = 518
33.5.1. HookProc.cpp = 519
33.5.2. stealth.cpp = 520
33.6. 글로벌 API 후킹 = 530
33.6.1. Kernel32.CreateProcess( ) API = 530
33.6.2. Ntdll.ZwResumeThread( ) API = 532
33.7. 실습 #2(HideProc2.exe, stealth2.dll) = 532
33.7.1. stealth2.dll 파일을 %SYSTEM% 폴더에 복사 = 533
33.7.2. HideProc2.exe -hide 실행 = 533
33.7.3. ProcExp.exe&notepad.exe 실행 = 534
33.7.4. HideProc2.exe -show 실행 = 535
33.8. 소스코드 분석 = 535
33.8.1. HideProc2.cpp = 535
33.8.2. stealth2.cpp = 535
33.9. 핫 패치 방식의 API 후킹 = 538
33.9.1. 기존 API 코드 패치 방법의 문제점 = 538
33.9.2. 핫 패치(7바이트 코드 패치) = 539
33.10. 실습 #3 - stealth3.dll = 543
33.11. 소스코드 분석 = 543
33.11.1. Stealth3.cpp = 543
33.12. 핫 패치 방식의 API 후킹에서 고려사항 = 547
33.13. 마무리 = 548
34장 고급 글로벌 API 후킹 - IE 접속 제어 = 551
34.1. 후킹 대상 API = 551
34.1.1. 검증 - IE 프로세스 디버깅 = 553
34.2. IE 프로세스 구조 = 555
34.3. 글로벌 API 후킹 개념 정리 = 557
34.3.1. 일반적인 API 후킹 = 557
34.3.2. 글로벌 API 후킹 = 558
34.4. ntdll!ZwResumeThread( ) API = 559
34.5. 실습 예제 - IE 접속 제어 = 565
34.5.1. IE 실행 = 566
34.5.2. DLL 인젝션 = 566
34.5.3. 새로운 탭 생성 = 567
34.5.4. 포털 사이트 접속 = 568
34.5.5. DLL 이젝션 = 569
34.5.6. 추가 실습 = 570
34.6. 예제 소스코드 = 571
34.6.1. DllMain( ) = 571
34.6.2. NewInternetConnectW( ) = 572
34.6.3. NewZwResumeThread( ) = 574
34.7. 마무리 = 576
35장 좋은 분석 도구를 선택하는 5가지 기준 = 577
35.1. 도구 = 577
35.2. 리버스 코드 엔지니어 = 577
35.3. 좋은 분석 도구 선택의 5가지 기준 = 578
35.3.1. 도구 개수를 최소화한다 = 578
35.3.2. 도구는 기능이 단순하고 사용방법이 편리한 것이 좋다 = 578
35.3.3. 기능을 철저히 익힌다 = 579
35.3.4. 꾸준히 업데이트한다 = 579
35.3.5. 도구의 핵심 동작 원리를 이해한다 = 579
35.4. 숙련도의 중요성 = 579
5부 64비트&Windows Kernel 6 = 581
36장 64bit Computing = 583
36.1. 64비트 컴퓨팅 환경 = 583
36.1.1. 64비트 CPU = 583
36.1.2. 64비트 OS = 584
36.1.3. Win32 API = 585
36.1.4. WOW64 = 586
36.1.5. 실습 - WOW64Test = 590
36.2. 64비트 빌드 = 591
36.2.1. Microsoft Windows SDK(Software Development Kit) = 592
36.2.2. Visual C++2010 Express 환경 설정 = 592
37장 x64 프로세서 이야기 = 595
37.1. x64에서 추가/변경된 사항 = 595
37.1.1. 64비트 = 595
37.1.2. 메모리 = 595
37.1.3. 범용 레지스터 = 596
37.1.4. CALL/JMP Instruction = 597
37.1.5. 함수 호출 규약 = 598
37.1.6. 스택&스택 프레임 = 599
37.2. 실습 - Stack64.exe&Stack32.exe = 600
37.2.1. Stack32.exe = 601
37.2.2. Stack64.exe = 603
37.2. 마무리 = 607
38장 PE32+ = 609
38.1. PE32+(PE+, PE64) = 609
38.1.1. IMAGE_NT_HEADERS = 609
38.1.2. IMAGE_FILE_HEADER = 610
38.1.3. IMAGE_OPTIONAL_HEADER = 611
38.1.4. IMAGE_THUNK_DATA = 614
38.1.5. IMAGE_TLS_DIRECTORY = 616
39장 WinDbg = 619
39.1. WinDbg = 619
39.1.1. WinDbg 특징 = 620
39.1.2. WinDbg 실행 = 620
39.1.3. 커널 디버깅 = 622
39.1.4. WinDbg 기본 명령어 = 625
40장 64비트 디버깅 = 627
40.1. x64 환경에서의 디버거 선택 = 627
40.2. 64비트 디버깅 = 628
40.2.1. 실습 예제 - WOW64Test = 628
40.3. PE32 : WOW64Test_x86.exe = 630
40.3.1. EP 코드 = 630
40.3.2. Startup 코드 = 631
40.3.3. main( ) 함수 = 632
40.4. PE32+: WOW64Test_x64.exe = 634
40.4.1. System Breakpoint = 634
40.4.2. EP 코드 = 635
40.4.3. Startup 코드 = 636
40.4.4. main( ) 함수 = 639
40.5. 마무리 = 643
41장 ASLR = 645
41.1. Windows Kernel Version = 645
41.2. ASLR = 645
41.3. Visual C++ = 646
41.4. ASLR.exe = 647
41.4.1. 섹션 정보 = 649
41.4.2. IMAGE_FILE_HEADER\Characteristics = 650
41.4.3. IMAGE_OPTIONAL_HEADER \DLL Characteristics = 650
41.5. 실습 - ASLR 기능 제거 = 651
41.5.1. ASLR 기능 제거 = 651
42장 Session in Kernel 6 = 653
42.1. 세션 = 653
42.2. Session 0 Isolation = 656
42.3. 보안 강화 = 656
43장 DLL Injection in Kernel 6 = 659
43.1. DLL 인젝션 실패 재현 = 659
43.1.1. 소스코드 = 660
43.1.2. 인젝션 테스트 = 662
43.2. 원인 분석 = 663
43.2.1. 디버깅 #1 = 663
43.2.2. 디버깅 #2 = 666
43.3. 실습 - CreateRemoteThread( ) 성공시키는 방법 = 669
43.3.1. 방법 #1 - CreateSuspended 파라미터 변경 = 670
43.3.2. 방법 #2 - 조건 분기 조작 = 671
43.4. 간단 정리 = 673
43.5. InjectDll_new.exe = 674
43.5.1. InjectDll_new.cpp = 674
43.5.2. 인젝션 실습 = 677
44장 InjDll.exe - DLL 인젝션 전용 도구 = 679
44.1. InjDll.exe = 679
44.1.1. 사용방법 = 679
44.1.2. 사용 예 = 680
44.1.3. 주의사항 = 681
6부 고급 리버싱 = 683
45장 TLS 콜백 함수 = 685
45.1. 실습 #1 - HelloTls.exe = 685
45.2. TLS = 686
45.2.1. IMAGE_DATA_DIRECTORY[9] = 687
45.2.2. IMAGE_TLS_DIRECTORY = 687
45.2.3. 콜백 함수 주소 배열 = 689
45.3. TLS 콜백 함수 = 689
45.3.1. IMAGE_TLS_CALLBACK = 689
45.4. 실습 #2 - TlsTest.exe = 690
45.4.1. DLL_PROCESS_ATTACH = 692
45.4.2. DLL_THREAD_ATTACH = 692
45.4.3. DLL_THREAD_DETACH = 693
45.4.4. DLL_PROCESS_DETACH = 693
45.5. TLS 콜백 디버깅 = 693
45.6. 수작업으로 TLS 콜백 함수 추가하기 = 695
45.6.1. 실습 재료 = 696
45.6.2. 설계 = 696
45.6.3. PE 헤더 편집 = 698
45.6.4. IMAGE_TLS_DIRECTORY 구성 = 700
45.6.5. TLS 콜백 함수 프로그래밍 = 701
45.6.6. 최종 완성 = 702
45.7. 마무리 = 703
46장 TEB = 705
46.1. TEB = 705
46.1.1. TEB 구조체 정의 = 705
46.1.2. TEB 구조체 내용 = 706
46.1.3. 중요 멤버 = 709
46.2. TEB 접근 방법 = 711
46.2.1. Ntdll.NtCurrentTeb( ) = 711
46.2.2. FS 세그먼트 레지스터 = 712
46.3. 마무리 = 714
47장 PEB = 717
47.1. PEB = 717
47.1.1. PEB 접근 방법 = 717
47.1.2. PEB 구조체 정의 = 719
47.1.3. PEB 구조체 내용 = 720
47.2. PEB 중요 멤버 설명 = 723
47.2.1. PEB.BeingDebugged = 723
47.2.2. PEB.ImageBaseAddress = 725
47.2.3. PEB.Ldr = 725
47.2.4. PEB.ProcessHeap&PEB.NtGlobalFlag = 727
47.3. 마무리 = 727
48장 SEH = 729
48.1. SEH = 729
48.1.1. 기본 설명 = 729
48.2. SEH 예제 실습 #1 = 729
48.2.1. 일반 실행 = 730
48.2.2. 디버거에서 실행 = 730
48.3. OS의 예외 처리 방법 = 734
48.3.1. 일반 실행의 경우 예외 처리 방법 = 734
48.3.2. 디버깅 실행의 경우 예외 처리 방법 = 734
48.4. 예외 = 736
48.4.1. EXCEPTION_ACCESS_VIOLATION(C0000005) = 736
48.4.2. EXCEPTION_BREAKPOINT(80000003) = 737
48.4.3. EXCEPTION_ILLEGAL_INSTRUCTION(C000001D) = 739
48.4.4. EXCEPTION_INT_DIVIDE_BY_ZERO(C0000094) = 740
48.4.5. EXCEPTION_SINGLE_STEP(80000004) = 741
48.5. SEH 상세 설명 = 741
48.5.1. SEH 체인 = 741
48.5.2. 함수 정의 = 742
48.5.3. TEB.NtTib.ExceptionList = 745
48.5.4. SEH 설치 방법 = 746
48.6. SEH 예제 실습 #2(seh.exe) = 746
48.6.1. SEH 체인 확인 = 747
48.6.2. SEH 추가 = 748
48.6.3. 예외 발생 = 749
48.6.4. 예외 처리기 파라미터 확인 = 750
48.6.5. 예외 처리기 디버깅 = 752
48.6.6. SEH 제거 = 756
48.7. OllyDbg 옵션 설정 = 756
48.7.1. KERNEL32 예외 무시 = 757
48.7.2. 예외를 디버기에게 전달 = 758
48.7.3. 기타 예외 처리 = 758
48.7.4. 간단 실습 = 759
48.8. 마무리 = 760
49장 IA-32 Instruction = 761
49.1. IA-32 Instruction = 761
49.2. 용어 정리 = 762
49.2.1. Disassembler = 763
49.2.2. Decompiler = 764
49.2.3. Decompile 간단 소개 = 764
49.3. IA-32 Instruction 포맷 = 767
49.3.1. Instruction Prefixes = 768
49.3.2. Opcode = 768
49.3.3. ModR/M = 769
49.3.4. SIB = 770
49.3.5. Displacement = 770
49.3.6. Immediate = 771
49.4. Instruction 해석 매뉴얼 = 771
49.4.1. IA-32 Manuals 다운로드 = 771
49.4.2. Instruction 해석 메뉴얼 출력 = 772
49.5. Instruction 해석 실습 = 773
49.5.1. Opcode Map = 773
49.5.2. Operand = 774
49.5.3. ModR/M = 776
49.5.4. Group = 779
49.5.5. Prefix = 782
49.5.6. 2바이트 Opcode = 785
49.5.7. Displacement&Immediate = 786
49.5.8. SIB = 789
49.6. Instruction 해석 추가 연습 = 794
49.7. 마무리 = 795
7부 안티 디버깅 = 797
50장 Anti-Debugging = 799
50.1. 안티 디버깅 기법 = 799
50.1.1. 의존성 = 799
50.1.2. 다양한 기법 = 800
50.2. 안티 안티 디버깅 기법 = 800
50.3. 안티 디버깅 분류 = 800
50.3.1. Static 안티 디버깅 = 802
50.3.2. Dynamic 안티 디버깅 = 802
51장 Static 안티 디버깅 = 805
51.1. Static 안티 디버깅의 목적 = 805
51.2. PEB = 805
51.2.1. BeingDebugged(+0x2) = 808
51.2.2. Ldr(+0xC) = 809
51.2.3. Process Heap(+0x18) = 810
51.2.4. NtGlobalFlag(+0x68) = 811
51.2.5. 실습 - StaAD_PEB.exe = 812
51.2.6. 회피 방법 = 813
51.3. NtQueryInformationProcess( ) = 817
51.3.1. ProcessDebugPort(0x7) = 818
51.3.2. ProcessDebugObjectHandle(0x1E) = 819
51.3.3. ProcessDebugFlags(0x1F) = 820
51.3.4. 실습 - StaAD_NtQIP.exe = 820
51.3.5. 회피 방법 = 821
51.4. NtQuerySystemInformation( ) = 824
51.4.1. SystemKernelDebuggerInformation(0x23) = 826
51.4.2. 실습 - StaAD_NtQSI.exe = 828
51.4.3. 회피 방법 = 828
51.5. NtQueryObject( ) = 828
51.5.1. 실습 - StaAD_NtQO.exe = 832
51.6. ZwSetInformationThread( ) = 833
51.6.1. 실습 - StaAD_ZwSIT.exe = 834
51.6.2. 회피 방법 = 835
51.7. TLS 콜백 함수 = 836
51.8. ETC = 836
51.8.1. 실습 - StaAD_FindWindow.exe = 837
51.8.2. 회피 방법 = 837
51.9. 마무리 = 839
52장 Dynamic 안티 디버깅 = 841
52.1. Dynamic 안티 디버깅의 목적 = 841
52.2. 예외 = 841
52.2.1. SEH = 842
52.2.2. SetUnhandledExceptionFilter( ) = 848
52.3. Timing Check = 853
52.3.1. 시간 간격 측정 방법 = 854
52.3.2. RDTSC = 854
52.4. Trap Flag = 858
52.4.1. Single Step = 859
52.4.2. INT 2D = 863
52.5. 0xCC Detection = 868
52.5.1. API Break Point = 869
52.5.2. Checksum 비교 = 871
53장 고급 안티 디버깅 = 875
53.1. 고급 안티 디버깅 기법 = 875
53.2. 가비지 코드 = 876
53.3. Breaking Code Alignment = 877
53.4. Encryption/Decryption = 881
53.4.1. 간단한 디코딩 코드의 경우 = 881
53.4.2. 복잡한 디코딩 코드의 경우 = 882
53.4.3. 특수한 경우 - 코드 재조합 = 884
53.5. Stolen Bytes(Remove OEP) = 886
53.6. API 리다이렉션 = 889
53.6.1. 원본 코드 = 890
53.6.2. API Redirection 예제 #1 = 891
53.6.3. API Redirection 예제 #2 = 893
53.7. Debug Blocker(Self Debugging) = 898
53.8. 마무리 = 902
8부 디버깅 실습 = 903
54장 디버깅 실습 1 - 서비스 = 905
54.1. 서비스 프로세스 동작 원리 = 905
54.1.1. 서비스 제어기 = 906
54.1.2. 서비스 시작과정의 이해 = 907
54.2. DebugMe1.exe 예제 설명 = 909
54.2.1. 서비스 설치 = 909
54.2.2. 서비스 시작 = 911
54.2.3. 소스코드 = 913
54.3. 서비스 프로세스의 디버깅 이슈 = 916
54.3.1. 문제는 SCM = 916
54.3.2. 디버거로 안 되는 것은 없다 = 917
54.3.3. 정석대로 해보자 = 917
54.4. 서비스 디버깅 실습 = 917
54.4.1. 그냥 디버깅 - EIP 강제 셋팅 = 918
54.4.2. 서비스 디버깅의 정석 - Attach 방식 = 922
54.5. 마무리 = 929
55장 디버깅 실습 2 - Self Creation = 931
55.1. Self-Creation = 931
55.2. 동작 원리 = 933
55.2.1. Create Child Process(SUSPEND mode) = 933
55.2.2. Change EIP = 934
55.2.3. Resume Main Thread = 934
55.3. 예제 소스코드 설명 = 934
55.4. 디버깅 실습 = 937
55.4.1. 고려 사항 = 937
55.4.2. JIT 디버깅 = 939
55.4.3. DebugMe2.exe = 940
55.5. 마무리 = 945
56장 디버깅 실습 3 - PE Image Switching = 947
56.1. PE Image = 947
56.2. PE Image Switching = 949
56.3. 예제 파일 - Fake.exe, Real.exe, DebugMe3.exe = 949
56.4. 디버깅 1 = 952
56.4.1. Open - 실행 파라미터 입력 = 952
56.4.2. main( ) = 954
56.4.3. SubFunc_1( ) = 956
56.4.4. CreateProcess("fake.exe", CREATE_SUSPENDED) = 957
56.4.5. SubFunc_2( ) = 958
56.4.6. SubFunc_3( ) = 966
56.4.7. ResumeThread( ) = 971
56.5. 디버깅 2 = 972
56.5.1. 아이디어 = 973
56.5.2. EP에 무한루프 설치하기 = 973
56.6. 마무리 = 976
57장 디버깅 실습 4 - Debug Blocker = 977
57.1. Debug Blocker = 977
57.2. 안티 디버깅 특성 = 978
57.2.1. 부모 - 자식 관계 = 978
57.2.2. 디버기 프로세스는 다른 디버거(예: OllyDbg)에서 디버깅을 할 수 없습니다 = 978
57.2.3. 디버거 프로세스를 종료하면 동시에 디버기 프로세스도 종료됩니다 = 979
57.2.4. 디버거에서 디버기의 코드를 조작합니다 = 979
57.2.5. 디버기의 예외(Exception)를 디버거에서 처리합니다 = 979
57.3. 디버깅 실습 - DebugMe4.exe = 980
57.4. 1차 시도 = 980
57.4.1. 디버깅 시작 위치 선정 = 980
57.4.2. main( ) = 981
57.5. 2차 시도 = 983
57.6. 3차 시도 = 985
57.7. 4차 시도 = 990
57.8. 5차 시도 = 993
57.8.1. System Break Point = 993
57.8.2. EXCEPTION_ILLEGAL_INSTRUCTION (1) = 995
57.8.3. EXCEPTION_ILLEGAL_INSTRUCTION (2) = 997
57.9. 6차 시도 = 998
57.9.1. 40121D(첫 번째 예외) = 998
57.9.2. 401299(두 번째 예외) = 1004
57.10. 7차 시도 = 1007
57.10.1. Static 방법 = 1007
57.10.2. Dynamic 방법 = 1009
57.11. 마무리 = 1016
책을 마치며 = 1017
1. 창의성과 경험(바둑과 장기 - 프로그래밍과 리버싱) = 1017
바둑과 장기 = 1017
프로그래밍과 리버싱 = 1019
2. 독자님들께… = 1020
찾아보기 = 1021