还是毛主席说得对,自力更生,丰衣足食啊!!!多谢各位大富翁的热心帮助!! (100分)

W

wlmmlw

Unregistered / Unconfirmed
GUEST, unregistred user!
function DoEmbedDll: DWORD; stdcall;
var
lpProcAddr: Pointer;
begin
Result := 0;
if EmbedDll = nil then exit;

if (EmbedDll.FHaveHook <> 0) then exit; //已经设置了钩子
EmbedDll.FMyThreadId := GetCurrentThreadId(); //取得运行线程

//获得本模块所在运行的线程号
lpProcAddr := @DoEmbedDll;
EmbedDll.FDllHinst := Cardinal(ModuleFromAddress(lpProcAddr));
//将钩子安装到指定的线程里
//EmbedDll.FThreadId := 0;
EmbedDll.FHaveHook := SetWindowsHookEx(WH_GETMESSAGE,//WH_CALLWNDPROC,
GetMsgProc,
EmbedDll.FDllHinst,
EmbedDll.FThreadId);
if (EmbedDll.FHaveHook <> 0) then begin //如果挂接成功
//激活被挂接的线程
if (PostThreadMessage(EmbedDll.FThreadId, WM_NULL, 0, 0)
= LongBool(0) ) then begin
ShowMessage(format('PostThreadMessageError: %d',[GetLastError]));
end;
//PostMessage(HWND_BROADCAST, WM_HookFinished, 0, 0);
ShowMessage(format('finish hook thread: %d', [EmbedDll.FThreadId]));
Result := 1;
end;
end;
 
那你继续失望吧
 
怎么这么狠心?????????
 
呵...
你又不说你的程序哪里有问题
 
我看不懂她,嘿嘿……
 
可能是安装一个消息钩子后
马上让那个线程加载你的dll吧?
 
照程序的运行,则应该在
//激活被挂接的线程
if (PostThreadMessage(EmbedDll.FThreadId, WM_NULL, 0, 0)
= LongBool(0) ) then begin
ShowMessage(format('PostThreadMessageError: %d',[GetLastError]));
end;
后,被挂接的线程就应该调用我的GetMsgProc,但事实上并没有,就是没有钩到。
请各位高手把把脉。谢谢
 
能钩到本进程的,当不能钩到其它进程里的。
为什么?
我已经失望了很久了,别再让我失望了。
 
小马,我也要去钓鱼台,呵呵!
 
请把相关代码全部贴出来才好诊治!
 
好吧!!!!
unit AddDLL;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ImageHlp, WinNT, TlHelp32;

const
//设置完钩子,通知控制程序
WM_HOOKFINISHED = WM_USER + 9001;

C_PUSHOPCODE = $68;

type
PROC = Pointer;
PPROC = ^PROC;
{------------------------------------------------------------------------------
定义记录_APIHOOK32_ENTRY方便我们引入参数和管理所挂接的钩子
------------------------------------------------------------------------------}
_APIHOOK32_ENTRY = record
APIName: AnsiString; //需要挂接的API名称
CalleeModuleName: AnsiString; //函数所在模块名称
OriginApiAddress: PROC; //还有函数地址
DummyFuncAddress: PROC; //挂接后函数地址
ModCallerModule: HMODULE; //挂接函数所在模块as LongWord
end;
APIHOOK32_ENTRY = _APIHOOK32_ENTRY;
PAPIHOOK32_ENTRY = ^_APIHOOK32_ENTRY;

{------------------------------------------------------------------------------
定义设置钩子的对象,使用WH_GETMESSAGE 类型钩子
------------------------------------------------------------------------------}

TEmbedDll = class //使用WH_GETMESSAGE 钩子进行挂接
private
FDllHinst: HINST; //用于挂接动态库
FThreadId: DWORD; //要挂接的线程
FHaveHook: HHOOK; //是否已经设置了钩子 as LongWord
//如果设置了钩子,则保存着钩子号
FMyThreadId: DWORD; //所在运行线程
FFirstTime: Boolean; //第一次运行钩子

FCallBackThreadId: DWORD; //控制程序所在的线程号
public
function UnEmbed: DWORD; //取消挂接
constructor Create(DllHinst: HINST; ThreadId: DWORD;
CallBackThreadId: DWORD);
destructor Destroy; override;

