首页
社区
课程
招聘
[原创]Devoney CrackMe2.0分析
发表于: 2007-2-4 17:40 6121

[原创]Devoney CrackMe2.0分析

2007-2-4 17:40
6121

【文章标题】: Devoney CrackMe2.0分析
【文章作者】: yugung
【软件名称】: Devoney's CrackMe 2.0; Find the secret text
【软件大小】: 3k
【下载地址】: http://www.crackmes.de/
【加壳方式】: 无壳
【编写语言】: Asm32
【使用工具】: peid+OD+IDA
【操作平台】: Windows
【作者声明】: 我是一只小菜鸟,偶有所得,愿与大家分享。
--------------------------------------------------------------------------------
【详细过程】
  偶然在crackme.de上看到这个cm,感觉还算新颖,顺手分析了一下,把过程发上来与大家分享。不当之处,敬请指正。
  1.Peid侦壳,无可,32位汇编编写。
  2.整个程序的交互界面为DialogBoxIndirectParamA创建的一对话框,由DialogBoxIndirectParamA的参数不难找到回调
  函数的位置在.text:004011A2处。输入的字符串由GetDlgItemTextA获取
  3.关键代码如下:
  .text:004011E6 push    48                    ; nMaxCount
  .text:004011E8 push    offset szInput        ; lpString
  .text:004011ED push    65h                   ; nIDDlgItem
  .text:004011EF push    [ebp+hWnd]            ; hDlg
  .text:004011F2 call    GetDlgItemTextA
  .text:004011F2
  .text:004011F7 mov     edx, offset szInput
  .text:004011FC mov     ebx, -1
  .text:00401201 mov     ecx, -1
  .text:00401201
  .text:00401206
  .text:00401206 NextInByte:                   ; CODE XREF: DialogFunc+B4j
  .text:00401206                               ; DialogFunc+D6j DialogFunc+F8j
  .text:00401206                               ; DialogFunc+11Dj DialogFunc+138j
  .text:00401206                               ; DialogFunc+14Cj ...
  .text:00401206 inc     ebx
  .text:00401207 mov     cl, ss:[edx+ebx]
  .text:0040120B test    cl, cl
  .text:0040120D jz      TreatComplete
  .text:0040120D
  .text:00401213 cmp     ebx, 0
  .text:00401216 ja      short Is_1
  .text:00401216
  .text:00401218 sub     cl, 5Bh
  .text:0040121B mov     byte ptr ss:szByteList+1, cl
  .text:00401222 mov     byte ptr ss:szByteList+6, cl
  .text:00401229 mov     byte ptr ss:szByteList+0Bh, cl
  .text:00401230 mov     byte ptr ss:szByteList+0Dh, cl
  .text:00401237 mov     byte ptr ss:szByteList+10h, cl
  .text:0040123E mov     byte ptr ss:szByteList+11h, cl
  .text:00401245 mov     byte ptr ss:szByteList+12h, cl
  .text:0040124C add     cl, 72h
  .text:0040124F mov     byte ptr ss:szSecretText+15h, cl
  .text:00401256 jmp     short NextInByte
  .text:00401256
  .text:00401258 ; ---------------------------------------------------------------------------
  .text:00401258
  .text:00401258 Is_1:                         ; CODE XREF: DialogFunc+74j
  .text:00401258 cmp     ebx, 1
  .text:0040125B ja      short Is_2
  .text:0040125B
  .text:0040125D add     cl, 0Bh
  .text:00401260 mov     byte ptr ss:szByteList, cl ; "1234567890123456789"
  .text:00401267 mov     byte ptr ss:szByteList+0Ch, cl
  .text:0040126E sub     cl, 3
  .text:00401271 mov     byte ptr ss:szSecretText+14h, cl
  .text:00401278 jmp     short NextInByte
  .text:00401278
  .text:0040127A ; ---------------------------------------------------------------------------
  .text:0040127A
  .text:0040127A Is_2:                         ; CODE XREF: DialogFunc+B9j
  .text:0040127A cmp     ebx, 2
  .text:0040127D ja      short Is_3
  .text:0040127D
  .text:0040127F add     cl, 25h
  .text:00401282 mov     byte ptr ss:szByteList+2, cl
  .text:00401289 mov     byte ptr ss:szByteList+7, cl
  .text:00401290 sub     cl, 3
  .text:00401293 mov     byte ptr ss:szSecretText+16h, cl
  .text:0040129A jmp     NextInByte
  .text:0040129A
  .text:0040129F ; ---------------------------------------------------------------------------
  .text:0040129F
  .text:0040129F Is_3:                         ; CODE XREF: DialogFunc+DBj
  .text:0040129F cmp     ebx, 3
  .text:004012A2 ja      short Is_4
  .text:004012A2
  .text:004012A4 sub     cl, 42h
  .text:004012A7 mov     byte ptr ss:szByteList+4, cl
  .text:004012AE mov     byte ptr ss:szByteList+9, cl
  .text:004012B5 add     cl, 35h
  .text:004012B8 mov     byte ptr ss:szSecretText+17h, cl
  .text:004012BF jmp     NextInByte
  .text:004012BF
  .text:004012C4 ; ---------------------------------------------------------------------------
  .text:004012C4
  .text:004012C4 Is_4:                         ; CODE XREF: DialogFunc+100j
  .text:004012C4 cmp     ebx, 4
  .text:004012C7 ja      short Is_5
  .text:004012C7
  .text:004012C9 sub     cl, 21h
  .text:004012CC mov     byte ptr ss:szByteList+5, cl
  .text:004012D3 mov     byte ptr ss:szByteList+0Ah, cl
  .text:004012DA jmp     NextInByte
  .text:004012DA
  .text:004012DF ; ---------------------------------------------------------------------------
  .text:004012DF
  .text:004012DF Is_5:                         ; CODE XREF: DialogFunc+125j
  .text:004012DF cmp     ebx, 5
  .text:004012E2 ja      short Is_6
  .text:004012E2
  .text:004012E4 add     cl, 85h
  .text:004012E7 mov     byte ptr ss:szByteList+0Eh, cl
  .text:004012EE jmp     NextInByte
  .text:004012EE
  .text:004012F3 ; ---------------------------------------------------------------------------
  .text:004012F3
  .text:004012F3 Is_6:                         ; CODE XREF: DialogFunc+140j
  .text:004012F3 cmp     ebx, 6
  .text:004012F6 ja      short Is_7
  .text:004012F6
  .text:004012F8 sub     cl, 2Ch
  .text:004012FB mov     byte ptr ss:szByteList+3, cl
  .text:00401302 jmp     NextInByte
  .text:00401302
  .text:00401307 ; ---------------------------------------------------------------------------
  .text:00401307
  .text:00401307 Is_7:                         ; CODE XREF: DialogFunc+154j
  .text:00401307 cmp     ebx, 7
  .text:0040130A ja      short over
  .text:0040130A
  .text:0040130C sub     cl, 3Ah
  .text:0040130F mov     byte ptr ss:szByteList+8, cl
  .text:00401316 add     cl, 3Fh
  .text:00401319 mov     byte ptr ss:szSecretText+18h, cl
  .text:00401320 jmp     NextInByte
  .text:00401320
  .text:00401325 ; ---------------------------------------------------------------------------
  .text:00401325
  .text:00401325 over:                         ; CODE XREF: DialogFunc+168j
  .text:00401325 sub     cl, 2Bh
  .text:00401328 mov     byte ptr ss:szByteList+0Fh, cl
  .text:00401328
  .text:0040132F
  .text:0040132F TreatComplete:                ; CODE XREF: DialogFunc+6Bj
  .text:0040132F push    lpNumberOfBytesWritten ; lpNumberOfBytesWritten
  .text:00401335 push    nSize                 ; nSize
  .text:0040133B push    offset szByteList     ; lpBuffer
  .text:00401340 push    offset AddrToWrite    ; lpBaseAddress
  .text:00401345 push    hThisProcess          ; hProcess
  .text:0040134B call    WriteProcessMemory
  .text:0040134B
  .text:00401350 nop
  .text:00401350
  .text:00401351
  .text:00401351 ; void AddrToWrite
  .text:00401351 AddrToWrite:                  ; DATA XREF: DialogFunc+19Eo
  .text:00401351 nop
  .text:00401352 nop
  .text:00401353 nop
  .text:00401354 nop
  .text:00401355 nop
  .text:00401356 nop
  .text:00401357 nop
  .text:00401358 nop
  .text:00401359 nop
  .text:0040135A nop
  .text:0040135B nop
  .text:0040135C nop
  .text:0040135D nop
  .text:0040135E nop
  .text:0040135F nop
  .text:00401360 nop
  .text:00401361 nop
  .text:00401362 nop
  .text:00401363 nop
  .text:00401364 nop
  
  4.分析:
  整个CM有点smc的意思。
  在数据段中定义了一个19byte的字节串
  szByteList db '1234567890123456789',0
  根据输入字符串的不同,程序将动态更新这个字节串的内容;并调用WriteProcessMemory将其写入text:00401351开始的
  19个字节。注意! 这19个字节的内容不是随便什么值就可以的,否则很容易就会一起程序异常。
  具体写入什么内容呢?查看一下输入表,可以看到函数MessageBoxA,但纵观整个程序并没有见到对其进行调用的地方;
  看来是留给我们自己调用了 ^_^
  5.详解MessageBoxA
  对于这个函数大家并不陌生,但是现在我们要从字节的角度来观察对这个函数的调用。先找个例子看看,MessageBoxA调用
  过程对应的字节码张什么样子? 下面是我找的一个例子,
  004046E7   .  6A 40              push 40                                                  ; /Style =
  004046E9   .  68 A4364100        push CrackMe_.004136A4                                   ; |Title =
  004046EE   .  68 4C364100        push CrackMe_.0041364C                                   ; |Text =
  004046F3   .  50                 push eax                                                 ; |hOwner
  004046F4   .  FF15 DC204100      call dword ptr ds:[<&USER32.MessageBoxA>]                ; \MessageBoxA
  上述这个调用过程正好占用19个字节,我们就在这基础上进行修改。
  
  首先,MessageBoxA的调用过程涉及两个字符串,分别用于Title和Text,问:从哪里来?
  作者已经给我们准备好了,数据段里早定义了两个字符串
  .data:00403025 szSecretText db 'The Secret Text is: 00000',0
  .data:0040303F szCheckAtHttp db 'Check at http://members.lycos.nl/wietsite/fp.php?x=secret_text',0
  技术上,哪个做Title,哪个做Text都无所谓。考虑到这里我们选择szSecretText做Text,另一字符串做Title解得的SecretText更加有意义, 则这两个参数对应的10各字节应为 "68 3f 30 40 00 68 25 30 40 00" (感谢aalloverred的指正 )
  
  6.拼凑19个字节的值
  对原CM的反汇编代码进行分析,可知19个字节按照数值的不同可以分为9组(各字节按其次序用0~0x12标识):
  1,6,b,d,10,11,12
  0,c
  2,7
  4,9
  5,a
  e
  3
  8
  f
  
  细心的朋友会发现 第2,4,5,6字节和第7,9,0xA,0xB字节这正好与上一部分分析得到的10个字节相符合。
  由此,可以确定19个字节具有如下的形式:
  ?? ?? 68 25 30 40 00 68 3f 30 40 00 ?? ?? ?? ?? ?? ?? ??
  又1,6,b,d,10,11,12 这7个字节值相等,故进一步得出:
  ?? 00 68 25 30 40 00 68 3f 30 40 00 ?? 00 ?? 00 00 00
  同前面我们找的调用MessageBoxA的例子进行比较,易知0,0xC两个字节为6a
  ==>6a 00 68 25 30 40 00 68 3f 30 40 00 6a 00 ?? ?? 00 00 00
  
  下面就call MessageBoxA语句对应的字节码了,注意:现在只有两个字节可以变动了!
  如果我们直接使用"call MessageBoxA",利用OD的汇编功能可知对应的字节码为 E8 93 F1 94 77, 显然不是我们所
  需要的;换一个角度,考虑到 .text:00401396处为 "jmp     ds:MessageBoxA", 我们间接的"call 00401396".
  对应的字节码为 "E8 32 00 00 00", 所以可以填补未知的两个字节。
  
  最后得到, 所需的19个字节的值为
  "6a 00 68 25 30 40 00 68 3f 30 40 00 6a 00 e8 32 00 00 00"
  
  7.反推输入字符串
  由反汇编代码可知,上述9组数值由输入字符串的前九个字符的Ascii通过加减运算得到。
  具体比较简单,只给出结果, 前九个字符字节值为 "5B 5F 43 72 61 63 51 79 5D",
  对应的字符串为 "[_Crack_]"
  
  输入此字符串,程序自动算出对应的SecretText为"greed"
  
  Done

