//首先创建dll~~这个没什么说的~~我也是抄习论坛里某位高手的(不好意思不记得名字了)~
library dllProject1;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StrUtils,
dllUnit1 in 'dllUnit1.pas' {dllfrom1},
threadUnit1 in 'threadUnit1.pas';
var
hhk:HHOOK=0;
homd:pointer;
hthread:thandle;
//--------------------------勾子子程-----------------------------------
function hookpro(ncode:integer;wparam:WPARAM;lparam:LPARAM):LRESULT;stdcall;
label
toexit;
begin
if ncode<0 then goto toexit;
if ncode<>HC_ACTION then goto toexit;
if (LPARAM and $80000000)=0 then goto toexit;
if WPARAM=VK_F12 then
begin
if dllfrom1<>nil then
begin
if dllfrom1.Visible=true then
dllfrom1.hide
else
dllfrom1.Show;
end
else
dllfrom1:=Tdllfrom1.Create(application);
end;
toexit:
result:=CallNexthookex(hhk,ncode,wparam,lparam);
end;
//--------------------------安装勾子-----------------------------------
function hookon(han:hwnd):longint;stdcall;export;
begin
hthread:=getwindowthreadprocessid(han,homd);
if hthread<>0 then hhk:=setwindowshookex(WH_KEYBOARD,@HOOKPRO,hinstance,hthread);
result:=hhk;
end;
//--------------------------关闭勾子-----------------------------------
function hookoff():boolean;stdcall;export;
begin
if hhk<>0 then
begin
unhookwindowshookex(hhk);
hhk:=0;
result:=true;
end
else
result:=false;
end;
{$R *.res}
exports hookon,hookoff;
begin
end.
再下来就是在DLL里创建一个窗口~这个窗口就是我们注入后在游戏中呼出的窗口~游戏的主要功能都在这个窗口中实现;
unit dllUnit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
Tdllfrom1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure hp();
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
dllfrom1: Tdllfrom1;
hhp:boolean=false;
baseaddr:pointer;
const
jz:cardinal=$981b34;
implementation
uses threadunit1;
var
thread1:rw;//声明线程变量~~
{$R *.dfm}
//-----------------------------取人名-------------------------------------------
procedure Tdllfrom1.Button1Click(Sender: TObject);
var
name:string;
name1:dword;
begin
name1:=pdword(jz)^;
name1:=pdword(name1+$1c)^;
name1:=pdword(name1+$24)^;
name1:=pdword(name1+$3d8)^;
name:=pwidechar(name1);
dllfrom1.caption:=name;
end;
//-----------------取人物HP过程-------------------------------------------
procedure Tdllfrom1.hp();
var
rw_hp:cardinal;
begin
while hhp do
begin
rw_hp:=pdword(pdword(pdword(pdword($981b34)^+$1c)^+$24)^+$260)^;
label2.caption:=inttostr(rw_hp);
sleep(1000);
end;
end;
//----------------------汇篇取人物血-------------------------------------------
//--------------------------------加载人物线程显血-----------------------------
procedure Tdllfrom1.Button2Click(Sender: TObject);
begin
if hhp=false then
begin
hhp:=true;
thread1:=rw.create;//创建线程~~
end else
hhp:=false;
end;
{procedure Tdllfrom1.Button3Click(Sender: TObject);//这个不用看~想实现HOOK人物HP~但没成功(这个太难了~看得)~在论坛上听兔哥说在这篇文章里看~~http://www.ghoffice.com/bbs/read-htm-tid-63001-keyword-%D2%D1%B7%E8%BF%F1.html
var
dllmodule:Hmodule;
begin
//dllmodule:=GetModuleHandle(Pchar('dllProject1.dll'));
//BaseAddr:=Pointer(GetProcAddress(DllModule,PChar('jx1')));
pbyte($00456088)^:=$e8;
//pdword($00456089)^:=baseaddr;
pbyte($0045608e)^:=$90;
end;}
end.
接下来再创建一个工程~~窗体上有一个列表框各两个按钮~程序一启动就自动读取游戏人名显示在列表框中,选中后点'开始游戏'按钮注入~~在游戏中按F12呼出开始在dll中创建的窗体;
unit Unit1
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
function hookon(hwn:hwnd):longint;stdcall;external 'dllproject1.dll';
function hookoff():boolean;stdcall;external 'dllproject1.dll';
function GetTitle(hhwnd:thandle;param:pointer):boolean;stdcall;
var
id:array[0..10]of hwnd;
x:cardinal=0;
hhk:longint;
const
jz:dword=$00981b34;
implementation
{$R *.dfm}
//enumwindows函数的参数~用来读出所有武林窗体的句柄~并显示游戏人名;
function GetTitle(hhwnd:thandle;param:pointer):boolean;stdcall;
var
text:string;
dd:cardinal;
hid:thandle;
name:cardinal;
nname:array[0..15]of widechar;
begin
setlength(text,100);
getwindowtext(hhwnd,pchar(text),100);
if pchar(text)='Element Client' then//找到是武林窗体的就写入列表框
begin
id[x]:=hhwnd;//把窗口句柄保存在数组ID中
x:=x+1;
getwindowthreadprocessid(hhwnd,@dd);
hid:=openprocess(PROCESS_ALL_ACCESS,false,dd);
readprocessmemory(hid,pointer(jz),@name,4,dd);
readprocessmemory(hid,pointer(name+$1c),@name,4,dd);//取人名
readprocessmemory(hid,pointer(name+$24),@name,4,dd);
readprocessmemory(hid,pointer(name+$3d8),@name,4,dd);
readprocessmemory(hid,pointer(name+0),@nname,16,dd);
form1.listbox1.items.Add(nname);
closehandle(hid);//关闭打开的进程;
end;
end;
//------------------窗口载入----------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
listbox1.Items.Clear;
enumwindows(@gettitle,0);
end;
//-------------------刷新列表框-------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
listbox1.Items.Clear;
enumwindows(@gettitle,0);
end;
//------------------------程序退出---------------------------------------------
procedure TForm1.FormDestroy(Sender: TObject);
begin
if hhk<>0 then hookoff();
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if hhk<>0 then hookoff();
end;
//-----------------------注入--------------------------------------------------
procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
begin
if listbox1.Items.Count>0 then//列表框总数大于0~也就是要打开游戏~
begin
if listbox1.itemindex<>-1 then//已经选择了要注入的游戏~
begin
i:=listbox1.ItemIndex;
hhk:=hookon(id[i]);//提取数组中的句柄~注入游戏~
showmessage('已注入,请在游戏内按下F12');
end
else
showmessage('请选择要注入的游戏');
end
else
showmessage('请打开游戏');
end;
end.
OK了~~下面是在DLL窗体中创建的一个线程~用来显示人物HP~这个没什么说的~.
unit threadUnit1;
interface
uses
Classes;
type
rw = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
constructor create;
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 rw.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }
{ rw }
uses dllunit1;
constructor rw.create;
begin
inherited create(false);
end;
procedure rw.Execute;
begin
{ Place thread code here }
dllfrom1.hp;//线程创建调用HP函数显血`~
end;
end.