程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi用hook實現dll注入詳解

Delphi用hook實現dll注入詳解

編輯:Delphi

需要一個用來注入的dll(inject.dll)及一個調用程序(caller.exe)

流程:

caller.exe
procedure TestHook;
var pwnd,hChild, hwndInject :hwnd;
  msg:tmsg;
begin
  //通過窗口標題用FindWindow找到要注入的程序的主窗口句柄pwnd
  pwnd := findwindow('Progman',nil);
  //用FindwindowEx(hMain,0,nil,nil)找到要處理的子窗口句柄hChild
  hChild := findWindowEx(pwnd,0,nil,nil);
  //用getwindowThreadProcessid(hChild,nil)找到要注入的線程
  dwThreadID := getwindowThreadProcessid(hChild,nil);
  //調用 inject.dll的SetInjectHook方法
  SetInjectHook(dwThreadID);
  //等待消息返回
  getmessage(msg,0,0,0);
  //找到注入的窗口
  hwndInject:= findwindow(nil,'InjectForm');
  //發送控制消息,將目標窗體的句柄作為wparam,控制參數以lparam傳入
  sendMessage( hwndInject, wm_app,hChild,integer(true));
  //關閉注入的窗口
  sendMessage( hwndInject,wm_close,0,0);
  //等待窗口關閉
  sleep(500);
  //檢查是否成功關閉
  assert(not iswindow( hwndInject));
  //去掉掛鉤
  setDipsHook(0);
end; 
//下面說明 Inject.dll的SetInjectHook的具體操作
在全局定義以下變量
var
  g_hhook :Hhook=0;
  g_dwThreadidInject :dword=0;
  g_hInjectfrm:hwnd;
function SetInjectHook(dwThreadid:DWORD):boolean;
begin
 result := false;
 //如果線程標志為0則用於去掉鉤子,否則進行動態庫注入
 if dwThreadid<>0 then
 begin
  assert(g_hhook=0);
  //保存當前線程的ID到 g_dwThreadidInject
  g_dwThreadidInject := getCurrentThreadid;
  //下一個GetMessage的鉤子到目標線程
  //GetMsgProc是在下面定義的一個函數,在第一次調用時將自定義的form在目標線程中創建出來
  //這樣就能通過這個自定義的form對目標線程進行進程內控制了
  g_hhook := setWindowsHookEx(wh_getMessage,GetMsgProc,hInstance,dwThreadid);
  result := g_hhook <> null;
  if result then
   //發一個空的信息以便於立即創建這個自定義form
   result := postThreadMessage(dwThreadid, wm_Null,0,0);
  //等待半秒鐘,以保證調用者可以找到這個剛創建的form
  sleep(500);
 end else
 begin
  assert(g_hhook<>0);
  //去掉鉤子
  result := unHookWindowsHookEx(g_hhook);
  g_Hhook := 0;
 end;
end;
//定義一個全局的是否第一個消息的標志
var
 fFirstTime:boolean = true;
//這個函數用於在收到第一個消息時創建自定義窗體,以便於遠程控制
function GetMsgProc(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT; stdcall;
begin
 //如果是第一次
 if fFirstTime then
 begin
  fFirstTime := false;
  //創建窗體
  InjectFrm := TinjectFrm.create(nil);
  //保存窗體句柄
  g_hInjectfrm := InjectFrm.handle;
 end;
 //調用默認處理,這一句可不能忘記
 result := callNexthookEx(g_hhook,code,wparam,lparam);
end;
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved