procedure Runtest; stdcall;
begin
WriteLog('DLL: runtest');
end;
procedure InstallHook; stdcall;
begin
WriteLog('DLL: 正在安装Hook');
try
@TrampolineGetLocalTime := InterceptCreate(kernel32, 'GetLocalTime', @HookedGetLocalTime);
if Assigned(TrampolineGetLocalTime) then
WriteLog('DLL: Hook安装成功,原始函数地址: ' + IntToHex(NativeInt(@TrampolineGetLocalTime), 8))
else
WriteLog('DLL: Hook安装失败 - InterceptCreate返回nil');
except
on E: Exception do
WriteLog('DLL: Hook安装异常: ' + E.Message);
end;
end;
procedure RemoveHook; stdcall;
begin
WriteLog('DLL: 正在移除Hook');
if Assigned(TrampolineGetLocalTime) then
begin
InterceptRemove(@TrampolineGetLocalTime);
TrampolineGetLocalTime := nil;
WriteLog('DLL: Hook已移除');
end;
end;
// DLL 入口(初始化)
procedure DLLMain(Reason: DWORD);
begin
case Reason of
DLL_PROCESS_ATTACH:
begin
// 获取目标进程句柄
hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or
PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False,
ProcessID);
if hProcess = 0 then
begin
WriteLog('打开进程失败,错误代码: ' + inttostr(GetLastError));
RaiseLastOSError;
end;
try
// 在目标进程中分配内存
pRemoteMemory := VirtualAllocEx(hProcess, nil, Length(DllPath) + 1,
MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
if pRemoteMemory = nil then
begin
WriteLog('分配远程内存失败');
RaiseLastOSError;
end;
try
// 写入DLL路径到目标进程
if not WriteProcessMemory(hProcess, pRemoteMemory, PChar(DllPath),
Length(DllPath) + 1, BytesWritten) then
begin
WriteLog('写入远程内存失败');
RaiseLastOSError;
end;
// 获取 LoadLibraryA 地址
LoadLibAddr := GetProcAddress(GetModuleHandle('kernel32.dll'),
'LoadLibraryA');
if LoadLibAddr = nil then
begin
WriteLog('获取LoadLibraryA地址失败');
RaiseLastOSError;
end;
// 创建远程线程调用 LoadLibraryA
hThread := CreateRemoteThread(hProcess, nil, 0, LoadLibAddr,
pRemoteMemory, 0, ThreadId);
if hThread = 0 then
begin
WriteLog('创建远程线程失败');
RaiseLastOSError;
end;
try
me32.dwSize := SizeOf(TModuleEntry32);
if Module32First(hSnapshot, me32) then
begin
repeat
if SameText(me32.szModule, ModuleName) then
begin
Result := HMODULE(me32.modBaseAddr);
Break;
end;
until not Module32Next(hSnapshot, me32);
end;
finally
CloseHandle(hSnapshot);
end;
end;
在调用 GetRemoteModuleHandle 时,确保 ModuleName 是 DLL 文件名(例如 TimeHookDLL.dll),并且大小写匹配。
LoadLibAddr := GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryW');
if LoadLibAddr = nil then
begin
WriteLog('获取LoadLibraryW地址失败');
RaiseLastOSError;
end;
同时,修改 DLL 路径的写入为宽字符:
pRemoteMemory := VirtualAllocEx(hProcess, nil, (Length(DllPath) + 1) * SizeOf(WideChar), MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
if not WriteProcessMemory(hProcess, pRemoteMemory, PWideChar(DllPath), (Length(DllPath) + 1) * SizeOf(WideChar), BytesWritten) then
begin
WriteLog('写入远程内存失败');
RaiseLastOSError;
end;
5. 确保 DLL 和目标进程的位数匹配
确认目标进程和 DLL 的位数(32 位或 64 位)是否一致。如果目标进程是 32 位,DLL 也必须是 32 位编译的。
在 Delphi 中,检查项目设置,确保 DLL 和注入程序的位数与目标进程匹配。
6. 添加调试日志
为了进一步定位问题,建议在 runProcess 中添加更多日志,记录 hDll 和 pInstallHook,例如:
hDll := GetRemoteModuleHandle(hProcess, DllName);
if hDll <> 0 then
begin
WriteLog('DLL已加载,模块句柄: ' + IntToHex(hDll, 8));
pInstallHook := GetProcAddress(hDll, PAnsiChar(hanshu)); // 或 PWideChar(hanshu)
if Assigned(pInstallHook) then
WriteLog(hanshu + ' 函数地址: ' + IntToHex(NativeInt(pInstallHook), 8))
else
WriteLog('无法获取 ' + hanshu + ' 函数地址,错误代码: ' + IntToStr(GetLastError));
end
else
WriteLog('DLL未正确加载到目标进程,错误代码: ' + IntToStr(GetLastError));
7. 检查目标进程的上下文
确保目标进程的 PID 有效,并且 DLL 已正确加载。
使用 Process Explorer 或类似的工具,检查目标进程是否加载了 TimeHookDLL.dll。
8. 验证 DLL 的初始化
你的 DLL 在加载时会自动调用 InstallHook(通过 DLLMain)。确保 InstallHook 没有抛出异常,可能导致 DLL 初始化失败。可以在 DLLMain 中添加更多日志:
procedure DLLMain(Reason: DWORD);
begin
case Reason of
DLL_PROCESS_ATTACH:
begin
WriteLog('DLL 已开始运行: ' + IntToStr(GetCurrentProcessId));
try
InstallHook;
except
on E: Exception do
WriteLog('DLL 初始化失败: ' + E.Message);
end;
end;
DLL_PROCESS_DETACH:
begin
WriteLog('DLL 已卸载');
RemoveHook;
end;
end;
end;
修改后的 runProcess 函数
以下是修改后的 runProcess 函数,综合了上述建议:
procedure runProcess(ProcessID: DWORD; const DllPath: string; hanshu: string);
var
hProcess, hThread: THandle;
pRemoteMemory: Pointer;
ThreadId: DWORD;
BytesWritten: SIZE_T;
LoadLibAddr: Pointer;
dwExitCode: DWORD;
hDll: HMODULE;
pInstallHook: Pointer;
DllName: string;
begin
WriteLog('准备注入DLL到进程: ' + IntToStr(ProcessID));
WriteLog('DLL路径: ' + DllPath);
hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or
PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False, ProcessID);
if hProcess = 0 then
begin
WriteLog('打开进程失败,错误代码: ' + IntToStr(GetLastError));
RaiseLastOSError;
end;
try
pRemoteMemory := VirtualAllocEx(hProcess, nil, (Length(DllPath) + 1) * SizeOf(WideChar),
MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
if pRemoteMemory = nil then
begin
WriteLog('分配远程内存失败,错误代码: ' + IntToStr(GetLastError));
RaiseLastOSError;
end;
try
if not WriteProcessMemory(hProcess, pRemoteMemory, PWideChar(DllPath),
(Length(DllPath) + 1) * SizeOf(WideChar), BytesWritten) then
begin
WriteLog('写入远程内存失败,错误代码: ' + IntToStr(GetLastError));
RaiseLastOSError;
end;
LoadLibAddr := GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryW');
if LoadLibAddr = nil then
begin
WriteLog('获取LoadLibraryW地址失败,错误代码: ' + IntToStr(GetLastError));
RaiseLastOSError;
end;
hThread := CreateRemoteThread(hProcess, nil, 0, LoadLibAddr,
pRemoteMemory, 0, ThreadId);
if hThread = 0 then
begin
WriteLog('创建远程线程失败,错误代码: ' + IntToStr(GetLastError));
RaiseLastOSError;
end;