共享软件要注册,于是很多人动了歪主意,然后美其名日——逆向工程。
用“网络填表终结者(共享软件)”做例子简单介绍一下。
下载了网络填表终结者后用langague.exe侦壳发现加的是aspack壳
用aspcakdie脱壳后,就可以对它进行注册破解了。
要达到免注册的目的可以有很多方式,简单介绍一下。
1、 爆破
先注册一下,
用win32dasm反汇编一下下载的网络填表终结者的主程序FormGhost.exe,找到参考字符串(注册码错误),
向上看代码发现call。。。jne。。。语句
,这是一种经典的垃圾算法,意思就是跟正确注册码对比,如果错误则跳转到错误提示处(jump not equal---jne),只要改成je,即正确才跳转即可。
效果如图
2、 完全破解
这指的是明白了注册机制后得到或者算出注册码,还是这个例子,这下用ollydebug载入那个垃圾软件,在刚才的语句处下中断,然后注册试试
注册机制是在中断处拿出正确码与输入做比较,所以可以在寄存器EAX中和堆栈中看到484c8f9,这是注册码,旁边的222是我输入的,很明显它想让它们对比,看相不相等。
3、 注册补丁
这又有一个问题了,没有这些工具怎么办,一般人谁会准备着这些东西,难道要先下载一通?所以可以做一个补丁然后发布给其他所有人
补丁制作工具很多,现在用codefusion做例子。
Codefusion不但可以制作文件补丁,意思就是通过比较破解前和破解后程序的区别,自动生成补丁。 也可以制作内存补丁,意思就是通过修改程序在运行时的内存指令达到目的。
生成补丁后放到原目录下,首先运行它一次即可注册了。
效果如图
4.高级语言修改内存(我以vc为例)
//cracked by zhuang
#include<windows.h>
/*实际上APIENTRY是个宏,其定义为 #define APIENTRY WINAPI而WINAPI也是个宏,其定义为
#define WINAPI __stdcall 这是个关于调用时压栈顺序的修饰符. (调用约定)*/ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {unsigned int OBJ_ip1=0x004ACAD7;//修改代码的偏移地址
unsigned int OBJ_patch[1]={0x90};//其中的90则是NOP的十六进制,占一个字节 unsigned int OBJ_ip2=0x004ACAD8;//修改代码的偏移地址unsigned int OBJ_ip3=0x004ACAD9;//修改代码的偏移地址
unsigned int OBJ_ip4=0x004ACADA;//修改代码的偏移地址 unsigned int OBJ_ip5=0x004ACADB;//修改代码的偏移地址
unsigned int OBJ_ip6=0x004ACADC;//修改代码的偏移地址
HWND hwndOBJ=FindWindow(NULL,"FormGhost 网络填表终结者 -未注册版");//获得游戏的窗口句柄 DWORD PID; HANDLE hProcess;//HANDLE是操作系统一系列内核对象的句柄。HWND仅是窗口对象的句柄 if (hwndOBJ!=0) { SetForegroundWindow(hwndOBJ);//找到句柄后将游戏设置为当前窗口 GetWindowThreadProcessId(hwndOBJ,&PID);//得到游戏的进程ID hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID);//打开游戏进程 WriteProcessMemory(hProcess,(void *)OBJ_ip1,OBJ_patch,1,0);//写入修改后的代码 WriteProcessMemory(hProcess,(void *)OBJ_ip2,OBJ_patch,1,0);//写入修改后的代码 WriteProcessMemory(hProcess,(void *)OBJ_ip3,OBJ_patch,1,0);//写入修改后的代码 WriteProcessMemory(hProcess,(void *)OBJ_ip4,OBJ_patch,1,0);//写入修改后的代码 WriteProcessMemory(hProcess,(void *)OBJ_ip5,OBJ_patch,1,0);//写入修改后的代码 WriteProcessMemory(hProcess,(void *)OBJ_ip6,OBJ_patch,1,0);//写入修改后的代码 CloseHandle(hwndOBJ); CloseHandle(hProcess); } else MessageBox(NULL,"没有启动吧?","错误!",NULL); return 0;}