首页
社区
课程
招聘
[原创]准CM的灌水贴
发表于: 2009-5-10 12:42 4029

[原创]准CM的灌水贴

2009-5-10 12:42
4029
警告:本贴仅供菜鸟灌水消遣,浪费了时间,本人概不负责

PS:热烈欢迎板砖

CM地址在这里:http://bbs.pediy.com/showthread.php?t=88307

我写的,VC,静态库,遵照r大标准,没有加壳(CM加壳干P呃...)

首先,常规开局,运行,什么都不输,点击,有提示框报错,那么bp        MessageBosA

断在这里:

00410C92  |> \85FF          test    edi, edi
00410C94  |.  74 05         je      short 00410C9B
00410C96  |.  8B7F 78       mov     edi, dword ptr [edi+78]
00410C99  |.  EB 1A         jmp     short 00410CB5
00410C9B  |>  8D85 ECFEFFFF lea     eax, dword ptr [ebp-114]
00410CA1  |.  68 04010000   push    104                              ; /BufSize = 104 (260.)
00410CA6  |.  50            push    eax                              ; |PathBuffer
00410CA7  |.  6A 00         push    0                                ; |hModule = NULL
00410CA9  |.  8DBD ECFEFFFF lea     edi, dword ptr [ebp-114]         ; |
00410CAF  |.  FF15 E4414100 call    dword ptr [<&KERNEL32.GetModuleF>; \GetModuleFileNameA
00410CB5  |>  53            push    ebx                              ; /Style
00410CB6  |.  57            push    edi                              ; |Title
00410CB7  |.  FF75 08       push    dword ptr [ebp+8]                ; |Text
00410CBA  |.  FF75 F4       push    dword ptr [ebp-C]                ; |hOwner
00410CBD  |.  FF15 80434100 call    dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA

上下看了下,都是些不知所云的东西,于是很有成就感:嗯,这次可以忽悠多点人了

不过,这里很明显是根据CM输入为空则报错的惯例,而判断输入为空的代码显然不在这里,看看了栈顶,果然是个函数调用,那么继续Enter跟进

接下来的地方好像有个为空比较的test:

00410CFD  |.  85C0          test    eax, eax
00410CFF  |.  74 15         je      short 00410D16

然而,既然是需要同时判断用户名和注册码,一个这样的结构怎么可能完成?唯一的解释是被调用两次,但实

践证明,这家伙似乎确凿只执行一次,那应该不是这里了,看下栈顶,还在函数内,那么Enter继续找

来到这里:

00401319   > \53            push    ebx
0040131A   .  53            push    ebx
0040131B   .  68 A0904100   push    004190A0                         ;  u lost
00401320   .  E8 CDF90000   call    00410CF2

显然,这里是错误提示,那么,会调用这个错误提示函数的就是比较的地方了,跟上去,果然:

004012C7   .  33DB          xor     ebx, ebx
004012C9   .  3958 F8       cmp     dword ptr [eax-8], ebx
004012CC   .  74 4B         je      short 00401319
004012CE   .  8B46 60       mov     eax, dword ptr [esi+60]
004012D1   .  83C6 60       add     esi, 60
004012D4   .  3958 F8       cmp     dword ptr [eax-8], ebx
004012D7   .  74 40         je      short 00401319

可以看到是分别与ebx比较,相等则跳至错误,而ebx一开始已被清0,显然只要不为0则不会报错

好,接下来就没必要按常规分析了,这个CM是个半成品,未隐藏字符串(怎么知道的?我写的嘛,而且说明里也有哦,俺很老实地)

针对这个,只要直接查找敏感字符串,说明说了,正确提示为i lost,就查这个来到:

004014CB   .  6A 00         push    0
004014CD   .  6A 00         push    0
004014CF   .  68 A8904100   push    004190A8                         ;  i lost
004014D4   .  E8 19F80000   call    00410CF2
004014D9   .  C3            retn
004014DA  /$  C741 0C CB144>mov     dword ptr [ecx+C], 004014CB      ;  j
004014E1  \.  C3            retn
004014E2  /$  B8 B02E4100   mov     eax, 00412EB0                    ;  咐ga
004014E7  |.  E8 D00B0000   call    004020BC
004014EC  |.  83EC 0C       sub     esp, 0C
004014EF  |.  53            push    ebx
004014F0  |.  56            push    esi
004014F1  |.  8BF1          mov     esi, ecx
004014F3  |.  57            push    edi
004014F4  |.  8965 F0       mov     dword ptr [ebp-10], esp
004014F7  |.  68 B8904100   push    004190B8                         ;  suno2009
004014FC  |.  8B46 08       mov     eax, dword ptr [esi+8]
004014FF  |.  50            push    eax
00401500  |.  E8 D60B0000   call    004020DB
00401505  |.  8945 EC       mov     dword ptr [ebp-14], eax
00401508  |.  8B46 04       mov     eax, dword ptr [esi+4]
0040150B  |.  68 B0904100   push    004190B0                         ;  @qq.com
00401510  |.  50            push    eax
00401511  |.  E8 C50B0000   call    004020DB
00401516  |.  83C4 10       add     esp, 10
00401519  |.  8945 E8       mov     dword ptr [ebp-18], eax
0040151C  |.  8B45 EC       mov     eax, dword ptr [ebp-14]
0040151F  |.  0B45 E8       or      eax, dword ptr [ebp-18]
00401522  |.  8945 EC       mov     dword ptr [ebp-14], eax
00401525  |.  8B45 EC       mov     eax, dword ptr [ebp-14]
00401528  |.  85C0          test    eax, eax
0040152A  |.  7D 03         jge     short 0040152F
0040152C  |.  83C0 0F       add     eax, 0F
0040152F  |>  8B4E 0C       mov     ecx, dword ptr [esi+C]
00401532  |.  8365 FC 00    and     dword ptr [ebp-4], 0
00401536  |.  8D0481        lea     eax, dword ptr [ecx+eax*4]
00401539  |.  FFD0          call    eax

注册码就爆出来了,这一part可谓最大的败笔,而且现在估计除了在下,没有第二个人用静态字符串做注册码

了吧?然而,设计这个CM,预想的功能是防爆

我的防爆设想是基于这样俩个假设:

1.爆破是使关键的条件跳转无效

2.“call 正确” 的地址为常数

因此,我的解决方法是:

00401519  |.  8945 E8       mov     dword ptr [ebp-18], eax
0040151C  |.  8B45 EC       mov     eax, dword ptr [ebp-14]
0040151F  |.  0B45 E8       or      eax, dword ptr [ebp-18]
00401522  |.  8945 EC       mov     dword ptr [ebp-14], eax
00401525  |.  8B45 EC       mov     eax, dword ptr [ebp-14]
00401528  |.  85C0          test    eax, eax
0040152A      7D 03         jge     short 0040152F
0040152C  |.  83C0 0F       add     eax, 0F
0040152F  |>  8B4E 0C       mov     ecx, dword ptr [esi+C]
00401532  |.  8365 FC 00    and     dword ptr [ebp-4], 0
00401536  |.  8D0481        lea     eax, dword ptr [ecx+eax*4]
00401539  |.  FFD0          call    eax                              ;  PuzzleBo.004014C7

对于第一条,可以看到这里并没出现关键的比较,至于0040152A的jge,其实并不重要,改为jmp也不会提示成功,为什么要加这条我忘了,这两天在改0.02版,代码乱七八糟的,原来的代码全丢了,不过记得此处判断可有可无,删掉好像并没实际影响

对于第二条,用call eax代替了常数,想要爆破的话,也没这么轻易了,如果是静态分析,估计还要难些

改进想法:至少先把那万恶的静态字符给hide了...

好,这就是对我的第一个CM的分析以及设计思路,文章和CM一样烂,权当灌水吧,如果有错还请前辈不吝斧正

:)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
2
能看看防暴的原代码吗?
2009-5-10 12:54
0
雪    币: 65
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
呃...写0.02版时改乱了,连CM我都是从原贴里下的..OIZ

其实机制是极简单的,能力有限,只能想到那个,如果我说出来全世界都会鄙视的,然而第二版还得指望它来忽悠,暂时卖个关子

LS看反汇编码就应该看出来了吧,您这么强,不过先别说出来好吗,不然第二版就没意义了
2009-5-10 13:06
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
4
呵呵,我没那么厉害,我想知道的是[esi+c]这个变量你是怎么定义的,又是怎么取得值的.
我编程不行,想向你学习一下.
2009-5-10 13:48
0
雪    币: 65
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
[esi+c]这个是编译器弄出来的,具体过程我也不太清楚

如果是取地址的话,C的&和*,都可以做到这样的功能的
2009-5-10 13:59
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
6
我直接引用函数名,编译器就直接优化成常数了.
你内联汇编了吗?
如果没有的话call eax又是怎么实现的?
2009-5-10 14:07
0
雪    币: 65
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
call eax 这句没用

应该是动态获取函数地址就可以编出call eax吧,我是这样理解,不知道对不对,编的时候也有点碰运气的成分,看看一会有没对编译器了解的前辈来回答吧
2009-5-10 14:15
0
游客
登录 | 注册 方可回帖
返回
//