property DllHinst: HINST read FDllHinst write FDllHinst;
property ThreadId: DWORD read FThreadId write FThreadId;
property MyThreadId: DWORD read FMyThreadId;
property CallBckThreadId: DWORD read FCallBackThreadId
write FCallBackThreadId;
end;

{------------------------------------------------------------------------------
修改输入节来挂接API
------------------------------------------------------------------------------}
PAPIHook = ^TAPIHook;
TAPIHook = class
private
FPHK: PAPIHOOK32_ENTRY;
FAPIHookNext: PAPIHook;
class procedure FixupNewlyLoadeModule(hmod: HMODULE; dwFlags: DWORD);
class function _SetApiHookUp(phk: PAPIHOOK32_ENTRY): DWORD;
class function SetWindowsAPIHook(phk: PAPIHOOK32_ENTRY): Boolean;
class function LoadLibraryA(lpLibFileName: PAnsiChar): HMODULE;
class function LoadLibraryW(lpLibFileName: PWideChar): HMODULE;
class function LoadLibraryExA(lpLibFileName: PAnsiChar; hFile: THandle;
dwFlags: DWORD): HMODULE;
class function LoadLibraryExW(lpLibFileName: PWideChar; hFile: THandle;
dwFlags: DWORD): HMODULE;

class function GetProcAddress(hmod: HMODULE; ProcName: PChar): PROC;
public
constructor Create(CalleeModuleName: AnsiString; APIName: AnsiString;
DummyFuncAddress: PROC);
constructor CreateAPIHook(phk: PAPIHOOK32_ENTRY);
destructor Destroy; override;
end;

function CreateEmbedDll(DllHinst: HINST; ThreadId: DWORD;
CallBackTheadId: DWORD): TEmbedDll; stdcall;
function DoEmbedDll: DWORD; stdcall;
procedure FreeEmbedDll; stdcall;

function _SetApiHookUp(phk: PAPIHOOK32_ENTRY): DWORD; stdcall;
function SetWindowsAPIHook(phk: PAPIHOOK32_ENTRY): Boolean; stdcall;
function GetProcAddressRaw(hmod: HMODULE; ProcName: PChar): PROC;
function _SetWindowLong(hWnd: HWND; nIndex: Integer;
dwNewLong: Longint): Longint; stdcall;
function ModuleFromAddress(lpAddress: Pointer): Pointer;

function GetMsgProc(Code: Integer; wPrm: WParam;
lPrm: LParam): LongInt; stdcall;
function HookDefaultAPI: LongInt; stdcall;

exports
_SetApiHookUp,
SetWindowsAPIHook,
CreateEmbedDll,
FreeEmbedDll,
DoEmbedDll,
GetMsgProc;

var
EmbedDll: TEmbedDll; //全局对象
APIHookHead: PAPIHook; //所有TAPIHook对象的头指针
APIHookMaxAppAddr: Pointer;

APIHook_LoadLibraryA: TAPIHook;
APIHook_LoadLibraryW: TAPIHook;
APIHook_LoadLibraryExA: TAPIHook;
APIHook_LoadLibraryExW: TAPIHook;
APIHook_GetProcAddress: TAPIHook;

implementation

{------------------------------------------------------------------------------
使用WH_GetMessage 类型设置钩子
------------------------------------------------------------------------------}
function DoEmbedDll: DWORD; stdcall;
var
lpProcAddr: Pointer;
begin
Result := 0;
if EmbedDll = nil then exit;

if (EmbedDll.FHaveHook <> 0) then exit; //已经设置了钩子
EmbedDll.FMyThreadId := GetCurrentThreadId(); //取得运行线程

