好友
阅读权限35
听众
最后登录1970-1-1
|
solly
发表于 2019-6-18 16:50
本帖最后由 solly 于 2019-6-19 17:18 编辑
160 个 CrackMe 之 041 - defiler.1 是一个 Delphi 编制的 CrackMe,论坛中至少已有3贴説明了,pk8900也有收集,我这里再说明一下,主要是觉得:
1、原有几种方式操作有些复杂;
2、没有充分利用 Delphi 的特性;
3、修改程序的代码量有点多。
既然是 Delphi 程序,当然先用 DeDeDark 打开看看吧:
按 rules.txt 的要求,要做一个 Exit 菜单项的事件处理。但在 DeDeDark中可以看到,“窗体”代码中,Exit 菜单项没有 OnClick 事件属性,再看看过程:
可以看到,事件过程也只有一个:About2Click,这个就是 About 的事件处理过程,因此,可以断定,CrackMe 中没的 Exit 菜单的对应事件处理过程。
我们先看看 About2Click() 事件的代码,双击上图的事件名即可打开代码查看器,如下图:
可以看到 About2Click() 函数的代码,具体内容如下:[Delphi] 纯文本查看 复制代码 0043E270 6A40 push $40
* Possible String Reference to: 'bleh'
|
0043E272 B98CE24300 mov ecx, $0043E28C
* Possible String Reference to: 'See rules.txt, mail your solution t
| o [url=mailto:defiler@immortaldescendants.org]defiler@immortaldescendants.org[/url]'
|
0043E277 BA94E24300 mov edx, $0043E294
0043E27C A1D0FB4300 mov eax, dword ptr [$0043FBD0]
0043E281 8B00 mov eax, [eax]
* Reference to: forms.TApplication.MessageBox(TApplication;PChar;PChar;Longint):Integer;
|
0043E283 E88CE9FFFF call 0043CC14
0043E288 C3 ret
在 OD 中也可以看到这段代码及其资源:
[Asm] 纯文本查看 复制代码 0043E270 . 6A 40 push 40
0043E272 . B9 8CE24300 mov ecx, 0043E28C ; ASCII "bleh"
0043E277 . BA 94E24300 mov edx, 0043E294 ; ASCII "See rules.txt, mail your solution to [url=mailto:defiler@immortaldescendants.org]defiler@immortaldescendants.org[/url]"
0043E27C . A1 D0FB4300 mov eax, dword ptr [43FBD0]
0043E281 . 8B00 mov eax, dword ptr [eax]
0043E283 . E8 8CE9FFFF call 0043CC14 ; call forms.TApplication.MessageBox()
0043E288 . C3 retn
0043E289 00 db 00
0043E28A 00 db 00
0043E28B 00 db 00
0043E28C . 62 6C 65 68 0>ascii "bleh",0
0043E291 00 db 00
0043E292 00 db 00
0043E293 00 db 00
0043E294 . 53 65 65 20 7>ascii "See rules.txt, m"
0043E2A4 . 61 69 6C 20 7>ascii "ail your solutio"
0043E2B4 . 6E 20 74 6F 2>ascii "n to defiler@imm"
0043E2C4 . 6F 72 74 61 6>ascii "ortaldescendants"
0043E2D4 . 2E 6F 72 67 0>ascii ".org",0
0043E2D9 00 db 00
0043E2DA 00 db 00
编过 Delphi 程序的人应该知道,Delphi 的事件是可以重用的,也就是説 Exit 菜单也可以使用这个事件处理过程,我们使用另一个工具来完成这个修改:eXeScope。我们用 eXeScope 打开 CrackMe 来修改 Delphi 程序的 RCData 资源,如下图:
在左侧的资源树中,选中“TFORM1”,然后在右侧的编辑区,在 Exit1 菜单对象中,增加一行 OnClick = About2Click,如下:
[Delphi] 纯文本查看 复制代码 object MainMenu1: TMainMenu
Left = 120
Top = 80
object About1: TMenuItem
Caption = '&Ficken'
object About2: TMenuItem
Caption = '&About'
OnClick = About2Click
end
object Exit1: TMenuItem
Caption = '&Exit'
OnClick = About2Click
end
end
end
可以从上面的 About2 菜单项中复制,改好后保存,如下图所示:
先择“OK”就可以了。
这样修改后,点 Exit 菜单,也会执行 About2Click() 函数,这样,我们只要修改 0x0043E270 处的 About2Click()就可以了。
用 OD 载入修改了资源的 CrackMe 程序,按 Ctrl+G,输入 0043E270,如下图所示:
我们来到了 Exit 和 About 的事件处理过程:
先在函数中的 0x0043E27C 处,下一个断点,如上图所示,再按 F9 运行 CrackMe,然后我们点击一个菜单项(About 或 Exit 均可),就会来到上面的断点。然后几个 F8 后,来到下图所示位置:
这里就是菜单处理事件回调处,如果[ebx+0x82]处为0,则表示没有指定 OnClick 事件,不用回调用户代码。如果不为0,则在 0x0042F428 处的 call 指令回调用户编写的代码。
再按多次 F8 返回到下图代码范围,往上翻,就可以看到Windows消息处理的代码,其中[esi]中保存的是消息代码,我们需要处理两个消息:WM_COMMAND 和 WM_CLOSE。我们在 0x00420285 处下一个条件断点,如下图所示:
为什么要拦截 WM_CLOSE 消息呢,因为我们要先找到 WM_CLOSE 消息的处理过程,然后才能改造 Exit 菜单的代码,用来退出 CrackMe。
经过几个来回的分析,我们确定,下图处就是 WM_COMMAND 和 WM_CLOSE 消息处理的分发处,从这里开始,进入不同的事件处理过程(jmp ecx):
上图ecx == 0x00438B68,是菜单事件处理,以及下图:
这里 ecx == 0x00438CEC,这是点击窗口右上角的关闭图标(即 WM_CLOSE)时的处理过程。
也就是 WM_COMMAND 和 WM_CLOSE 消息处理的分发,是通过一个 jmp ecx 跳转到不同的事件处理来完成的,具体代码如下:
[Asm] 纯文本查看 复制代码 00402E64 . 53 push ebx
00402E65 . 66:8B1A mov bx, word ptr [edx]
00402E68 . 66:09DB or bx, bx
00402E6B . 74 17 je short 00402E84
00402E6D . 66:81FB 00C0 cmp bx, 0C000
00402E72 . 73 10 jnb short 00402E84
00402E74 . 50 push eax
00402E75 . 8B00 mov eax, dword ptr [eax]
00402E77 . E8 74FFFFFF call 00402DF0
00402E7C . 58 pop eax
00402E7D . 74 05 je short 00402E84
00402E7F . 89D9 mov ecx, ebx
00402E81 . 5B pop ebx
00402E82 . FFE1 jmp ecx ; 跳转到不同的事件处理过程
00402E84 > 5B pop ebx
00402E85 . 8B08 mov ecx, dword ptr [eax]
00402E87 . FF61 F0 jmp dword ptr [ecx-10]
00402E8A . C3 retn
其中,处理 WM_CLOSE 的事件处理代码如下:
[Asm] 纯文本查看 复制代码 00438CEC . E8 DF0B0000 call 004398D0
00438CF1 . C3 retn
这里看不出什么,我们用 IDA 打开 CrackMe ,通过地址找到上面代码,如下:
[Asm] 纯文本查看 复制代码 CODE:00438CEC sub_438CEC proc near ; DATA XREF: CODE:00432EBE↑o
CODE:00438CEC call @Forms@TCustomForm@Close$qqrv ; Forms::TCustomForm::Close(void)
CODE:00438CF1 retn
CODE:00438CF1 sub_438CEC endp
IDA中指明了我们调用的函数名是 Forms::TCustomForm::Close,这个就是关闭表单的过程,我们在后面要修改 Exit 菜单的事件代码,调用这里的代码退出 CrackMe。
另外,按 Delphi 事件处理过程的规则,每次调用事件时,至少都会传入一个 Sender 参数,所以我们手动调用 Form.Close()时,也要传入 Form 对象指针,这个指针 Delphi 会存于 ebx 中,所以我们可以根据 ebx 的值来区分是哪个组件在调用事件处理过程。通过几次观察,可以得到
[Asm] 纯文本查看 复制代码 ;============= Sender ===============
Menu.Exit ===> EBX = 021D357C
Menu.About ===> EBX = 021D344C
Form.Close ===> EBX = 021D1738
上面就是每次调用时传入的 Sender 参数并会存于 ebx 中,并且 ebx 的高 16 bits 是变化的,而低 16 bits 不变,我们只要判断低 16 bits (即bx)就可以了。
下面,我们开始构建一个新的事件过程,用于处理菜单消息,我们来到前面找到的About 事件处理过程(0x0043E270处),往下拖动滚动条,寻找用来填充代码的空白区域,到 0x0043E4C0 处,可以找到一大片空白区域,我们在这里填充我们的事件处理代码和数据,如下图所示:
上图已输入了所需代码(上图的第2行的je指令还没修正偏移量,下图是修正了的),正在填充字符串数据,数据填充完后:
具体代码如下:
[Asm] 纯文本查看 复制代码 ;======================================================================================
0043E4C0 66:81FB 7C35 cmp bx, 357C ; Sender 是否为 Exit 菜单项
0043E4C5 74 1B je short 0043E4E2 ; 是则跳转去执行 Exit 操作
0043E4C7 90 nop ; 下面是原有 About 事件处理代码
0043E4C8 6A 40 push 40 ; MB_OK | MB_ICONINFORMATION
0043E4CA B9 8CE24300 mov ecx, 0043E28C ; ASCII "bleh"
0043E4CF BA 94E24300 mov edx, 0043E294 ; ASCII "See rules.txt, mail your solution to [url=mailto:defiler@immortaldescendants.org]defiler@immortaldescendants.org[/url]"
0043E4D4 A1 D0FB4300 mov eax, dword ptr [43FBD0]
0043E4D9 8B00 mov eax, dword ptr [eax]
0043E4DB E8 34E7FFFF call 0043CC14 ; call forms.TApplication.MessageBox()
0043E4E0 C3 retn ; eax == IDOK == 1
0043E4E1 90 nop ; 下面是新加的 Exit 事件处理代码
0043E4E2 6A 44 push 44 ; MB_YESNO | MB_ICONINFORMATION
0043E4E4 B9 8CE24300 mov ecx, 0043E28C ; ASCII "bleh"
0043E4E9 BA 10E54300 mov edx, 0043E510 ; ASCII "Do you fickbirne really want to quit?"
0043E4EE A1 D0FB4300 mov eax, dword ptr [43FBD0]
0043E4F3 8B00 mov eax, dword ptr [eax]
0043E4F5 E8 1AE7FFFF call 0043CC14 ; call forms.TApplication.MessageBox()
0043E4FA 83F8 06 cmp eax, 6 ; IDOK = 1, IDYES = 6, IDNO = 7 (这里为6表示选择了“YES”)
0043E4FD /75 0C jnz short 0043E50B ; 不为IDYES则跳转并返回,否则调用 CustomForm.Close(Sender)退出程序
0043E4FF |8BC3 mov eax, ebx ; eax为Sender参数,从ebx取得 Sender 对象高16位
0043E501 |66:B8 3817 mov ax, 1738 ; 修改Sender对象的低 16 位,修改成 CustomForm 对象。
0043E505 ^|E9 E2A7FFFF jmp 00438CEC ; 调用 CustomForm.Close(Sender)
0043E50A |90 nop
0043E50B \C3 retn ; 如果选择“NO”,则 eax == IDNO,在这里返回
数据如下:
[Asm] 纯文本查看 复制代码 ;---------------------------------------------------------------------------------------
0043E510 44 6F 20 79 6F 75 20 66 69 63 6B 62 69 72 6E 65 Do you fickbirne
0043E520 20 72 65 61 6C 6C 79 20 77 61 6E 74 20 74 6F 20 really want to
0043E530 71 75 69 74 3F 00 00 00 00 00 00 00 00 00 00 00 quit?...........
以上事件处理过程和数据录入完成后,就修改(0043E270)处的原事件代码,指向新的事件处理代码:
具体代码改动后,如下所示:
[Asm] 纯文本查看 复制代码 ;=======================================================================================
0043E270 /E9 4B020000 jmp 0043E4C0 ; 直接跳转到新的事件处理代码
0043E275 |90 nop
0043E276 |90 nop
0043E277 . |BA 94E24300 mov edx, 0043E294 ; ASCII "See rules.txt, mail your solution to [url=mailto:defiler@immortaldescendants.org]defiler@immortaldescendants.org[/url]"
0043E27C . |A1 D0FB4300 mov eax, dword ptr [43FBD0]
0043E281 . |8B00 mov eax, dword ptr [eax]
0043E283 . |E8 8CE9FFFF call 0043CC14
0043E288 . |C3 retn
搞完这些操作后,需要把这些变动保存起来,先把我们设置的所有断点禁用。
在改动了的代码上按右键,如下:
选择“复制到可执行文件==>所有修改”。会有一个确认提示:
选择“复制”,一共进行3次确认后,如下图:
再点右键,如下图:
选择”保存文件“,然后输入一个新的文件名保存即可。
我们运行刚才保存的新文件程序,击”Exit“菜单项,可以看到下面的提示:
按”是“就退出 CrackMe, 按”否“则不会退出。
下面是直接修改文件(eXeScope修改后的文件)时的地方,新事件和资源:
[Asm] 纯文本查看 复制代码 ;==== File =======
0003d8c0h: 66 81 FB 7C 35 74 1B 90 6A 40 B9 8C E2 43 00 BA ; f侞|5t.恓@箤釩.?
0003d8d0h: 94 E2 43 00 A1 D0 FB 43 00 8B 00 E8 34 E7 FF FF ; 斺C.⌒鸆.????
0003d8e0h: C3 90 6A 44 B9 8C E2 43 00 BA 10 E5 43 00 A1 D0 ; 脨jD箤釩.?錍.⌒
0003d8f0h: FB 43 00 8B 00 E8 1A E7 FF FF 83 F8 06 75 0C 8B ; 鸆.????凐.u.?
0003d900h: C3 66 B8 38 17 E9 E2 A7 FF FF 90 C3 00 00 00 00 ; 胒?.殁??惷....
0003d910h: 44 6F 20 79 6F 75 20 66 69 63 6B 62 69 72 6E 65 ; Do you fickbirne
0003d920h: 20 72 65 61 6C 6C 79 20 77 61 6E 74 20 74 6F 20 ; really want to
0003d930h: 71 75 69 74 3F 00 00 00 00 00 00 00 00 00 00 00 ; quit?...........
原事件处理代码的修改:
[Asm] 纯文本查看 复制代码 ;----------------------------------------------------------------------------
0003d670h: E9 4B 02 00 00 90 90 BA 94 E2 43 00 A1 D0 FB 43 ; 镵...悙簲釩.⌒鸆
分析完毕!!!
|
-
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|