关于我们
![]() ![]() |
逆向工程核心原理 ![]()
《逆向工程核心原理》十分详尽地介绍了代码逆向分析的核心原理。作者在Ahnlab 研究所工作多年,书中不仅包括其以此经验为基础亲自编写的大量代码,还包含了逆向工程研究人员必须了解的各种技术和技巧。彻底理解并切实掌握逆向工程这门技术,就 能在众多IT相关领域进行拓展运用,这本《逆向工程核心原理》就是通向逆向工程大门的捷径。
想成为逆向工程研究员的读者或正在从事逆向开发工作的开发人员一定会通过《逆向工程核心原理》获得很大帮助。同时,想成为 安全领域专家的人也可从《逆向工程核心原理》轻松起步。
书中用到的几乎所有示例都基于作者在逆向分析实践中获得的知识与经验,是其亲自开发的程序,紧扣各章主题,绝无累赘。
作者将培训经验应用到本书的组织结构、内容讲解、示例选择等各方面,以求将较为难懂的技术以更易懂的方式呈现给各位。 作者几年前就开设了一个逆向技术学习博客并运营至今,通过与访问者之间的交流,充分了解了初学者们的困惑和需求。
李承远
在AhnLab从事恶意代码分析工作,一直维护着一个逆向分析技术专业学习博客。从接触逆向分析技术开始就为其迷人魅力深深吸引,对逆向分析技术的传播及多领域应用非常关注,喜欢读书、发呆,也向往新的挑战。
第一部分 代码逆向技术基础
第1章 关于逆向工程 2 1 1 逆向工程 2 1 2 代码逆向工程 2 1 2 1 逆向分析法 2 1 2 2 源代码、十六进制代码、汇编代码 4 1 2 3 “打补丁”与“破解” 5 1 3 代码逆向准备 5 1 3 1 目标 5 1 3 2 激情 6 1 3 3 谷歌 6 1 4 学习逆向分析技术的禁忌 6 1 4 1 贪心 6 1 4 2 急躁 7 1 5 逆向分析技术的乐趣 7 第2章 逆向分析Hello World!程序 8 2 1 Hello World!程序 8 2 2 调试HelloWorld exe程序 9 2 2 1 调试目标 9 2 2 2 开始调试 9 2 2 3 入口点 10 2 2 4 跟踪40270C函数 10 2 2 5 跟踪40104F跳转语句 12 2 2 6 查找main()函数 12 2 3 进一步熟悉调试器 14 2 3 1 调试器指令 14 2 3 2 “大本营” 15 2 3 3 设置“大本营”的四种方法 15 2 4 快速查找指定代码的四种方法 17 2 4 1 代码执行法 18 2 4 2 字符串检索法 19 2 4 3 API检索法(1):在调用代码中设置断点 20 2 4 4 API检索法(2):在API代码中设置断点 21 2 5 使用“打补丁”方式修改“Hello World!”字符串 23 2 5 1 “打补丁” 23 2 5 2 修改字符串的两种方法 24 2 6 小结 28 第3章 小端序标记法 31 3 1 字节序 31 3 1 1 大端序与小端序 32 3 1 2 在OllyDbg中查看小端序 32 第4章 IA-32寄存器基本讲解 34 4 1 什么是CPU寄存器 34 4 2 IA-32寄存器 34 4 3 小结 40 第5章 栈 41 5 1 栈 41 5 1 1 栈的特征 41 5 1 2 栈操作示例 41 第6章 分析abex’ crackme#1 44 6 1 abex’ crackme #1 44 6 1 1 开始调试 45 6 1 2 分析代码 45 6 2 破解 47 6 3 将参数压入栈 47 6 4 小结 48 第7章 栈帧 49 7 1 栈帧 49 7 2 调试示例:stackframe exe 49 7 2 1 StackFrame cpp 50 7 2 2 开始执行main()函数&生成栈帧 51 7 2 3 设置局部变量 52 7 2 4 add()函数参数传递与调用 53 7 2 5 开始执行add()函数&生成栈帧 54 7 2 6 设置add()函数的局部变量(x, y) 55 7 2 7 ADD运算 55 7 2 8 删除函数add()的栈帧&函数执行完毕(返回) 56 7 2 9 从栈中删除函数add()的参数(整理栈) 57 7 2 10 调用printf()函数 58 7 2 11 设置返回值 58 7 2 12 删除栈帧&main()函数终止 58 7 3 设置OllyDbg选项 59 7 3 1 Disasm选项 59 7 3 2 Analysis1选项 60 7 4 小结 61 第8章 abex’ crackme #2 62 8 1 运行abex’ crackme #2 62 8 2 Visual Basic文件的特征 63 8 2 1 VB专用引擎 63 8 2 2 本地代码和伪代码 63 8 2 3 事件处理程序 63 8 2 4 未文档化的结构体 63 8 3 开始调试 63 8 3 1 间接调用 64 8 3 2 RT_MainStruct结构体 64 8 3 3 ThunRTMain()函数 65 8 4 分析crackme 65 8 4 1 检索字符串 65 8 4 2 查找字符串地址 66 8 4 3 生成Serial的算法 68 8 4 4 预测代码 69 8 4 5 读取Name字符串的代码 69 8 4 6 加密循环 70 8 4 7 加密方法 70 8 5 小结 72 第9章 Process Explorer——最优秀的进程管理工具 74 9 1 Process Explorer 74 9 2 具体有哪些优点呢 75 9 3 sysinternals 75 第10章 函数调用约定 76 10 1 函数调用约定 76 10 1 1 cdecl 76 10 1 2 stdcall 77 10 1 3 fastcall 78 第11章 视频讲座 79 11 1 运行 79 11 2 分析 79 11 2 1 目标(1):去除消息框 79 11 2 2 打补丁(1):去除消息框 81 11 2 3 目标(2):查找注册码 83 11 3 小结 85 第12章 究竟应当如何学习代码逆向分析 86 12 1 逆向工程 86 12 1 1 任何学习都应当有目标 86 12 1 2 拥有积极心态 86 12 1 3 要感受其中的乐趣 86 12 1 4 让检索成为日常生活的一部分 87 12 1 5 最重要的是实践 87 12 1 6 请保持平和的心态 87 第二部分 PE文件格式 第13章 PE文件格式 90 13 1 介绍 90 13 2 PE文件格式 90 13 2 1 基本结构 91 13 2 2 VA&RVA 92 13 3 PE头 92 13 3 1 DOS头 93 13 3 2 DOS存根 94 13 3 3 NT头 94 13 3 4 NT头:文件头 95 13 3 5 NT头:可选头 97 13 3 6 节区头 101 13 4 RVA to RAW 104 13 5 IAT 105 13 5 1 DLL 105 13 5 2 IMAGE_IMPORT_DESCRIPTOR 107 13 5 3 使用notepad exe练习 108 13 6 EAT 112 13 6 1 IMAGE_EXPORT_DIRECTORY 113 13 6 2 使用kernel32 dll练习 114 13 7 高级PE 116 13 7 1 PEView exe 116 13 7 2 Patched PE 117 13 8 小结 118 第14章 运行时压缩 121 14 1 数据压缩 121 14 1 1 无损压缩 121 14 1 2 有损压缩 121 14 2 运行时压缩器 122 14 2 1 压缩器 122 14 2 2 保护器 123 14 3 运行时压缩测试 123 第15章 调试UPX压缩的notepad程序 127 15 1 notepad exe的EP代码 127 15 2 notepad_upx exe的EP代码 127 15 3 跟踪UPX文件 129 15 3 1 OllyDbg的跟踪命令 129 15 3 2 循环 #1 129 15 3 3 循环 #2 130 15 3 4 循环 #3 131 15 3 5 循环 #4 131 15 4 快速查找UPX OEP的方法 132 15 4 1 在POPAD指令后的JMP指令处设置断点 132 15 4 2 在栈中设置硬件断点 133 15 5 小结 133 第16章 基址重定位表 135 16 1 PE重定位 135 16 1 1 DLL/SYS 135 16 1 2 EXE 136 16 2 PE重定位时执行的操作 136 16 3 PE重定位操作原理 138 16 3 1 基址重定位表 138 16 3 2 IMAGE_BASE_RELOCATION结构体 139 16 3 3 基址重定位表的分析方法 139 16 3 4 练习 141 第17章 从可执行文件中删除 reloc节区 142 17 1 reloc节区 142 17 2 reloc exe 142 17 2 1 删除 reloc节区头 142 17 2 2 删除 reloc节区 143 17 2 3 修改IMAGE_FILE_HEADER 143 17 2 4 修改IMAGE_OPTIONAL_HEADER 144 17 3 小结 145 第18章 UPack PE文件头详细分析 146 18 1 UPack说明 146 18 2 使用UPack压缩notepad exe 146 18 3 使用Stud_PE工具 148 18 4 比较PE文件头 148 18 4 1 原notepad exe的PE文件头 149 18 4 2 notepad_upack exe运行时压缩的PE文件头 149 18 5 分析UPack的PE文件头 150 18 5 1 重叠文件头 150 18 5 2 IMAGE_FILE_HEADER SizeOfOptionalHeader 150 18 5 3 IMAGE_OPTIONAL_HEADER NumberOf-RvaAndSizes 152 18 5 4 IMAGE_SECTION_HEADER 153 18 5 5 重叠节区 155 18 5 6 RVA to RAW 156 18 5 7 导入表(IMAGE_IMPORT_DESCRIPTOR array) 158 18 5 8 导入地址表 160 18 6 小结 161 第19章 UPack调试? 查找OEP 162 19 1 OllyDbg运行错误 162 19 2 解码循环 163 19 3 设置IAT 165 19 4 小结 166 第20章 “内嵌补丁”练习 167 20 1 内嵌补丁 167 20 2 练习:Patchme 168 20 3 调试:查看代码流 168 20 4 代码结构 172 20 5 “内嵌补丁”练习 173 20 5 1 补丁代码要设置在何处呢 173 20 5 2 制作补丁代码 175 20 5 3 执行补丁代码 176 20 5 4 结果确认 177 第三部分 DLL注入 第21章 Windows消息钩取 180 21 1 钩子 180 21 2 消息钩子 180 21 3 SetWindowsHookEx() 181 21 4 键盘消息钩取练习 182 21 4 1 练习示例HookMain exe 182 21 4 2 分析源代码 185 21 5 调试练习 187 21 5 1 调试HookMain exe 188 21 5 2 调试Notepad exe进程内的KeyHook dll 190 21 6 小结 192 第22章 恶意键盘记录器 194 22 1 恶意键盘记录器的目标 194 22 1 1 在线游戏 194 22 1 2 网上银行 194 22 1 3 商业机密泄露 194 22 2 键盘记录器的种类与发展趋势 195 22 3 防范恶意键盘记录器 195 22 4 个人信息 195 第23章 DLL注入 197 23 1 DLL注入 197 23 2 DLL注入示例 198 23 2 1 改善功能与修复Bug 198 23 2 2 消息钩取 198 23 2 3 API钩取 198 23 2 4 其他应用程序 199 23 2 5 恶意代码 199 23 3 DLL注入的实现方法 199 23 4 CreateRemoteThread() 199 23 4 1 练习示例myhack dll 199 23 4 2 分析示例源代码 203 23 4 3 调试方法 208 23 5 AppInit_DLLs 210 23 5 1 分析示例源码 211 23 5 2 练习示例myhack2 dll 212 23 6 SetWindowsHookEx() 214 23 7 小结 214 第24章 DLL卸载 216 24 1 DLL卸载的工作原理 216 24 2 实现DLL卸载 216 24 2 1 获取进程中加载的DLL信息 219 24 2 2 获取目标进程的句柄 220 24 2 3 获取FreeLibrary() API地址 220 24 2 4 在目标进程中运行线程 220 24 3 DLL卸载练习 220 24 3 1 复制文件及运行notepad exe 220 24 3 2 注入myhack dll 221 24 3 3 卸载myhack dll 222 第25章 通过修改PE加载DLL 224 25 1 练习文件 224 25 1 1 TextView exe 224 25 1 2 TextView_patched exe 225 25 2 源代码 - myhack3 cpp 227 25 2 1 DllMain() 227 25 2 2 DownloadURL() 228 25 2 3 DropFile() 229 25 2 4 dummy() 230 25 3 修改TextView exe文件的准备工作 231 25 3 1 修改思路 231 25 3 2 查看IDT是否有足够空间 231 25 3 3 移动IDT 233 25 4 修改TextView exe 235 25 4 1 修改导入表的RVA值 235 25 4 2 删除绑定导入表 235 25 4 3 创建新IDT 235 25 4 4 设置Name、INT、IAT 236 25 4 5 修改IAT节区的属性值 238 25 5 检测验证 240 25 6 小结 241 第26章 PE Tools 242 26 1 PE Tools 242 26 1 1 进程内存转储 243 26 1 2 PE编辑器 245 26 2 小结 245 第27章 代码注入 247 27 1 代码注入 247 27 2 DLL注入与代码注入 247 27 3 练习示例 249 27 3 1 运行notepad exe 249 27 3 2 运行CodeInjection exe 249 27 3 3 弹出消息框 250 27 4 CodeInjection cpp 250 27 4 1 main()函数 251 27 4 2 ThreadProc()函数 251 27 4 3 InjectCode()函数 254 27 5 代码注入调试练习 256 27 5 1 调试notepad exe 256 27 5 2 设置OllyDbg选项 256 27 5 3 运行CodeInjection exe 257 27 5 4 线程开始代码 258 27 6 小结 259 第28章 使用汇编语言编写注入代码 260 28 1 目标 260 28 2 汇编编程 260 28 3 OllyDbg的汇编命令 260 28 3 1 编写ThreadProc()函数 262 28 3 2 保存文件 265 28 4 编写代码注入程序 266 28 4 1 获取ThreadProc()函数的二进制代码 266 28 4 2 CodeInjection2 cpp 267 28 5 调试练习 270 28 5 1 调试notepad exe 270 28 5 2 设置OllyDbg选项 270 28 5 3 运行CodeInjection2 exe 271 28 5 4 线程起始代码 272 28 6 详细分析 272 28 6 1 生成栈帧 272 28 6 2 THREAD_PARAM结构体指针 273 28 6 3 “User32 dll”字符串 274 28 6 4 压入“user32 dll”字符串参数 274 28 6 5 调用LoadLibraryA(“user32 dll”) 275 28 6 6 “MessageBoxA”字符串 276 28 6 7 调用GetProcAddress(hMod,“MessageBoxA”) 276 28 6 8 压入MessageBoxA()函数的参数 1 -MB_OK 277 28 6 9 压入MessageBoxA()函数的参数 2 -“ReverseCore” 277 28 6 10 压入MessageBoxA()函数的参数 3 -“ reversecore ” 278 28 6 11 压入MessageBoxA()函数的参数 4 -NULL 279 28 6 12 调用MessageBoxA() 279 28 6 13 设置ThreadProc()函数的返回值 280 28 6 14 删除栈帧及函数返回 280 28 7 小结 280 第四部分 API钩取 第29章 API钩取:逆向分析之“花” 282 29 1 钩取 282 29 2 API是什么 282 29 3 API钩取 283 29 3 1 正常调用API 283 29 3 2 钩取API调用 284 29 4 技术图表 284 29 4 1 方法对象(是什么) 285 29 4 2 位置(何处) 285 29 4 3 技术(如何) 286 29 4 4 API 286 第30章 记事本WriteFile() API钩取 288 30 1 技术图表—调试技术 288 30 2 关于调试器的说明 289 30 2 1 术语 289 30 2 2 调试器功能 289 30 2 3 调试器的工作原理 289 30 2 4 调试事件 289 30 3 调试技术流程 290 30 4 练习 291 30 5 工作原理 293 30 5 1 栈 293 30 5 2 执行流 295 30 5 3 “脱钩”&“钩子” 295 30 6 源代码分析 295 30 6 1 main() 296 30 6 2 DebugLoop() 296 30 6 3 EXIT_PROCESS_DEBUG_EVENT 298 30 6 4 CREATE_PROCESS_DEBUG_EVENT-OnCreateProcess-DebugEvent() 298 30 6 5 EXCEPTION_DEBUG_EVENT-OnException-DebugEvent() 300 第31章 关于调试器 305 31 1 OllyDbg 305 31 2 IDA Pro 305 31 3 WinDbg 306 第32章 计算器显示中文数字 308 32 1 技术图表 308 32 2 选定目标API 309 32 3 IAT钩取工作原理 312 32 4 练习示例 314 32 5 源代码分析 316 32 5 1 DllMain() 316 32 5 2 MySetWindowTextW() 317 32 5 3 hook_iat() 319 32 6 调试被注入的DLL文件 322 32 6 1 DllMain() 325 32 6 2 hook_iat() 325 32 6 3 MySetWindowTextW() 327 32 7 小结 328 第33章 隐藏进程 329 33 1 技术图表 329 33 2 API代码修改技术的原理 329 33 2 1 钩取之前 330 33 2 2 钩取之后 330 33 3 进程隐藏 332 33 3 1 进程隐藏工作原理 332 33 3 2 相关API 332 33 3 3 隐藏技术的问题 333 33 4 练习 #1(HideProc exe,stealth dll) 333 33 4 1 运行notepad exe、procexp exe、taskmgr exe 334 33 4 2 运行HideProc exe 334 33 4 3 确认stealth dll注入成功 334 33 4 4 查看notepad exe进程是否隐藏成功 335 33 4 5 取消notepad exe进程隐藏 336 33 5 源代码分析 336 33 5 1 HideProc cpp 336 33 5 2 stealth cpp 338 33 6 全局API钩取 344 33 6 1 Kernel32 CreateProcess() API 344 33 6 2 Ntdll ZwResumeThread() API 345 33 7 练习#2(HideProc2 exe,Stealth2 dll) 345 33 7 1 复制stealth2 dll文件到%SYSTEM%文件夹中 345 33 7 2 运行HideProc2 exe -hide 346 33 7 3 运行ProcExp exe¬epad exe 346 33 7 4 运行HideProc2 exe -show 347 33 8 源代码分析 348 33 8 1 HideProc2 cpp 348 33 8 2 stealth2 cpp 348 33 9 利用“热补丁”技术钩取API 350 33 9 1 API代码修改技术的问题 350 33 9 2 “热补丁”(修改7个字节代码) 350 33 10 练习 #3:stealth3 dll 353 33 11 源代码分析 353 33 12 使用“热补丁”API钩取技术时需要考虑的问题 356 33 13 小结 357 第34章 高级全局API钩取:IE连接控制 359 34 1 目标API 359 34 2 IE进程结构 361 34 3 关于全局API钩取的概念 362 34 3 1 常规API钩取 363 34 3 2 全局API钩取 363 34 4 ntdll!ZwResumeThread() API 364 34 5 练习示例:控制IE网络连接 368 34 5 1 运行IE 368 34 5 2 注入DLL 369 34 5 3 创建新选项卡 369 34 5 4 尝试连接网站 370 34 5 5 卸载DLL 371 34 5 6 课外练习 372 34 6 示例源代码 372 34 6 1 DllMain() 372 34 6 2 NewInterConnectW() 373 34 6 3 NewZwResumeThread() 374 34 7 小结 375 第35章 优秀分析工具的五种标准 376 35 1 工具 376 35 2 代码逆向分析工程师 376 35 3 优秀分析工具的五种标准 376 35 3 1 精简工具数量 377 35 3 2 工具功能简单、使用方便 377 35 3 3 完全掌握各种功能 377 35 3 4 不断升级更新 377 35 3 5 理解工具的核心工作原理 377 35 4 熟练程度的重要性 377 第五部分 64位&Windows内核6 第36章 64位计算 380 36 1 64位计算环境 380 36 1 1 64位CPU 380 36 1 2 64位OS 381 36 1 3 Win32 API 381 36 1 4 WOW64 381 36 1 5 练习:WOW64Test 384 36 2 编译64位文件 385 36 2 1 Microsoft Windows SDK(Software Development Kit) 386 36 2 2 设置Visual C 2010 Express环境 386 第37章 x64处理器 389 37 1 x64中新增或变更的项目 389 37 1 1 64位 389 37 1 2 内存 389 37 1 3 通用寄存器 389 37 1 4 CALL/JMP指令 390 37 1 5 函数调用约定 391 37 1 6 栈 & 栈帧 392 37 2 练习:Stack32 exe & Stack64 exe 392 37 2 1 Stack32 exe 392 37 2 2 Stack64 exe 394 37 3 小结 397 第38章 PE32 398 38 1 PE32 (PE 、PE64) 398 38 1 1 IMAGE_NT_HEADERS 398 38 1 2 IMAGE_FILE_HEADER 398 38 1 3 IMAGE_OPTIONAL_HEADER 399 38 1 4 IMAGE_THUNK_DATA 401 38 1 5 IMAGE_TLS_DIRECTORY 403 第39章 WinDbg 405 39 1 WinDbg 405 39 1 1 WinDbg的特征 405 39 1 2 运行WinDbg 406 39 1 3 内核调试 407 39 1 4 WinDbg基本指令 409 第40章 64位调试 411 40 1 x64环境下的调试器 411 40 2 64位调试 411 40 3 PE32:WOW64Test_x86 exe 413 40 3 1 EP代码 414 40 3 2 Startup代码 414 40 3 3 main()函数 415 40 4 PE32 :WOW64Test_x64 exe 416 40 4 1 系统断点 416 40 4 2 EP代码 417 40 4 3 Startup代码 418 40 4 4 main()函数 420 40 5 小结 423 第41章 ASLR 424 41 1 Windows内核版本 424 41 2 ASLR 424 41 3 Visual C 424 41 4 ASLR exe 425 41 4 1 节区信息 426 41 4 2 IMAGE_FILE_HEADER\Characteristics 427 41 4 3 IMAGE_OPTIONAL_HEADER\DLL Characteristics 428 41 5 练习:删除ASLR功能 428 第42章 内核6中的会话 430 42 1 会话 430 42 2 会话0隔离机制 432 42 3 增强安全性 432 第43章 内核6中的DLL注入 433 43 1 再现DLL注入失败 433 43 1 1 源代码 433 43 1 2 注入测试 435 43 2 原因分析 436 43 2 1 调试 #1 436 43 2 2 调试 #2 438 43 3 练习:使CreateRemoteThread()正常工作 440 43 3 1 方法 #1:修改CreateSuspended参数值 440 43 3 2 方法 #2:操纵条件分支 441 43 4 稍作整理 443 43 5 InjectDll_new exe 443 43 5 1 InjectDll_new cpp 443 43 5 2 注入练习 446 第44章 InjDll exe:DLL注入专用工具 448 44 1 InjDll exe 448 44 1 1 使用方法 448 44 1 2 使用示例 449 44 1 3 注意事项 450 第六部分 高级逆向分析技术 第45章 TLS回调函数 452 45 1 练习 #1:HelloTls exe 452 45 2 TLS 453 45 2 1 IMAGE_DATA_DIRECTORY 453 45 2 2 IMAGE_TLS_DIRECTORY 454 45 2 3 回调函数地址数组 454 45 3 TLS回调函数 455 45 4 练习 #2:TlsTest exe 456 45 4 1 DLL_PROCESS_ATTACH 457 45 4 2 DLL_THREAD_ATTACH 457 45 4 3 DLL_THREAD_DETACH 457 45 4 4 DLL_PROCESS_DETACH 457 45 5 调试TLS回调函数 458 45 6 手工添加TLS回调函数 459 45 6 1 修改前的原程序 460 45 6 2 设计规划 460 45 6 3 编辑PE文件头 461 45 6 4 设置IMAGE_TLS_DIRECTORY结构体 463 45 6 5 编写TLS回调函数 464 45 6 6 最终完成 464 45 7 小结 465 第46章 TEB 466 46 1 TEB 466 46 1 1 TEB结构体的定义 466 46 1 2 TEB结构体成员 466 46 1 3 重要成员 469 46 2 TEB访问方法 470 46 2 1 Ntdll NtCurrentTeb() 470 46 2 2 FS段寄存器 471 46 3 小结 472 第47章 PEB 473 47 1 PEB 473 47 1 1 PEB访问方法 473 47 1 2 PEB结构体的定义 474 47 1 3 PEB结构体的成员 475 47 2 PEB的重要成员 477 47 2 1 PEB BeingDebugged 478 47 2 2 PEB ImageBaseAddress 478 47 2 3 PEB Ldr 479 47 2 4 PEB ProcessHeap & PEB NtGlobalFlag 480 47 3 小结 480 第48章 SEH 481 48 1 SEH 481 48 2 SEH练习示例 #1 481 48 2 1 正常运行 481 48 2 2 调试运行 482 48 3 OS的异常处理方法 484 48 3 1 正常运行时的异常处理方法 484 48 3 2 调试运行时的异常处理方法 484 48 4 异常 485 48 4 1 EXCEPTION_ACCESS_VIOLATION(C0000005) 486 48 4 2 EXCEPTION_BREAKPOINT(80000003) 486 48 4 3 EXCEPTION_ILLEGAL_INSTRUCTION(C000001D) 488 48 4 4 EXCEPTION_INT_DIVIDE_BY_ZERO(C0000094) 488 48 4 5 EXCEPTION_SINGLE_STEP(80000004) 489 48 5 SEH详细说明 489 48 5 1 SEH链 489 48 5 2 异常处理函数的定义 489 48 5 3 TEB NtTib ExceptionList 491 48 5 4 SEH安装方法 492 48 6 SEH练习示例 #2(seh exe) 492 48 6 1 查看SEH链 493 48 6 2 添加SEH 493 48 6 3 发生异常 494 48 6 4 查看异常处理器参数 494 48 6 5 调试异常处理器 496 48 6 6 删除SEH 498 48 7 设置OllyDbg选项 499 48 7 1 忽略KERNEL32中发生的内存非法访问异常 500 48 7 2 向被调试者派送异常 500 48 7 3 其他异常处理 500 48 7 4 简单练习 500 48 8 小结 501 第49章 IA-32指令 502 49 1 IA-32指令 502 49 2 常用术语 502 49 2 1 反汇编器 503 49 2 2 反编译器 504 49 2 3 反编译简介 504 49 3 IA-32指令格式 506 49 3 1 指令前缀 507 49 3 2 操作码 507 49 3 3 ModR/M 507 49 3 4 SIB 508 49 3 5 位移 508 49 3 6 立即数 509 49 4 指令解析手册 509 49 4 1 下载IA-32用户手册 509 49 4 2 打印指令解析手册 509 49 5 指令解析练习 510 49 5 1 操作码映射 510 49 5 2 操作数 511 49 5 3 ModR/M 512 49 5 4 Group 514 49 5 5 前缀 516 49 5 6 双字节操作码 518 49 5 7 移位值&立即数 519 49 5 8 SIB 520 49 6 指令解析课外练习 524 49 7 小结 524 第七部分 反调试技术 第50章 反调试技术 526 50 1 反调试技术 526 50 1 1 依赖性 526 50 1 2 多种反调试技术 526 50 2 反调试破解技术 526 50 3 反调试技术的分类 527 50 3 1 静态反调试技术 528 50 3 2 动态反调试技术 528 第51章 静态反调试技术 529 51 1 静态反调试的目的 529 51 2 PEB 529 51 2 1 BeingDebugged( 0x2) 531 51 2 2 Ldr( 0xC) 531 51 2 3 Process Heap( 0x18) 532 51 2 4 NtGlobalFlag( 0x68) 533 51 2 5 练习:?StaAD_PEB exe 534 51 2 6 破解之法 534 51 3 NtQueryInformationProcess() 537 51 3 1 ProcessDebugPort(0x7) 538 51 3 2 ProcessDebugObjectHandle(0x1E) 539 51 3 3 ProcessDebugFlags(0x1F) 539 51 3 4 练习:StaAD_NtQIP exe 540 51 3 5 破解之法 540 51 4 NtQuerySystemInformation() 542 51 4 1 SystemKernelDebugger-Information(0x23) 544 51 4 2 练习:StaAD_NtQSI exe 545 51 4 3 破解之法 545 51 5 NtQueryObject() 545 51 6 ZwSetInformationThread() 549 51 6 1 练习:StaAD_ZwSIT exe 549 51 6 2 破解之法 550 51 7 TLS回调函数 550 51 8 ETC 551 51 8 1 练习:StaAD_FindWindow exe 551 51 8 2 破解之法 551 51 9 小结 553 第52章 动态反调试技术 554 52 1 动态反调试技术的目的 554 52 2 异常 554 52 2 1 SEH 554 52 2 2 SetUnhandledException-Filter() 558 52 3 Timing Check 562 52 3 1 时间间隔测量法 562 52 3 2 RDTSC 563 52 4 陷阱标志 565 52 4 1 单步执行 566 52 4 2 INT 2D 569 52 5 0xCC探测 572 52 5 1 API断点 573 52 5 2 比较校验和 575 第53章 高级反调试技术 577 53 1 高级反调试技术 577 53 2 垃圾代码 577 53 3 扰乱代码对齐 578 53 4 加密/解密 581 53 4 1 简单的解码示例 581 53 4 2 复杂的解码示例 582 53 4 3 特殊情况:代码重组 584 53 5 Stolen Bytes(Remove OEP) 584 53 6 API重定向 587 53 6 1 原代码 588 53 6 2 API重定向示例 #1 588 53 6 3 API重定向示例#2 589 53 7 Debug Blocker(Self Debugging) 593 53 8 小结 595 第八部分 调试练习 第54章 调试练习1:服务 598 54 1 服务进程的工作原理 598 54 1 1 服务控制器 598 54 1 2 服务启动过程 599 54 2 DebugMe1 exe示例讲解 600 54 2 1 安装服务 600 54 2 2 启动服务 602 54 2 3 源代码 604 54 3 服务进程的调试 606 54 3 1 问题在于SCM 606 54 3 2 调试器无所不能 606 54 3 3 常用方法 606 54 4 服务调试练习 606 54 4 1 直接调试:强制设置EIP 606 54 4 2 服务调试的常用方法:“附加”方式 609 54 5 小结 615 第55章 调试练习2:自我创建 616 55 1 自我创建 616 55 2 工作原理 617 55 2 1 创建子进程(挂起模式) 617 55 2 2 更改EIP 618 55 2 3 恢复主线程 618 55 3 示例程序源代码 618 55 4 调试练习 620 55 4 1 需要考虑的事项 620 55 4 2 JIT调试 621 55 4 3 DebugMe2 exe 622 55 5 小结 626 第56章 调试练习3:PE映像切换 627 56 1 PE映像 627 56 2 PE映像切换 628 56 3 示例程序:Fake exe、Real exe、DebugMe3 exe 628 56 4 调试1 631 56 4 1 Open? 输入运行参数 631 56 4 2 main()函数 632 56 4 3 SubFunc_1() 634 56 4 4 CreateProcess(“fake exe”,CREATE_SUSPENDED) 635 56 4 5 SubFunc_2() 635 56 4 6 SubFunc_3() 641 56 4 7 ResumeThread() 644 56 5 调试2 644 56 5 1 思考 645 56 5 2 向EP设置无限循环 645 56 6 小结 647 第57章 调试练习4:Debug Blocker 648 57 1 Debug Blocker 648 57 2 反调试特征 648 57 2 1 父与子的关系 649 57 2 2 被调试进程不能再被其他调试器调试 649 57 2 3 终止调试进程的同时也终止被调试进程 649 57 2 4 调试器操作被调试者的代码 649 57 2 5 调试器处理被调试进程中发生的异常 649 57 3 调试练习:DebugMe4 exe 650 57 4 第一次调试 650 57 4 1 选定调试的起始位置 650 57 4 2 main() 650 57 5 第二次调试 651 57 6 第三次调试 653 57 7 第四次调试 656 57 8 第五次调试 658 57 8 1 系统断点 658 57 8 2 EXCEPTION_ILLEGAL_INSTRUCTION(1) 659 57 8 3 EXCEPTION_ILLEGAL_INSTRUCTION(2) 660 57 9 第六次调试 661 57 9 1 40121D(第一个异常) 661 57 9 2 401299(第二个异常) 665 57 10 第七次调试 667 57 10 1 静态方法 668 57 10 2 动态方法 669 57 11 小结 673 结束语 674 索引 676
你还可能感兴趣
我要评论
|