首页
社区
课程
招聘
[分享] 直捣黄龙——Delphi程序的快速定位关键点之方法。给新手看,高手早已掌握了。
发表于: 2008-10-29 22:48 20198

[分享] 直捣黄龙——Delphi程序的快速定位关键点之方法。给新手看,高手早已掌握了。

2008-10-29 22:48
20198

【文章标题】: 直捣黄龙——Delphi程序的快速定位关键点之方法
【文章作者】: 书呆彭
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  看到ximo在论坛发贴,说一个CrackMe找不到关键点。正好想找个CM练练手,就拿来分析了一下。
  
  这里是原贴,该CrackMe程序也请到这里下载。
  
  http://bbs.pediy.com/showthread.php?t=75528
  
  拿到手中第一件事,就是查壳。
  
  ximo说原来是UPX壳,已经脱掉了。用PEiD载入一看,是Delphi的。
  
  
  心中一阵窃喜。最喜欢宝蓝的开发工具生成的程序了。一是代码非常规整,容易阅读,二是有专门的工具Dede来对付它。
  
  (话说Dede是使用宝蓝RAD工具的程序员的噩梦。。。)
  
  先运行程序,出来一个窗口。
  
  好,我们找下输入注册码的地方。点文件菜单,什么。。。。
  
  只有退出一个选项???
  
  点关于,弹出作者留下的话。
  
  “I hope it will take you some time to find 'where the dog is burried' ”
  
  哦,原来如此,作者让我们自己找输入注册码的方法。
  
  找呀找呀找朋友,在窗口上乱点半天,键盘乱按半天,都没有任何反应。
  
  这可如何是好???
  
  
  哈哈,下面就是本文的标题提到的“直捣黄龙”的内容了。
  
  我说过了,对于Delphi,我们有个利器名叫Dede。
  
  现在我们请它出场。
  
  等Dede忙活完了,我们先来到”窗体“这个页面。
  
  看一下程序的布局,如图:

  
  
  一个主窗口,叫Form1,它上面是一个图像控件和一个菜单,而菜单只包含退出和关于两个功能。
  
  好,我们几乎可以确定,核心的功能代码应该在Form1的一些方法中,图像控件可能性不大,而菜单已经排除。
  
  那我们再转到“过程”页面。可以看到左边单元列表中只有个main,右边的事件响应函数也只有4个。太好了。基本上我们已经确定了。
  
  看这4个函数
  
  About1Click,这个是显示说明的,排除。

  Exit1Click,这个是退出的,排除。
  
  FormCreate,这个是程序初始化的一个过程。如果它采用文件注册的方式,那么这个函数值得怀疑。
  
  FormKeyPress,这个,,,,,,绝对的嫌疑。回想起软件运行起来后点哪都没反应,按什么键都没反应,实际上按键时程序是要处理的。
  
  
  
  我们先看看FormCreate函数中干了些什么。用OD载入,直接g 429b7C,这个地址是在Dede中看到的FormCreate的地址。
  
  等OD停下来时,看到这个函数非常简单,几层call跟进后,并没有文件操作等可疑行为,基本都是一些变量的初始化。这个函数用了一些代码

混淆,会影响反汇编器的输出,所以不要上下翻动反汇编窗口,否则显示的指令就乱了。
  
  最终,我们的目标完全确定,就是FormKeyPress。我们 bp 429954,然后F9运行,我们试着按一下键盘上的键,我就按个"1
  "试试,啪一下,OD给断下来的了。
  
  我们来详细分析一下这个函数。我们知道Delphi一般是采用寄存器传递参数的。我们看下OD显示的寄存器的值:
  
  EAX 00A02B14
  ECX 0012FDB5 ASCII "1A"
  EDX 00A02B14
  EBX 00A02B14
  ESP 0012FDA8
  EBP 0012FE40
  ESI 00A02B14
  EDI 0012FE48
  EIP 00429954 gncrk.00429954
  
  eax,edx,ebx中的值都是一样,猜测这个就是form1对象的指针。而ecx指向一个字符串,"1A",这是什么??由于这是按键消息的处理过程,

