- UID
- 52455
注册时间2008-6-1
阅读权限30
最后登录1970-1-1
龙战于野
TA的每日心情 | 郁闷 2021-10-2 23:26 |
---|
签到天数: 46 天 [LV.5]常住居民I
|
标 题: 【原创】 XX电话通 算法分析+Delphi注册机
作 者: as3852711
时 间: 2009-05-06,20:20
链 接: https://www.chinapyg.com/viewthr ... e%3D1&frombbs=1
―――――――――――――――――――――――――――――――――――――
【文章标题】: XX电话通 算法分析+Delphi注册机
【文章作者】: 莱莉
【程序名称】: XX电话通.exe
【程序大小】: 1.01 MB
【下载地址】: http://www.rayfile.com/zh-cn/fil ... -a7f4-0014221b798a/
【保护方式】: 注册码
【编写语言】: Borland Delphi 6.0 - 7.0
【使用工具】: PEID,OD
【操作平台】: D-Windows XP3
【程序介绍】: 一个供给菜鸟学习的练手程序.
【作者声明】: 我只是一只小菜鸟,失误之处难免,敬望诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
这是一个过期的软件,是N年的前估计已经没什么用了,不过算法就比较简单较为适合我们这种菜鸟学习算法时来练手!
一、用PEID对程序进行查壳 → UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo ,用ESP定律秒脱,脱完后修复一下便可.
二、用OD载入程序进行分析。
载入OD后运行程序,试注册一下,有错误提示。用F12暂停法来到下面的地方(0048DA63)。然后我们到段首(0048D628)设置断点.
------------------------------(第一部分)----------------------------------------------------------
- 0048D628 55 push ebp
- 0048D629 8BEC mov ebp, esp
- 0048D62B B9 6E000000 mov ecx, 6E
- 0048D630 6A 00 push 0
- 0048D632 6A 00 push 0
- 0048D634 49 dec ecx
- 0048D635 ^ 75 F9 jnz short 0048D630
- 0048D637 51 push ecx
- 0048D638 53 push ebx
- 0048D639 56 push esi
- 0048D63A 57 push edi
- 0048D63B 8945 FC mov dword ptr [ebp-4], eax
- 0048D63E 33C0 xor eax, eax
- 0048D640 55 push ebp
- 0048D641 68 BEDC4800 push 0048DCBE
- 0048D646 64:FF30 push dword ptr fs:[eax]
- 0048D649 64:8920 mov dword ptr fs:[eax], esp
- 0048D64C E8 D7EEFFFF call 0048C528 ; 到我们C盘的这个目录获取一些数值:"C:\Documents and Settings\All Users"
- 0048D651 E8 2254F7FF call 00402A78 ; 对数值作运算;
- 0048D656 52 push edx
- 0048D657 50 push eax
- 0048D658 8D85 F0FCFFFF lea eax, dword ptr [ebp-310]
- 0048D65E E8 F1ABF7FF call 00408254 ; 同上;
- 0048D663 8B85 F0FCFFFF mov eax, dword ptr [ebp-310]
- 0048D669 E8 CE6CF7FF call 0040433C
- 0048D66E 48 dec eax
- 0048D66F 50 push eax
- 0048D670 E8 B3EEFFFF call 0048C528 ; 也是到C盘获取数值;
- 0048D675 E8 FE53F7FF call 00402A78 ; 同样是运算得到的数值;
- 0048D67A 52 push edx
- 0048D67B 50 push eax
- 0048D67C 8D85 ECFCFFFF lea eax, dword ptr [ebp-314]
- 0048D682 E8 CDABF7FF call 00408254
- 0048D687 8B85 ECFCFFFF mov eax, dword ptr [ebp-314] ; 计算后得到一个字符串,我的是(ASCII "2953");
- 0048D68D 8D8D F4FCFFFF lea ecx, dword ptr [ebp-30C]
- 0048D693 5A pop edx
- 0048D694 E8 4F1DFAFF call 0042F3E8 ; 把字符串截取到前三位;
- 0048D699 8B85 F4FCFFFF mov eax, dword ptr [ebp-30C] ; 变成了(ASCII "295");
- 0048D69F E8 00ACF7FF call 004082A4 ; 字符转化成数字;
- 0048D6A4 05 F9030000 add eax, 3F9 ; EAX装的是我们转化后的数值(127),加上3F9;
- 0048D6A9 69C0 D3020000 imul eax, eax, 2D3 ; EAX(520)再乘于2D3;
- 0048D6AF 8945 F8 mov dword ptr [ebp-8], eax ; 把最后得到的数字(E7960)传递给[EBP-8]这个地址;
- 0048D6B2 8D95 E4FCFFFF lea edx, dword ptr [ebp-31C]
- 0048D6B8 33C0 xor eax, eax
复制代码 以上基本就是本程序的关键算法了,往下走就都是一些读取.INI文件的操作.我就不多说了就提一点,如果你的程序出现了自校验的话,就可到C盘WINDOWS的根目录下把WINDOWS.INI删掉就好了.下面再来说说注册验证的过程.
------------------------------(第二部分)-----------------------------------------------------------
- 0048D977 8B45 FC mov eax, dword ptr [ebp-4]
- 0048D97A 8B80 F8020000 mov eax, dword ptr [eax+2F8]
- 0048D980 8B80 08020000 mov eax, dword ptr [eax+208]
- 0048D986 BA 01000000 mov edx, 1
- 0048D98B E8 FCA3FAFF call 00437D8C
- 0048D990 50 push eax
- 0048D991 8D85 B4FCFFFF lea eax, dword ptr [ebp-34C]
- 0048D997 8B55 FC mov edx, dword ptr [ebp-4]
- 0048D99A 81C2 58050000 add edx, 558
- 0048D9A0 E8 3B69F7FF call 004042E0 ; 获取用户名:hanyu;
- 0048D9A5 8B8D B4FCFFFF mov ecx, dword ptr [ebp-34C]
- 0048D9AB 8D85 B8FCFFFF lea eax, dword ptr [ebp-348]
- 0048D9B1 BA 10DE4800 mov edx, 0048DE10 ; 授权使用:
- 0048D9B6 E8 CD69F7FF call 00404388
- 0048D9BB 8B95 B8FCFFFF mov edx, dword ptr [ebp-348] ; //在这里用户名不参与注册码的计算,只作标识罢了;
- 0048D9C1 58 pop eax
- 0048D9C2 E8 21A3FAFF call 00437CE8
- 0048D9C7 8D85 ACFCFFFF lea eax, dword ptr [ebp-354]
- 0048D9CD 8B55 FC mov edx, dword ptr [ebp-4]
- 0048D9D0 81C2 58050000 add edx, 558
- 0048D9D6 E8 0569F7FF call 004042E0
- 0048D9DB 8B8D ACFCFFFF mov ecx, dword ptr [ebp-354]
- 0048D9E1 8D85 B0FCFFFF lea eax, dword ptr [ebp-350]
- 0048D9E7 BA 24DE4800 mov edx, 0048DE24 ; 本软件授权于:
- 0048D9EC E8 9769F7FF call 00404388
- 0048D9F1 8B95 B0FCFFFF mov edx, dword ptr [ebp-350]
- 0048D9F7 8B45 FC mov eax, dword ptr [ebp-4]
- 0048D9FA 8B80 34030000 mov eax, dword ptr [eax+334]
- 0048DA00 E8 BB94FCFF call 00456EC0
- 0048DA05 8D85 A4FCFFFF lea eax, dword ptr [ebp-35C]
- 0048DA0B 8B55 FC mov edx, dword ptr [ebp-4]
- 0048DA0E 81C2 58060000 add edx, 658
- 0048DA14 E8 C768F7FF call 004042E0 ; 获取假码;
- 0048DA19 8B85 A4FCFFFF mov eax, dword ptr [ebp-35C] ; 把假码(ASCII "123456"),传递给EAX;
- 0048DA1F 8D95 A8FCFFFF lea edx, dword ptr [ebp-358]
- 0048DA25 E8 B2EBFFFF call 0048C5DC ; 关键算法CALL;
- 0048DA2A 8B85 A8FCFFFF mov eax, dword ptr [ebp-358] ; 计算后得到假码字符串:(ASCII "2296281783")
- 0048DA30 50 push eax
- 0048DA31 8D95 9CFCFFFF lea edx, dword ptr [ebp-364]
- 0048DA37 8B45 F8 mov eax, dword ptr [ebp-8]
- 0048DA3A E8 29A7F7FF call 00408168 ; 把第一部分算法得到的(E7960)数值转化成字符串;
- 0048DA3F 8B85 9CFCFFFF mov eax, dword ptr [ebp-364] ; 得到(ASCII "948576");
- 0048DA45 8D95 A0FCFFFF lea edx, dword ptr [ebp-360]
- 0048DA4B E8 8CEBFFFF call 0048C5DC ; 也是关键算法CALL它和假码的运算CALL是一样的都是(0048C5DC);
- 0048DA50 8B95 A0FCFFFF mov edx, dword ptr [ebp-360] ; 最后得到正确注册码:(ASCII "17643513783");
- 0048DA56 58 pop eax ; 假码运算后得到的字符串:ASCII "2296281783"
- 0048DA57 E8 2C6AF7FF call 00404488 ; 经典字符串比较CALL;
- 0048DA5C 74 05 je short 0048DA63 ; 关键跳转;(可作内存补丁);
- 0048DA5E E8 3DF9FFFF call 0048D3A0
- 0048DA63 8D85 F8FDFFFF lea eax, dword ptr [ebp-208]
复制代码 好了看完注册验证机制之后,我们再来看看关键算法CALL吧!
------------------------------(第三部分)-----------------------------------------------------------
- 0048C5DC 55 push ebp
- 0048C5DD 8BEC mov ebp, esp
- 0048C5DF 83C4 F8 add esp, -8
- 0048C5E2 53 push ebx
- 0048C5E3 33C9 xor ecx, ecx
- 0048C5E5 894D F8 mov dword ptr [ebp-8], ecx
- 0048C5E8 8BDA mov ebx, edx
- 0048C5EA 8945 FC mov dword ptr [ebp-4], eax
- 0048C5ED 8B45 FC mov eax, dword ptr [ebp-4]
- 0048C5F0 E8 377FF7FF call 0040452C
- 0048C5F5 33C0 xor eax, eax
- 0048C5F7 55 push ebp
- 0048C5F8 68 44C64800 push 0048C644
- 0048C5FD 64:FF30 push dword ptr fs:[eax]
- 0048C600 64:8920 mov dword ptr fs:[eax], esp
- 0048C603 8B45 FC mov eax, dword ptr [ebp-4]
- 0048C606 E8 99BCF7FF call 004082A4 ; 把字符串(ASCII "948576"),转化成数值;
- 0048C60B 69C0 BA000000 imul eax, eax, 0BA ; 得到数值(E7960)乘于OBA;
- 0048C611 40 inc eax ; 积(A842FC0)加1;
- 0048C612 8D55 F8 lea edx, dword ptr [ebp-8] ; 把[EBP-8]地址中的数值传递到EDX中;
- 0048C615 E8 4EBBF7FF call 00408168 ; 把数值转化成ASCII码;
- 0048C61A 8B55 F8 mov edx, dword ptr [ebp-8] ; 得到字符串:(ASCII "176435137")
- 0048C61D 8BC3 mov eax, ebx
- 0048C61F B9 58C64800 mov ecx, 0048C658 ; 83
- 0048C624 E8 5F7DF7FF call 00404388 ; 连接"83"和"176435137"两段字符串;
- 0048C629 33C0 xor eax, eax
- 0048C62B 5A pop edx
复制代码 那个算法CALL也就只是简单的对数值做一下加,乘运算罢了.好了,当我们了解了整个注册机制以后,那么软件的作者又是如何发放注册码的了,只要我们细心看看提示就知道了.它是通过机器码来提供注册信息的,好现在我们就来看它的机器码是如何获取的,运用DELPHI获取按钮入口的方法,来到如下代码段:
------------------------------(第四部分)-----------------------------------------------------------
- 0048DECC 55 push ebp
- 0048DECD 8BEC mov ebp, esp
- 0048DECF 33C9 xor ecx, ecx
- 0048DED1 51 push ecx
- 0048DED2 51 push ecx
- 0048DED3 51 push ecx
- 0048DED4 51 push ecx
- 0048DED5 53 push ebx
- 0048DED6 8BD8 mov ebx, eax
- 0048DED8 33C0 xor eax, eax
- 0048DEDA 55 push ebp
- 0048DEDB 68 68DF4800 push 0048DF68
- 0048DEE0 64:FF30 push dword ptr fs:[eax]
- 0048DEE3 64:8920 mov dword ptr fs:[eax], esp
- 0048DEE6 E8 3DE6FFFF call 0048C528
- 0048DEEB E8 884BF7FF call 00402A78
- 0048DEF0 52 push edx
- 0048DEF1 50 push eax
- 0048DEF2 8D45 F4 lea eax, dword ptr [ebp-C]
- 0048DEF5 E8 5AA3F7FF call 00408254
- 0048DEFA 8B45 F4 mov eax, dword ptr [ebp-C]
- 0048DEFD E8 3A64F7FF call 0040433C
- 0048DF02 48 dec eax
- 0048DF03 50 push eax
- 0048DF04 E8 1FE6FFFF call 0048C528
- 0048DF09 E8 6A4BF7FF call 00402A78
- 0048DF0E 52 push edx
- 0048DF0F 50 push eax
- 0048DF10 8D45 F0 lea eax, dword ptr [ebp-10]
- 0048DF13 E8 3CA3F7FF call 00408254
- 0048DF18 8B45 F0 mov eax, dword ptr [ebp-10]
- 0048DF1B 8D4D F8 lea ecx, dword ptr [ebp-8]
- 0048DF1E 5A pop edx
- 0048DF1F E8 C414FAFF call 0042F3E8 ; //以上的代码是不是很面熟啊!其实它和我们在开始看到的代码基本一样的都是用来获取 C盘的数据的;
- 0048DF24 8B45 F8 mov eax, dword ptr [ebp-8] ; 也是截取了头三位(ASCII "295");
- 0048DF27 E8 78A3F7FF call 004082A4 ; 同样是把字符转化成数字;
- 0048DF2C 69C0 D3020000 imul eax, eax, 2D3 ; 数值EAX(127)乘与2D3
- 0048DF32 05 F9030000 add eax, 3F9 ; eax=00034125再加上3F9;
- 0048DF37 8D55 FC lea edx, dword ptr [ebp-4]
- 0048DF3A E8 29A2F7FF call 00408168
- 0048DF3F 8B55 FC mov edx, dword ptr [ebp-4] ; 数值转换成字符了:(ASCII "214302");
- 0048DF42 8B83 44050000 mov eax, dword ptr [ebx+544] ; //其实机器码和开始认证时的算法只是颠倒了一下循序而已,一个先加
- 0048DF48 E8 738FFCFF call 00456EC0 ; //后乘,另一个先乘后加;
- 0048DF4D 33C0 xor eax, eax
- 0048DF4F 5A pop edx
- 0048DF50 59 pop ecx
- 0048DF51 59 pop ecx
复制代码 ---------------------------------------------------------------------------------------------
【经验总结】
1.我们要大概了解重启验证的程序它们的都有一个启动认证的注册部分,平时我们搞自校或是ANTI基本上都能在这里能搞定;
2.要看懂基本的汇编指令,不懂也没问题.但是人手要有一个汇编指令查询器,我个人一直以来都是用"黑夜"兄汇编查询器.如果你连指令都看不懂,那么程序对数值做了什么操作你又怎么能知道呢!
3.写算法注册机:放三个EXIT控件,以及一个BUTTON控件把源代码复制进去便可;
---------------------------------------------------------------------------------------------
【破解感悟】
本人认为这个算法机制相当的不切合实际,先不说它的注册码计算的难易程度.就取C盘数据而言,如果人家使用的是GHOST版本的XP的话,那么就只有一个超级用户.此时C盘的All Users文件里的数据就会不时的变动.我叫人帮我调试注册机时,就发生过这种情况机器码不停的发生改变.也不懂作者是如何解决这个问题的,难道连他本人都是用内存补丁么?再来就是注册码验证部分,做的实在是有点画蛇添足了.他在0048DA3F处把注册码呈现出来了,然后又让此数值给运算了一遍.我真的搞不懂他的用意何在,要是你说要屏蔽掉人家的内存注册机的话,那么你就不要在0048DA3F处把注册码给字符化,这样就可避免人家编写内存的可能性.你现在把它字符化了然后又再数值化,都在做"无用工"耗内存.最后提醒一下大家,我们设计注册机制时千万不要使用一些不稳定的数值,如本题的C盘数据你可用电脑用户名,网卡号等等不易改变的数值皆可!
【版权声明】: 转载请注明作者并保持文章的完整, 谢谢! 软件久远,如有雷同,敬请理解.
[ 本帖最后由 as3852711 于 2009-5-6 20:00 编辑 ] |
|