我这一周学<软件逆向>是薛老师讲课, 大多挺深,我就列出一个典型的吧。
准备工具: ollydbg ida vs2012
---------------------------------
我们先把目标程序winasm_0.exe拖入peid
主界面
那我们去输入表看看
也好像没什么特别值得关注的。
、那好 简单测试下程序 看有什么状况发生
看 弹出对话框 那我们该想到什么?API断点!messagebox相关!
不急我们把它拖入OD 直接ctrl+A分析
入口点:
习惯性的我把它上下一翻、发现:
这不是我们要找的字符串吗?(
PS:
如果我没翻到 步骤应该会是:
CPU Disasm
地址 十六进制数据 指令 Profile Comments
获取输入内容
00401066 |. E8 BF000000 CALL <JMP.&USER32.GetDlgItemTextA> ; \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 <JMP.&USER32.MessageBoxA> ; \USER32.MessageBoxA
0040109B |. 33C0 XOR EAX,EAX ;
0040109D |. C9 LEAVE ;
0040109E |. C2 1000 RETN 10 ;
CPU Disasm
地址 十六进制数据 指令 Profile Comments
0040106B A3 13114000 MOV DWORD PTR DS:[401113],EAX ; MOV DWORD PTR DS:[401113],EAX
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 <JMP.&USER32.MessageBoxA> ; 跳转至 USER32.MessageBoxA
.data:0040334A TopLevelExceptionFilter db ',0 ; DATA XREF: DialogFunc+E1o
.data:0040334E push esi
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;
}
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
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"
[B][COLOR="DarkRed"]0040107F |B9 06000000 MOV ECX,6 ;
00401084 |F3:A6 REPE CMPS BYTE PTR DS:[ESI],BYTE PTR ES: ;
00401086 |74 19 JE SHORT 004010A1 ;[/COLOR][/B]
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 <JMP.&USER32.MessageBoxA> ; 跳转至 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 <JMP.&USER32.GetDlgItem> ; 跳转至 USER32.GetDlgItem
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 ;
- 左键单击选中-右键-编辑-填充为NOP(有些OD可以直接DEL)
- 左键单击选中-右键-复制所有修改到可执行文件-”忽视所有警告“
- 在所弹出窗口-右键-保存文件-确定-重名为”1“(保存在桌面)
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)