首先声明,本方法有一定局限性,可以在不脱壳,反调试的情况下实现修改硬盘序列号,以国外某邮件群发软件为例,破解思路和代码如下:

该软件为asprotect加壳,并在程序中使用asprotect sdk调用壳参数实现注册和功能限制,现已获取某个硬盘指纹的永久注册码,需要破解硬盘物理序号的限制,以便多台电脑使用。

因为该程序带有自校验和并使用加密壳的sdk调用到壳的参数,所以不推荐脱壳和修复(费时),通过内存搜索,获取硬盘指纹的存储地址为00164398,尝试使用keymake制作内存补丁修改该地址,失败,提示不能在调试进程运行该程序,换用ppatcher,结果一样。既然如此,只能自己编程解决这个问题了。以下是跨进程修改内存的代码:
注:因为不能创建调试进程,所以代码使用了比较笨拙的方式实现内存的修改和锁定。

unit Unit2;

interface

uses
  Classes,SysUtils,Windows,Variants,TLHELP32_Hss,unit1;

type
  crack = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;

  public
   procedure docrack;
  end;

implementation

{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure crack.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ crack }
function  FindMission(EXENAME:String):longint;// FProcessesID
var
 Snapshot: TProcessList;
begin
    Snapshot:=TProcessList.Create();
    result:=Snapshot.GetProcessID(EXENAME);
    Snapshot.Free;
end;
function WriteValue(pid:longint;address:string;value:string):Dword;
var
LGet: Dword;
ValueAddress:pointer;
begin
    pid:=OpenProcess(PROCESS_ALL_ACCESS,False,pid);
    ValueAddress:=ptr(strtoint('$'+address));
    WriteProcessMemory(pid,ValueAddress,@value[1],length(value),LGet);
    result:=LGet;
end;
procedure crack.docrack;

var
p:longint;
begin
 while true do
   begin
    p:=FindMission('sendsafe.exe');
    if p>0 then
     begin

 //    WriteValue(p,'12F824','212487602000');//锁定硬盘物理序号
       WriteValue(p,'00164398','5BQ5MgAQGNw=');//锁定指纹
     end;

     end;

end;
procedure crack.Execute;

begin
    docrack
end;

end.


运行需破解程序前创建这个线程对象,就可以不必在调试状态实现对其他程序进程的内存修改和锁定。最后,把这个内存patch程序和原版exe作为资源压缩在另外一个exe,运行则先后释放和执行内存patch程序和原版exe,方便用户使用。(备注:最好在patch中加入检测代码,在不必要的时候停止锁定并退出,以释放系统资源。)

2005/7/24 网网 QQ:108508999