1、破解序列号

我们打开程序后会提示这个框框

然后打开IDA使用IDA打开我们的程序

Shift+F12打开字符串引用表_,_Ctrl+F搜索我们干菜看到的提示内容

搜索出一个结果我们双击进去,然后双击光标指向的位置。打开数据交叉引用。看到了我们引用的地方。

按F5或Tab打开伪代码分析,发现调用了一个函数。然后判断函数的返回值来确定是否注册成功。双击黄色的地方进入函数分析。

只有在v6返回值为0x2D的是都才会返回0xDB,继续进入到该函数。这个函数可能是注册码的算法,我们不管直接把return的值全部改成0x2D

我们点击return关键字的发现有5个地方return了数据我们把这5个return都改成return 0x2D。在汇编中返回值是存放在我们的eax寄存器中的。我们只要把鼠标点击return的地方再按Tab就能快速定位到对应的汇编代码。使用keypatcher patch指令。改完后按F5重新加载伪代码看看都改完了。

回到刚刚的函数发现有个地方判断了直接返回导致函数没被调用,这时候我们把0x113切换的汇编代码patch 为0xdb即可

2、网络验证破解

上面的改完后基本上是可以使用了,不过有时候使用途中会进行网络验证。所以需要把这个也去除

在字符串引用窗口(前面提到的Shift+F12)搜索Could not contact the webserver. Please check your internet connection.双击进来后,双击黄色的地方找到引用的位置

在这个地方引用了这个字符串,只有当v13小于0的时候会提示。v13就是我们网络验证的函数我们直接把它patch,按tab切换到对应的汇编可以看到jns跳转,jns只有在符号位SF=1的时候才会跳转。可以看到test eax,eax这个指令会修改符号位SF。也就是说只有当eax为正数的时候会跳转,我们直接把call patch成mov eax,0x200即可

破解完成我们需要把它导出exe,Edit->Patch Program->Apply patchs to input file…

这样这个程序就是我们破解后的程序,可以直接打开使用

3、文件补丁

用IDA修改是比较容易的,如果脱离了IDA该如何修改呢?其实在IDA中修改了反汇编的指令以后,对应的在文件的修改的是机器码。只要在文件中能定位到指令对应的机器码的位置,那么直接修改机器码就可以了,只要在文件中找到这个要修改的位置,进行文件读写修改指令即可。如何把内存中的地址定位到文件地址呢?只要把VA转换成FOA就好了。原理就是修改我们文件中代码块中地址对应的指令。我们用IDA打开一个PE程序可以看到我们每个指令所在的虚拟地址。虚拟地址就是我们加载到内存中的地址和我们文件中的地址是不对应的。在内存中的地址就是我们的VA,所以需要把我们的VA转换成FOV我们的文件偏移。

知道什么是VA,RVA,FOA,ImageBase懂得他们互相转换

ImageBase

意思是基址,指的是程序在虚拟空间中被装载的位置。一般为140000000h

VA

Virual Address(VA),意思是虚拟地址。指的是文件被载入虚拟空间后的地址。

RVA

Relatively Virtual Address(RVA)。偏移(又称“相对虚拟地址”)。相对 ImageBase 的偏移。

FOA

File Offset Address(FOA),意思是文件偏移地址。可以理解为文件在磁盘上存放时相对于文件开头的偏移。它的对齐方式一般是以200h为单位在硬盘中对齐的(512对齐),具体对齐需要参照IMAGE_OPTIONAL_HEADER中的FileAlignment成员

PE文件格式的解析,我们只需要一小部分的知识就好了,不过我建议既然玩逆向把PE文件格式解析学好也是很必要的。如果你懂得PE文件格式更好。没了解过这边先建议谷歌学习一下。下面是我谷歌的一张图。这个图作者也是很厉害。

在这个工作中我们只需要了解以下那么几个就行了。

结构体名称

成员

作用

IMAGE_DOS_HEADER

e_lfanew

PE头部的偏移

IMAGE_OPTIONAL_HEADER

BaseOfCode

代码区块RVA

IMAGE_OPTIONAL_HEADER

ImageBase

文件在内存中首选装载的位置

IMAGE_SECTION_HEADER

PointerToRawData

区块在文件中的偏移

VA,RVA,FOA相互转换

只要记住下面两个公式即可实现它们之间的无脑转换

VA = ImageBase + RVA

FOA = 区块文件偏移+ (RVA - 区块RVA) =

我们现在进行实测转换试试,首先用IDA打开我们的程序

可以看到这个指令的VA是0x1401E42BA现在我们需要转换成FOA

用010Editor打开分析可以发现我们的ImageBase为0x140000000,代码区块的RVA是0x1000,代码区块的文件偏移是0x400

通过上面的公式计算得

RVA = VA - ImageBase

FOA = 区块文件偏移+ (RVA - 区块RVA) = 区块文件偏移+ (VA - Image - 区块RVA) = 0x400 + ( 0x1401E42BA - 0x140000000 - 0x1000) = 1E36BA

可以看到对应了我们IDA中的6个字节,这个指令可以通过上图IDA看到是JNZ到一个地址,假设这个是判断是否成功的指令我要要把他nop只需要把这6个字节改成0x90就好了,0x90对应的指令就是NOP。用编程实现我们的修改工作即可

4、内存补丁

内存补丁相对来说比文件补丁简单许多,其原理是使用CreateProcess函数打开目标程序为子程序且暂停,使用WriteProcessMemory函数进行内存的指令写入修改原始指令,再继续运行子程序

但是也有一个问题如何获取程序的VA,因为程序打开后有些基址是不一样的所以我们需要获指令在内存中的VA地址

我们文件补丁讲过

VA = ImageBase + RVA

所以我们只需要获取RVA后+上我们的模块基址就可以得到我们的VA

ImageBase如何获取获取?一开始我想到了TlHelp32库中的CreateToolhelp32Snapshot获取发现返回-1无法获取到,后尝试EnumProcessModules返回299错误码也无法获取到。只能想到这么一个方法但不确保每台电脑加载的地址都是这个地址,如果有知道其他方法的还请告知谢谢。当我们IDA或者Xdbg64附加进程的时候可以看到基址这个就是ImageBase。前提是得确定在哪个模块中的指令

怎么获取RVA?一个一个算吗?其实不用在IDA中有个功能很强大就是Edit->Segments -> ReBase programing…

这个功能是重新设置ImageBase我们只需要把ImageBase设置为0后,复制的地址就是我们的RVA

参考源码