//获得本模块所在运行的线程号
lpProcAddr := @DoEmbedDll;
EmbedDll.FDllHinst := Cardinal(ModuleFromAddress(lpProcAddr));
//将钩子安装到指定的线程里
//EmbedDll.FThreadId := 0;
EmbedDll.FHaveHook := SetWindowsHookEx(WH_GETMESSAGE,//WH_CALLWNDPROC,
GetMsgProc,
EmbedDll.FDllHinst,//hInstance ,
EmbedDll.FThreadId);
if (EmbedDll.FHaveHook <> 0) then begin //如果挂接成功
//激活被挂接的线程
if (PostThreadMessage(EmbedDll.FThreadId, WM_NULL, 0, 0)
= LongBool(0) ) then begin
ShowMessage(format('PostThreadMessageError: %d',[GetLastError]));
end;
//PostMessage(HWND_BROADCAST, WM_HookFinished, 0, 0);
ShowMessage(format('finish hook thread: %d', [EmbedDll.FThreadId]));
Result := 1;
end;
end;
{------------------------------------------------------------------------------
挂接几个主要的API,这样才可以全面正确的挂接想到挂接的API
------------------------------------------------------------------------------}
function HookDefaultAPI: LongInt; stdcall;
begin
Result := 1;
if (APIHook_LoadLibraryA = nil) then begin
APIHook_LoadLibraryA := TAPIHook.Create('Kernel32.dll', 'LoadLibraryA',
@TAPIHook.LoadLibraryA);
end;
if (APIHook_LoadLibraryW = nil) then begin
APIHook_LoadLibraryW := TAPIHook.Create('Kernel32.dll', 'LoadLibraryW',
@TAPIHook.LoadLibraryW);
end;
if (APIHook_LoadLibraryExA = nil) then begin
APIHook_LoadLibraryExA := TAPIHook.Create('Kernel32.dll', 'LoadLibraryExA',
@TAPIHook.LoadLibraryExA);
end;
if (APIHook_LoadLibraryExW = nil) then begin
APIHook_LoadLibraryExW := TAPIHook.Create('Kernel32.dll', 'LoadLibraryExW',
@TAPIHook.LoadLibraryExW);
end;
if (APIHook_GetProcAddress = nil) then begin
APIHook_GetProcAddress := TAPIHook.Create('Kernel32.dll', 'GetProcAddress',
@TAPIHook.GetProcAddress);
end;

end;

{------------------------------------------------------------------------------
返回指定模块中指定函数的地址(真正的地址)
在TAPIHook中将挂接GetProcAddress,其中会用到此函数
------------------------------------------------------------------------------}
function GetProcAddressRaw(hmod: HMODULE; ProcName: PChar): PROC;
begin
Result := Windows.GetProcAddress(hmod, ProcName);
end;

{------------------------------------------------------------------------------
返回包含指定的内存地址lpAddress 的模块在WinNT.pas 和Windows.pas 中都是声明
TMemoryBasicInformation,但两者不同,使用Windows.pas 中的,不然编译会出错
------------------------------------------------------------------------------}
function ModuleFromAddress(lpAddress: Pointer): Pointer;
var
lpBuffer: Windows.TMemoryBasicInformation;
iSize: LongWord;
begin
iSize := Sizeof(lpBuffer);
if (Windows.VirtualQuery(lpAddress, lpBuffer, iSize) <> 0) then begin
Result := Pointer(lpBuffer.AllocationBase);
end else begin
Result := nil;
end;
end;

{------------------------------------------------------------------------------
使用WH_GETMESSAGE 钩子的函数
------------------------------------------------------------------------------}
function GetMsgProc(Code: Integer; wPrm: WParam;
lPrm: LParam): LongInt; stdcall;
begin
Result := 0;
if (EmbedDll = nil) then exit; //嵌入对象还未被创建
if (EmbedDll.FFirstTime) then begin //如果是第一次运行钩子
EmbedDll.FFirstTime := false;

ShowMessage('now Embed the dll ');
//通知控制程序钩子已设置完毕
PostThreadMessage(EmbedDll.FCallBackThreadId, WM_HookFinished, 0, 0);
end;

//调用下一个钩子
Result := CallNextHookEx(EmbedDll.FHaveHook, Code, wPrm, lPrm);
end;

{------------------------------------------------------------------------------
创建嵌入DLL 类型全局对象
------------------------------------------------------------------------------}
function CreateEmbedDll(DllHinst: HINST; ThreadId: DWORD;
CallBackTheadId: DWORD): TEmbedDll;
begin
Result := nil;
if EmbedDll <> nil then exit;
EmbedDll := TEmbedDll.Create(DllHinst, ThreadId, CallBackTheadId);
Result := EmbedDll;
end;

