软件名称:spacecad
整理日期:2003.10.17
最新版本:3.0.1.273
使用平台:Win9x/Me/NT/2000/XP
发布公司:http://www.spacecad.com/
软件简介:火箭造型,弹道计算
加密方式:用户名+注册码
功能限制:试用30天,启动过程中出现注册窗体。
PJ工具:pelord ,win32dasm
PJ日期:2003-10-15
作者申明:只是学习,请不用于商业用途或是将本文方法制作的注册机任意传播,造成后果,本人一概不负。
收获:参考着课本,加上实践,基本对PE文件结构了解,可以增加或修改PE的功能
×××××××××××××××××××××××××××
看雪老大你这下明白我一买到书立刻看到PE结构一章了吧:)
×××××××××××××××××××××××××××
该软件未注册有30天的试用期,在启动过程中,将出现一个大大的对话框,提示用了多少天,输入注册码,网上定购等等,可以不理睬继它继续启动,进入主程序后好像没有什么限制。在启动过程中出现的窗体是调用pxr.dll。经检查程序
没有加密,采用DELPHI编写,本打算调试出注册机,可惜功力不够,一怒之下决定爆破。既然是与时间有关的,那就朝时间函数下手:GetSystemTime,GetLocalTime。爆破的目标就朝向调用时间函数的地方,让他乖乖调用我的时间函数:使得到的当前日期永远不变,你想设定为多少就多少,具体时间还是系统的时间(否则,时间将永远停止^_^)
下面是自己写的GetTime函数,以及反汇编的结果。
void GetTime(LPSYSTEMTIME lpSystemTime)
{
//这里设置的日期只是一个初始值,具体日期要使用后面的程序设定
GetLocalTime(lpSystemTime);
lpSystemTime->wYear=2003;
lpSystemTime->wMonth=10;
lpSystemTime->wDayOfWeek=1;
lpSystemTime->wDay=1;
}
:6E7011F8 55 push ebp
:6E7011F9 89E5 mov ebp, esp
:6E7011FB 83EC08 sub esp, 00000008
:6E7011FE 83EC0C sub esp, 0000000C
:6E701201 FF7508 push [ebp+08]
* Reference To: KERNEL32.GetLocalTime, Ord:0120h
|
:6E701204 E8F7170000 Call GetLocalTime
:6E701209 83C40C add esp, 0000000C
:6E70120C 8B4508 mov eax, dword ptr [ebp+08]
:6E70120F 66C700D407 mov word ptr [eax], 07D3
:6E701214 8B4508 mov eax, dword ptr [ebp+08]
:6E701217 66C740020A00 mov [eax+02], 000A
:6E70121D 8B4508 mov eax, dword ptr [ebp+08]
:6E701220 66C740040100 mov [eax+04], 0001
:6E701226 8B4508 mov eax, dword ptr [ebp+08]
:6E701229 66C740060100 mov [eax+06], 0001
:6E70122F C9 leave
:6E701230 C20400 ret 0004
利用LordPe给两个文件(spacecad.exe,pxr.dll)各增加一个区块,初始令Vsize=1000,Rsize=200
在新增区块开头输入上述指令对应的机器码,将咱的钩子先造出来的说。
注意:
:6E701204 E8F7170000 Call GetLocalTime
这一句的机器码需要手工计算一下,方法是:用GetLocalTime或者GetSystemTime的入口地址减去当前的地址,再减去当
前指令长度5
以我的操作结果为例:
spacecad新增区块中上面指令的VA为6fd00c,检查GetLocalTime的入口为4012ac,那么跳转地址为:4012ac-6fd00c-5=FFD
042CB,则对应的机器码为E8CB42D0FF。至于具体为什么这么排列,那就不用说了吧(-:
到此只是加入了自己的GetTime函数,钩子造好了,还要装上去呢,OK,找需要装的地方:凡是调用GetSystemTime,GetL
ocalTime函数的地方统统装上,检查一下:
spacecad.exe共有四处:402bd6,40b100,40b12c,40b178
pxr.dll共有两处:40939c,4093e8
把他们统统改为 call GetTime,对应的机器码计算方法和上面一样。
运行一下吧,我KAO,嘣嘣地出了两个错误提示框:一个是没有找到30 day key,另一个是什么系统错误,不理他。哈哈,原先那个大大的窗体没了,可惜这两个框比较难看,没办法,水平有限,将就吧。
经过上面的修改后,程序得到的日期永远是2003-10-1,如果我在2004-1-1安装怎么办?下面的程序就起作用了:获得当前的日期,分别补丁到spacecad.exe和pxr.dll。这下子就没问题了,你想什么时间装就随便吧,不过万一出了千万年虫问题怎么办?^_^
#include <iostream>
#include <stdlib.h>
#include <fstream>
using namespace std;
int dat[4]; //存储需要写入到文件的时间数据
int offset[4]={0x1a,0x23,0x2c,0x35}; //需要补丁的地方
int base[2]={0x106a00,0x2d4000};//dll和exe的补丁基址 ,也即所增加的段偏移地址
void patch_file(string filename,int base);//文件打补丁,将安装日期固化到程序
int main(int argc, char *argv[])
{
cout<<"******** attention *********
"<<endl;
cout<<"** 1. copy \"pxr.dll\" to system dir replacing old file
"<<endl;
cout<<"** for win2k ,it's winnt\system\system32
"<<endl;
cout<<"** for win98 ,it's windows\system
"<<endl;
cout<<"** 2. copy \"spacecad.exe\" to program dir replacing old file"<<endl;
cout<<"*****************************
"<<endl<<endl;
LPSYSTEMTIME lpSystemTime=new SYSTEMTIME;
GetLocalTime(lpSystemTime);
//获得当前时间,仅对年月日进行修改,具体时间保留不动
dat[0]=lpSystemTime->wYear;
dat[1]=lpSystemTime->wMonth;
dat[2]=lpSystemTime->wDayOfWeek;
dat[3]=lpSystemTime->wDay;
delete lpSystemTime;
patch_file("pxr.dll",base[0]);
patch_file("spacecad.exe",base[1]);
system("PAUSE");
return 0;
}
void patch_file(string filename,int base)
{
ofstream file(filename.c_str(),std::ios::in | std::ios::out | std::ios::binary);
if(file==NULL)
{
cout<<"error opening "<<filename<<endl;
system("PAUSE");
exit(0);
}
for(int i=0;i<=3;i++)
{
file.seekp(base+offset[i]);//找到需要补丁的位置,写入数据
file.write((char *)&dat[i],2);
}
file.close();
cout<<"succeeding patch "<<filename<<" !"<<endl;
}