1 目的:
获得系统中打开的程序。所以我这里选择HCBT_ACTIVATE来判断。
2 将要处理的信息 我用log方式写入到本地文件
3 代码:(Google 浏览器居然没有高亮代码的工具栏)
{Dll加载时调用}
{因为在主程序中有对该DLL引用,故应该先执行}procedure OnDllProcessAttach;
var
title: array[0..255] of Char;
M1: TMemoryStream;
begin
if GetModuleFileName(0, title, 256) <> 0 then //获得加载Dll的程序进程名
begin
CreateGameShareData; //创建共享数据块 ProcessName := ExtractFileName(title);
{$IFDEF Dll_log}
logFileName := 'c:\log\' + ProcessName + '.log';
logFile('1:dll is in the process:' + ProcessName);
{$ENDIF}
IsMainProc := (CompareText('TestRunCapture.exe', ProcessName) = 0) or
(CompareText('YOYO.exe', ProcessName) = 0); IsSpecialProcess := IsInterSpecialProc; //是否是特殊进程 if IsSpecialProcess then
{$IFDEF Dll_log}
logFile('2:' + ProcessName + ' is a special process')
{$ENDIF}
else
if IsMainProc then //如果是宿主程序,则将共享数据初始化
begin
{$IFDEF Dll_log}
logFile('2:' + ProcessName + ' is a main process');
{$ENDIF}
end
else
begin
{$IFDEF Dll_log}
logFile('2:' + ProcessName + ' is a other process');
{$ENDIF}
M1 := TMemoryStream.Create;
M1.Position := 0;
M1.Write(GameShareData^.Buf[0], GameShareData^.BufSize);
M1.Position := 0;
M1.ReadComponent(Lib);
M1.Free;
end;
end
else
begin
IsMainProc := False;
IsSpecialProcess := False;
CurGameID := 0;
HaveCheck := True;
end;
end;procedure OnDllProcessDetach;
begin
{$IFDEF Dll_log}
logFile('100:dll detach');
{$ENDIF}
if MapHandle <> 0 then //关闭共享内存块
begin
UnmapViewOfFile(GameShareData);
CloseHandle(mapHandle);
mapHandle := 0;
end;
end;回调函数:
function HookCbtProc(nCode: integer; wParam: WPARAM; lParam: LPARAM): HRESULT; stdcall;
var
title: array[0..256] of Char;
WndCaption, WndClassName: string;
label 1;
begin
Result := 0;
if nCode < 0 then
goto 1;
case nCode of
HCBT_ACTIVATE:
begin
{$IFDEF Dll_log}
logFile('3:Get CBT_Active,wParam' + IntToStr(wParam));
{$ENDIF}
if HaveCheck then goto 1;
if IsSpecialProcess or IsMainProc then goto 1;
{$IFDEF Dll_log}
logFile('4:进程没有被过滤掉');
logFile('5:process name is ' + ProcessName);
{$ENDIF}
if Lib.IsSpecialNode(ProcessName) then //说明为特殊进程,下面不进行
IsSpecialProcess := True
else //
begin
{$IFDEF Dll_log}
logFile('6:start Judging Process');
{$ENDIF}
FillChar(title, 257, 0);
GetWindowText(wParam, title, 257); WndCaption := title;
FillChar(title, 257, 0);
GetClassName(wParam, title, 257);
WndClassName := title;
{$IFDEF Dll_log}
logFile(Format('7:ProcessName:%S,Caption:%S,ClassName:%S', [ProcessName, WndCaption, WndClassName]));
{$ENDIF}
Node := Lib.FindGameDef(ProcessName, WndCaption, WndClassName);
if Node <> nil then
begin
CurGameID := Node.GameID;
HaveCheck := True;
TopHandle := wParam;
GameShareData^.GameHwnd := TopHandle;
{$IFDEF Dll_log}
logFile('8:' + ProcessName + ' is a game ,now send msg to main Process。TopHandle:' + IntToStr(TopHandle));
{$ENDIF}
SendMessage(GameShareData^.AppHandle, WM_CBT_CREATEWND, Node.GameID, wParam); //这个时候wParam为HWND
end;
end;
end;
HCBT_DESTROYWND:
begin
{$IFDEF Dll_log}
logFile('a3:Get CBT_DestroyWnd,wParam' + IntToStr(wParam));
{$ENDIF}
if IsSpecialProcess or IsMainProc then goto 1;
if not Assigned(Node) then
goto 1;
if (not IsWindow(wParam))then
goto 1;
if Node.GameExitJudge and (Cardinal(wParam) <> GameShareData^.GameHwnd) then
goto 1;
{$IFDEF Dll_log}
logFile(Format('a4:Wparam:%D,TopHandle:%D', [wParam, TopHandle]));
{$ENDIF}
if not HaveCheck then goto 1;
if (CurGameID <> 0) then
begin
{$IFDEF Dll_log}
logFile('a5:Game Process is about to Destroy,notifying Main Process');
{$ENDIF}
SendMessage(GameShareData^.AppHandle, WM_CBT_DESTROYWND, CurGameID, wParam);
CurGameID := 0; //避免发送多次
end;
end;
else ;
end;
1:
Result := CallNextHookEx(CbtHk, nCode, wParam, lParam)
end;4 问题描述:
一般情况下正常,每个程序激活就会在C:\log\进程名.log的文件。
现在问题是 在某些特定的进程,如大话西游,如果我先开程序和钩子,然后大话西游,ok,什么都没有,log不会写,而且后续开的其他所有程序都没有log了,我觉得钩子死掉了。
可能有人觉得 大话西游 卸钩子了。ok,先开大话西游,它运行起来,然后开钩子,激活大话西游,log又出来了 程序一切正常。后续其他程序钩子也注入了。5 问题总结
某些特定的进程在钩子先开的情况下,钩子会失效 但是 钩子后开 运行正常。我在这里想问下 大家 觉得 是什么原因?
调试dll都有些什么方法。。
获得系统中打开的程序。所以我这里选择HCBT_ACTIVATE来判断。
2 将要处理的信息 我用log方式写入到本地文件
3 代码:(Google 浏览器居然没有高亮代码的工具栏)
{Dll加载时调用}
{因为在主程序中有对该DLL引用,故应该先执行}procedure OnDllProcessAttach;
var
title: array[0..255] of Char;
M1: TMemoryStream;
begin
if GetModuleFileName(0, title, 256) <> 0 then //获得加载Dll的程序进程名
begin
CreateGameShareData; //创建共享数据块 ProcessName := ExtractFileName(title);
{$IFDEF Dll_log}
logFileName := 'c:\log\' + ProcessName + '.log';
logFile('1:dll is in the process:' + ProcessName);
{$ENDIF}
IsMainProc := (CompareText('TestRunCapture.exe', ProcessName) = 0) or
(CompareText('YOYO.exe', ProcessName) = 0); IsSpecialProcess := IsInterSpecialProc; //是否是特殊进程 if IsSpecialProcess then
{$IFDEF Dll_log}
logFile('2:' + ProcessName + ' is a special process')
{$ENDIF}
else
if IsMainProc then //如果是宿主程序,则将共享数据初始化
begin
{$IFDEF Dll_log}
logFile('2:' + ProcessName + ' is a main process');
{$ENDIF}
end
else
begin
{$IFDEF Dll_log}
logFile('2:' + ProcessName + ' is a other process');
{$ENDIF}
M1 := TMemoryStream.Create;
M1.Position := 0;
M1.Write(GameShareData^.Buf[0], GameShareData^.BufSize);
M1.Position := 0;
M1.ReadComponent(Lib);
M1.Free;
end;
end
else
begin
IsMainProc := False;
IsSpecialProcess := False;
CurGameID := 0;
HaveCheck := True;
end;
end;procedure OnDllProcessDetach;
begin
{$IFDEF Dll_log}
logFile('100:dll detach');
{$ENDIF}
if MapHandle <> 0 then //关闭共享内存块
begin
UnmapViewOfFile(GameShareData);
CloseHandle(mapHandle);
mapHandle := 0;
end;
end;回调函数:
function HookCbtProc(nCode: integer; wParam: WPARAM; lParam: LPARAM): HRESULT; stdcall;
var
title: array[0..256] of Char;
WndCaption, WndClassName: string;
label 1;
begin
Result := 0;
if nCode < 0 then
goto 1;
case nCode of
HCBT_ACTIVATE:
begin
{$IFDEF Dll_log}
logFile('3:Get CBT_Active,wParam' + IntToStr(wParam));
{$ENDIF}
if HaveCheck then goto 1;
if IsSpecialProcess or IsMainProc then goto 1;
{$IFDEF Dll_log}
logFile('4:进程没有被过滤掉');
logFile('5:process name is ' + ProcessName);
{$ENDIF}
if Lib.IsSpecialNode(ProcessName) then //说明为特殊进程,下面不进行
IsSpecialProcess := True
else //
begin
{$IFDEF Dll_log}
logFile('6:start Judging Process');
{$ENDIF}
FillChar(title, 257, 0);
GetWindowText(wParam, title, 257); WndCaption := title;
FillChar(title, 257, 0);
GetClassName(wParam, title, 257);
WndClassName := title;
{$IFDEF Dll_log}
logFile(Format('7:ProcessName:%S,Caption:%S,ClassName:%S', [ProcessName, WndCaption, WndClassName]));
{$ENDIF}
Node := Lib.FindGameDef(ProcessName, WndCaption, WndClassName);
if Node <> nil then
begin
CurGameID := Node.GameID;
HaveCheck := True;
TopHandle := wParam;
GameShareData^.GameHwnd := TopHandle;
{$IFDEF Dll_log}
logFile('8:' + ProcessName + ' is a game ,now send msg to main Process。TopHandle:' + IntToStr(TopHandle));
{$ENDIF}
SendMessage(GameShareData^.AppHandle, WM_CBT_CREATEWND, Node.GameID, wParam); //这个时候wParam为HWND
end;
end;
end;
HCBT_DESTROYWND:
begin
{$IFDEF Dll_log}
logFile('a3:Get CBT_DestroyWnd,wParam' + IntToStr(wParam));
{$ENDIF}
if IsSpecialProcess or IsMainProc then goto 1;
if not Assigned(Node) then
goto 1;
if (not IsWindow(wParam))then
goto 1;
if Node.GameExitJudge and (Cardinal(wParam) <> GameShareData^.GameHwnd) then
goto 1;
{$IFDEF Dll_log}
logFile(Format('a4:Wparam:%D,TopHandle:%D', [wParam, TopHandle]));
{$ENDIF}
if not HaveCheck then goto 1;
if (CurGameID <> 0) then
begin
{$IFDEF Dll_log}
logFile('a5:Game Process is about to Destroy,notifying Main Process');
{$ENDIF}
SendMessage(GameShareData^.AppHandle, WM_CBT_DESTROYWND, CurGameID, wParam);
CurGameID := 0; //避免发送多次
end;
end;
else ;
end;
1:
Result := CallNextHookEx(CbtHk, nCode, wParam, lParam)
end;4 问题描述:
一般情况下正常,每个程序激活就会在C:\log\进程名.log的文件。
现在问题是 在某些特定的进程,如大话西游,如果我先开程序和钩子,然后大话西游,ok,什么都没有,log不会写,而且后续开的其他所有程序都没有log了,我觉得钩子死掉了。
可能有人觉得 大话西游 卸钩子了。ok,先开大话西游,它运行起来,然后开钩子,激活大话西游,log又出来了 程序一切正常。后续其他程序钩子也注入了。5 问题总结
某些特定的进程在钩子先开的情况下,钩子会失效 但是 钩子后开 运行正常。我在这里想问下 大家 觉得 是什么原因?
调试dll都有些什么方法。。
我也在看delphi深入windows核心编程。
http://topic.csdn.net/u/20090627/10/b46475d6-fa60-414a-9cd9-3d481e4dfe28.html?69360