首页
社区
课程
招聘
[原创]不是破解的破解(老鸟飘过)
发表于: 2008-10-19 11:04 4417

[原创]不是破解的破解(老鸟飘过)

2008-10-19 11:04
4417
从看雪下的CM太多了,随便拿个来学习下,第一次写破文,不好不要见笑啊!也不知有没有写过这个的,如有重复实属意外。高手飘过!
附件: gge.rar
首先用PE检查有无加壳及其是什么软件编写的。恩,没有加壳且是VC编写的,运气不错! VC个人觉得还是比较好看懂的!
运行之查看基本情况,简单的界面,可是发现确定按扭无法使用,看来是被作者禁止使用了,没有确定如何注册?看来先要把它变成可以使用才行。

查资料得知,EnbleWindow、EnbleMenuItem使用来把按扭变成灰色的
OK,把文件丢近OD,用API工具在两函数下断点
运行之,OD断下,停在USER32系统领空
汇编代码如下
77D29849 U>  8BFF             mov edi,edi ; USER32.SendMessageA
77D2984B     55               push ebp
77D2984C     8BEC             mov ebp,esp
77D2984E     6A 60            push 60
77D29850     FF75 0C          push dword ptr ss:[ebp+C]
77D29853     FF75 08          push dword ptr ss:[ebp+8]
77D29856     E8 DAFFFFFF      call USER32.77D29835
这里应该是发送一个消息使之变灰的函数
查看下堆栈窗口
0012F7EC               73D37E00     /CALL 到 EnableWindow 来自 MFC42.73D37DFA
0012F7F0               0007057E     |hWnd = 0007057E ('确  定',class='Button',parent=000E0532)
0012F7F4               00000000     \Enable = FALSE
堆栈的参数都是由调用的函数传递过来的
可以看出Enable = FALSE是确定按扭不能使用的罪魁祸首
ALT+F9返回程序,查看函数调用前参数情况
代码如下
00401513    .  6A 00          push 0
00401515    .  68 EA030000    push 3EA
0040151A    .  8BCE           mov ecx,esi
0040151C    .  E8 FB040000    call <jmp.&MFC42.#3092>
00401521    .  8BC8           mov ecx,eax
00401523    .  E8 EE040000    call <jmp.&MFC42.#2642>
00401528    .  8B4C24 0C      mov ecx,dword ptr ss:[esp+C]
0040152C    .  5F             pop edi
0040152D    .  B8 01000000    mov eax,1
00401532    .  5E             pop esi
00401533    .  64:890D 000000>mov dword ptr fs:[0],ecx
0040153A    .  83C4 10        add esp,10
返回到00401528,往前既是传递的参数
PUSH 0,有问题!改之,PUSH 1
保存之
运行,按扭可以使用
解决按扭问题

