学软件汉化与破解都快一年了
没什么出息,除了汉化就是暴力破解
昨天晚上碰到群里的一个兄弟给了个CRACK ME
为了展示下俺的“技术水平”硬着头皮做了下,结果居然被我找到了算法
本想把这文章发在论坛上,又觉得有点什么了,毕竟很简单的东西,放在我的破解博客又不能用图片说明,于是就把它放在新浪咯。又想显摆下,就想放到论坛上来咯
废话说够多了。
程序名:KeyGenMe #2 作者:Ank83
工具软件:FEiD,OD,Procdump,W32DASM,HIEW7.2(后两者是暴力破解用的)
说明:第一次写关于算法的介绍,把我累的,有些语言不清楚的地方还望见谅
那时候当他给我发过来的时候我就试运行了下出现以下画面
(图一)
<br>
我第一反应就是暴力破解
先用FEiD查看了下,发现是UPX的壳。
用procdump脱壳
然后用W32DASM进行反汇编,菜单“参考/串式参考”,复制如下
" ============================================="
" Data: <%s> %s
"
" Greetz to: Gago, Blesav, LiquidWorm, "
"
Do svite kumanovski "
"
============================================"
"
Now enter the serial: "
"
So let's begin by entering ID "
"
Please try again " --------错误的时候的显示
"
Wow ! You did it. Congratulation. "------注册成功显示
"
我们双击Wow ! You did it. Congratulation.来到它所对应的地址段
往上走,找到关键跳转。
(图二)
<br>
跟入,发现定位于Please try again的上方,于是我们只要把JNE 004011DE(if no equal then jump 004011de)改为je 004011de(if no equal then jump 004011de)这样就意味着只有你写成功注册号才能显示错误提示。呵呵
用HIEW打开文件,在7CD的地方把 jne->75 改为 je->74
保存退出后运行
(图三)
<br>
恩???基本可以了,不过后面还有个比较烦人的东西在。真是的。回到W32DASM中,找到
Please try again对应的CALL把它NOP掉!!!-----有问题!!(求教下各位大虾)
运行下。哈哈哈!!!
(图四)
<br>
于是我就把做好的东西给兄弟看,结果他说鄙视暴力破解的。
为了显示下风范,于是我就硬着头皮来个动态调试。
启动OD调试
00404790 8B15 E4CA4200 mov edx,dword ptr ds:[42CAE4]
00404796 52 push edx
00404797 A1 DCCA4200 mov eax,dword ptr ds:[42CADC]
0040479C 50 push eax
0040479D 8B0D D8CA4200 mov ecx,dword ptr ds:[42CAD8]
004047A3 51 push ecx
004047A4 E8 5CC8FFFF call unshell.00401005 -----关键的CALL,设断点。
004047A9 83C4 0C add esp,0C
004047AC 8945 E4 mov dword ptr ss:[ebp-1C],eax
004047AF 8B55 E4 mov edx,dword ptr ss:[ebp-1C]
004047B2 52 push edx
004047B3 E8 982E0000 call unshell.00407650
004047B8 8B45 EC mov eax,dword ptr ss:[ebp-14]
重新加载,在call unshell.00401005 步入。发现有些字符,原来是开始显示的部分。
00401136 68 1C814200 push unshell.0042811C ; ASCII " =============================================================================
"
0040113B B9 68CA4200 mov ecx,unshell.0042CA68
00401140 E8 AB050000 call unshell.004016F0
00401145 68 E8804200 push unshell.004280E8 ; ASCII "
So let's begin by entering ID (0...999): "
0040114A B9 68CA4200 mov ecx,unshell.0042CA68
0040114F E8 9C050000 call unshell.004016F0
00401154 8D45 FC lea eax,dword ptr ss:[ebp-4]
00401157 50 push eax
00401158 B9 18CA4200 mov ecx,unshell.0042CA18
0040115D E8 DE000000 call unshell.00401240---读入ID
取消第一个断点,在0040115D这设断。重新加载
00401162 8B4D FC mov ecx,dword ptr ss:[ebp-4]
-----把输入的数字转化成16进制,并保存在ECX 设我们输入的数是X
00401165 83C1 01 add ecx,1
-----ECX+1保存在ECX 现在是X+1
00401168 894D FC mov dword ptr ss:[ebp-4],ecx
0040116B 8B55 FC mov edx,dword ptr ss:[ebp-4]
-----把ECX中的数存入EDX
0040116E 0355 FC add edx,dword ptr ss:[ebp-4]
-----将ECX和EDX相加存入EDX 就等于2*ECX 现在是(X+1)*2
00401171 8955 FC mov dword ptr ss:[ebp-4],edx
00401174 8B45 FC mov eax,dword ptr ss:[ebp-4]
00401177 83E8 01 sub eax,1
-----把EDX的数存入EAX并减1 现在是(X+1)*2-1
0040117A 8945 FC mov dword ptr ss:[ebp-4],eax
0040117D 8B4D FC mov ecx,dword ptr ss:[ebp-4]
00401180 0FAF4D FC imul ecx,dword ptr ss:[ebp-4]
-----把数存入ECX,相乘,保存在ECX 现在是[(X+1)*2-1]^2
00401184 894D FC mov dword ptr ss:[ebp-4],ecx
-----保存结果
00401187 C745 F8 01000000 mov dword ptr ss:[ebp-8],1
-----记数开始
现在我们基本上把算法分析出来一半了
现在我们的数已经成了[(X+1)*2-1]^2并且保存在ss:[ebp-8],注意了:
当ss:[ebp-8]为1的时候,就跳到了
00401199 837D F8 14 cmp dword ptr ss:[ebp-8],14
比较是否大于或等于14(16进制),于是就有[(X+1)*2-1]^2-1。
做完这一步后才跳回到了
004011A8 ^ EB E6 jmp short unshell.00401190
ss:[ebp-8]+1的循环中,所以我们说的循环是从ss:[ebp-8]=2开始的。
好现在有个循环开始:
00401190 8B55 F8 mov edx,dword ptr ss:[ebp-8]
00401193 83C2 01 add edx,1
------记数器累加
00401196 8955 F8 mov dword ptr ss:[ebp-8],edx
00401199 837D F8 14 cmp dword ptr ss:[ebp-8],14
------判断是否是累加到14,这是16进制,换成10进制是20
0040119D 7D 0B jge short unshell.004011AA
------大于等于则跳出循环
0040119F 8B45 FC mov eax,dword ptr ss:[ebp-4]
004011A2 2B45 F8 sub eax,dword ptr ss:[ebp-8]
------[(X+1)*2-1]^2减记数器的值(注意:减的计算在判断之后,也就是说其实它只减到19,而不是20,所以最后的结果是[(X+1)*2-1]^2-190)
[大家主要会出问题的是在想究竟是减189呢还是190,其实要看清楚第一次进入循环的地方就知道肯定是190了]
004011A5 8945 FC mov dword ptr ss:[ebp-4],eax
------保存结果到ss:[ebp-4]
004011A8 ^ EB E6 jmp short unshell.00401190
看看循环结束后是做什么
004011B9 8D4D F4 lea ecx,dword ptr ss:[ebp-C]
004011BC 51 push ecx
004011BD B9 18CA4200 mov ecx,unshell.0042CA18
004011C2 E8 79000000 call unshell.00401240
------ss:[ebp-C]装入地址,保存我们输入的serial
004011C7 8B55 FC mov edx,dword ptr ss:[ebp-4]
004011CA 3B55 F4 cmp edx,dword ptr ss:[ebp-C]
------比较输入的数是否等于[(X+1)*2-1]^2-190
004011CD 75 0F jnz short unshell.004011DE
------不等于就显示“ Please try again ! It's easyer than you think !”
004011CF 68 6C804200 push unshell.0042806C ; ASCII "
Wow ! You did it. Congratulation. Now write a tutorial - it's easy !
"
004011D4 B9 68CA4200 mov ecx,unshell.0042CA68
004011D9 E8 12050000 call unshell.004016F0
004011DE 8B45 FC mov eax,dword ptr ss:[ebp-4]
004011E1 3B45 F4 cmp eax,dword ptr ss:[ebp-C]
004011E4 74 0F je short unshell.004011F5
004011E6 68 1C804200 push unshell.0042801C ; ASCII "
Please try again ! It's easyer than you think !
"
004011EB B9 68CA4200 mov ecx,unshell.0042CA68
004011F0 E8 FB040000 call unshell.004016F0
所以呢
我们刚才输入的是12
利用公式[(X+1)*2-1]^2-190,得出结果是435
(图五)
<br>
哈哈哈
有点成就感
顺便也写个注册机
用C写很简单的
就是y=[(X+1)*2-1]^2-190.然后输出y。
第一次完全自主完成。不带什么侥幸心理的去做。
其实学习这东西要是一个人学实在是没什么劲头。多个人学就有种竞争的意识。而且相互有个交流就能解决很多问题,学到许多东西。
谢谢小敏同学
真是的。没有办法贴图只好用这种苯方法咯
还请斑竹原谅
还请各位大虾多多指教
谢谢
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)