【文章标题】: 新兵初试手-XX聊天记录查看器5.3爆破手记
【文章作者】: MagicWolf
【作者邮箱】: magicwolf@126.com
【作者主页】: www.magicwolf.cn
【作者XX号】: 63630001
【软件名称】: XX聊天记录查看器5.3
【软件大小】: 38 元/套
【下载地址】: http://www.sharebank.com.cn/soft/SoftView_15375.htm
【加壳方式】: 无壳
【保护方式】: 说不来
【编写语言】: Borland Delphi 6.0 - 7.0
【使用工具】: OD,DEDE,PEID
【操作平台】: winXP
【软件介绍】: XX聊天记录查看器5.3 本软件绿色软件,无需安装,可以直接运行,对所有XX版本都有效. 使用方法,直接运行,然后选者要读取的XX号码,然后点击查看就可以查看聊天记录了. 本软件原理是对XX消息数据库文件直接读取,解决了以前版本不能查看 XX2006beta2版本的问题.未注册版本只能使用3次。 软件更新日期 2007.08.16
【作者声明】: 练练手,第一次亲自尝试破解一个软件,算法我分析得头大了,还没分析出来,结果当然是算是失败了,只好爆破(‘爆破’是不是这个意思啊)!
--------------------------------------------------------------------------------
【详细过程】
菜鸟拙作,高手飘过~~
从学习《汇编语言》到看《加密与解密》差不多半个月了,稀里糊涂地学了点皮毛,实在忍不住开始了人生的第一次破解实战,真可惜败下来了~~
下载到软件后第一步运行下看看,可以试用两次。只要输入序列号就能注册,没什么用户名,试用无功能限制。接着就是PEid探壳:Borland Delphi 6.0 - 7.0 无壳,开心(我不会手动脱壳) 既然是delphi程序那就请上DEDE,找到注册按钮的事件触发处的RVA :0046EF30
F9运行,打开注册窗体,输入123456,回到OD ,bp 0046EF30下个断点 点击按钮!
断下!
0046EF30 /. 55 push ebp
0046EF31 |. 8BEC mov ebp, esp
0046EF33 |. 83C4 F4 add esp, -0C
0046EF36 |. 33C9 xor ecx, ecx
0046EF38 |. 894D F4 mov dword ptr [ebp-C], ecx
0046EF3B |. 8955 F8 mov dword ptr [ebp-8], edx
0046EF3E |. 8945 FC mov dword ptr [ebp-4], eax
0046EF41 |. 33C0 xor eax, eax
0046EF43 |. 55 push ebp
0046EF44 |. 68 EFEF4600 push 0046EFEF
0046EF49 |. 64:FF30 push dword ptr fs:[eax]
0046EF4C |. 64:8920 mov dword ptr fs:[eax], esp
0046EF4F |. 8D55 F4 lea edx, dword ptr [ebp-C]
0046EF52 |. 8B45 FC mov eax, dword ptr [ebp-4]
0046EF55 |. 8B80 F0020000 mov eax, dword ptr [eax+2F0]
0046EF5B |. E8 F495FCFF call 00438554
0046EF60 |. 8B55 F4 mov edx, dword ptr [ebp-C]
0046EF63 |. B8 E89C4800 mov eax, 00489CE8
0046EF68 |. E8 6353F9FF call 004042D0
0046EF6D |. A1 E89C4800 mov eax, dword ptr [489CE8]
0046EF72 |. E8 EDFCFFFF call 0046EC64
0046EF77 |. A3 EC9C4800 mov dword ptr [489CEC], eax
0046EF7C |. 833D EC9C4800>cmp dword ptr [489CEC], 0
0046EF83 74 34 je short 0046EFB9
0046EF85 |. 6A 00 push 0
0046EF87 |. A1 E89C4800 mov eax, dword ptr [489CE8]
0046EF8C |. E8 9B57F9FF call 0040472C
0046EF91 |. 50 push eax
0046EF92 |. 68 FCEF4600 push 0046EFFC
0046EF97 |. 8B45 FC mov eax, dword ptr [ebp-4]
0046EF9A |. E8 35FCFCFF call 0043EBD4
0046EF9F |. 50 push eax ; |hOwner
0046EFA0 |. E8 0380F9FF call <jmp.&user32.MessageBoxA> ; \MessageBoxA
0046EFA5 |. A1 E89C4800 mov eax, dword ptr [489CE8]
0046EFAA |. E8 A1FEFFFF call 0046EE50
0046EFAF |. 8B45 FC mov eax, dword ptr [ebp-4]
0046EFB2 |. E8 355DFEFF call 00454CEC
0046EFB7 |. EB 20 jmp short 0046EFD9
0046EFB9 |> 6A 00 push 0
0046EFBB |. A1 E89C4800 mov eax, dword ptr [489CE8]
0046EFC0 |. E8 6757F9FF call 0040472C
0046EFC5 |. 50 push eax
0046EFC6 |. 68 08F04600 push 0046F008
0046EFCB |. 8B45 FC mov eax, dword ptr [ebp-4]
0046EFCE |. E8 01FCFCFF call 0043EBD4
0046EFD3 |. 50 push eax ; |hOwner
0046EFD4 |. E8 CF7FF9FF call <jmp.&user32.MessageBoxA> ; \MessageBoxA
0046EFD9 |> 33C0 xor eax, eax
0046EFDB |. 5A pop edx
0046EFDC |. 59 pop ecx
0046EFDD |. 59 pop ecx
0046EFDE |. 64:8910 mov dword ptr fs:[eax], edx
0046EFE1 |. 68 F6EF4600 push 0046EFF6
0046EFE6 |> 8D45 F4 lea eax, dword ptr [ebp-C]
0046EFE9 |. E8 8E52F9FF call 0040427C
0046EFEE \. C3 retn
0046EFEF .^ E9 B04CF9FF jmp 00403CA4
0046EFF4 .^ EB F0 jmp short 0046EFE6
0046EFF6 . 8BE5 mov esp, ebp
0046EFF8 . 5D pop ebp
0046EFF9 . C3 retn
F8跟下去看了下,0046EF83 处跳到0046EFB9 接着就是明显就是错误提示窗口了
按下F9,果然是。再点注册,重新看,每个call我都F7跟进去了(没经验,发现走了很多弯路,好些都只是处理我输的字符串的,白跟),跟了好久好久,终于在
0046EF72 |. E8 EDFCFFFF call 0046EC64
这里跟进去,有了发现:
[发现]
0046EC64 /$ 55 push ebp
0046EC65 |. 8BEC mov ebp, esp
0046EC67 |. 83C4 C8 add esp, -38
0046EC6A |. 8945 FC mov dword ptr [ebp-4], eax ; 将假注册码地址放到内存
0046EC6D |. 8B45 FC mov eax, dword ptr [ebp-4]
0046EC70 |. E8 A75AF9FF call 0040471C ;跟进去了,但是没理解,于是继续跟
0046EC75 |. 33C0 xor eax, eax
0046EC77 |. 55 push ebp
0046EC78 |. 68 B6ED4600 push 0046EDB6
0046EC7D |. 64:FF30 push dword ptr fs:[eax]
0046EC80 |. 64:8920 mov dword ptr fs:[eax], esp
0046EC83 |. 33C0 xor eax, eax
0046EC85 |. 8945 F8 mov dword ptr [ebp-8], eax
0046EC88 |. 8B45 FC mov eax, dword ptr [ebp-4]
0046EC8B |. E8 A458F9FF call 00404534 ;跟进去,当时也没大明白干什么
0046EC90 |. 83F8 10 cmp eax, 10 ; 从这里看出是上面的call是返回我输入的注册码的长度到EAX,这里与10h比较,就是看是不是输入了16个字节以上.
0046EC93 |. 0F8C 07010000 jl 0046EDA0 ;不是就跳走,下了个断点,重新输了个16位的数字1234567890123456 到这里接着分析 ,因此没跳
0046EC99 |. 8B45 FC mov eax, dword ptr [ebp-4]
0046EC9C |. E8 9358F9FF call 00404534 ;这里跟上面那个call一样的,不知道为什么.
0046ECA1 |. 83F8 10 cmp eax, 10
0046ECA4 |. 0F8F F6000000 jg 0046EDA0
0046ECAA |. 8B45 FC mov eax, dword ptr [ebp-4]
0046ECAD |. BA CCED4600 mov edx, 0046EDCC ; ASCII "1163659294813585" 这里还有下面居然有好几串16字节的数字或字母,难道明码(当然不是,不过当时有过这样的念头),跟进下面那个call,但是进去了却不知道里面在搞什么,跳来跳去,怀疑是迷惑用的!!!下面那4个call也一样~都call同一个地址的...在这里我搅和了很久,没搅和出个所以来~~郁闷啊~可能也敢注册算法有关~
0046ECB2 |. E8 C159F9FF call 00404678
0046ECB7 |. 0F84 E3000000 je 0046EDA0
0046ECBD |. 8B45 FC mov eax, dword ptr [ebp-4]
0046ECC0 |. BA E8ED4600 mov edx, 0046EDE8 ; ASCII "0386848021608060"
0046ECC5 |. E8 AE59F9FF call 00404678
0046ECCA |. 0F84 D0000000 je 0046EDA0
0046ECD0 |. 8B45 FC mov eax, dword ptr [ebp-4]
0046ECD3 |. BA 04EE4600 mov edx, 0046EE04 ; ASCII "8319E4005F00PYG0"
0046ECD8 |. E8 9B59F9FF call 00404678
0046ECDD |. 0F84 BD000000 je 0046EDA0
0046ECE3 |. 8B45 FC mov eax, dword ptr [ebp-4]
0046ECE6 |. BA 20EE4600 mov edx, 0046EE20 ; ASCII "0566838690673180"
0046ECEB |. E8 8859F9FF call 00404678
0046ECF0 |. 0F84 AA000000 je 0046EDA0
0046ECF6 |. 8B45 FC mov eax, dword ptr [ebp-4]
0046ECF9 |. BA 3CEE4600 mov edx, 0046EE3C ; ASCII "0386748036909760"
0046ECFE |. E8 7559F9FF call 00404678
0046ED03 |. 0F84 97000000 je 0046EDA0
0046ED09 |. 33C0 xor eax, eax ;结果搅和到这里了,发现只要是输入了16字节的任何数字字母都能到这里,感觉下面这一大段才是核心.
0046ED0B |. 8945 DC mov dword ptr [ebp-24], eax
0046ED0E |> 8B45 FC /mov eax, dword ptr [ebp-4]
0046ED11 |. 8B55 DC |mov edx, dword ptr [ebp-24]
0046ED14 |. 8A0410 |mov al, byte ptr [eax+edx]
0046ED17 |. E8 00FFFFFF |call 0046EC1C ;这里跟进去是:
0046EC1C /$ 55 push ebp
0046EC1D |. 8BEC mov ebp, esp
0046EC1F |. 51 push ecx
0046EC20 |. 8845 FF mov byte ptr [ebp-1], al
0046EC23 |. 807D FF 30 cmp byte ptr [ebp-1], 30
0046EC27 |. 72 10 jb short 0046EC39
0046EC29 |. 807D FF 39 cmp byte ptr [ebp-1], 39
0046EC2D |. 77 0A ja short 0046EC39
0046EC2F |. 8A45 FF mov al, byte ptr [ebp-1]
0046EC32 |. 2C 30 sub al, 30
0046EC34 |. 8845 FD mov byte ptr [ebp-3], al
0046EC37 |. EB 1C jmp short 0046EC55
0046EC39 |> 807D FF 41 cmp byte ptr [ebp-1], 41
0046EC3D |. 72 12 jb short 0046EC51
0046EC3F |. 807D FF 46 cmp byte ptr [ebp-1], 46
0046EC43 |. 77 0C ja short 0046EC51
0046EC45 |. 8A45 FF mov al, byte ptr [ebp-1]
0046EC48 |. 2C 41 sub al, 41
0046EC4A |. 04 0A add al, 0A
0046EC4C |. 8845 FD mov byte ptr [ebp-3], al
0046EC4F |. EB 04 jmp short 0046EC55
0046EC51 |> C645 FD FF mov byte ptr [ebp-3], 0FF
0046EC55 |> 8A45 FD mov al, byte ptr [ebp-3]
0046EC58 |. 8845 FE mov byte ptr [ebp-2], al
0046EC5B |. 8A45 FE mov al, byte ptr [ebp-2]
0046EC5E |. 59 pop ecx
0046EC5F |. 5D pop ebp
0046EC60 \. C3 retn
0046ED1C |. 8B55 DC |mov edx, dword ptr [ebp-24]
0046ED1F |. 884415 CB |mov byte ptr [ebp+edx-35], al
0046ED23 |. FF45 DC |inc dword ptr [ebp-24]
0046ED26 |. 837D DC 10 |cmp dword ptr [ebp-24], 10 ;循环16次,但是我不太会分析上面那个call,头大啊.也不知道干了什么.到这一步也就注定了我的失败.想到了爆破.
0046ED2A |.^ 75 E2 \jnz short 0046ED0E
0046ED2C |. 33C0 xor eax, eax
0046ED2E |. 8945 E0 mov dword ptr [ebp-20], eax
0046ED31 |> 8B45 E0 /mov eax, dword ptr [ebp-20]
0046ED34 |. 03C0 |add eax, eax
0046ED36 |. 8A4405 CC |mov al, byte ptr [ebp+eax-34]
0046ED3A |. C1E0 04 |shl eax, 4
0046ED3D |. 8B55 E0 |mov edx, dword ptr [ebp-20]
0046ED40 |. 03D2 |add edx, edx
0046ED42 |. 024415 CB |add al, byte ptr [ebp+edx-35]
0046ED46 |. 8B55 E0 |mov edx, dword ptr [ebp-20]
0046ED49 |. 884415 EF |mov byte ptr [ebp+edx-11], al
0046ED4D |. FF45 E0 |inc dword ptr [ebp-20]
0046ED50 |. 837D E0 09 |cmp dword ptr [ebp-20], 9
0046ED54 |.^ 75 DB \jnz short 0046ED31
0046ED56 |. 8A45 F2 mov al, byte ptr [ebp-E]
0046ED59 |. 3245 EF xor al, byte ptr [ebp-11]
0046ED5C |. 8845 E6 mov byte ptr [ebp-1A], al
0046ED5F |. 8A45 F0 mov al, byte ptr [ebp-10]
0046ED62 |. 3245 F6 xor al, byte ptr [ebp-A]
0046ED65 |. 8845 E7 mov byte ptr [ebp-19], al
0046ED68 |. 8A45 F1 mov al, byte ptr [ebp-F]
0046ED6B |. 3245 F4 xor al, byte ptr [ebp-C]
0046ED6E |. 8845 E8 mov byte ptr [ebp-18], al
0046ED71 |. 8A45 F5 mov al, byte ptr [ebp-B]
0046ED74 |. 3245 F3 xor al, byte ptr [ebp-D]
0046ED77 |. 8845 E9 mov byte ptr [ebp-17], al
0046ED7A |. 807D E6 38 cmp byte ptr [ebp-1A], 38
0046ED7E 75 1B jnz short 0046ED9B
0046ED80 |. 807D E7 6E cmp byte ptr [ebp-19], 6E
0046ED84 |. 75 15 jnz short 0046ED9B
0046ED86 |. 807D E8 4E cmp byte ptr [ebp-18], 4E
0046ED8A |. 75 0F jnz short 0046ED9B
0046ED8C |. 807D E9 1A cmp byte ptr [ebp-17], 1A
0046ED90 |. 75 09 jnz short 0046ED9B
0046ED92 |. C745 F8 FFFFF>mov dword ptr [ebp-8], -1
0046ED99 |. EB 05 jmp short 0046EDA0
0046ED9B |> 33C0 xor eax, eax
0046ED9D |. 8945 F8 mov dword ptr [ebp-8], eax
0046EDA0 |> 33C0 xor eax, eax
0046EDA2 |. 5A pop edx
0046EDA3 |. 59 pop ecx
0046EDA4 |. 59 pop ecx
0046EDA5 |. 64:8910 mov dword ptr fs:[eax], edx
0046EDA8 |. 68 BDED4600 push 0046EDBD
0046EDAD |> 8D45 FC lea eax, dword ptr [ebp-4]
0046EDB0 |. E8 C754F9FF call 0040427C
0046EDB5 \. C3 retn
0046EDB6 .^ E9 E94EF9FF jmp 00403CA4
0046EDBB .^ EB F0 jmp short 0046EDAD
0046EDBD 8B45 F8 mov eax, dword ptr [ebp-8]
0046EDC0 8BE5 mov esp, ebp
0046EDC2 . 5D pop ebp
0046EDC3 . C3 retn
[/发现]
一直看到这里,,[发现]分析完了(分析个P,啥也没分析还出来),放弃了...一个头两个大,决定采取爆破了~~~几次跟踪中发现点击程序"查看"按钮(弹出注册码输入窗口)的时候会去检测注册码的(从反汇编窗口跟数据窗口间的那个窗口注意到的)之后如果保存在某处的注册码错误的话才会弹出注册码输入窗口,于是查找那几个16字节长度的字符串(在以上[发现]内的),在
0046ED68 |. 8A45 F1 mov al, byte ptr [ebp-F]
处随便断了个点~~~发现断的太后面了,在
0046ED7E /75 1B jnz short 0046ED9B
下了个断点,重新调试:
0046ED74 |. 3245 F3 xor al, byte ptr [ebp-D]
0046ED77 |. 8845 E9 mov byte ptr [ebp-17], al
0046ED7A |. 807D E6 38 cmp byte ptr [ebp-1A], 38
0046ED7E 75 1B jnz short 0046ED9B
0046ED80 |. 807D E7 6E cmp byte ptr [ebp-19], 6E
0046ED84 |. 75 15 jnz short 0046ED9B
0046ED86 |. 807D E8 4E cmp byte ptr [ebp-18], 4E
0046ED8A |. 75 0F jnz short 0046ED9B
0046ED8C |. 807D E9 1A cmp byte ptr [ebp-17], 1A
0046ED90 |. 75 09 jnz short 0046ED9B
0046ED92 |. C745 F8 FFFFF>mov dword ptr [ebp-8], -1
0046ED99 |. EB 05 jmp short 0046EDA0
0046ED9B |> 33C0 xor eax, eax
0046ED9D |. 8945 F8 mov dword ptr [ebp-8], eax
0046EDA0 |> 33C0 xor eax, eax
0046EDA2 |. 5A pop edx
0046EDA3 |. 59 pop ecx
0046EDA4 |. 59 pop ecx
0046EDA5 |. 64:8910 mov dword ptr fs:[eax], edx
0046EDA8 |. 68 BDED4600 push 0046EDBD
0046EDAD |> 8D45 FC lea eax, dword ptr [ebp-4]
0046EDB0 |. E8 C754F9FF call 0040427C
0046EDB5 \. C3 retn
0046EDB6 .^ E9 E94EF9FF jmp 00403CA4
0046EDBB .^ EB F0 jmp short 0046EDAD
0046EDBD 8B45 F8 mov eax, dword ptr [ebp-8]
0046EDC0 8BE5 mov esp, ebp
0046EDC2 . 5D pop ebp
0046EDC3 . C3 retn
这里发现
0046ED7E 75 1B jnz short 0046ED9B
以及下面的几个jnz
跳与不跳的结果是导致ds:[ebp-8]是00000000还是FFFFFFFF (这个应该是爆破关键了)
那我就改
0046ED7E 75 1B jmp short 0046ED92
F8慢慢跟下去
跟到这:0046EDBD 8B45 F8 mov eax, dword ptr [ebp-8]
EAX=FFFFFFFF了,它应该就是这个[发现]call的返回值吧 .
继续跟,返回到这么一个地方,感觉这返回值没用啊:
0046FAA0 |. 8B15 D0884800 mov edx, dword ptr [4888D0] ; QQ聊天记.00489CEC
0046FAA6 |. 8902 mov dword ptr [edx], eax
0046FAA8 |. 8B45 FC mov eax, dword ptr [ebp-4]
0046FAAB |. 8B80 F8020000 mov eax, dword ptr [eax+2F8]
0046FAB1 |. 8B10 mov edx, dword ptr [eax]
0046FAB3 |. FF92 C8000000 call dword ptr [edx+C8]
比较陌生的,继续跟,跟进0046FAB3这里的call,又出来了,跟昏掉了~~~
不跟了,F9,结果好,狗屎运啊,直接跳过注册窗口可以用了!!!
但是那个FFFFFFFF返回值干什么的?带着疑问,重新来,出现那个点出注册窗口后我再在上面那处下断点,同样改0046ED7E 75 1B jmp short 0046ED92,之后F8跟,
retn出来后到这里了,熟悉啊~~~:
0046EF77 |. A3 EC9C4800 mov dword ptr [489CEC], eax
0046EF7C |. 833D EC9C4800>cmp dword ptr [489CEC], 0
0046EF83 74 34 je short 0046EFB9
0046EF85 |. 6A 00 push 0
0046EF87 |. A1 E89C4800 mov eax, dword ptr [489CE8]
0046EF8C |. E8 9B57F9FF call 0040472C
0046EF91 |. 50 push eax
0046EF92 |. 68 FCEF4600 push 0046EFFC
0046EF97 |. 8B45 FC mov eax, dword ptr [ebp-4]
0046EF9A |. E8 35FCFCFF call 0043EBD4
0046EF9F |. 50 push eax ; |hOwner
0046EFA0 |. E8 0380F9FF call <jmp.&user32.MessageBoxA> ; \MessageBoxA
0046EFA5 |. A1 E89C4800 mov eax, dword ptr [489CE8]
0046EFAA |. E8 A1FEFFFF call 0046EE50
0046EFAF |. 8B45 FC mov eax, dword ptr [ebp-4]
0046EFB2 |. E8 355DFEFF call 00454CEC
0046EFB7 |. EB 20 jmp short 0046EFD9
0046EFB9 |> 6A 00 push 0
0046EFBB |. A1 E89C4800 mov eax, dword ptr [489CE8]
0046EFC0 |. E8 6757F9FF call 0040472C
0046EFC5 |. 50 push eax
0046EFC6 |. 68 08F04600 push 0046F008
0046EFCB |. 8B45 FC mov eax, dword ptr [ebp-4]
0046EFCE |. E8 01FCFCFF call 0043EBD4
0046EFD3 |. 50 push eax ; |hOwner
0046EFD4 |. E8 CF7FF9FF call <jmp.&user32.MessageBoxA> ; \MessageBoxA
0046EFD9 |> 33C0 xor eax, eax
0046EFDB |. 5A pop edx
0046EFDC |. 59 pop ecx
0046EFDD |. 59 pop ecx
0046EFDE |. 64:8910 mov dword ptr fs:[eax], edx
0046EFE1 |. 68 F6EF4600 push 0046EFF6
0046EFE6 |> 8D45 F4 lea eax, dword ptr [ebp-C]
0046EFE9 |. E8 8E52F9FF call 0040427C
0046EFEE \. C3 retn
0046EFEF .^ E9 B04CF9FF jmp 00403CA4
0046EFF4 .^ EB F0 jmp short 0046EFE6
0046EFF6 . 8BE5 mov esp, ebp
0046EFF8 . 5D pop ebp
0046EFF9 . C3 retn
~~~这回知道那个返回值用处了,0046EF83 74 34 je short 0046EFB9
返回0则跳,非0不跳,此处先下个断点,再F9 提示注册成功!
可惜我没搞明白算法(这才是软件逆向工程的核心吧)
我找的这个爆破点就是:0046ED7E处 改成 jmp short 0046ED92
【经验总结】这是我第一次自己分析一个软件(前些日子都是看书做那些Crackme的小例子),尽管没有分析处算法,但是通过这个软件的练习对一些跳转的分析,下断点的位置等等方面有了或多或少的提高,对OD的操作也熟悉了不少~~总之收获很大啊~~
PS.文章写得不好还请见谅哈~~
[课程]FART 脱壳王!加量不加价!FART作者讲授!