我这一周学<软件逆向>是薛老师讲课, 大多挺深,我就列出一个典型的吧。
准备工具: ollydbg ida vs2012
--------------------------------- 我们先把目标程序winasm_0.exe拖入peid 主界面
、那好 简单测试下程序 看有什么状况发生
不急我们把它拖入OD 直接ctrl+A分析 那好 我们暂且就这样分析 在地址00401066 处F2断点 F9运行! 那此时肯定会弹出对话框 我们随便输入点什么 以”15PB“为例 再点击check! 会在刚刚所设断点处停下来:
废话不多说 我们分析代码: 关掉OD 我们用字符串”fubar“去试试 为什么? 你再想想看
看到这里估计就会有人说了 就这么点 也想混优秀精华?没什么好看的 哼~! 回帖嘲讽下楼主 再右上角 深藏功与名。
---------------------- 楼主为了保住节操 亦为了不被嘲讽 遂再花点时间
那么我们再进入节奏 我们从上面分析得到了那些关键信息?
来到
来到真正的异常处理回调函数
我们左键单击此行 做如下操作: 按”c“键 将数据转换为代码 按”d“键 转换dword类型 可得到: 说干就干 (ctrl+F5运行) 来我们回到IDA反汇编代码: 分析完毕 那么此时根据所分析得到数据回到OD ctrl+G 地址”40107f“ : 为什么? 不说~!算是我留的作业吧 不太难
我们将它提取出来更好地去分析 来 我们把字符串”magic“输入试试
看到这里又会有熟悉IDA的人说了 这傻×(友善地
或直接 F5 得到代码
准备工具: ollydbg ida vs2012
--------------------------------- 我们先把目标程序winasm_0.exe拖入peid 主界面
、那好 简单测试下程序 看有什么状况发生
不急我们把它拖入OD 直接ctrl+A分析
- 搜索字符串
- 下API断点
- 其它...
代码:
CPU Disasm 地址 十六进制数据 指令 Profile Comments 获取输入内容 00401066 |. E8 BF000000 CALL; /USER32.GetDlgItemTextA 0040106B A3 13114000 MOV DWORD PTR DS:[401113],EAX ; MOV DWORD PTR DS:[401113],EAX 比较eax 00401070 |. 83F8 05 CMP EAX,5 ; 00401073 |. 75 13 JNE SHORT 00401088 ; 比较 fubar? 00401075 |. BE 2A334000 MOV ESI,OFFSET 0040332A ; 0040107A |. BF 41304000 MOV EDI,OFFSET 00403041 ; ASCII "fubar" 0040107F |. B9 06000000 MOV ECX,6 ; 00401084 |. F3:A6 REPE CMPS BYTE PTR DS:[ESI],BYTE PTR ES: ; 看ZF标志以决定转移与否 00401086 |. 74 19 JE SHORT 004010A1 ; 00401088 |> 6A 00 PUSH 0 ; /Type = MB_OK|MB_DEFBUTTON1|MB_APPLMODAL 0040108A |. 68 1F334000 PUSH OFFSET 0040331F ; |Caption = " try again" 0040108F |. 68 0F334000 PUSH OFFSET 0040330F ; |Text = "no, not really." 00401094 |. 6A 00 PUSH 0 ; |hOwner = NULL 00401096 |. E8 95000000 CALL ; /USER32.MessageBoxA 0040109B |. 33C0 XOR EAX,EAX ; 0040109D |. C9 LEAVE ; 0040109E |. C2 1000 RETN 10 ; [/cpp]
代码:
CPU Disasm 地址 十六进制数据 指令 Profile Comments 0040106B A3 13114000 MOV DWORD PTR DS:[401113],EAX ; MOV DWORD PTR DS:[401113],EAX [/cpp]
- 左键单击选中-右键-编辑-填充为NOP(有些OD可以直接DEL)
- 左键单击选中-右键-复制所有修改到可执行文件-”忽视所有警告“
- 在所弹出窗口-右键-保存文件-确定-重名为”1“(保存在桌面)
废话不多说 我们分析代码:
代码:
CPU Disasm 地址 十六进制数据 指令 Profile Comments eax与5相比较 00401070 83F8 05 CMP EAX,5 ; 判断ZF标志位 若zf=0 跳转至地址“00401088” 显然是错的 00401073 75 13 JNE SHORT 00401088 ; 00401075 BE 2A334000 MOV ESI,OFFSET 0040332A ; 0040107A BF 41304000 MOV EDI,OFFSET 00403041 ; ASCII "fubar" ecx 一般做循环比较次数 6? 等等 与上面那个5有什么关系? 字符串自带反斜杠0 如果去掉呢?就是长度5 ! 我们再往下分析 0040107F B9 06000000 MOV ECX,6 ; esi与字符串“fubar”相比较 00401084 F3:A6 REPE CMPS BYTE PTR DS:[ESI],BYTE PTR ES: ; JE ? 结果很显然了 00401086 74 19 JE SHORT 004010A1 ; 00401088 6A 00 PUSH 0 ; 0040108A 68 1F334000 PUSH OFFSET 0040331F ; ASCII " try again" 0040108F 68 0F334000 PUSH OFFSET 0040330F ; ASCII "no, not really." 00401094 6A 00 PUSH 0 ; 00401096 E8 95000000 CALL; 跳转至 USER32.MessageBoxA [/cpp]
看到这里估计就会有人说了 就这么点 也想混优秀精华?没什么好看的 哼~! 回帖嘲讽下楼主 再右上角 深藏功与名。
---------------------- 楼主为了保住节操 亦为了不被嘲讽 遂再花点时间
那么我们再进入节奏 我们从上面分析得到了那些关键信息?
- ”内存访问异常!在不可写处写数据“
- ”PEID导入表可疑函数:SetUnhandledExceptionFilter:设置异常处理函数“
来到
来到真正的异常处理回调函数
我们左键单击此行
代码:
.data:0040334A TopLevelExceptionFilter db ',0 ; DATA XREF: DialogFunc+E1o [/cpp]
- 获取异常中断值
- 获取esi 即 第一条指令
代码:
.data:0040334E push esi [/cpp]
代码:
long __stdcall callback(_EXCEPTION_POINTERS* pexcp) { //异常 printf("%p/n",pexcp->ExceptionRecord->ExceptionCode); printf("%p/n",pexcp->ContextRecord->Esi); //ESI辅助分析 getchar(); return EXCEPTION_EXECUTE_HANDLER; }
int _tmain(int argc, _TCHAR* argv[]) { SetUnhandledExceptionFilter(callback); unsigned ueax,uebx,uecx,uedx,uebp; __asm //使用__asm进行内联汇编 { //使用mov指令将eax寄存器的内容保存到ueax变量 mov ueax, eax mov uebx, ebx mov uecx, ecx mov uedx, edx mov uebp,ebp } printf("eax=%x/tebx=%x/tecx=%x/tedx=%x/nuebp=%x/n", ueax, uebx, uecx, uedx,uebp); //设置异常 int *f =0; *f = 9; system("pause"); return 0; } [/cpp]
代码:
ta:0040334A enter 0, 0 .data:0040334E push esi ;将结构体压入堆栈 .data:0040334F mov esi, [ebp+arg_0] ; 取结构体EXCEPTION_POINTERS pexcp .data:00403352 lodsd ; 取pexcp->ExceptionRecord 此时esi+4 .data:00403353 mov eax, [eax] ; 将pexcp->ExceptionRecord->ExceptionCode内容给eax .data:00403353 ; 即EAX= C0000005 从demo得到 .data:00403355 and eax, 0DEADFFh ; EAX=5 .data:0040335A shl eax, 5 ; EAX=A0 .data:0040335D mov ebx, eax ; EBX=A0 .data:0040335F lea eax, [eax+402FAEh] ; 40304E 即 magic .data:00403365 mov esi, [esi] ; 取 pexcp->ContextRecord .data:00403367 mov [esi+9Ch], eax ; 取pexcp->ContextRecord+9c 即pexcp->ContextRecord->edi .data:0040336D add eax, 2DCh ; eax=2ac .data:00403372 mov [ebx+esi], eax ; pexcp->ContextRecord->esi=2ac .data:00403375 mov eax, 400FDFh ; eax=400fdf .data:0040337A add eax, ebx ; eax=40107f .data:0040337C mov [esi+0B8h], eax ; pexcp->ContextRecord->esi+b8 .data:0040337C ; 即 pexcp->ContextRecord->eip=40107f 即做完异常处理函数后跳转到地址40107f .data:00403382 xor eax, eax .data:00403384 dec eax .data:00403385 pop esi [/cpp]
代码:
CPU Disasm 地址 十六进制数据 指令 Profile Comments 00401073 /75 13 JNE SHORT 00401088 ; 00401075 |BE 2A334000 MOV ESI,OFFSET 0040332A ; 0040107A |BF 41304000 MOV EDI,OFFSET 00403041 ; ASCII "fubar" 0040107F |B9 06000000 MOV ECX,6 ; 00401084 |F3:A6 REPE CMPS BYTE PTR DS:[ESI],BYTE PTR ES: ; 00401086 |74 19 JE SHORT 004010A1 ; 00401088 /6A 00 PUSH 0 ; 0040108A 68 1F334000 PUSH OFFSET 0040331F ; ASCII " try again" 0040108F 68 0F334000 PUSH OFFSET 0040330F ; ASCII "no, not really." 00401094 6A 00 PUSH 0 ; 00401096 E8 95000000 CALL; 跳转至 USER32.MessageBoxA 0040109B 33C0 XOR EAX,EAX ; 0040109D C9 LEAVE ; 0040109E C2 1000 RETN 10 ; 004010A1 68 B90B0000 PUSH 0BB9 ; 004010A6 FF75 08 PUSH DWORD PTR SS:[EBP+8] ; 004010A9 E8 76000000 CALL ; 跳转至 USER32.GetDlgItem [/cpp]
我们将它提取出来更好地去分析
代码:
CPU Disasm 地址 十六进制数据 指令 Profile Comments 循环比较5次 (忽视反斜杠0) 0040107F B9 06000000 MOV ECX,6 ; 与字符串magic相比较 我们刚刚不是分析出来了么? 00401084 F3:A6 REPE CMPS BYTE PTR DS:[ESI],BYTE PTR ES: ; 跳转至地址“004010A1” 00401086 74 19 JE SHORT 004010A1 ; [/cpp]
看到这里又会有熟悉IDA的人说了 这傻×(友善地
或直接 F5 得到代码
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2300
- 用户1336
- 访客10863260
每日一句
True success inspires others to act.
真正的成功是激励他人行动。
真正的成功是激励他人行动。
新会员