{------------------------------------------------------------------------------
释放嵌入DLL 类型全局对象
------------------------------------------------------------------------------}
procedure FreeEmbedDll;
begin
if EmbedDll = nil then exit;
FreeAndNil(EmbedDll);
end;

{------------------------------------------------------------------------------
程序调用API函数,是通过调用某处所储存的调用函数的地址来 实现间接调用,该处被
命名为import address table 简称IAT, 在PE文件结构中有一个.idata段,记录执行程
序调用的各种函数住处。它是由一个IMAGE_IMPORT_DESCRIPTOR结构的数组开始, 其中,
结构中的Name属性是一个偏移量,加上基址,就能得到所指向的DLL的名字,而
FirstThunk经过同样处理后则得到IAT 的地址,IAT实际上是一个同IMAGE_THUNK_DATA组
成的数组,每一个IMAGE_THUNK_DATA对应一个供调用Windows API函数模块的输入节包含
一组该模块运行时需要的DLL, 另外,它还包含该模块从每个DLL输入的符号的列表当该
调用一个输入函数时,线程实际上要从模块的输入节中捕获需要的输入函数的地址,然
后转移该地址。
------------------------------------------------------------------------------}
function _SetApiHookUp(phk: PAPIHOOK32_ENTRY): DWORD;
var
pImportDesc: PIMAGE_IMPORT_DESCRIPTOR;
pszModName: AnsiString;
iSize, iWrite: ULong;
pThunk: PIMAGE_THUNK_DATA;
ppfn: PPROC;
bFound: Boolean;
begin
Result := 0;
pImportDesc := PIMAGE_IMPORT_DESCRIPTOR(
ImageDirectoryEntryToData(Pointer(phk.ModCallerModule), TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT, iSize)
);
if (pImportDesc = nil) then begin
exit; //这个模块并没有输入节.
end;

//找出指定的需要挂接的模块
while pImportDesc.Name <> 0 do begin
pszModName := String(PChar(Cardinal(phk.ModCallerModule)
+ pImportDesc.Name));
if (StrComp(PChar(pszModName), PChar(phk.CalleeModuleName)) = 0) then
break; //如果找到了则退出
Inc(pImportDesc);
end;
if (pImportDesc.Name = 0) then begin
//这个模块并没有输入指定的模块.
exit;
end;

//找到被挂接模块的函数表
pThunk := PIMAGE_THUNK_DATA(
Cardinal(phk.ModCallerModule) + pImportDesc.FirstThunk);

//用新的地址值代替被挂接函数地址.
while pThunk.Function_ <> 0 do begin
//找出被挂接函数地址.
ppfn := PPROC(pThunk.Function_);
//该函数是否为被指定的挂接函数
bFound := PROC(ppfn) = phk.OriginApiAddress;

//判断是否已经找到了指定的函数
if (bFound) then begin
//如果地址匹配,则修改输入节被挂接模块被挂接函数的地址
WriteProcessMemory(GetCurrentProcess(),
phk.OriginApiAddress,
phk.DummyFuncAddress,
sizeof(phk.DummyFuncAddress),
iWrite);
Result := 1;
exit; //已经完成,可以退出.
end;
Inc(pThunk.Function_);
end;
//如果程序运行到这样,则函数不在输入节中

end;

{------------------------------------------------------------------------------
挂接据模块中指定的函数, 一般情况下并不挂接自身中的函数。
为了达到象全局钩子那样的效果,我们遍历进程中运行的模块,并且为每个模块挂接API
钩子。同时,为了防止进程在运行中动态加载别的模块,我们还必须临视LoadLibrary和
LoadLibraryEx两个API函数,由于Unicode的总是,我们实际上要分别监视这两个函数的
Unicode版本和ASCII版本。通过调用ToolHelpFunction(TlHelp32.pas)中的函数来实现。
真正实现全监视还必须挂接GetProcAddress API,这样是防止程序是直接取得地址来调用
API的。
------------------------------------------------------------------------------}
function SetWindowsAPIHook(phk: PAPIHOOK32_ENTRY): Boolean;
var
mInfo: Windows.MEMORY_BASIC_INFORMATION;
me: MODULEENTRY32;
hModHookDLL: HMODULE;
hSnapshot: Cardinal;
bOK: Boolean;
begin
Result := false;
if (phk.APIName = '') then exit;
if (phk.CalleeModuleName = '') then exit;
if (phk.OriginApiAddress = nil) then exit;
if (phk.ModCallerModule = 0) then begin
//me := sizeof(MODULEENTRY32);
VirtualQuery(@_SetApiHookUp, mInfo, sizeof(mInfo));
hModHookDLL := HMODULE(mInfo.AllocationBase);
hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);

