OllyDbg 使用笔记 (二)
OllyDbg 使用笔记 (二)
參考
书:《加密与解密》
视频:小甲鱼 解密系列 视频
TraceMe.exe下载地址:http://pan.baidu.com/s/1c0s2twO
TraceMe.exe 程序破解
程序见下图。破解目标:使我们可以验证成功。
图片1
因为输入肯定会用到获取对话框文本的API。所以在反汇编面板 按Ctrl+G搜索GetDlgItemTextA,试试看。
图片2
也能够按Ctrl+N 打开程序的导入表。
查看程序导入了那些函数,选中GetDlgItemTextA,右键 选择在反汇编窗体中尾随输入函数。
图片3
能够看到搜索到了对应的API函数。
按F2下断点。再按Ctrl+F2 又一次加载。再按F9,会先弹出窗体。任意写入username和序列号,按Check。之后就会执行到断点处。
接着一边按F8,一边观察以下的信息面板的提示信息,直到发现前面填的username和序列号。
图片4
004011D7 . 8D5424 4C lea edx, dword ptr [esp+4C] 004011DB . 53 push ebx 004011DC . 8D8424 A00000>lea eax, dword ptr [esp+A0] 004011E3 . 52 push edx 004011E4 . 50 push eax 004011E5 . E8 56010000 call 00401340 004011EA . 8B3D BC404000 mov edi, dword ptr [<&USER32.GetDlg>; USER32.GetDlgItem 004011F0 . 83C4 0C add esp, 0C 004011F3 . 85C0 test eax, eax 004011F5 . 74 37 je short 0040122E
观察此时的代码,call 00401340 前面有3个PUSH,是00401340这个函数的參数,各自是username,序列号和序列号长度。
还有以下的test eax,eax 值得注意,函数的返回值都是储存在eax中的。
能够从上面得出call 00401340 就是推断输入的username和序列号是否正确的函数。
暴力破解
接着按F8接着执行。执行到 je short 0040122E 处停下。
但我们输入的是错误的时候,我们能够发现这个地方 je 是跳转的,我们能够通过在右边改动标志寄存器(点击Z 后面的1)让je不跳转 或者直接把 je short 0040122E改成 nop(选中,按下空格键输入nop),进行暴力破解。
图片5
图片6
然后执行就能够看到“恭喜你成功”
获取正确序列号
执行到
004011E5 . E8 56010000 call 00401340
后按F7进入函数,能够看到以下的代码
00401340 /$ 55 push ebp 00401341 |. 8B6C24 0C mov ebp, dword ptr [esp+C] 00401345 |. 56 push esi 00401346 |. 57 push edi 00401347 |. 8B7C24 18 mov edi, dword ptr [esp+18] 0040134B |. B9 03000000 mov ecx, 3 00401350 |. 33F6 xor esi, esi 00401352 |. 33C0 xor eax, eax 00401354 |. 3BF9 cmp edi, ecx 00401356 |. 7E 21 jle short 00401379 00401358 |. 53 push ebx 00401359 |> 83F8 07 /cmp eax, 7 0040135C |. 7E 02 |jle short 00401360 0040135E |. 33C0 |xor eax, eax 00401360 |> 33D2 |xor edx, edx 00401362 |. 33DB |xor ebx, ebx 00401364 |. 8A1429 |mov dl, byte ptr [ecx+ebp] 00401367 |. 8A98 30504000 |mov bl, byte ptr [eax+405030] 0040136D |. 0FAFD3 |imul edx, ebx 00401370 |. 03F2 |add esi, edx 00401372 |. 41 |inc ecx 00401373 |. 40 |inc eax 00401374 |. 3BCF |cmp ecx, edi 00401376 |.^ 7C E1 \jl short 00401359 00401378 |. 5B pop ebx 00401379 |> 56 push esi ; /<%ld> 0040137A |. 68 78504000 push 00405078 ; |Format = "%ld" 0040137F |. 55 push ebp ; |s 00401380 |. FF15 9C404000 call dword ptr [<&USER32.wsprintfA>; \wsprintfA 00401386 |. 8B4424 1C mov eax, dword ptr [esp+1C] 0040138A |. 83C4 0C add esp, 0C 0040138D |. 55 push ebp ; /String2 0040138E |. 50 push eax ; |String1 0040138F |. FF15 04404000 call dword ptr [<&KERNEL32.lstrcmp>; \lstrcmpA 00401395 |. F7D8 neg eax 00401397 |. 1BC0 sbb eax, eax 00401399 |. 5F pop edi 0040139A |. 5E pop esi 0040139B |. 40 inc eax 0040139C |. 5D pop ebp 0040139D \. C3 retn
我们能够发现call dword ptr [<&KERNEL32.lstrcmp>; lstrcmp指令。说明前面的两參数一定是用来比較的,一个是自己写的错误序列号,一个是这个函数计算出来的正确的序列号。
按F8执行到call dword ptr [<&KERNEL32.lstrcmp>; 处。我们能够发现ebp存放的是“6854”字符串的地址。eax就是我们写的字符串“12345678”的地址(输入的username为billvsme,序列号为12345678)。
从而我们就能够仅仅到username“billvsme”的序列号为6854。