Use a single dll(inject.dll(and a calling program (caller.exe)
Process:
Caller.exe
Procedure TestHook;
Var pwnd, hChild, hwndInject: hwnd;
Msg: tmsg;
Begin
// Use FindWindow in the window title to find the main window handle pwnd of the program to be injected
Pwnd: = findwindow (Progman, nil );
// Use finddomainwex (hMain, 0, nil, nil) to find the subwindow handle to be processed hChild
HChild: = find1_wex (pwnd, 0, nil, nil );
// Use getwindowThreadProcessid (hChild, nil) to find the thread to be injected
DwThreadID: = getwindowThreadProcessid (hChild, nil );
// Call the SetInjectHook method of inject. dll
SetInjectHook (dwThreadID );
// Wait for the message to return
Getmessage (msg, 0, 0 );
// Find the injection window
HwndInject: = findwindow (nil, InjectForm );
// Send a control message. The handle of the target form is used as wparam, and the control parameter is passed in as lparam.
SendMessage (hwndInject, wm_app, hChild, integer (true ));
// Close the injection window
SendMessage (hwndInject, wm_close, 0, 0 );
// Wait for the window to close
Sleep (500 );
// Check whether the service is disabled successfully
Assert (not iswindow (hwndInject ));
// Remove the hook
SetDipsHook (0 );
End;
// The following describes the specific operations of Inject. dll SetInjectHook.
Define the following variables globally
Var
G_hhook: Hhook = 0;
G_dwThreadidInject: dword = 0;
G_hInjectfrm: hwnd;
Function SetInjectHook (dwThreadid: DWORD): boolean;
Begin
Result: = false;
// If the thread flag is 0, the hook is removed; otherwise, dynamic library injection is performed.
If dwThreadid <> 0 then
Begin
Assert (g_hhook = 0 );
// Save the ID of the current thread to g_dwThreadidInject
G_dwThreadidInject: = getCurrentThreadid;
// Hook the next GetMessage to the target thread
// GetMsgProc is a function defined below. During the first call, the custom form is created in the target thread.
// You can use this custom form to control the target thread in the process.
G_hhook: = setWindowsHookEx (wh_getMessage, GetMsgProc, hInstance, dwThreadid );
Result: = g_hhook <> null;
If result then
// Send an empty message to create the custom form immediately
Result: = postThreadMessage (dwThreadid, wm_Null, 0, 0 );
// Wait for half a second to ensure that the caller can find the newly created form
Sleep (500 );
End else
Begin
Assert (g_hhook <> 0 );
// Remove the hook
Result: = unHookWindowsHookEx (g_hhook );
G_Hhook: = 0;
End;
End;
// Define whether a global flag is the first message
Var
FFirstTime: boolean = true;
// This function is used to create a custom form when the first message is received for remote control.
Function GetMsgProc (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT; stdcall;
Begin
// If it is the first time
If fFirstTime then
Begin
FFirstTime: = false;
// Create a form
InjectFrm: = TinjectFrm. create (nil );
// Save the form handle
G_hInjectfrm: = InjectFrm. handle;
End;
// Call the default processing, which cannot be forgotten
Result: = callNexthookEx (g_hhook, code, wparam, lparam );
End;