windows软件进行反汇编修复流程

本文以Crackme160为例子,示例文件都在该例子中https://gitee.com/cnhellorui/Crackme160

节一:x64dbg逐步调试修复

前言与总结

该节里只需x64dbg即可,windows 7和windows 10,xp都可以。

该节中修复掉那个弹框关键做法:找到关键call,找到关键跳

找到关键call的目的是:确定你所看到的那个弹框或者事件,在反汇编代码的哪个位置发生的,那么你知道那个事件在哪里发生的后,你所想要修复的逻辑就在他的附近。幸运汇编语言按行一条一条执行,找到那个关键call后,那个逻辑一般就在它的关键call的前面几行。

确定逻辑的大概位置后,我们不需要过于了解反汇编中的每个细节,只需要知道关键跳如jmp,je,jne,test,cmp这些的比较指令。因为这些关键跳工作后,会修改ZF这种标志位寄存器。

那么其他的程序会根据这个修改后的ZF标志位寄存器,从而跳转到指定位置。

我们着手去修改这些关键跳后,让它不跳转到那些不想要的弹框和事件后就可以完成反汇编修复了。

示例

首先我们自己打开运行该需要修复的可执行软件(开始就打开只能在修改程序中用,在病毒和未知软件检查的时候不能冒然打开软件)。

打开软件后,我们发现需要killme第一个窗口。
在这里插入图片描述
这时直接将该软件拖入x64dbg中,显示成如下界面。
在这里插入图片描述
首先使用简单粗暴的方式,一步一步调试下去,像调试一个Java业务逻辑代码一样,只是它是汇编而已,直到出现hello you have to kill me那个弹框(是的,反编译修复软件就是这样繁琐,需要有耐心)。

不断的步过(step over)调试,我们发现到如下图的关键call,执行完了这个关键call后出现了hello you have to kill me那个弹框。那么我们需要在这里加一个注释和断点提示自己。
在这里插入图片描述
在关键call也就是0042FD97位置附近没有发现有关键跳(类似je, test, cmp这种比较语句)。那么我再需要进入到这个call的函数里面。再次寻找。
在这里插入图片描述
如上图进入函数后,再次不断的执行到关键call,检查这里的关键call。该关键call附近依然没有关键跳(就是一些标志的生成汇编指令)。再次进入这个关键call的函数里,然后再一步一步的调试下去。

然后再次到达位置0042563D的关键call,我们找一下关键跳,竟然发现就在它的前四行,我们发现到了关键跳je acid burn.425643
在这里插入图片描述
此时从强大的x64dbg上能够看到它的跳转方向,可以到达地址00425643位置。那么为了进一步验证是否可以跳转。我们重新运行调试到这个关键跳位置,尝试修改一下ZF标志位寄存器数据,检测是否是关键跳。
在这里插入图片描述
如上图重新修改了标志位后,是可以不跳转到hello you have to kill me那个弹框。那么我们就验证了该je是我们所想要的关键跳,为了保障这个软件以后也不走这个弹框,我们修改一下汇编代码,让它不用验证ZF标志位寄存器的值,直接跳转到指定位置。

修改方式如下图所示。
在这里插入图片描述
如上图选择位置,鼠标右击对其汇编,je改成jmp。jmp acid burn.425643。那么将修改的文件另存位新的一个可执行文件。

鼠标右键,选择补丁,然后修补文件,填写名称,后缀名改为exe即可。
在这里插入图片描述
我们可以运行一下看看,软件没有hello you have to kill me出现那个弹框了。

节二:IDA Pro协助下快速找到大概的逻辑位置,x64dbg再验证并修复

在上一节中,我们只使用了x64dbg一步一步的跟踪,找到大概的逻辑位置,也就是关键跳和关键call。在本节中,IDA pro的加入帮助我们快速找到关键跳和call的大概位置。

首先打开待修复的软件,还是先运行到我们所期待功能处,并随意填写一些内容。如下图显示,显示Failed失败弹框。现在我们要做的是,让它弹出来一个成功的弹框。
在这里插入图片描述
通过功能分析后,将该软件拖入IDA中,根据弹框中的Failed和Try Again提示的字符串进行搜索,确定该字符串在代码中的位置。如下图显示是IDA显示Strings窗口。
在这里插入图片描述
在Strings窗口中找到了Failed或者Try again字符串后,双击进去;然后可以看到该字符串在汇编中是数据段来表示的。

查看这些数据段被哪些汇编代码所引用的就知道了Failed在汇编代码逻辑的位置了。 ctrl + x 快捷键是查找交叉引用的快捷键。
在这里插入图片描述
双击进去找到了所在汇编逻辑代码的位置。小技巧:space快捷键是显示和关闭下图的结构性的汇编,选择Options -> Disassembly -> line prefixes是显示行号的。
在这里插入图片描述

下面是简要步骤总结

Strings
找到Failed, ctrl + x交叉引用,找到所在代码的位置

关键call函数
CODE:0042F470 _Tserial_button1Click proc near

关键call可以改变标志位寄存器ZF
CODE:0042F4D0 call sub_4039FC

从而影响 关键跳 会跳转到哪里
关键跳
CODE:0042F4D5 jnz short loc_42F4F1

成功
CODE:0042F4D7 push 0 ; uType

失败
CODE:0042F4F1

x64dbg修复

IDA完成了大致逻辑分析后,需要采用x64dbg进行修复与验证。

根据上面的简要步骤里总结的关键call和关键跳,以及成功和失败的地址,在x64dbg中找到对应的位置,然后下断点进行逐一调试(调试方法跟节一中一样,只是加了这些断点后能够直接运行到断点处了)。

根据如下图,我们可以发现到关键call函数是修改ZF标志位寄存器的。在自己的测试中,可以点进去看看里面的逻辑。
在这里插入图片描述
我这里采用的方式不管,关键call函数如何对比,将关键跳给nop掉,直接nop掉,让它持续性的往下走。
在这里插入图片描述
然后再补丁,然后点击修复文件,最后产生新的修复后的可执行文件。

Guess you like

Origin blog.csdn.net/Hello_Ray/article/details/120700148