bOK := Module32First(hSnapshot, me);
while (bOK) do begin
if (me.hModule <> hModHookDLL) then begin
phk.ModCallerModule := me.hModule;
_SetApiHookUp(phk);
end;
bOK := Module32Next(hSnapshot, me);
end;
Result := True;
exit;
end else begin
_SetApiHookUp(phk);
Result := True;
exit;
end;
Result := False;
end;

{------------------------------------------------------------------------------
调用这个就没有跨进程的限制了,可以在指定的线程里挂上一个WinProc
------------------------------------------------------------------------------}
function _SetWindowLong(hWnd: HWND; nIndex: Integer;
dwNewLong: Longint): Longint; stdcall;
begin
Result := Windows.SetWindowLong(Hwnd, nIndex, dwNewLong);

end;

{ TEmbedDll }

constructor TEmbedDll.Create(DllHinst: HINST; ThreadId: DWORD;
CallBackThreadId: DWORD);
begin
inherited Create;
FDllHinst := DllHinst;
FThreadId := ThreadId;

FHaveHook := 0; //未设置钩子
FMyThreadId := 0;
FFirstTime := True; //还未运行钩子

FCallBackThreadId := CallBackThreadId; //控制程序所在的线程
end;

destructor TEmbedDll.Destroy;
begin
if (FHaveHook <> 0) then UnEmbed; //取消钩子
inherited;
end;

function TEmbedDll.UnEmbed: DWORD;
begin
Result := 0;
if (FHaveHook = 0) then exit;
UnHookWindowsHookEx(FHaveHook); //释放钩子
FHaveHook := 0; //不存在钩子
Result := 1;
end;

{ TAPIHook }

constructor TAPIHook.CreateAPIHook(phk: PAPIHOOK32_ENTRY);
var
si: SYSTEM_INFO;
pa: array of Byte;
pb: PBYTE;
begin
if (APIHookMaxAppAddr = nil) then begin
//Functions with addres above lpMaximumApplicationAddres require
//special processing (Windows 98 only)
GetSystemInfo(si);
APIHookMaxAppAddr := si.lpMaximumApplicationAddress;
end;

FAPIHookNext := APIHookHead;
APIHookHead := PAPIHook(self); //在表头插入

FPHK := phk;
FPHK.OriginApiAddress := GetProcAddressRaw(
GetMOduleHandleA(PChar(FPHK.CalleeModuleName)),
PChar(FPHK.APIName));
if (FPHK = nil) then begin
raise Exception.Create(format('can''t find the function ''%s'' in ''%s''',
[FPHK.APIName, FPHK.CalleeModuleName]));
end;
if (LongWord(FPHK.OriginApiAddress) > LongWord(APIHookMaxAppAddr)) then begin
pb := PBYTE(FPHK.OriginApiAddress);
pa := @pb;
if (pa[0] = C_PUSHOPCODE) then begin
FPHK.OriginApiAddress := PROC(pa[1]);
end;
end;

//在已加载的所有模块中挂接指定的函数
SetWindowsAPIHook(FPHK);
end;

destructor TAPIHook.Destroy;
var
mid: PROC;
p: PAPIHook;
begin
//把修改过的地址改回来
mid := FPHK.OriginApiAddress;
FPHK.OriginApiAddress := FPHK.DummyFuncAddress;
FPHK.DummyFuncAddress := mid;

//取消挂接
SetWindowsAPIHook(FPHK);
p := APIHookHead;
if (p = PAPIHook(self)) then begin
APIHookHead := p.FAPIHookNext;
end else begin
//从链中删除自己
while (p.FAPIHookNext <> nil) do begin
if (p.FAPIHookNext = PAPIHook(self)) then begin
p.FAPIHookNext := p.FAPIHookNext.FAPIHookNext;
break;
end;
p := p.FAPIHookNext;
end;
end;
inherited;
end;

