dll注入,多开,多线程(转)

 

//首先创建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.

posted @ 2009-11-07 11:42  装配中的脑袋  阅读(1638)  评论(0编辑  收藏  举报