为什么改PUSH 1就可以了呢? 疑问,查阅API函数大全如下
Declare Function EnableWindow Lib "user32" Alias "EnableWindow" (ByVal hwnd As Long, ByVal fEnable As Long) As Long
说明 在指定的窗口里允许或禁止所有鼠标及键盘输入(在vb里使用:在vb窗体和控件中使用Enabled属性) 返回值 Long,非零表示成功,零表示失败。会设置GetLastError 参数表 参数 类型及说明 hwnd Long,窗口句柄 fEnable Long,非零允许窗口,零禁止
VC传递参数由右边往左传,所以
00401513    .  6A 00          push 0
00401515    .  68 EA030000    push 3EA
fEnable = 0;hwnd=3EA
把0改为一就可以完成第一步了
===============================================================
在运行文件为第二步准备
随便输入 用户名:123 密码abc
出错,有提示(好现象)
用OD插件查找字符串
OH!GOOD!字符串找到如下
Ultra 字符串参考
地址       反汇编                                           文本字符串
00401528   mov ecx,dword ptr ss:[esp+C]                     (初始化 CPU 选择状态)
004016B2   mov esi,gge.0040304C                             hanyu
004016EF   mov esi,gge.00403044                             9527888hanyu
00401729   push gge.00403034                                恭喜你成功了!
0040173D   push gge.00403020                                别灰心,继续努力!
00401762   mov esi,gge.00403054                             William
OK。双击00401729到如下代码
004016A0    .  53             push ebx
004016A1    .  56             push esi
004016A2    .  57             push edi
004016A3    .  8BF9           mov edi,ecx
004016A5    .  6A 01          push 1
004016A7    .  E8 A0030000    call <jmp.&MFC42.#6334>
004016AC    .  8B87 E4000000  mov eax,dword ptr ds:[edi+E4]    ;用户名放进EAX
004016B2    .  BE 4C304000    mov esi,gge.0040304C                       ;  ASCII "hanyu"取内存地址40304C处的值并传递给ESI
004016B7    >  8A10           mov dl,byte ptr ds:[eax]          ;按字节把输入的用户名传递给DL寄存器
004016B9    .  8A1E           mov bl,byte ptr ds:[esi]          ;把ESI中的字符按位传递给BL
004016BB    .  8ACA           mov cl,dl                         ;DL中的数值传递给CL
004016BD    .  3AD3           cmp dl,bl                         ;比较两寄存器值
004016BF    .  75 1E          jnz short gge.004016DF            ;不等则跳
004016C1    .  84C9           test cl,cl                        ;是否取完
004016C3    .  74 16          je short gge.004016DB             ;完了就跳
004016C5    .  8A50 01        mov dl,byte ptr ds:[eax+1]        ;传递下一位输入用户名
004016C8    .  8A5E 01        mov bl,byte ptr ds:[esi+1]        ;传递下一位固定值
004016CB    .  8ACA           mov cl,dl                         ;
004016CD    .  3AD3           cmp dl,bl
004016CF    .  75 0E          jnz short gge.004016DF            ;不等跳
004016D1    .  83C0 02        add eax,2                         ;EAX+2(下一位)
004016D4    .  83C6 02        add esi,2                         ;ESI+2
004016D7    .  84C9           test cl,cl                        ;是否完
004016D9    .^ 75 DC          jnz short gge.004016B7            ;完跳
004016DB    >  33C0           xor eax,eax
004016DD    .  EB 05          jmp short gge.004016E4
004016DF    >  1BC0           sbb eax,eax                       ;注意这个运算符,不是SUB哦
004016E1    .  83D8 FF        sbb eax,-1
004016E4    >  83F8 01        cmp eax,1
004016E7    .  75 50          jnz short gge.00401739
004016E9    .  8B87 E8000000  mov eax,dword ptr ds:[edi+E8]
004016EF    .  BE 44304000    mov esi,gge.00403044                       ;  ASCII "9527888"
004016F4    >  8A10           mov dl,byte ptr ds:[eax]
004016F6    .  8A1E           mov bl,byte ptr ds:[esi]
004016F8    .  8ACA           mov cl,dl
004016FA    .  3AD3           cmp dl,bl
004016FC    .  75 1E          jnz short gge.0040171C
004016FE    .  84C9           test cl,cl
00401700    .  74 16          je short gge.00401718
00401702    .  8A50 01        mov dl,byte ptr ds:[eax+1]
00401705    .  8A5E 01        mov bl,byte ptr ds:[esi+1]
00401708    .  8ACA           mov cl,dl
0040170A    .  3AD3           cmp dl,bl
0040170C    .  75 0E          jnz short gge.0040171C
0040170E    .  83C0 02        add eax,2
00401711    .  83C6 02        add esi,2
00401714    .  84C9           test cl,cl
00401716    .^ 75 DC          jnz short gge.004016F4
00401718    >  33C0           xor eax,eax
0040171A    .  EB 05          jmp short gge.00401721
0040171C    >  1BC0           sbb eax,eax
0040171E    .  83D8 FF        sbb eax,-1
00401721    >  85C0           test eax,eax
00401723    .  6A 00          push 0
00401725    .  6A 00          push 0
00401727    .  75 14          jnz short gge.0040173D            
00401729    .  68 34304000    push gge.00403034                ;跳这就对
0040172E    .  8BCF           mov ecx,edi
00401730    .  E8 11030000    call <jmp.&MFC42.#4224>
00401735    .  5F             pop edi
00401736    .  5E             pop esi
00401737    .  5B             pop ebx
00401738    .  C3             retn
00401739    >  6A 00          push 0                          ;任何跳转到这就会有出错框了,所以有有跳到这不行
0040173B    .  6A 00          push 0
0040173D    >  68 20304000    push gge.00403020
00401742    .  E8 F9020000    call <jmp.&MFC42.#1200>
00401747    .  5F             pop edi
00401748    .  5E             pop esi
00401749    .  5B             pop ebx
0040174A    .  C3             retn
出现两个可疑字符hanyu,9527888
酷似用户名和密码哦(窃喜,太简单了吧)
抱着一试的态度输入
OH!NO!出错的提示筐击碎了我弱小的心
看来只有跟跟看了
往上翻之,004016A0之前代码全是NOP,经验在此断之
F9运行,单步F8,到004016AC时,EAX得到输入用户名字符,可以想象可能要处理用户名了,往下翻翻代码
得到结论如下
。输入的用户名处理符合要求则处理输入的注册码,码对则正确
2。注册码处理较为简单,只是和固定值做按位比较
2。用户名的处理规则为:前一为符合要求则后面不用处理;只是和hanyu按位比较,如相同则错;第一不等,后面随便输;第一位等,二位不等,后随便输…
随意实验
o,9527888;ho,9527888;hat,9527888;都正确 。正得意间,用a,9527888试之,错误框在次出现!心情马上跌入谷地!
还有点问题
没办法,回头再次重新阅读代码
终于找到问题所在,一个奇怪的代码被发现
0040171C    >  1BC0           sbb eax,eax
显然我是直接把它当成减法运算了
仔细一看才知道并不简单的减法
查阅资料
带借位减去指令 SBB(SuBtraction with Borrow)