我们猜测这个和按下键码有关系。
  
  再试验一下,F9运行,然后按字母a,再次中断后,ecx指向的串变成了 "aA"
  
  就是这样。
  
  我们往下跟踪,看到这行代码:
  
  00429974     >INC     DWORD PTR DS:[42B710]
  0042997A     >LEA     EAX, DWORD PTR SS:[EBP-68]
  0042997D     >MOV     DL, BYTE PTR DS:[EBX]
  0042997F     >CALL    gncrk.004036D4
  00429984     >MOV     EDX, DWORD PTR SS:[EBP-68]
  00429987     >MOV     EAX, gncrk.0042B714
  0042998C     >CALL    <gncrk.strcat>
  00429991     >CMP     DWORD PTR DS:[42B710], 0C
  00429998     >JNZ     gncrk.00429B02
  
  
  每次按键,地址42b710处的变量都增加一,下面的分支语句的条件是该值42b710的值是否为0C。
  
  F4到00429991     >CMP     DWORD PTR DS:[42B710], 0C这一行,OD显示该地址的值为2
  
  没什么疑问,这是个计数值,表示已经输入的字符数。我们在数据窗口定位到42b710,给其加个标签,我命名为InputCount
  
  现在刚才那几行代码已经变成:
  
  00429974    >INC     DWORD PTR DS:[<InputCount>]
  0042997A    >LEA     EAX, DWORD PTR SS:[EBP-68]
  0042997D    >MOV     DL, BYTE PTR DS:[EBX]
  0042997F    >CALL    gncrk.004036D4
  00429984    >MOV     EDX, DWORD PTR SS:[EBP-68]
  00429987    >MOV     EAX, gncrk.0042B714
  0042998C    >CALL    <gncrk.strcat>
  00429991    >CMP     DWORD PTR DS:[<InputCount>], 0C
  00429998    >JNZ     gncrk.00429B02
  
  是不是好读一些了??
  
  现在回到这个函数的开头,我们知道注册码长度应该是x0C。我们在这一行按shift + F4,在条件满足次数里写9,确定后F9运行。

  
  
  现在我们在程序界面中随便按几个键,当按第10下时,OD重新暂停。
  
  所以刚才写9的意思是,在条件满足9次之后,断点生效,即第10次断点生效。因为刚才已经输入了两个字符了。
  
  现在我们输入的长度已经是0x0C了,下面就是分析算法了。
  
  关于算法分析不是我此文的重点,而且该软件的算法相对来说非常简单,像我基本没做什么注释,往下跟踪了几下,凭感觉猜测出所调用的

函数为 operator+(string,string),然后F8验证之,还有string.format()函数等。
  
  最后,把计算过程弄明白后,用纸笔将程序中的几个常数抄下来,然后算出一组满足条件的注册码。
  
  重新运行程序,依次输入12个字符,哈,成功了!
  
  
  
--------------------------------------------------------------------------------
【经验总结】
  本文重点并不是讲汇编代码阅读和算法分析,因为这主要是靠自己多多练习来提高的。
  本文旨在提示新手,工欲善其事,必先利其器。必须熟练掌握各种工具软件的使用方法了技巧。
  重点是对症下药,不同的程序适合用不同的工具去处理。
  
  我主要展示了我在逆向过程中常用的几个小技巧,高手们早就会了,这里我给新手们总结一下:
  
  1.使用OD的标签功能,每推断出一段代码的功能,或一个变量的用途,立即给它加上一个合适的标签,这样你会发现你的反
  汇编代码变得越来越容易读了。
  
  2.巧妙利用OD的条件断点功能。这个功能非常强大。有时候在一个被频繁调用的函数处下断点,会发生程序基本总处于暂停
  状态,根本运行不起来了。如果使用条件断点,对函数的返回地址范围,或参数进行过滤,会有意想不到的效果。
  
  3.本文的重点,对于delphi程序,一定先用Dede看一看,从Dede得到的信息,往往能够将程序“秒杀”。不用一个又一个地
  试API断点,可以直接来到程序的核心地带。
  
  4.顺带提一下,可能有的新手还不知道,对于Borland C++ Builder的程序,Dede同样可以得到大量的有用信息。这个中原
  因,只因为宝蓝公司所开发的应用程序框架,被Delphi和C++ Builder同时采用,因此它们内部记录的信息结构基本相同,
  不同之处只是所采用的语言了。
  
  对于Delphi,它的简单快速高效,一方面是它的优点,另一方面正好使它容易被分析。“小即是美”这一原则,对逆向工程
  同样适用。。。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年10月29日 22:29:44


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (52)
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
2
这个论坛只剩下我一个新手了
2008-10-30 01:14
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
3
我是第二个~~~~
2008-10-30 01:21
0
雪    币: 357
活跃值: (3598)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
4
我第三~~~
2008-10-30 01:50
0
雪    币: 215
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
新手来插队
2008-10-30 02:07
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
6
完全看不懂.
2008-10-30 06:01
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
全都是高手级人物。。看了后感觉没有那么迷惘了。谢谢帅哥~
2008-10-30 10:43
0
雪    币: 357
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
真正新来的,来看看拉
2008-10-30 13:18
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ppt
9
[QUOTE=书呆彭;527871]【文章标题】: 直捣黄龙——Delphi程序的快速定位关键点之方法
【文章作者】: 书呆彭
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