{------------------------------------------------------------------------------
挂接重新更正:当有新模块被载入时,挂接所指定的函数
------------------------------------------------------------------------------}
class procedure TAPIHook.FixupNewlyLoadeModule(hmod: HMODULE; dwFlags: DWORD);
var
p: PAPIHook;
begin
if ((hmod <> 0) and ((dwFlags and LOAD_LIBRARY_AS_DATAFILE) = 0)) then begin
p := APIHookHead;
while (p <> nil) do begin
_SetApiHookUp(p.FPHK);
p := p.FAPIHookNext;
end;
end;
end;

{------------------------------------------------------------------------------
挂接指定模块中的指定函数
------------------------------------------------------------------------------}
class function TAPIHook._SetApiHookUp(phk: PAPIHOOK32_ENTRY): DWORD;
begin
Result := AddDll._SetApiHookUp(phk);
end;

{------------------------------------------------------------------------------
挂接所有模块中指定的函数
------------------------------------------------------------------------------}
class function TAPIHook.SetWindowsAPIHook(phk: PAPIHOOK32_ENTRY): Boolean;
begin
Result := AddDll.SetWindowsAPIHook(phk);
end;

{------------------------------------------------------------------------------
挂接GetProcAddress防止程序是通过调用GetProcAddress直接调用模块中的地址来调用
API的,例如:
HMODULE hmod = GetModuleHandle("user32.dll")
PROC pAPIFunc = GetProcAddress(hMod, "MessageBoxEx");
------------------------------------------------------------------------------}
class function TAPIHook.GetProcAddress(hmod: HMODULE;
ProcName: PChar): PROC;
var
pfn: PROC;
p: PAPIHook;
begin
//取得真正的地址
pfn := GetProcAddressRaw(hmod, ProcName);
//如果它是一个我们所要挂接的函数
p := APIHookHead;
while (pfn <> nil) and (p <> nil) do begin
//如果所返回的地址和我们所要挂接的地址相符
//则用挂接地址代替之
if (pfn = p.FPHK.OriginApiAddress) then begin
pfn := p.FPHK.DummyFuncAddress;
break;
end;
//查看下一个
p := p.FAPIHookNext;
end;
Result := pfn;
end;

{------------------------------------------------------------------------------
挂接LoadLibrary,这样当程序每当加载一个新模块新,控制程序都能及时挂接上模块中
的指定函数,使得控制程序能全面的监视被挂接程序的运行
------------------------------------------------------------------------------}
class function TAPIHook.LoadLibraryA(lpLibFileName: PAnsiChar): HMODULE;
var
hmod: HMODULE;
begin
hmod := Windows.LoadLibraryA(lpLibFileName);
FixupNewlyLoadeModule(hmod, 0);
Result := hmod;
end;

class function TAPIHook.LoadLibraryExA(lpLibFileName: PAnsiChar;
hFile: THandle; dwFlags: DWORD): HMODULE;
var
hmod: HMODULE;
begin
hmod := Windows.LoadLibraryExA(lpLibFileName, hFile, dwFlags);
FixupNewlyLoadeModule(hmod, dwFlags);
Result := hmod;
end;

class function TAPIHook.LoadLibraryExW(lpLibFileName: PWideChar;
hFile: THandle; dwFlags: DWORD): HMODULE;
var
hmod: HMODULE;
begin
hmod := Windows.LoadLibraryExW(lpLibFileName, hFile, dwFlags);
FixupNewlyLoadeModule(hmod, dwFlags);
Result := hmod;
end;

class function TAPIHook.LoadLibraryW(lpLibFileName: PWideChar): HMODULE;
var
hmod: HMODULE;
begin
hmod := Windows.LoadLibraryW(lpLibFileName);
FixupNewlyLoadeModule(hmod, 0);
Result := hmod;
end;

constructor TAPIHook.Create(CalleeModuleName, APIName: AnsiString;
DummyFuncAddress: PROC);
begin
FPHK.APIName := APIName;
FPHK.CalleeModuleName := CalleeModuleName;
FPHK.DummyFuncAddress := DummyFuncAddress;
CreateAPIHook(FPHK);
end;

initialization
APIHookHead := nil;
APIHookMaxAppAddr := nil;

