我感觉这个破解非常好,分析的也很透彻,大家不妨看看。。。不管大家看过没有哈。。。
【文章标题】: 电脑算命专家(原名:半仙算命)2010 build07.01 爆破+追码+算法分析+注册机编写
文章作者】: 2666fff
【作者邮箱】: wan0001@brauer.vic.edu.au
【软件名称】: 电脑算命专家(软件原名:半仙算命) 2010 build 07.01
【下载地址】: http://www.onlinedown.net/soft/45454.htm
--------------------------------------------------------------------------------
【详细过程】
Peid查壳 PECompact 2.x -> Jeremy Collake
exe info查 PEcompact ver.2.78a ~2.94 - www.bitsum.com
反正就是pecompact了,脱吧。
OD载入
00401000 > B8 74BA6E00 mov eax,ssbx.006EBA74
00401005 50 push eax ; 有push就esp吧
00401006 64:FF35 0000000>push dword ptr fs:[0]
0040100D 64:8925 0000000>mov dword ptr fs:[0],esp
00401014 33C0 xor eax,eax
00401016 8908 mov dword ptr ds:[eax],ecx
00401018 50 push eax
F9一次之后硬件断点不要删除,继续按,我这里是一直按了4次f9,然后就直接到了这里:
006EBB36 - FFE0 jmp eax ; 4次F9到了这里
006EBB38 1852 58 sbb byte ptr ds:[edx+0x58],dl
一个大跳,很明显就是要到oep的地方,单步一下。
00585218 55 push ebp ; 这里就是OEP了 直接dump
00585219 8BEC mov ebp,esp
0058521B 83C4 F0 add esp,-0x10
0058521E 53 push ebx
0058521F B8 284B5800 mov eax,ssbx.00584B28
00585224 E8 AB20E8FF call ssbx.004072D4
00585229 8B1D 6C9C5800 mov ebx,dword ptr ds:[0x589C6C] ; ssbx.0058AC38
0058522F 8B03 mov eax,dword ptr ds:[ebx]
00585231 E8 7241EEFF call ssbx.004693A8
loadpe 脱壳, import REC修复,PEID再查壳 Borland Delphi 6.0 - 7.0
Delphi 写的,载入DEDE吧。
载入后,点击 窗体 一栏,发现有很多TForm,一个个点开看下,然后,就在TForm2这里发现了 注册声明 字样,
往下拉,又发现:
object BitBtn1: TBitBtn
Left = 12
Top = 268
Width = 89
Height = 25
Caption = 确认注册
TabOrder = 2
OnClick = BitBtn1Click
end
恩,BitBtn1Click 这个就是注册的按钮了, 进入 窗体 旁边的 过程 一栏,单击 TForm2, 里面果然有 BitBtn1Click
这个,看RVA是 0056D034 很明显,这个就是按钮事件的地址了。
ok,OD载入我们脱好壳的文件, Ctrl + G 进入 0056D034 这个地址,F2下断,F9运行。
0056D034 . 55 push ebp //F2
0056D035 . 8BEC mov ebp,esp
0056D037 . 81C4 80FEFFFF add esp,-0x180
0056D03D . 53 push ebx
0056D03E . 33C9 xor ecx,ecx
0056D040 . 898D 80FEFFFF mov dword ptr ss:[ebp-0x180],ecx
0056D046 . 898D 8CFEFFFF mov dword ptr ss:[ebp-0x174],ecx
0056D04C . 898D 88FEFFFF mov dword ptr ss:[ebp-0x178],ecx
0056D052 . 898D 84FEFFFF mov dword ptr ss:[ebp-0x17C],ecx
0056D058 . 898D 94FEFFFF mov dword ptr ss:[ebp-0x16C],ecx
0056D05E . 898D 90FEFFFF mov dword ptr ss:[ebp-0x170],ecx
0056D064 . 898D 9CFEFFFF mov dword ptr ss:[ebp-0x164],ecx
0056D06A . 898D 98FEFFFF mov dword ptr ss:[ebp-0x168],ecx
0056D070 . 898D A4FEFFFF mov dword ptr ss:[ebp-0x15C],ecx
0056D076 . 898D A0FEFFFF mov dword ptr ss:[ebp-0x160],ecx
0056D07C . 8945 FC mov dword ptr ss:[ebp-0x4],eax
0056D07F . 33C0 xor eax,eax
程序打开了,进入注册页面,随便输入序列号以及注册码,点击注册按钮,OD已经断下来了。
F8单步向下走。
0056D0A6 . E8 514BF0FF call dumped_.00471BFC
0056D0AB . 8945 F8 mov dword ptr ss:[ebp-0x8],eax
0056D0AE . BA 02000080 mov edx,0x80000002
0056D0B3 . 8B45 F8 mov eax,dword ptr ss:[ebp-0x8]
0056D0B6 . E8 E14BF0FF call dumped_.00471C9C
0056D0BB . B1 01 mov cl,0x1
0056D0BD . BA 68D35600 mov edx,dumped_.0056D368 ; SOFTWARE\Microsoft\Yhds
0056D0C2 . 8B45 F8 mov eax,dword ptr ss:[ebp-0x8]
0056D0C5 . E8 364CF0FF call dumped_.00471D00 ; 读取注册表信息
0056D0CA . 8D95 A0FEFFFF lea edx,dword ptr ss:[ebp-0x160]
0056D0D0 . 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
0056D0D3 . 8B98 F8020000 mov ebx,dword ptr ds:[eax+0x2F8]
0056D0D9 . 8BC3 mov eax,ebx
0056D0DB . E8 60B1EDFF call dumped_.00448240
0056D0E0 . 8B85 A0FEFFFF mov eax,dword ptr ss:[ebp-0x160] ; 出现注册名
0056D0E6 . 8D95 A4FEFFFF lea edx,dword ptr ss:[ebp-0x15C]
0056D0EC . E8 0BC4E9FF call dumped_.004094FC
0056D0F1 . 8B95 A4FEFFFF mov edx,dword ptr ss:[ebp-0x15C]
0056D0F7 . 8BC3 mov eax,ebx
0056D0F9 . E8 72B1EDFF call dumped_.00448270
0056D0FE . 8D95 98FEFFFF lea edx,dword ptr ss:[ebp-0x168]
0056D104 . 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
0056D107 . 8B98 00030000 mov ebx,dword ptr ds:[eax+0x300]
0056D10D . 8BC3 mov eax,ebx
0056D10F . E8 2CB1EDFF call dumped_.00448240
0056D114 . 8B85 98FEFFFF mov eax,dword ptr ss:[ebp-0x168]
0056D11A . 8D95 9CFEFFFF lea edx,dword ptr ss:[ebp-0x164] ; 出现假注册码
0056D120 . E8 D7C3E9FF call dumped_.004094FC
0056D125 . 8B95 9CFEFFFF mov edx,dword ptr ss:[ebp-0x164]
0056D12B . 8BC3 mov eax,ebx
0056D12D . E8 3EB1EDFF call dumped_.00448270
0056D132 . 8D95 94FEFFFF lea edx,dword ptr ss:[ebp-0x16C]
0056D138 . 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
0056D13B . 8B80 00030000 mov eax,dword ptr ds:[eax+0x300]
0056D141 . E8 FAB0EDFF call dumped_.00448240
0056D146 . 83BD 94FEFFFF>cmp dword ptr ss:[ebp-0x16C],0x0
0056D14D . 74 1D je short dumped_.0056D16C
0056D14F . 8D95 90FEFFFF lea edx,dword ptr ss:[ebp-0x170]
0056D155 . 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
0056D158 . 8B80 F8020000 mov eax,dword ptr ds:[eax+0x2F8]
0056D15E . E8 DDB0EDFF call dumped_.00448240
0056D163 . 83BD 90FEFFFF>cmp dword ptr ss:[ebp-0x170],0x0
0056D16A . 75 0F jnz short dumped_.0056D17B
0056D16C > B8 88D35600 mov eax,dumped_.0056D388 ; 注册信息没有填写齐全
0056D171 . E8 563EEDFF call dumped_.00440FCC
0056D176 . E9 6D010000 jmp dumped_.0056D2E8
0056D17B > 8D95 8CFEFFFF lea edx,dword ptr ss:[ebp-0x174]
0056D181 . 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
0056D184 . 8B80 00030000 mov eax,dword ptr ds:[eax+0x300]
0056D18A . E8 B1B0EDFF call dumped_.00448240
0056D18F . 8B85 8CFEFFFF mov eax,dword ptr ss:[ebp-0x174]
0056D195 . 50 push eax
0056D196 . 8D95 84FEFFFF lea edx,dword ptr ss:[ebp-0x17C]
0056D19C . 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
0056D19F . 8B80 F8020000 mov eax,dword ptr ds:[eax+0x2F8]
0056D1A5 . E8 96B0EDFF call dumped_.00448240
0056D1AA . 8B85 84FEFFFF mov eax,dword ptr ss:[ebp-0x17C]
0056D1B0 . E8 4BC7E9FF call dumped_.00409900
0056D1B5 . 6BC0 70 imul eax,eax,0x70 ; 用户名的16进制乘上70
0056D1B8 . 8D95 88FEFFFF lea edx,dword ptr ss:[ebp-0x178]
0056D1BE . E8 7DFDFFFF call dumped_.0056CF40 ; 关键算法call,F7进入。
0056D1C3 . 8B95 88FEFFFF mov edx,dword ptr ss:[ebp-0x178]
0056D1C9 . 58 pop eax ; 这里堆栈出现真码,追码一直到这里就算完成了。
0056D1CA . E8 217EE9FF call dumped_.00404FF0
0056D1CF 0F85 F3000000 jnz dumped_.0056D2C8 ; 关键跳,跳了就死,nop掉就爆破了。
0056D1D5 . BA A8D35600 mov edx,dumped_.0056D3A8 ; ssbf.dll
0056D1DA . 8D85 A8FEFFFF lea eax,dword ptr ss:[ebp-0x158]
0056D1E0 . E8 535DE9FF call dumped_.00402F38
0056D1E5 . BA 01000000 mov edx,0x1
追码跟爆破都很简单,一步就完成了。
进入关键call之后就是算法了:
0056CF40 /$ 55 push ebp
0056CF41 |. 8BEC mov ebp,esp
0056CF43 |. 33C9 xor ecx,ecx
0056CF45 |. 51 push ecx
0056CF46 |. 51 push ecx
0056CF47 |. 51 push ecx
0056CF48 |. 51 push ecx
0056CF49 |. 53 push ebx
0056CF4A |. 56 push esi
0056CF4B |. 8BF2 mov esi,edx
0056CF4D |. 8BD8 mov ebx,eax
0056CF4F |. 33C0 xor eax,eax
0056CF51 |. 55 push ebp
0056CF52 |. 68 10D05600 push dumped_.0056D010
0056CF57 |. 64:FF30 push dword ptr fs:[eax]
0056CF5A |. 64:8920 mov dword ptr fs:[eax],esp
0056CF5D |. 81F3 F1250B00 xor ebx,0xB25F1 ; ebx值(用户名的16进制乘上70后)与B25F1异或
0056CF63 |. 8BC3 mov eax,ebx
0056CF65 |. 33D2 xor edx,edx
0056CF67 |. 52 push edx
0056CF68 |. 50 push eax
0056CF69 |. 8D45 FC lea eax,[local.1]
0056CF6C |. E8 5BC9E9FF call dumped_.004098CC ; 将异或得出的值转为10进制
0056CF71 |. 8B45 FC mov eax,[local.1]
0056CF74 |. 0FB600 movzx eax,byte ptr ds:[eax] ; 取结果的第一位ASCII
0056CF77 |. 8B55 FC mov edx,[local.1]
0056CF7A |. 0FB652 01 movzx edx,byte ptr ds:[edx+0x1] ; 第二位ASCII
0056CF7E |. 03C2 add eax,edx ; 第二位ASCII加上第一位的,结果放入eax
0056CF80 |. B9 05000000 mov ecx,0x5 ; ecx为5
0056CF85 |. 99 cdq ; 置EDX为0
0056CF86 |. F7F9 idiv ecx ; 除ecx(0x5)商保存至eax余数保存至edx
0056CF88 |. 80C2 34 add dl,0x34 ; edx+34
0056CF8B |. 8855 F8 mov byte ptr ss:[ebp-0x8],dl ; +34后结果保存 注册码倒数第二位计算完成
0056CF8E |. 8B45 FC mov eax,[local.1] ; 0056CF6C处10进制结果入eax
0056CF91 |. 0FB640 02 movzx eax,byte ptr ds:[eax+0x2] ; 取10进制结果的第3位ASCII
0056CF95 |. 8B55 FC mov edx,[local.1]
0056CF98 |. 0FB652 03 movzx edx,byte ptr ds:[edx+0x3] ; 取10进制结果第4位ASCII
0056CF9C |. 03C2 add eax,edx ; 相加三、四位ASCII码
0056CF9E |. B9 05000000 mov ecx,0x5 ; ecx为5
0056CFA3 |. 99 cdq ; edx置0
0056CFA4 |. F7F9 idiv ecx ; eax值除ecx(5)
0056CFA6 |. 8BDA mov ebx,edx
0056CFA8 |. 80C3 33 add bl,0x33 ; 结果+33
0056CFAB |. 885D F9 mov byte ptr ss:[ebp-0x7],bl ; 存放+33后的结果 注册码最后一位计算结束
0056CFAE |. 8D45 F4 lea eax,[local.3]
0056CFB1 |. 8A55 F8 mov dl,byte ptr ss:[ebp-0x8]
0056CFB4 |. E8 1B7EE9FF call dumped_.00404DD4
0056CFB9 |. 8B45 F4 mov eax,[local.3]
0056CFBC |. 8D55 FC lea edx,[local.1]
0056CFBF |. B9 1B000000 mov ecx,0x1B
0056CFC4 |. E8 C381E9FF call dumped_.0040518C
0056CFC9 |. 8D45 F0 lea eax,[local.4]
0056CFCC |. 8BD3 mov edx,ebx
0056CFCE |. E8 017EE9FF call dumped_.00404DD4
0056CFD3 |. 8B45 F0 mov eax,[local.4]
0056CFD6 |. 8D55 FC lea edx,[local.1]
0056CFD9 |. B9 19000000 mov ecx,0x19
0056CFDE |. E8 A981E9FF call dumped_.0040518C ; 出现注册码
0056CFE3 |. 8BC6 mov eax,esi
0056CFE5 |. 8B55 FC mov edx,[local.1]
0056CFE8 |. E8 5B7CE9FF call dumped_.00404C48
0056CFED |. 33C0 xor eax,eax
0056CFEF |. 5A pop edx
0056CFF0 |. 59 pop ecx
0056CFF1 |. 59 pop ecx
0056CFF2 |. 64:8910 mov dword ptr fs:[eax],edx
0056CFF5 |. 68 17D05600 push dumped_.0056D017
0056CFFA |> 8D45 F0 lea eax,[local.4]
0056CFFD |. BA 02000000 mov edx,0x2
0056D002 |. E8 117CE9FF call dumped_.00404C18
0056D007 |. 8D45 FC lea eax,[local.1]
0056D00A |. E8 E57BE9FF call dumped_.00404BF4
0056D00F \. C3 retn
总结下算法吧:
用户名先转为16进制,然后与70相乘,乘出来之后的结果再与B25F1异或,结果再转为10进制,这个10进制结果就是注册码的前几位
,然后取10进制结果第一位数的ASCII16进制码,与第二位的ASCII16进制码相加,结果除以5,除得的余数加上34,作为倒数第二位注册码的ASCII,
再取10进制结果第三位数的ASCII 16进制码,与第四位的ASCII 16进制码相加,结果除以5,除得的余数加上33,作为最后一位注册码的ASCII。
下面开始写注册机,用的是易语言,大牛不要笑。
.版本 2
.局部变量 a, 整数型
.局部变量 b, 整数型
.局部变量 c, 文本型
.局部变量 d1, 双精度小数型
.局部变量 d2, 双精度小数型
.局部变量 d3, 双精度小数型
.局部变量 d4, 双精度小数型
.局部变量 e, 整数型
.局部变量 f, 整数型
a = 到整数 (编辑框1.内容) ' 给a赋值
b = a × 112 ' a的值就是注册码的10进制,然后乘上 (16进制的70转换为10进制) 也就是112。
c = 到文本 (位异或 (b, 730609)) ' 与B25F1异或也就等于,与10进制的730609异或,这就算出来注册码的前一部分了。
d1 = 到小数 (取代码 (c, 1)) ' 取注册码前一部分文本的第一位的ASCII
d2 = 到小数 (取代码 (c, 2)) ' 取注册码前一部分文本的第2位ASCII
d3 = 到小数 (取代码 (c, 3)) ' 取注册码前一部分文本的第3位ASCII
d4 = 到小数 (取代码 (c, 4)) ' 取注册码前一部分文本的第4位ASCII
e = (d1 + d2) % 5 + 34 - 30 ' 这里下面有特别说明。
f = (d3 + d4) % 5 + 33 - 30 ' 同上
编辑框2.内容 = c + 到文本 (e) + 到文本 (f) '拼接上最后两个数字,然后输出注册码。
e 的值:
第一位的ASCII与第二位ASCII相加,但是易语言取得的ASCII码是10进制的,所以我们加出来是10进制的,
但是与5求余求出来的还是和16进制相等的。而除以5后的余数最大是4,所以+34后最大也就是38,对照ASCII表,
16进制的0的ascii为30,1的为31,以此类推,所以我们只要减去30就会是结果。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课