MessageHook问题,请真正的Hook高手解答 ( 积分: 200 )

  • 主题发起人 主题发起人 newzhang2009
  • 开始时间 开始时间
N

newzhang2009

Unregistered / Unconfirmed
GUEST, unregistred user!
现在正开发一个项目,有一个dll注入其他程序,主程序(exe)如何与dll通信,我考虑用MessageHook,但总也试不成,请高手指导。

**************************************************************
dll程序中:

const
wm_mymessage=wm_user+456;
var
HookHandle:HHook;

//钩子回调函数
function TestHookProc(Code:Integer;WParam:WParam;Msg:LongInt):LRESULT;stdcall;
begin
if Code=HC_ACTION then
begin
if PMsg(Msg)^.message=wm_mymessage then
begin
showmessage('ok');
end;
end;
Result := CallNextHookEx(HookHandle, Code, WParam, Longint(@Msg));
end;//钩子回调函数



procedure EntryPoint(Reason: dword);
begin
HookHandle:=SetWindowsHookEx(WH_CALLWNDPROC,@TestHookProc,0,GetCurrentThreadId);
end;

begin
DLLProc := @EntryPoint;
EntryPoint(DLL_PROCESS_ATTACH);
end;

**************************************************************************

主程序(exe):


const
wm_mymessage=wm_user+456;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure Inject;
var
ProcessHandle: THandle;
Process32: TProcessEntry32;
ProcessSnapshot: THandle;
begin
ProcessSnapshot := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
Process32.dwSize := SizeOf(TProcessEntry32);
Process32First(ProcessSnapshot, Process32);
repeat
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, Process32.th32ProcessID);
if ProcessHandle <> 0 then
begin
if Process32.th32ProcessID=776 then //钩住指定ID的程序,测试用
begin
InjectLibrary(ProcessHandle, ExtractFilePath(ParamStr(0)) + 'hook.dll');
end;
end;
CloseHandle(ProcessHandle);
until not (Process32Next(ProcessSnapshot, Process32));
CloseHandle(ProcessSnapshot);
end;



procedure unInject;
var
ProcessHandle: THandle;
Process32: TProcessEntry32;
ProcessSnapshot: THandle;
begin
ProcessSnapshot := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
Process32.dwSize := SizeOf(TProcessEntry32);
Process32First(ProcessSnapshot, Process32);
repeat
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, Process32.th32ProcessID);
if ProcessHandle <> 0 then
begin
if Process32.th32ProcessID=776 then //钩住指定ID的程序,测试用
begin
SendMessage(ProcessHandle, wm_mymessage, 0, 0);
end;
end;
CloseHandle(ProcessHandle);
until not (Process32Next(ProcessSnapshot, Process32));
CloseHandle(ProcessSnapshot);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
Inject;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
unInject;
end;
 
InjectLibrary 在98里面不支持,是什么函数??
 
主程序(exe)如何与dll通信 为什么不用内存映象文件?
 
既然是Message Hook 又何须 inject?
 
在加载dll时hook了窗体过程(那么uninject里应该向窗体发送消息,ProcessHandle??)....
看到后面InjectLibrary(ProcessHandle, ExtractFilePath(ParamStr(0)) + 'hook.dll')不明白InjectLibrary???

我不是高手!
 
凤冠坡,linuxping:
InjectLibrary是注入其他程序用的函数,将自己的dll文件放在其他进程执行用的。

白河愁:
能否详细说明原因,没明白什么意思
用hookmessage是为了主程序发送一个自定义message,注入的dll线程接收到后,进行卸载操作。
 
to newzhang2009:
能否把你的mad包发给我一份~~
据说,现在的mad包中的madCodeHook不带源码,而是Dll...
邮箱: wpwplplp85@21cn.com
 
也就是,我想要老版本的mad包.....不用DLL的..

多谢~~~
 
找到了,不过是dcu
 
hook message后,线程就会存在于目标进程中,根本无须额外inject
 
白河愁:
能否提供hook message的具体例子,需要自定义message的,多谢。
 
就用 WM_GetMessage和 0, Hinstance
那就注入所有程序了。
 
library RunNewApp;