--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
                                                       2007年02月04日 17:30:09


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (10)
雪    币: 461
活跃值: (93)
能力值: ( LV9,RANK:1170 )
在线值:
发帖
回帖
粉丝
2
强,支持楼主!
2007-2-4 22:05
0
雪    币: 297
活跃值: (21)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
3
看到这么多字的就要顶一下,支持~~・!
2007-2-4 22:26
0
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
4
这么详细的分析就要顶一下
2007-2-4 22:41
0
雪    币: 333
活跃值: (116)
能力值: ( LV9,RANK:570 )
在线值:
发帖
回帖
粉丝
5
好文章,顶!

(另: 楼上的KAN大哥,啥时你的泡妞大全才出呀?
自从在群上一别之后,我可是一直等到拜读的呀!)
2007-2-4 22:50
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
很具体,谢谢分享,
2007-2-4 23:03
0
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
7
最初由 acafeel 发布
好文章,顶!

(另: 楼上的KAN大哥,啥时你的泡妞大全才出呀?
自从在群上一别之后,我可是一直等到拜读的呀!)


啊,这。。。。这。。。。难说了,还有我是乱说的,千万别当真。。。。
2007-2-4 23:20
0
雪    币: 342
活跃值: (318)
能力值: ( LV12,RANK:740 )
在线值:
发帖
回帖
粉丝
8
hehe,支持楼主。

