破解入门学习笔记题四十六
004011F3 | FF2485 60124000 | jmp dword ptr ds:[eax*4+401260] | //跳转表
| eax | [eax*4+401260] | 自定义代码处 |
|---|---|---|
| Load菜单(eax=0) | [401260] | =403B42 |
| Save菜单(eax=4) | [401270] | =403BAE |
| Exit菜单(eax=2) | [401268] | =401159 |
![]() |
|---|
Exit菜单
修复方案:将跳转指向现有的退出代码(00401159),该代码调用PostQuitMessage。
修改步骤:
当前00401268处的值为0040124B(指向SetFocus调用)。修改为00401159(退出代码地址)。
汇编修改:将00401268处的4字节值从0040124B改为00401159。
|
|---|
Load菜单
内存布局:
405A70:文件路径缓冲区(260字节)
405AB0:文件内容缓冲区(1024字节)
[405544]:存储Edit控件句柄的指针
核心流程:
调用自定义的OpenFileDialog函数让用户选择文件
使用ReadFileContent函数读取选中的文件内容
通过SetWindowTextAAPI将文件内容显示到Edit控件中
; ================================================== ; 文件加载并更新Edit控件文本的汇编代码注解 ; 地址范围:00403B42 - 00403BA2 ; ================================================== 00403B42 | 60 | pushad | ; 保存所有通用寄存器现场 00403B43 | 33C0 | xor eax,eax | ; 清空EAX寄存器 00403B45 | C605 705A4000 00 | mov byte ptr ds:[405A70],0 | ; 初始化文件路径缓冲区首字节为0(空字符串) ; 空指令区域 - 为后续代码调整预留的空间 00403B4C | 90 | nop | 00403B4D | 90 | nop | 00403B4E | 90 | nop | ; ========== 第一阶段:打开文件对话框 ========== 00403B4F | 68 04010000 | push 104 | ; 参数3:缓冲区大小(260字节,MAX_PATH) 00403B54 | 68 705A4000 | push douby_2.405A70 | ; 参数2:文件路径缓冲区地址(405A70) 00403B59 | 6A 00 | push 0 | ; 参数1:父窗口句柄(0表示桌面) 00403B5B | B8 FF100110 | mov eax,<46.OpenFileDialog> | ; 加载OpenFileDialog函数地址到EAX 00403B60 | FFD0 | call eax | ; 调用打开文件对话框函数 00403B62 | 85C0 | test eax,eax | ; 检查返回值(用户是否选择了文件) 00403B64 | 74 3B | je douby_2.403BA1 | ; 如果取消或失败,跳转到清理退出 ; 空指令区域 - 预留空间 00403B66 | 90 | nop | 00403B67 | 90 | nop | 00403B68 | 90 | nop | 00403B69 | 90 | nop | 00403B6A | 90 | nop | 00403B6B | 90 | nop | ; ========== 第二阶段:读取文件内容 ========== 00403B6C | 68 00040000 | push 400 | ; 参数3:读取的最大字节数(1024字节) 00403B71 | 68 B05A4000 | push douby_2.405AB0 | ; 参数2:文件内容缓冲区地址(405AB0) 00403B76 | 68 705A4000 | push douby_2.405A70 | ; 参数1:文件路径字符串地址 00403B7B | B8 76120110 | mov eax,<46.ReadFileContent> | ; 加载ReadFileContent函数地址到EAX 00403B80 | FFD0 | call eax | ; 调用读取文件内容函数 00403B82 | 85C0 | test eax,eax | ; 检查读取是否成功 00403B84 | 74 1B | je douby_2.403BA1 | ; 如果读取失败,跳转到清理退出 ; ========== 第三阶段:更新Edit控件文本 ========== 00403B86 | 90 | nop | 00403B87 | 68 B05A4000 | push douby_2.405AB0 | ; 参数2:文件内容缓冲区地址(要显示的文本) 00403B8C | FF35 44554000 | push dword ptr ds:[405544] | ; 参数1:从内存[405544]获取Edit控件句柄 00403B92 | E8 E9376E76 | call <user32.SetWindowTextA> | ; 调用系统API设置Edit控件文本 ; ========== 成功返回处理 ========== 00403B97 | B8 01000000 | mov eax,1 | ; 设置成功返回值(EAX=1) 00403B9C | EB 03 | jmp douby_2.403BA1 | ; 跳转到清理退出 ; 空指令区域 00403B9E | 90 | nop | 00403B9F | 90 | nop | 00403BA0 | 90 | nop | ; ========== 清理退出部分 ========== 00403BA1 | 61 | popad | ; 恢复所有通用寄存器 00403BA2 | E9 66D6FFFF | jmp douby_2.40120D | ; 跳转回主程序流程
|
|---|
Save菜单
; ================================================== ; Save功能完整注解 ; 功能:将文本框内容通过保存对话框保存到文件 ; 起始地址: 00403BAE ; ================================================== 00403BAE: 60 pushad ; 保存所有通用寄存器状态 00403BAF: 33C0 xor eax, eax ; 清空EAX寄存器,确保初始状态干净 ; -------------------------------------------------- ; 1. 获取文本框内容 ; -------------------------------------------------- 00403BB1: 90 nop 00403BB2: 90 nop 00403BB3: 90 nop 00403BB4: 68 00040000 push 400h ; 参数3: 缓冲区大小(1024字节) 00403BB9: 68 A0674000 push 4067A0h ; 参数2: 文本缓冲区地址(用于接收文本框内容) 00403BBE: FF35 44554000 push dword ptr [405544h] ; 参数1: 文本框句柄(从内存405544h读取) 00403BC4: E8 D7206E76 call GetWindowTextA ; 调用API获取文本框文本内容 00403BC9: 90 nop ; -------------------------------------------------- ; 2. 调用保存文件对话框 ; -------------------------------------------------- 00403BCA: 68 04010000 push 104h ; 参数3: 文件路径缓冲区大小(260字节) 00403BCF: 68 50674000 push 406750h ; 参数2: 文件路径缓冲区地址 00403BD4: 6A 00 push 0 ; 参数1: 父窗口句柄(NULL) 00403BD6: B8 63110110 mov eax, 10011163h ; SaveFileDialog函数地址 00403BDB: FFD0 call eax ; 调用保存文件对话框 00403BDD: 85C0 test eax, eax ; 测试对话框返回值 00403BDF: 74 3B je 403C1Ch ; 如果用户取消(返回0),跳转到清理部分 ; -------------------------------------------------- ; 3. 调用文件写入功能 ; -------------------------------------------------- 00403BE1: 90 nop 00403BE2: 90 nop ; ... 多个nop指令用于代码对齐 00403BE9: 68 00040000 push 400h ; 参数3: 要写入的数据大小(1024字节) 00403BEE: 68 A0674000 push 4067A0h ; 参数2: 文本数据缓冲区(包含文本框内容) 00403BF3: 68 50674000 push 406750h ; 参数1: 文件路径(从对话框获取) 00403BF8: B8 49120110 mov eax, 10011249h ; WriteFileContent函数地址 00403BFD: FFD0 call eax ; 调用文件写入功能 00403BFF: 85C0 test eax, eax ; 测试写入结果 00403C01: 74 19 je 403C1Ch ; 如果写入失败,跳转到清理部分 ; -------------------------------------------------- ; 4. 成功处理路径 ; -------------------------------------------------- 00403C03: 90 nop 00403C04: 90 nop ; ... 多个nop指令 00403C0A: 33C0 xor eax, eax ; 设置EAX=0(失败状态) 00403C0C: EB 0E jmp 403C1Ch ; 跳转到清理代码 ; -------------------------------------------------- ; 5. 成功执行路径 ; -------------------------------------------------- 00403C14: B8 01000000 mov eax, 1 ; 设置EAX=1(成功状态) 00403C19: 90 nop 00403C1A: 90 nop ; -------------------------------------------------- ; 6. 清理和返回 ; -------------------------------------------------- 00403C1C: 61 popad ; 恢复所有通用寄存器 00403C1D: E9 EBD5FFFF jmp 40120Dh ; 跳转回主程序(已验证的安全返回点)
![]() |
|---|
编写DLL文件,实现文件打开保存读写功能。 OpenFileDialog 、 SaveFileDialog 、ReadFileContent 、WriteFileContent 。
把随机基址改成否,这样在OD里调用地址就不会变了。
![]() |
|---|
把写好的dll静态注入程序,这样可以少写点汇编代码。
![]() |
|---|
把生成的dll文件放在程序同一目录下,程序运行会自动加载dll。
![]() |
|---|