{ 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
ExceptionLog,
Windows,
SysUtils,
madCodeHook,madRemote;

// ***************************************************************

function IsAllowed(appNameA, cmdLineA: pansichar; appNameW, cmdLineW: PWideChar) : boolean;
// ask the user whether the current process may execute the specified command line
var arrChA : array [0..MAX_PATH] of char;
arrChW : array [0..500] of wideChar;
pc : PAnsiChar;
question : array [0..500] of char;
i1, i2 : integer;
str:string;
PW:PWideChar;
w:WideString;
p:Pointer;
CurDir:string;
temp:string ;
begin
CurDir:=IncludeTrailingBackslash(GetCurrentDir);
if not AmSystemProcess then
begin
if (cmdLineA <> nil) or (appNameA<>nil) then //use Ansi API
begin
if appNameA=nil then //路径在cmdLineA中,用空格分割
begin
temp:=StrPas(cmdLineA);
i1:=Pos(' ',temp);
pc:=PAnsiChar(Copy(temp,1,i1-1));
end else if (appNameA<>nil) and (pos('/',appNameA)<0) then //使用当前驱动器和当前目录
begin
pc:=PAnsiChar(curdir+strpas(appNameA));
end else
pc := appNameA;
end
else // use unicode API
begin
if appNameW= nil then //路径在cmdLineW中,用空格分割
begin
temp:=WideCharLenToString(cmdLineW,lstrlenW(cmdLineW)+1);
i1:=Pos(' ',temp);
pc:=PAnsiChar(Copy(temp,1,i1-1));
end
else if (appNameW<>nil) then
begin
temp:= WideCharLenToString(appNameW,lstrlenW(appNameW)+1);
if (Pos('/',temp)<>-1) then
pc:=PAnsiChar(temp)
else //使用当前驱动器和当前目录
begin
pc:=PAnsiChar(CurDir+temp);
end;
end;
end;

if not SendIpcMessage('CreateProcessIpc',pc,Length(StrPas(pc))+1,@Result,SizeOf(Boolean)) then
Result:=true;
end
else result := true; // let's allow system processes do execute whatever they want


end;

// ***************************************************************

var
CreateProcessANext : function (appName, cmdLine: pchar;
processAttr, threadAttr: PSecurityAttributes;
inheritHandles: bool; creationFlags: dword;
environment: pointer; currentDir: pchar;
const startupInfo: TStartupInfo;
var processInfo: TProcessInformation) : bool; stdcall;
CreateProcessWNext : function (appName, cmdLine: pwidechar;
processAttr, threadAttr: PSecurityAttributes;
inheritHandles: bool; creationFlags: dword;
environment: pointer; currentDir: pwidechar;
const startupInfo: TStartupInfo;
var processInfo: TProcessInformation) : bool; stdcall;
WinExecNext : function (cmdLine: pchar; show: dword) : dword; stdcall;

//***************************************************************


function CreateProcessACallback(appName, cmdLine: pchar;
processAttr, threadAttr: PSecurityAttributes;
inheritHandles: bool; creationFlags: dword;
environment: pointer; currentDir: pchar;
const startupInfo: TStartupInfo;
var processInfo: TProcessInformation) : bool; stdcall;
var
bAllow,ret:Boolean;
str:string;
I:Integer;
begin
if not IsAllowed(appName, cmdLine, nil, nil) {not bAllow} then begin
// the user doesn't like this CreateProcess call, so we block it
result := false;
SetLastError(ERROR_SUCCESS); // 不提示
end else begin
// this CreateProcess call is okay
result := CreateProcessANext(appName, cmdLine, processAttr, threadAttr,
inheritHandles, creationFlags,
environment, currentDir,
startupInfo, processInfo);
// CreateProcess hooks are used very often, so to be sure we renew the hook
RenewHook(@CreateProcessANext);
end;
end;

function CreateProcessWCallback(appName, cmdLine: pwidechar;
processAttr, threadAttr: PSecurityAttributes;
inheritHandles: bool; creationFlags: dword;
environment: pointer; currentDir: pwidechar;
const startupInfo: TStartupInfo;
var processInfo: TProcessInformation) : bool; stdcall;
begin
if not IsAllowed(nil, nil, appName, cmdLine) then begin
result := false;
SetLastError(ERROR_SUCCESS); // 不提示
end else begin
result := CreateProcessWNext(appName, cmdLine, processAttr, threadAttr,
inheritHandles, creationFlags,
environment, currentDir,
startupInfo, processInfo);
RenewHook(@CreateProcessWNext);
end;
end;

function WinExecCallback(cmdLine: pchar; show: dword) : dword; stdcall;
begin
if not IsAllowed(nil, cmdLine, nil, nil) then
result :=ERROR_SUCCESS // ERROR_ACCESS_DENIED // 不提示
else begin
result := WinExecNext(cmdLine, show);
RenewHook(@WinExecNext);
end;
end;



// ***************************************************************

begin
CollectHooks();
HookAPI('kernel32.dll', 'CreateProcessA', @CreateProcessACallback, @CreateProcessANext);
HookAPI('kernel32.dll', 'CreateProcessW', @CreateProcessWCallback, @CreateProcessWNext);
HookAPI('kernel32.dll', 'WinExec', @WinExecCallback, @WinExecNext );
FlushHooks();
end.

//=================================
procedure RunNewQueueCallback(name : pchar;
messageBuf : pointer;
messageLen : dword;
answerBuf : pointer;
answerLen : dword); stdcall;
begin
//add code here
end;

//=================
CreateIpcQueue('CreateProcessIpc',@RunNewQueueCallback);
InjectLibrary((ALL_SESSIONS or SYSTEM_PROCESSES) and (not CURRENT_PROCESS), 'RunNewApp.dll');



//======================================
UninjectLibrary((ALL_SESSIONS or SYSTEM_PROCESSES) and (not CURRENT_PROCESS), 'RunNewApp.dll');
DestroyIpcQueue('CreateProcessIpc');
 
后退
顶部