【文章标题】: 奇怪思路:菜鸟破解不是办法的办法(菜鸟写给菜鸟看,高手勿进)
【文章作者】: BoXer[ICY]
【作者邮箱】: scship@163.com
【作者主页】: http://boxer.yo2.cn
【作者QQ号】: **********
【软件名称】: Extreme Picture Finder
【软件大小】: 1.03 MB(安装后的主程序)
【下载地址】: http://www.exisoftware.com/picture_finder/download.php/PictureFinderSetup.exe
【加壳方式】: UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo
【保护方式】: 是加壳方式嘛?
【编写语言】: delphi
【使用工具】: OD,peid,鼠标,键盘,显示器,主机
【操作平台】: 盗版中的正版xp sp2
【软件介绍】: 能搜索网站里面的指定文件(对图片网是绝杀),推荐
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
1。脱壳
下载,安装,查壳:UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo
peid插件脱就可以了(什么?你不会?那我也没办法了。。。(-_-!) )。
再看看程序是delphi写的。
==================顽皮的分隔线===============
2。收集信息
运行软件,出现nag,点输入注册码,随便输入后发现重启验证。
脑子里立刻想出重启验证的方法,找出假注册码放在那里
如果放在注册表就下注册表断点,如果放在文件就下文件断点
==================华丽的分隔线===============
3。初步试探
od载入,尝试下一些注册表断点(像我们这样的菜鸟可以找带有API断点插件的OD一次多下几个)
以下是百度回来的一些常识,给像我这样的菜鸟学习一下。
访问注册表类常用API
RegOpenKeyA 打开一个现有的注册表项
RegOpenKeyExA 打开一个现有的注册表项
RegCreateKeyA 在指定的项下创建或打开一个项
RegCreateKeyExA 在指定项下创建新项的更复杂的方式
RegDeleteKeyA 删除现有项下方一个指定的子项
RegDeleteValueA 删除指定项下方的一个值
RegQueryValueA 获取一个项的设置值
RegQueryValueExA 获取一个项的设置值
RegSetValueA 设置指定项或子项的值
RegSetValueExA 设置指定项的值
RegCloseKey 关闭系统注册表中的一个项(或键)
访问文件类常用API
CreateFileA 打开和创建文件、管道、邮槽、通信服务、设备以及控制台
OpenFile 这个函数能执行大量不同的文件操作
ReadFile 从文件中读出数据
ReadFileEx 与ReadFile相似,只是它只能用于异步读操作,并包含了一个完整的回调
在这里bp RegOpenKeyExA可以断下来,但是没有找到什么有用的信息(可能是我菜。。。)
==================漂亮的分隔线===============
3。苦力跟进
既然下断没什么用,DeDe也试过没用。。。那么我只好一步一步的跟了。。。
当然不是整天F8,恰当的几个F4是比较快的。
005AB320 >/$ 55 PUSH EBP ;od载入停在这里
005AB321 |. 8BEC MOV EBP,ESP
005AB323 |. 83C4 E0 ADD ESP,-20
005AB326 |. 33C0 XOR EAX,EAX
005AB328 |. 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX
005AB32B |. 8945 E0 MOV DWORD PTR SS:[EBP-20],EAX
005AB32E |. 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
005AB331 |. 8945 EC MOV DWORD PTR SS:[EBP-14],EAX
005AB334 |. B8 08AC5A00 MOV EAX,dump.005AAC08
005AB339 |. E8 0EBEE5FF CALL dump.0040714C ;读取注册表的call,是初始化一些东西
。。。。。。。。。。(菜鸟最爱的省略号)。。。。。。。。。。。。。。
005AB575 |. 8B15 34FA5B00 MOV EDX,DWORD PTR DS:[5BFA34]
005AB57B |. 8902 MOV DWORD PTR DS:[EDX],EAX
005AB57D |. A1 34FA5B00 MOV EAX,DWORD PTR DS:[5BFA34]
005AB582 |. 8B00 MOV EAX,DWORD PTR DS:[EAX]
005AB584 |. E8 17F3FFFF CALL dump.005AA8A0 ; 重点!出现nag!,重新载入F7跟进!
005AB589 |> 33C0 XOR EAX,EAX
005AB58B |. 5A POP EDX
005AB58C |. 59 POP ECX
005AB58D |. 59 POP ECX
005AB58E |. 64:8910 MOV DWORD PTR FS:[EAX],EDX
005AB591 |. 68 ABB55A00 PUSH dump.005AB5AB
005AB596 |> 8D45 E0 LEA EAX,DWORD PTR SS:[EBP-20]
005AB599 |. BA 04000000 MOV EDX,4
005AB59E |. E8 0998E5FF CALL dump.00404DAC
005AB5A3 \. C3 RETN
我们跟进 005AB584 |. E8 17F3FFFF CALL dump.005AA8A0 去看看
005AA8A0 /$ A1 A4F85B00 MOV EAX,DWORD PTR DS:[5BF8A4] ;来到这里
005AA8A5 |. 8B00 MOV EAX,DWORD PTR DS:[EAX]
005AA8A7 |. BA C0A85A00 MOV EDX,dump.005AA8C0 ; ASCII "Extreme Picture Finder"
005AA8AC |. E8 2B80F2FF CALL dump.004D28DC
005AA8B1 |. E8 CAF9FFFF CALL dump.005AA280 ; 出现nag,再次od载入F7跟进!
005AA8B6 \. C3 RETN
我们跟进 005AA8B1 |. E8 CAF9FFFF CALL dump.005AA280 去看看
005AA280 $ 55 PUSH EBP ; 来到这里
005AA281 . 8BEC MOV EBP,ESP
005AA283 . 83C4 DC ADD ESP,-24
005AA286 . 53 PUSH EBX
005AA287 . 56 PUSH ESI
005AA288 . 33C0 XOR EAX,EAX
。。。。。。。。。。(又是菜鸟最爱的省略号)。。。。。。。。。。。
005AA3B3 . E8 B4BCE5FF CALL dump.0040606C
005AA3B8 . BA EC995A00 MOV EDX,dump.005A99EC ; |入口地址
005AA3BD . 0355 F4 ADD EDX,DWORD PTR SS:[EBP-C] ; |
005AA3C0 . 03C2 ADD EAX,EDX ; |
005AA3C2 . 50 PUSH EAX ; |Address
005AA3C3 . E8 10D2E5FF CALL <JMP.&KERNEL32.GetCurrentProcess> ; |[GetCurrentProcess
005AA3C8 . 50 PUSH EAX ; |hProcess
005AA3C9 . E8 BAD4E5FF CALL <JMP.&KERNEL32.WriteProcessMemory> ; \WriteProcessMemory
005AA3CE . EB 06 JMP SHORT dump.005AA3D6
005AA3D0 . 1313 ADC EDX,DWORD PTR DS:[EBX]
005AA3D2 . FD STD
005AA3D3 . 95 XCHG EAX,EBP
005AA3D4 . 1BCF SBB ECX,EDI
005AA3D6 > E8 11F6FFFF CALL dump.005A99EC ; 出现nag,同样要跟进去!
我们跟进 005AA3D6 > E8 11F6FFFF CALL dump.005A99EC 去看看
005A99EC $ 55 PUSH EBP ;来到这里
005A99ED . 8BEC MOV EBP,ESP
005A99EF . 51 PUSH ECX
005A99F0 . 53 PUSH EBX
005A99F1 . 56 PUSH ESI
005A99F2 . 57 PUSH EDI
005A99F3 . 33C0 XOR EAX,EAX
005A99F5 . 55 PUSH EBP
005A99F6 . 68 4B9A5A00 PUSH dump.005A9A4B
005A99FB . 64:FF30 PUSH DWORD PTR FS:[EAX]
005A99FE . 64:8920 MOV DWORD PTR FS:[EAX],ESP
005A9A01 . EB 06 JMP SHORT dump.005A9A09
005A9A03 . 4D DEC EBP
005A9A04 . 0D 0C591E75 OR EAX,751E590C
005A9A09 > E8 E217F3FF CALL dump.004DB1F0 ; 算法call,返回AL的值
005A9A0E . 84C0 TEST AL,AL
005A9A10 . 75 22 JNZ SHORT dump.005A9A34 ; AL=1就跳过nag,AL=0就继续执行
005A9A12 . 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
005A9A15 . E8 9A21F3FF CALL dump.004DBBB4
005A9A1A . A1 8C395C00 MOV EAX,DWORD PTR DS:[5C398C]
005A9A1F . 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
005A9A22 . 8950 0C MOV DWORD PTR DS:[EAX+C],EDX
005A9A25 . A1 8C395C00 MOV EAX,DWORD PTR DS:[5C398C]
005A9A2A . 8B10 MOV EDX,DWORD PTR DS:[EAX]
005A9A2C . FF92 EC000000 CALL DWORD PTR DS:[EDX+EC] ; 上面没有跳转的话这里就出现nag
005A9A32 . EB 0D JMP SHORT dump.005A9A41
005A9A34 > E8 DF090000 CALL dump.005AA418 ;上面如果跳下来的话就出现主程序而没有nag
如果来到这里没有完全显示代码的话,可以选一大部分,右键-分析-分析代码,就可以看到了
我们分析了这些代码,找到了除去nag的关键跳,但是如果我们直接改跳是不能运行的
所以只好用标志位改法。
重新载入od,几个F4就到了这个call
005A9A09 > E8 E217F3FF CALL dump.004DB1F0
F7跟进去,把开始2句改为:
mov al,1
retn
直接保存后运行程序,nag去了!但是还是显示没注册。。。
(其实找nag关键跳,卡卡后来告诉我一个方法,但是我表达能力差,就不写出来了)
==================无敌的分隔线===============
4。不会算法
去了nag给我们信心,给我们力量,给我们。。。
既然改了关键call不行,那么我们不妨进去研究一下关键call
几个F4来到 005A9A09 > E8 E217F3FF CALL dump.004DB1F0 , F7跟进去
004DB1F0 . 55 PUSH EBP ;来到这里
004DB1F1 . 8BEC MOV EBP,ESP
004DB1F3 . 83C4 DC ADD ESP,-24
。。。。。。。。。。(还是菜鸟最爱的省略号)。。。。。。。。。。。
我们跟啊跟。。。跟到下面那个call进去后发现是算法call
004DB33A . 0355 F4 ADD EDX,DWORD PTR SS:[EBP-C] ; |
004DB33D . 03C2 ADD EAX,EDX ; |
004DB33F . 50 PUSH EAX ; |Address
004DB340 . E8 93C2F2FF CALL <JMP.&KERNEL32.GetCurrentProcess> ; |[GetCurrentProcess
004DB345 . 50 PUSH EAX ; |hProcess
004DB346 . E8 3DC5F2FF CALL <JMP.&KERNEL32.WriteProcessMemory> ; \WriteProcessMemory
004DB34B . E8 1CFAFFFF CALL dump.004DAD6C ;进去这个call,应该是算法call
进去 004DB34B . E8 1CFAFFFF CALL dump.004DAD6C 后来到下面:
004D7C44 /$ 55 PUSH EBP ;来到这里,这时候寄存器EAX会显示我们的假注册码
004D7C45 |. 8BEC MOV EBP,ESP
004D7C47 |. B9 05000000 MOV ECX,5
然后我们在下面不远会发现一个大跳
004D7CCE |. 85FF TEST EDI,EDI
004D7CD0 0F8E 7A010000 JLE dump.004D7E50 ;这个跳的很大,改jmp保存试试
004D7CD6 |. BE 01000000 MOV ESI,1
004D7E58 |. 85C0 TEST EAX,EAX
004D7E5A 0F84 83030000 JE dump.004D81E3 ; 这个跳的也很大,改jmp保存试试
004D7E60 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
发现无论改上面那个跳,程序都是天数用完了。。。进不去主程序了。。。。
这时候我灵光一闪,如果我们把用完天数的程序再去掉nag,程序会怎样呢?
说干就干
od载入用完天数的程序,然后用步骤三把
005A9A09 > E8 E217F3FF CALL dump.004DB1F0
F7跟进去,把开始2句改为:
mov al,1
retn
保存,发现程序可以用了!而且提示是没有注册名而已,而不是没注册!
不知道是不是真的可以永远能用了。。。
--------------------------------------------------------------------------------
【经验总结】
没什么总结的,就是思路有点怪。。。这是不懂算法的菜鸟的一些思路,写给同样是菜鸟的人一个参考
高手就不要笑了,希望进来看的高手能照顾一下我们这些不会算法的菜鸟
能分析一下这个程序,写出1字节完美破解或者写个算法分析给我们菜鸟
那么我们菜鸟是非常的感激。。。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2007年03月28日 1:42:03
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课