转载自:OllyDbg入门教程

现在进入第三篇,这一篇我们重点讲解怎样使用 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 中存放的是我们输入的注册码经过计算后的值。我们来看一下信息窗口:

ESIE6B5F2F9

EAXFF439EBE

左键选择信息窗口中的 ESIE6B5F2F9,再按右键,在弹出菜单上选“修改寄存器”,我们会看到这样一个窗口:

可能你的显示跟我不一样,因为这个 crackme 中已经说了每个机器的序列号不一样。关掉上面的窗口,再对信息窗口中的 EAXFF439EBE 做同样操作:

上图我们知道了原来前面分析的对我们输入的注册码进行处理后的结果就是把字符格式转为数字格式。我们原来输入的是字串“12345666”,现在转换为了数字 12345666。这下就很清楚了,随便在上面那个修改 ESI 图中显示的有符号或无符号编辑框中复制一个,粘贴到我们调试的程序中的编辑框中试一下:

转载于:https://www.cnblogs.com/shercy/p/6512278.html

CrackMe-CrackHead相关推荐

  1. 某CrackMe算法分析

    平时看了一些CrackMe,算法都比较简单,这次拿到的这个算法自己觉得还是比较有难度,首先自己分析时并没有完全分析出算法的结论,后来参照答案才得到较完整的分析: 1.OD载入,F9运行,输入序列号,点 ...

  2. crackme算法分析---CRC32算法的妙用

    loveasm的crackme算法分析-----CRC32算法的妙用 [作者]:onlyu[FCG][DFCG] [软件介绍]:loveasm[YCG][DFCG]兄弟的crackme,主要锻炼算法分 ...

  3. Crackme006 - 全新160个CrackMe学习系列(图文|视频|注册机源码)

    知乎:逆向驿站 原文链接 CrackMe006 | 难度适中适合练手 |160个CrackMe深度解析(图文+视频+注册机源码) crackme006,依然是delphi的,而且没壳子,条线比较清晰, ...

  4. 逆向工程核心原理学习笔记(十三):分析abex' crackme #1 的延伸:将参数压入栈

    还是上一次的abex' crackme #1,我们用OD附加看一下. 我们发现在调用这个MessageBox函数的时候,用了4个PUSH指令,我们在后面的注释中可以清楚的看到压入参数的内容. 如果我们 ...

  5. IDA Pro逆向实战之Crackme(简单篇)

    IDA Pro逆向实战之Crackme(简单篇) 今天手闲的很,没事就拿出了以前没解决的逆向题来做一下,具体的源程序在附件里,废话少说,直接上菜: 0.   源程序运行效果(输入不对的,直接退出): ...

  6. 记对一个key file crackme的破解

    crackme下载地址: http://kssd.pediy.com/tutorial/exercise/section04/chap6-1-4-03.zip -------------------- ...

  7. nsa构架_我如何使用NSA的Ghidra解决了一个简单的CrackMe挑战

    nsa构架 by Denis Nuțiu 丹尼斯·努尤(Denis Nuțiu) 我如何使用NSA的Ghidra解决了一个简单的CrackMe挑战 (How I solved a simple Cra ...

  8. 逆向破解之160个CrackMe —— 007

    CrackMe -- 007 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...

  9. 170621 逆向-CrackMe之027

    1625-5 王子昂 总结<2017年6月21日> [连续第262天总结] A. CrackMe B. 大概了解了一下ELF文件,Linux平台下的可执行文件,使用终端可以执行 在win平 ...

  10. crackme.chm之Chafe1

    这个程序没有注册或者确定按钮,所以我们只有找到窗口过程才能知道 按下F5便可知道窗口过程的处理流程 LRESULT __stdcall sub_401239(HWND hWnd, UINT Msg, ...

最新文章

  1. python random 随机生成一个数
  2. 基于uFUN开发板的心率计(一)DMA方式获取传感器数据
  3. python脚本编写_【PyQGIS】编写用于处理框架(QGIS3)的Python脚本
  4. 一个“小白”眼中的容器
  5. 【WebRTC---入门篇】(十)NAT
  6. 使用开源的openssl的md5头文件,实现对于文件的md5代码
  7. CV初级研究工程师,苏黎世联邦理工学院招聘
  8. Unity3D调用android方法(非插件方式)
  9. 【OpenCV学习笔记】【函数学习】十八(保存图片)
  10. CSDN博客下载器v2.5(解决严重bug)
  11. hmcl手机版_hmcl启动器手机版软件下载-我的世界hmcl启动器官网版最新下载v3.3.159-飘荡下载...
  12. 格雷码转十进制 c语言,格雷码的转换方法
  13. 怎么更改计算机用户开机密码,如何更改Windows开机密码?修改电脑开机密码教程...
  14. html将四张图片合并,照片拼图在线制作 自带多种照片拼图模板,自由排版将多张照片合成一张...
  15. mysql无法创建partition_mysql的partition分区
  16. Java实现简单日期计算功能
  17. Debian参考手册读书摘要
  18. 如何在windows11系统中打开ie11浏览网页
  19. 2411681-90-6,Thalidomide-O-amido-PEG4-propargyl它结合了基于沙利度胺的cereblon配体和用于PROTAC技术的PEG4连接剂
  20. sendgrid html text,在Node.js中的SendGrid的“发件人”字段中添加名称

热门文章

  1. 给CentOS添加第三方源
  2. 你真的会用Android的Dialog吗?由一个Exception想到的
  3. Linux vsftp服务
  4. 你真的会vue-router吗?
  5. (十)mybatis之配置(mybatis-config.xml)
  6. 从ORA-27300,ORA-27301到ORA-00064
  7. Ios中checkBox
  8. 微软(MICROSOFT)试用版企业软件下载地址
  9. 利用Eventlog Analyzer分析日志
  10. Windows Mobile 7 梦幻之旅系列1之- What’s New?