没什么疑问,这是个计数值,表示已经输入的字符数。我们在数据窗口定位到42b710,给其加个标签,我命名为InputCount
  
  现在刚才那几行代码已经变成:
  
  00429974    >INC     DWORD PTR DS:[<InputCount>
  0042997A    >LEA     EAX, DWORD PTR SS:[EBP-68]
  0042997D    >MOV     DL, BYTE PTR DS:[EBX]
  0042997F    >CALL    gncrk.004036D4
  00429984    >MOV     EDX, DWORD PTR SS:[EBP-68]
  00429987    >MOV     EAX, gncrk.0042B714
  0042998C    >CALL    <gncrk.strcat>
  00429991    >CMP     DWORD PTR DS:[<InputCount>], 0C
  00429998    >JNZ     gncrk.00429B02
  
  是不是好读一些了??
------------------------------------------------------------------...[/QUOTE]

请教下怎么在OD里添加标签,至今不会用
2008-10-30 13:24
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ppt
10
看来OD工具还有很多不会
2008-10-30 13:27
0
雪    币: 264
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我新手,来学习一下...
2008-10-30 14:15
0
雪    币: 224
活跃值: (147)
能力值: ( LV9,RANK:970 )
在线值:
发帖
回帖
粉丝
12
天书...无法理解
2008-10-30 19:07
0
雪    币: 269
活跃值: (51)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
上楼的都不理解,我更不用说了。
2008-10-30 19:28
0
雪    币: 190
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
新手,俺是来学习的.
2008-10-30 20:07
0
雪    币: 36277
活跃值: (7170)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
受教了,还可以。
2008-10-30 20:21
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
16
Alt + Shift + 数字 是设定

Shift + 数字 是使用

一直都离不开这东西,很有前景的功能
2008-10-30 20:55
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
原来我比新手还新~~~努力~~
2008-10-30 22:53
0
雪    币: 186
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
凭感觉猜测出所调用的

函数为 operator+(string,string),然后F8验证之,还有string.format()函数等。
  
  最后,把计算过程弄明白后,用纸笔将程序中的几个常数抄下来,然后算出一组满足条件的注册码。

这点能不能给大家详细一点?谢
2008-10-31 00:36
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
19
晕,我喝了点酒,刚想说这句,发现被你说了
2008-10-31 01:10
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
我是新手,来学习了
2008-10-31 13:06
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
21
今天晚上又写了点东西,希望有所帮助。

http://bbs.pediy.com/showthread.php?p=528771
2008-10-31 21:27
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
写得好,学习了
2008-10-31 22:19
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
从楼主的文章中学到东西了 感谢楼主分享
2008-11-1 11:45
0
雪    币: 340
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
我都是直接偷懒。用delphi魔法断点脚本。。。连DEDE都省掉了。。。
2008-12-18 16:04
0
雪    币: 136
活跃值: (125)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
25
啥叫魔法断点啊 不懂 呵呵 squn美女讲讲
2008-12-18 16:37
0
游客
登录 | 注册 方可回帖
返回
//