- 浏览: 2060539 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (1409)
- asp/asp.net学习 (241)
- oracle (10)
- delphi (295)
- java (27)
- pb (1)
- 每日点滴 (49)
- 学习方法 (40)
- 思想方面 (104)
- C语言 (5)
- C++ (1)
- 代码重构经验 (5)
- 软件工程 (3)
- 数据库 (99)
- 英语学习 (3)
- mysql (1)
- 该关注的网站或者网页 (42)
- 总结 (7)
- 要去做的事情 (33)
- 算法 (1)
- 网络方面 (29)
- 随感 (96)
- 操作系统 (36)
- UML (12)
- 常用工具的使用 (55)
- 脚本 (7)
- 汇编 (62)
- 数据结构 (2)
- 财务 (38)
- 语文作文 (16)
- 法律 (1)
- 股票 (88)
最新评论
-
devwang_com:
可以,学习了~~
列出文件夹下所有文件夹的树形结构--Dos命令 tree的使用 -
hvang1988:
不管用啊 frxrprt1.PreviewForm.Pare ...
fastReport预览时嵌入到别的窗体 -
00915132:
我也有这个疑问,非常 感 谢
left join加上where条件的困惑 --SQL优化 -
zhuyoulong:
学习了,高效读书
软件架构师要读的书 -
nTalgar:
非常感谢分享!
Application.ProcessMessages用法:
转自:http://bbs.pediy.com/showthread.php?t=21330
OllyDBG 入门系列(三)-函数参考
作者:CCDebuger
现在进入第三篇,这一篇我们重点讲解怎样使用 OllyDBG 中的函数参考(即名称参考)功能。仍然选择 crackmes.cjb.net 镜像打包中的一个名称为 CrackHead 的crackme。老规矩,先运行一下这个程序看看:
呵,竟然没找到输入注册码的地方!别急,我们点一下程序上的那个菜单“Shit”(真是 Shit 啊,呵呵),在下拉菜单中选“Try It”,会来到如下界面:
我们点一下那个“Check It”按钮试一下,哦,竟然没反应!我再输个“78787878”试试,还是没反应。再试试输入字母或其它字符,输不进去。由此判断注册码应该都是数字,只有输入正确的注册码才有动静。用 PEiD 检测一下,结果为 MASM32 / TASM32,怪不得程序比较小。信息收集的差不多了,现在关掉这个程序,我们用 OllyDBG 载入,按 F9 键直接让它运行起来,依次点击上面图中所说的菜单,使被调试程序显示如上面的第二个图。先不要点那个“Check It”按钮,保留上图的状态。现在我们没有什么字串好参考了,我们就在 API 函数上下断点,来让被调试程序中断在我们希望的地方。我们在 OllyDBG 的反汇编窗口中右击鼠标,在弹出菜单中选择 查找->当前模块中的名称 (标签),或者我们通过按 CTR+N 组合键也可以达到同样的效果(注意在进行此操作时要在 OllyDBG 中保证是在当前被调试程序的领空,我在第一篇中已经介绍了领空的概念,如我这里调试这个程序时 OllyDBG 的标题栏显示的就是“[CPU - 主线程, 模块 - CrackHea]”,这表明我们当前在被调试程序的领空)。通过上面的操作后会弹出一个对话框,如图:
对于这样的编辑框中输注册码的程序我们要设断点首选的 API 函数就是 GetDlgItemText 及 GetWindowText。每个函数都有两个版本,一个是 ASCII 版,在函数后添加一个 A 表示,如 GetDlgItemTextA,另一个是 UNICODE 版,在函数后添加一个 W 表示。如 GetDlgItemTextW。对于编译为 UNCODE 版的程序可能在 Win98 下不能运行,因为 Win98 并非是完全支持 UNICODE 的系统。而 NT 系统则从底层支持 UNICODE,它可以在操作系统内对字串进行转换,同时支持 ASCII 和 UNICODE 版本函数的调用。一般我们打开的程序看到的调用都是 ASCII 类型的函数,以“A”结尾。又跑题了,呵呵。现在回到我们调试的程序上来,我们现在就是要找一下我们调试的程序有没有调用 GetDlgItemTextA 或 GetWindowTextA 函数。还好,找到一个 GetWindowTextA。在这个函数上右击,在弹出菜单上选择“在每个参考上设置断点”,我们会在 OllyDBG 窗口最下面的那个状态栏里看到“已设置 2 个断点”。另一种方法就是那个 GetWindowTextA 函数上右击,在弹出菜单上选择“查找输入函数参考”(或者按回车键),将会出现下面的对话框:
看上图,我们可以把两条都设上断点。这个程序只需在第一条指令设断点就可以了。好,我们现在按前面提到的第一条方法,就是“在每个参考上设置断点”,这样上图中的两条指令都会设上断点。断点设好后我们转到我们调试的程序上来,现在我们在被我们调试的程序上点击那个“Check It”按钮,被 OllyDBG 断下:
00401323 |. E8 4C010000 CALL <JMP.&USER32.GetWindowTextA> ; GetWindowTextA
00401328 |. E8 A5000000 CALL CrackHea.004013D2 ; 关键,要按F7键跟进去
0040132D |. 3BC6 CMP EAX,ESI ; 比较
0040132F |. 75 42 JNZ SHORT CrackHea.00401373 ; 不等则完蛋
00401331 |. EB 2C JMP SHORT CrackHea.0040135F
00401333 |. 4E 6F 77 20 7> ASCII "Now write a keyg"
00401343 |. 65 6E 20 61 6> ASCII "en and tut and y"
00401353 |. 6F 75 27 72 6> ASCII "ou're done.",0
0040135F |> 6A 00 PUSH 0 ; Style = MB_OK|MB_APPLMODAL
00401361 |. 68 0F304000 PUSH CrackHea.0040300F ; Title = "Crudd's Crack Head"
00401366 |. 68 33134000 PUSH CrackHea.00401333 ; Text = "Now write a keygen and tut and you're done."
0040136B |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; hOwner
0040136E |. E8 19010000 CALL <JMP.&USER32.MessageBoxA> ; MessageBoxA
从上面的代码,我们很容易看出 00401328 地址处的 CALL CrackHea.004013D2 是关键,必须仔细跟踪。而注册成功则会显示一个对话框,标题是“Crudd's Crack Head”,对话框显示的内容是“Now write a keygen and tut and you're done.”现在我按一下 F8,准备步进到 00401328 地址处的那条 CALL CrackHea.004013D2 指令后再按 F7 键跟进去。等等,怎么回事?怎么按一下 F8 键跑到这来了:
00401474 $- FF25 2C204000 JMP DWORD PTR DS:[<&USER32.GetWindowText> ; USER32.GetWindowTextA
0040147A $- FF25 30204000 JMP DWORD PTR DS:[<&USER32.LoadCursorA>] ; USER32.LoadCursorA
00401480 $- FF25 1C204000 JMP DWORD PTR DS:[<&USER32.LoadIconA>] ; USER32.LoadIconA
00401486 $- FF25 20204000 JMP DWORD PTR DS:[<&USER32.LoadMenuA>] ; USER32.LoadMenuA
0040148C $- FF25 24204000 JMP DWORD PTR DS:[<&USER32.MessageBoxA>] ; USER32.MessageBoxA
原来是跳到另一个断点了。这个断点我们不需要,按一下 F2 键删掉它吧。删掉 00401474 地址处的断点后,我再按 F8 键,呵,完了,跑到 User32.dll 的领空了。看一下 OllyDBG 的标题栏:“[CPU - 主线程, 模块 - USER32],跑到系统领空了,OllyDBG 反汇编窗口中显示代码是这样:
77D3213C 6A 0C PUSH 0C
77D3213E 68 A021D377 PUSH USER32.77D321A0
77D32143 E8 7864FEFF CALL USER32.77D185C0
怎么办?别急,我们按一下 ALT+F9 组合键,呵,回来了:
00401328 |. E8 A5000000 CALL CrackHea.004013D2 ; 关键,要按F7键跟进去
0040132D |. 3BC6 CMP EAX,ESI ; 比较
0040132F |. 75 42 JNZ SHORT CrackHea.00401373 ; 不等则完蛋
光标停在 00401328 地址处的那条指令上。现在我们按 F7 键跟进:
004013D2 /$ 56 PUSH ESI ; ESI入栈
004013D3 |. 33C0 XOR EAX,EAX ; EAX清零
004013D5 |. 8D35 C4334000 LEA ESI,DWORD PTR DS:[4033C4] ; 把注册码框中的数值送到ESI
004013DB |. 33C9 XOR ECX,ECX ; ECX清零
004013DD |. 33D2 XOR EDX,EDX ; EDX清零
004013DF |. 8A06 MOV AL,BYTE PTR DS:[ESI] ; 把注册码中的每个字符送到AL
004013E1 |. 46 INC ESI ; 指针加1,指向下一个字符
004013E2 |. 3C 2D CMP AL,2D ; 把取得的字符与16进制值为2D的字符(即“-”)比较,这里主要用于判断输入的是不是负数
004013E4 |. 75 08 JNZ SHORT CrackHea.004013EE ; 不等则跳
004013E6 |. BA FFFFFFFF MOV EDX,-1 ; 如果输入的是负数,则把-1送到EDX,即16进制FFFFFFFF
004013EB |. 8A06 MOV AL,BYTE PTR DS:[ESI] ; 取“-”号后的第一个字符
004013ED |. 46 INC ESI ; 指针加1,指向再下一个字符
004013EE |> EB 0B JMP SHORT CrackHea.004013FB
004013F0 |> 2C 30 SUB AL,30 ; 每位字符减16进制的30,因为这里都是数字,如1的ASCII码是“31H”,减30H后为1,即我们平时看到的数值
004013F2 |. 8D0C89 LEA ECX,DWORD PTR DS:[ECX+ECX*4] ; 把前面运算后保存在ECX中的结果乘5再送到ECX
004013F5 |. 8D0C48 LEA ECX,DWORD PTR DS:[EAX+ECX*2] ; 每位字符运算后的值与2倍上一位字符运算后值相加后送ECX
004013F8 |. 8A06 MOV AL,BYTE PTR DS:[ESI] ; 取下一个字符
004013FA |. 46 INC ESI ; 指针加1,指向再下一个字符
004013FB |> 0AC0 OR AL,AL
004013FD |.^ 75 F1 JNZ SHORT CrackHea.004013F0 ; 上面一条和这一条指令主要是用来判断是否已把用户输入的注册码计算完
004013FF |. 8D040A LEA EAX,DWORD PTR DS:[EDX+ECX] ; 把EDX中的值与经过上面运算后的ECX中值相加送到EAX
00401402 |. 33C2 XOR EAX,EDX ; 把EAX与EDX异或。如果我们输入的是负数,则此处功能就是把EAX中的值取反
00401404 |. 5E POP ESI ; ESI出栈。看到这条和下一条指令,我们要考虑一下这个ESI的值是哪里运算得出的呢?
00401405 |. 81F6 53757A79 XOR ESI,797A7553 ; 把ESI中的值与797A7553H异或
0040140B \. C3 RETN
这里留下了一个问题:那个 ESI 寄存器中的值是从哪运算出来的?先不管这里,我们接着按 F8 键往下走,来到 0040140B 地址处的那条 RETN 指令(这里可以通过在调试选项的“命令”标签中勾选“使用 RET 代替 RETN”来更改返回指令的显示方式),再按一下 F8,我们就走出 00401328 地址处的那个 CALL 了。现在我们回到了这里:
0040132D |. 3BC6 CMP EAX,ESI ; 比较
0040132F |. 75 42 JNZ SHORT CrackHea.00401373 ; 不等则完蛋
光标停在了 0040132D 地址处的那条指令上。根据前面的分析,我们知道 EAX 中存放的是我们输入的注册码经过计算后的值。我们来看一下信息窗口:
ESI=E6B5F2F9
EAX=FF439EBE
左键选择信息窗口中的 ESI=E6B5F2F9,再按右键,在弹出菜单上选“修改寄存器”,我们会看到这样一个窗口:
可能你的显示跟我不一样,因为这个 crackme 中已经说了每个机器的序列号不一样。关掉上面的窗口,再对信息窗口中的 EAX=FF439EBE 做同样操作:
由上图我们知道了原来前面分析的对我们输入的注册码进行处理后的结果就是把字符格式转为数字格式。我们原来输入的是字串“12345666”,现在转换为了数字 12345666。这下就很清楚了,随便在上面那个修改 ESI 图中显示的有符号或无符号编辑框中复制一个,粘贴到我们调试的程序中的编辑框中试一下:
呵呵,成功了。且慢高兴,这个 crackme 是要求写出注册机的。我们先不要求写注册机,但注册的算法我们要搞清楚。还记得我在前面说到的那个 ESI 寄存器值的问题吗?现在看看我们上面的分析,其实对做注册机来说是没有多少帮助的。要搞清注册算法,必须知道上面那个 ESI 寄存器值是如何产生的,这弄清楚后才能真正清楚这个 crackme 算法。今天就先说到这里,关于如何追出 ESI 寄存器的值我就留到下一篇 OllyDBG 入门系列(四)-内存断点 中再讲吧。
发表评论
-
用汇编写的病毒代码
2010-05-29 08:04 1898转自:http://www.programfan.com ... -
堆和栈(堆栈)的区别
2010-05-20 16:47 866转自:http://www.360doc.com/sho ... -
OllyDBG 入门系列(二)-字串参考
2010-05-05 19:02 1142转自:http://bbs.pediy.com/s ... -
用汇编编写DOS下的内存驻留程序(5)
2010-05-05 11:05 1022转自:http://www.x86asm.com/Dis ... -
用汇编编写DOS下的内存驻留程序(4)
2010-05-05 11:04 1169转自:http://www.x86asm.com/Displa ... -
用汇编编写DOS下的内存驻留程序(3)
2010-05-05 11:03 896转自:http://www.x86asm. ... -
用汇编编写DOS下的内存驻留程序(2)
2010-05-05 11:02 767转自:http://www.x86asm. ... -
用汇编编写DOS下的内存驻留程序(1)
2010-05-05 11:01 1501转自:http://www.x86 ... -
补码 左移与右移 32位系统
2010-05-02 11:04 2796QQ:797801 计算机中 ... -
c语言控制语句对应的汇编语句代码
2010-04-29 18:15 2253转:http://blog.csdn.net/ ... -
调试windows程序
2010-03-21 10:11 814debug 只能支持1M的寻址 如果需要调 ... -
ds:[bp+2]
2009-11-28 13:22 907mov ax,0 mov ds ... -
程序的起始地址的段地址
2009-11-26 09:38 1325生成EXE之后用Debug加载后,查看寄存器内容如下: ... -
将内存FFFF:0--FFFF:b单元中的数据复制到0:200--0:20b单元中
2009-10-25 21:13 1677该程序的功能: 将内存FFFF:0--FF ... -
标志寄存器
2009-10-25 18:46 999方便记忆 OF 溢出(是/否) ... -
安全的一段内存空间 0:2000~0:02FF
2009-10-25 18:20 949看到120页了 我们要向内存里写东西 ... -
显示红心的汇编代码
2009-10-25 18:05 923assume cs:code code segment ... -
debug时 遇到loop 指令
2009-10-25 17:35 901debug时 遇到loop 指令 用 p指 ... -
Loop的使用
2009-10-23 21:06 1216看到107页了 王爽汇编第五章 Loop的使用 ... -
王爽汇编的第四章的一个小例子--待验证
2009-10-20 21:02 1171第四章的一些总结: 1. DOS系统是单任 ...
相关推荐
本文将基于给定的资料,深入探讨OllyDBG的函数参考功能,以及如何利用这一功能进行有效的逆向分析。 ### 函数参考的重要性 在逆向分析过程中,函数参考功能是极为关键的。它允许用户查看和跟踪特定函数或API调用的...
· OllyDBG 入门系列(三)-函数参考 · OllyDBG 入门系列(四)-内存断点 · OllyDBG 入门系列(五)-消息断点及 RUN 跟踪 · · OllyDBG 入门系列(七)-汇编功能 ========================= · 笑解 ...
· OllyDBG 入门系列(三)-函数参考 · OllyDBG 入门系列(四)-内存断点 · OllyDBG 入门系列(五)-消息断点及 RUN 跟踪 · OllyDBG 入门系列(七)-汇编功能 ·“PE文件格式”1.9版 完整译文 · 可...
第一卷 OllyDBG入门系列第一篇 认识OllyDBG第二篇 字串参考第三篇 函数参考第四篇 内存断点第五篇 消息断点及RUN跟踪第七篇 汇编功能第二卷 OllyDBG技巧系列第一篇 OllyDBG实用技巧六则第二篇 OllyDBG之万能断点篇第...
在学习和使用OllyDbg时,用户可以参考随软件提供的帮助文件,其中包含了理解和使用OllyDbg所必需的信息。如果用户拥有Windows API帮助文件,也可将其与OllyDbg结合使用,以便于快速查找系统函数的帮助信息。 虽然...
### OllyDbg插件开发入门知识点详解 #### 一、OllyDbg插件工作原理及前期准备 **OllyDbg插件工作原理** OllyDbg是一款功能强大的调试器,支持用户态下的软件调试。对于软件逆向工程师来说,OllyDbg提供了丰富的...
在OllyDBG入门教程的第七篇中,它将MyUninstaller 1.34版作为教学案例,讲解如何利用OllyDBG分析和理解软件的内部运作。通过对myuninst.exe进行调试,初学者可以学习到如何跟踪程序流程,识别汇编指令,理解函数调用...
为了深入学习OllyDbg,可以参考提供的资料,如压缩包内的OD1至OD6.mht文件,这些文件可能包含了OllyDbg的教程、实例分析等内容,是提升技能的好帮手。 总结,OllyDbg作为一款强大的逆向工程工具,不仅适合初学者...
两个文件分别是: OllyDB入门教程 第一卷 OllyDBG 入门系列 第二篇 字串参考 crackmes.cjb.net 镜像打包中的 CFF Crackme #3 第三篇 函数参考 crackmes.cjb.net 镜像打包中的一个名称为 CrackHead 的crackme
压缩包中的“OllyDB入门教程.chm”是OllyDBG的基础教程,涵盖了从安装到基本操作的全过程,包括如何启动调试、设置断点、跟踪内存、分析函数调用等。新手可以通过这个教程快速上手。 “Labeler.def”和“Labeler....
- **符号解析**: 能够解析并显示函数名、变量名等符号信息,帮助用户识别代码中的关键部分。 - **内存查看**: 允许用户查看和修改进程的内存内容,这对于分析内存相关的问题非常有用。 - **基本调试功能**: 虽然...
这本书不仅适合初学者入门,也对有一定经验的程序员有很高的参考价值。 汇编语言是一种低级编程语言,它直接对应于机器的指令集,每一个指令都与计算机硬件的特定操作相对应。学习汇编语言可以帮助我们理解计算机的...
参数 寄存器结构体, context_, 参考 可空, 可空,CONTEXT,返回寄存器结构体,方便写补丁函数;这个属于高级功能,看不懂的话就留空吧 .参数 进程信息结构体, PROCESS_INFORMATION, 参考 可空, 可空,PROCESS_INFORMATION,...
这份《Win32_ASM_编程指南》不仅适合初学者入门,也对有经验的开发者提供深入理解和实践的参考。通过深入学习,读者不仅可以掌握Win32环境下的汇编编程技术,还能提升对计算机系统底层运作的理解,从而更好地设计和...