APIHook_LoadLibraryA := nil;
APIHook_LoadLibraryW := nil;
APIHook_LoadLibraryExA := nil;
APIHook_LoadLibraryExW := nil;
APIHook_GetProcAddress := nil;

finalization
FreeAndNil(APIHook_LoadLibraryA);
FreeAndNil(APIHook_LoadLibraryW);
FreeAndNil(APIHook_LoadLibraryExA);
FreeAndNil(APIHook_LoadLibraryExW);
FreeAndNil(APIHook_GetProcAddress);
end.
 
FThreadId这个值哪里来的?
EmbedDll.FDllHinst := Cardinal(ModuleFromAddress(lpProcAddr));//??? 你的这个调用成功了?直接用GetModuleHandle试试
 
FThreadId := GetThreadProcessId(WindowsFromPoint(pt));

EmbedDll.FDllHinst := Cardinal(ModuleFromAddress(lpProcAddr));
成功调用。

 
//以下是调试代码

unit Unitdll;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AddDll, StdCtrls, ExtCtrls;

const
C_EmbedDll = 'ProDll.dll';
type
TForm1 = class(TForm)
btnCreate: TButton;
btnGetWindow: TButton;
btnHook: TButton;
TimerGetMsg: TTimer;
procedure btnCreateClick(Sender: TObject);
procedure btnGetWindowMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormDestroy(Sender: TObject);
procedure btnHookClick(Sender: TObject);
procedure TimerGetMsgTimer(Sender: TObject);
private
procedure WM_HOOKFINISHED(var Message: TMessage); message WM_HOOKFINISHED;
{ Private declarations }
public
{ Public declarations }
procedure GetThreadId;
end;

var
Form1: TForm1;
Embed: TEmbedDll;
ThreadId: DWORD;
aPoint: TPoint;

function CreateEmbedDll(DllHinst: HINST; ThreadId: DWORD;
CallBackTheadId: DWORD): TEmbedDll; stdcall;
function DoEmbedDll: DWORD; stdcall;

implementation

{$R *.dfm}

function CreateEmbedDll; external C_EmbedDll name 'CreateEmbedDll';
function DoEmbedDll; external C_EmbedDll name 'DoEmbedDll';

procedure TForm1.btnCreateClick(Sender: TObject);
var
DllHinst: HINST;
CallBackThreadId: DWORD;
begin
DllHinst := GetModuleHandle('ProDll.dll');
CallBackThreadId := GetCurrentThreadId;
Embed := CreateEmbedDll(DllHinst, ThreadId, CallBackThreadId);
end;

procedure TForm1.btnGetWindowMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
aPoint.X := X;
aPoint.Y := Y;
aPoint := ClientToScreen(aPoint);

GetThreadId;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
if Embed <> nil then
FreeAndNil(Embed);
end;

procedure TForm1.WM_HOOKFINISHED(var Message: TMessage);
begin
ShowMessage('完成了DLL的挂接');
end;

procedure TForm1.btnHookClick(Sender: TObject);
begin
if Embed = nil then exit;
DoEmbedDll;
//TimerGetMsg.Enabled := True;
end;

procedure TForm1.GetThreadId;
var
hwndLV: HWND;
begin
{ hwndLV := GetDesktopWindow;
hwndLV := FindWindowEx(hwndLV, 0, 'Progman', nil);
hwndLV := FindWindowEx(hwndLV, 0, 'SHELLDLL_DefView', nil);
hwndLV := FindWindowEx(hwndLV, 0, 'SysListView32', nil);

ThreadId := GetWindowThreadProcessId(hwndLV);
}
ThreadId := GetWindowThreadProcessId(WindowFromPoint(aPoint),nil);

Caption := format('Hook thread: %d', [ThreadId]);
end;

procedure TForm1.TimerGetMsgTimer(Sender: TObject);
var
msg: TMsg;
begin
GetMessage(msg, 0, 0, 0);
//TImerGetMsg.Enabled := False;
end;

initialization
aPoint := Point(0,0);
end.
 
问题已经解决,多谢各位大富翁的热心帮助。
 
很少有人光顾我的贴子,唉!
 
更有人说过,站在巨人的肩膀上。。。。
 
顶部