格式: SBB OPRD1,OPRD2

功能: 是进行两个操作数的相减再减去CF进位标志位,即从OPRD1<--OPRD1-OPRD2-CF,其结果放在OPDR1中.
原来最后还要与CF寄存器运算
CF运算器是啥呢?继续查
CF为进位标志位,当两个数据相加的时候,有可能产生从最高有效位向更高的进位。此进位标志放于CF中
加法运算可以影响其数值
上翻代码,没有发现加减法运算耶,迷茫
发现一CMP比较运算符
查阅资料,原来CMP也要影响CF标志位
恩,最终明白,每一位的ASC值都不能比固定值小
最后在发现没有限制用户名的长度,而固定值字符后ASC值都为0,所以前五位可以为hanyu,后在随便输任意字符都可以对,不知道作者是不是故意的!

总结
学习了VC下用EnbleWindow把灰色按扭变成可用按扭
学习了SBB运算符及CF标志位
=========================================================
第一次写,不要见笑啊

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持一个!
2008-10-19 11:49
0
雪    币: 203
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不错,很详细
2008-10-19 11:50
0
雪    币: 210
活跃值: (56)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
没有算法分析
技术含量极低
见笑拉
2008-10-19 11:53
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
让我这小菜鸟又长知识啦,谢谢分享
2008-10-19 12:53
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
6
分析得挺好,我全看完了。

如你分析,它是码固定而校验用户名的,校验过程也分析了,无所谓“算法”了,呵呵。

这个ReverseMe有点不太一样啊,不知道它内部有没有激活按键的代码,比如当输入框里的名和码都校验通过时,”确定“按钮会不会自己激活呢??

难道必须在内存中patch吗??

我也想分析分析,呵呵。
2008-10-19 15:06
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
顶~~
2008-10-19 16:23
0
雪    币: 199
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
挺强的啊!

我自己是改了
004016E4   > \83F8 00       CMP     EAX, 0

把1 改成0

用 hanyu  9527888

试的就成功了.

还有怎么判断

这个PUSH 0(PUSH 0,有问题!改之,PUSH 1)

是灰色按钮属性为FLASE
2008-10-19 17:03
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
9
首先,你这个修改程序,算爆破。
其次,push 0 改 push 1,用C 伪代码描述就是
将   EnableWindow( hWnd,FLASE )
改为EnableWindow( hWnd,TRUE )

仅此而已。

看来你逆向的基本功还差些,得加油啊,哈哈。
2008-10-19 21:02
0
雪    币: 251
活跃值: (25)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
10
支持一下
2008-10-23 11:40
0
雪    币: 331
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
[QUOTE=;]...[/QUOTE]
很详细,值得学习
2008-10-23 17:30
0
游客
登录 | 注册 方可回帖
返回
//