.data:00403025 szSecretText db 'The Secret Text is: 00000',0
.data:0040303F szCheckAtHttp db 'Check at http://members.lycos.nl/wietsite/fp.php?x=secret_text',0
至于哪个做Title,哪个做Text都无所谓。这里我们选择szSecretText做Title,另一字符串做Text

究竟是不是无所谓还应该再试试,实践一下。
2007-2-4 23:34
0
雪    币: 220
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
最初由 aalloverred 发布
hehe,支持楼主。

究竟是不是无所谓还应该再试试,实践一下。


严谨总是好的。

个人认为这里最关键的Title和Text这两个字符串硬地址的前三个字节相同必须相同。
2007-2-5 07:02
0
雪    币: 342
活跃值: (318)
能力值: ( LV12,RANK:740 )
在线值:
发帖
回帖
粉丝
10
当然我并不是说楼主不够严谨,如有冒犯请原谅。
虽然这个crackme没有一个严格的标准到底怎么样才算成功,但我还是觉得
=========================
密码:[_Crack_]
The Secret Text is: greed
=========================
相对更容易让人接受。
2007-2-5 12:26
0
雪    币: 220
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
最初由 aalloverred 发布
当然我并不是说楼主不够严谨,如有冒犯请原谅。
虽然这个crackme没有一个严格的标准到底怎么样才算成功,但我还是觉得
=========================
密码:[_Crack_]
The Secret Text is: greed
........


楼上的似乎更好一些。
cm里给的那个网址,我连不上去;所以,也不能确定我的结果是否真的正确。
2007-2-5 12:50
0
游客
登录 | 注册 方可回帖
返回
//