首页
社区
课程
招聘
[原创]菜鸟的第一次,crack KeyGenMe #2
发表于: 2006-3-19 01:12 9419

[原创]菜鸟的第一次,crack KeyGenMe #2

2006-3-19 01:12
9419

学软件汉化与破解都快一年了
没什么出息,除了汉化就是暴力破解
昨天晚上碰到群里的一个兄弟给了个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。
第一次完全自主完成。不带什么侥幸心理的去做。

其实学习这东西要是一个人学实在是没什么劲头。多个人学就有种竞争的意识。而且相互有个交流就能解决很多问题,学到许多东西。

谢谢小敏同学
真是的。没有办法贴图只好用这种苯方法咯
还请斑竹原谅
还请各位大虾多多指教
谢谢


[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (17)
雪    币: 200
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
请把原文件传上来!
2006-3-19 09:41
0
雪    币: 222
活跃值: (100)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
我没有权限发那些
像图片我还是通过比较什么的手法才穿上来的
55555
什么时候能让我有机会传文件呀
2006-3-19 11:06
0
雪    币: 50161
活跃值: (20665)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
最初由 rockandtcl 发布
我没有权限发那些
像图片我还是通过比较什么的手法才穿上来的
55555
什么时候能让我有机会传文件呀


你现在有精华帖,就有上传权限了。
2006-3-19 11:08
0
雪    币: 222
活跃值: (100)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
谢谢
2006-3-19 11:09
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
VOL版XP目前已封
2006-3-20 14:45
0
雪    币: 70
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
支持,学习了!
2006-3-22 14:16
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
算法貌似比较建单
2006-4-29 17:48
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
支持,好好学习
2006-4-30 06:20
0
雪    币: 252
活跃值: (82)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
学习了 谢谢
2006-4-30 16:53
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
学习......谢谢
2006-5-3 16:14
0
雪    币: 230
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
学习中,谢谢分享。
2006-5-3 20:43
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
...........................
2006-5-7 12:14
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14

....................
2006-5-7 12:17
0
雪    币: 202
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
学习,谢谢!
2006-5-9 08:12
0
雪    币: 721
活跃值: (350)
能力值: ( LV9,RANK:1250 )
在线值:
发帖
回帖
粉丝
16
老乡?我也是西安的。
2006-5-10 15:54
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
感谢楼主分享经验啊~
2006-5-10 20:13
0
雪    币: 222
活跃值: (100)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
18
最初由 happytown 发布
老乡?我也是西安的。

我是工大的大三的。1院1专业5班
有机会联系哦
我的QQ:254991946 请注明出处这样我好放在我的分组里。
2006-5-12 13:23
0
游客
登录 | 注册 方可回帖
返回
//