我把 CreateProcessInternalA 和 CreateProcessInternalW HOOK住了.运行没问题.但是一运行卸载 管理器什么的就直接奔溃
procedure Un_API_Hook;
Var
i : Integer ;
begin
for I := 0 to High(xHookClass) do
begin
// FreeAndNil(xHookClass[I]); xHookClass[i].Destore;// 写会地址
end; // if hhk <> 0 then
UnhookWindowsHookEx(hhk); // xHookClass.Destroy;
end;
在网上找了很多资料 都没具体说怎么可以 安全卸载..
procedure Un_API_Hook;
Var
i : Integer ;
begin
for I := 0 to High(xHookClass) do
begin
// FreeAndNil(xHookClass[I]); xHookClass[i].Destore;// 写会地址
end; // if hhk <> 0 then
UnhookWindowsHookEx(hhk); // xHookClass.Destroy;
end;
在网上找了很多资料 都没具体说怎么可以 安全卸载..
uses
Windows, Messages, Dialogs, Controls, Classes, SysUtils, psapi;type
TMyCreateProcessInternalA = function(hToken:THandle;
lpApplicationName,lpCommandLine:PAnsiChar;
lpProcessAttributes,lpThreadAttributes:PSecurityAttributes;
bInheritHandles:BOOL;
dwCreationFlags:LongWord;
lpEnvironment:Pointer;
lpCurrentDirectory:PAnsiChar;
lpStartupInfo:pStartupInfoA;
lpProcessInformation:PProcessInformation;
hNewToken:PHandle):BOOL; stdcall;
TMyCreateProcessInternalW = function(hToken:THandle;
lpApplicationName,lpCommandLine:pWideChar;
lpProcessAttributes,lpThreadAttributes:PSecurityAttributes;
bInheritHandles:BOOL;
dwCreationFlags:LongWord;
lpEnvironment:Pointer;
lpCurrentDirectory:pWideChar;
lpStartupInfo:pStartupInfoW;
lpProcessInformation:PProcessInformation;
hNewToken:PHandle):BOOL; stdcall;
//function CreateProcessInternal; external 'kernel32.dll' name 'CreateProcessInternalW';type
PImpCode = ^TImpCode;
TImpCode = packed record
JumpItn: Word; // 应该是$25FF,JUMP 指令
AddressFun: PPointer; // 真正的开始地址
end;
TLongJmp = packed record
JmpCode: ShortInt; {指令,用$E9来代替系统的指令}
FuncAddr: DWORD; {函数地址}
end; THookClass = Class
private
BaseAddr : Pointer ;
hProcess: Cardinal;
AlreadyHook: boolean;
Oldcode: array[0..4] of byte; {系统函数原来的前5个字节}
Newcode: TLongJmp; {将要写在系统函数的前5个字节}
public
OldFunction, NewFunction: Pointer;
Constructor Create(DllName, FuncName: string ; MYFun : Pointer);
Constructor Destore;
procedure Restore;
procedure Change;
end;procedure API_Hookup; stdcall;
procedure Un_API_Hook; stdcall;
function TrueFunctionAddress(func: Pointer): Pointer; stdcall ;type_HookProceName = function (Var NameStr : string ) : Boolean ;stdcall ;Var
xHookClass:array [0..1] of THookClass; Exe_ProcePoint : Pointer = nil;
hhk: HHOOK = 0 ;
// _MyCreateProcessInternalA : TMyCreateProcessInternalA ;
implementationfunction _MyCreateProcessInternalW(hToken:THandle;
lpApplicationName,lpCommandLine:pWideChar;
lpProcessAttributes,lpThreadAttributes:PSecurityAttributes;
bInheritHandles:BOOL;
dwCreationFlags:LongWord;
lpEnvironment:Pointer;
lpCurrentDirectory:pWideChar;
lpStartupInfo:pStartupInfoW;
lpProcessInformation:PProcessInformation;
hNewToken:PHandle):BOOL; stdcall;
Var
Temp_Str : string ;
begin
xHookClass[1].Restore; MessageBoxW(0,lpApplicationName,lpCommandLine,0); Result := TMyCreateProcessInternalW(xHookClass[1].OldFunction)(hToken,lpApplicationName,lpCommandLine,
lpProcessAttributes,lpThreadAttributes,
bInheritHandles,dwCreationFlags,
lpEnvironment,lpCurrentDirectory,lpStartupInfo,
lpProcessInformation,hNewToken) ;
xHookClass[1].Change;
end;function _MyCreateProcessInternalA(hToken:THandle;
lpApplicationName,lpCommandLine:PAnsiChar;
lpProcessAttributes,lpThreadAttributes:PSecurityAttributes;
bInheritHandles:BOOL;
dwCreationFlags:LongWord;
lpEnvironment:Pointer;
lpCurrentDirectory:PAnsiChar;
lpStartupInfo:pStartupInfoA;
lpProcessInformation:PProcessInformation;
hNewToken:PHandle):BOOL; stdcall;
Var
Temp_Str : string ;
begin xHookClass[0].Restore;
MessageBoxA(0,lpApplicationName,lpCommandLine,0); //Temp_Str := lpApplicationName;// if not _HookProceName(Exe_ProcePoint)( Temp_Str ) then
// _HookProceName(Exe_ProcePoint)( Temp_Str ) ;
Result := TMyCreateProcessInternalA( xHookClass[0].OldFunction)(hToken,lpApplicationName,lpCommandLine,
lpProcessAttributes,lpThreadAttributes,
bInheritHandles,dwCreationFlags,
lpEnvironment,lpCurrentDirectory,lpStartupInfo,
lpProcessInformation,hNewToken) ;
// else //------------
// Result := False ;
// Result := True ;
xHookClass[0].Change;end;
constructor THookClass.Create(DllName, FuncName: string ; MYFun : Pointer);
var
Pid: DWORD;
DllModule : THandle;
begin
//获取模块句柄
DllModule:=GetModuleHandle(PChar(DllName));
//如果得不到说明未被加载
if DllModule=0 then DllModule:=LoadLibrary(PChar(DllName));
//得到模块入口地址(基址)
BaseAddr:=Pointer(GetProcAddress(DllModule,PChar(FuncName)));
//获取当前进程句柄
//hProcess:=GetCurrentProcess;
OldFunction := TrueFunctionAddress(BaseAddr);
NewFunction := TrueFunctionAddress(MYFun); Pid := GetCurrentProcessID;
hProcess := OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
Newcode.JmpCode := ShortInt($E9);
Newcode.FuncAddr := DWORD(NewFunction) - DWORD(OldFunction) - 5;
Move(OldFunction^, Oldcode, 5);
AlreadyHook := FALSE; Change;
end;
procedure THookClass.Change;
var
nCount,addr ,Pid ,hProc: DWORD;
begin
if (AlreadyHook) or (OldFunction = nil) or (NewFunction = nil) then
exit;
AlreadyHook := true; {表示已经HOOK} Pid := GetCurrentProcessID;
hProc := OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid); VirtualProtectEx(hProc, OldFunction,5,PAGE_EXECUTE_READWRITE,addr) ;
WriteProcessMemory(hProc, OldFunction, @(Newcode), 5, nCount);
VirtualProtectEx(hProc, OldFunction,5,PAGE_EXECUTE_READ,addr) ; CloseHandle( hProc )
end;
procedure API_Hookup;
begin
xHookClass[0] := THookClass.Create('kernel32.dll','CreateProcessInternalA',@_MyCreateProcessInternalA);
xHookClass[1] := THookClass.Create('kernel32.dll','CreateProcessInternalW',@_MyCreateProcessInternalW);
// 'kernel32.dll','CreateProcessInternalA',@MyCreateProcessInternalA
Exe_ProcePoint:= GetProcAddress(GetModuleHandle(nil),'HookProceName');
end;procedure Un_API_Hook;
Var
i : Integer ;
begin
for I := 0 to High(xHookClass) do
begin
// FreeAndNil(xHookClass[I]); xHookClass[i].Destore;
end; // if hhk <> 0 then
UnhookWindowsHookEx(hhk); // xHookClass.Destroy;
end;constructor THookClass.Destore;
begin
//MessageBox(0,'卸载','',0);
// MessageBox(0,'写回地址','',0);
Restore; {if hProcess <> 0 then
begin CloseHandle(hProcess);
end; } {if hhk <> 0 then
begin
MessageBox(0,'关闭 hhk','',0);
UnhookWindowsHookEx(hhk); hhk :=0 ;
end; }
end;procedure THookClass.Restore;
var
nCount , addr ,Pid,hProc: DWORD;
begin
if (not AlreadyHook) or (OldFunction = nil) or (NewFunction = nil) then
exit; Pid := GetCurrentProcessID;
hProc := OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid); VirtualProtectEx(hProcess, OldFunction,5,PAGE_EXECUTE_READWRITE,addr) ;// MessageBox(0,'写回地址','',0);
WriteProcessMemory(hProcess, OldFunction, @(Oldcode), 5, nCount);
AlreadyHook := FALSE; {表示退出HOOK}
VirtualProtectEx(hProcess, OldFunction,5,PAGE_EXECUTE_READ,addr) ; CloseHandle(hProc);
end;
function TrueFunctionAddress(func: Pointer): Pointer;
var
Code: PImpCode;
begin
Result := func;
if func = nil then exit;
try
Code := func;
if (Code.JumpItn = $25FF) then begin
Result := Code.AddressFun^;
end;
except
Result := nil;
end;
end;
end.
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
SysUtils,
Windows,
Classes,
dialogs,Messages, Unit1 in 'Unit1.pas';
Var
//内存映射
MemFile: THandle;
startPid: PDWORD; //保存PIDBol: Boolean = False;
const
HOOK_MEM_FILENAME = 'tmp.hkt';{$R *.res}//传递消息
procedure HookProc(nCode, wParam, lParam: LongWORD);stdcall;
begin
if not Bol then
CallNextHookEx(hhk, nCode, wParam, lParam);
// CallNextHookEx(hhk, nCode, wParam, lParam);
end;
function InstallHook(pid: DWORD): Boolean stdcall;
begin
startPid^ := pid; //if hhk = 0 then
hhk := SetWindowsHookEx(WH_CALLWNDPROC, @HookProc, hInstance, 0);
Result := hhk <> 0;
end;//结束HOOK
procedure EndHook; stdcall;
Var
i : Integer;
begin if hhk <> 0 then
begin // MessageBox(0,'关闭 hhk','',0);
UnhookWindowsHookEx(hhk);
hhk :=0 ;
end;
//Un_API_Hook ; // SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,0); if startPid <> nil then
begin
// MessageBox(0,'关闭 startPid ','',0);
UnmapViewOfFile(startPid );
startPid := nil;
end;
if MemFile <> 0 then
begin
// MessageBox(0,'关闭 MemFile ','',0);
closehandle(MemFile);
MemFile := 0 ;
end; end;//内存映射共想
procedure MemShared();
begin
MemFile:=OpenFileMapping(FILE_MAP_ALL_ACCESS,False, HOOK_MEM_FILENAME);
if MemFile = 0 then begin //打开失败则衉c2建内存映射文件
MemFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
4, HOOK_MEM_FILENAME);
end;
if MemFile <> 0 then
begin
//映射文件到变量
startPid := MapViewOfFile(MemFile,FILE_MAP_ALL_ACCESS,0,0,0);
end;
end;
//环境处理
procedure DllEntry(dwResaon: DWORD);
begin
case dwResaon of
DLL_PROCESS_ATTACH: API_Hookup; //DLL载入
DLL_PROCESS_DETACH: Un_API_Hook; //DLL删除
end;
end;exports
InstallHook,EndHook ,Un_API_Hook;begin
MemShared;{ 分配DLL程序到 DllProc 变量 }
DllProc := @DllEntry;
{ 调用DLL加载处理 }
DllEntry(DLL_PROCESS_ATTACH);
end
或者关闭窗口就奔溃了.
Un_API_Hook;
这函数就是收到卸载信息.然后写会原来的地址啊procedure THookClass.Restore;
var
nCount , addr ,Pid,hProc: DWORD;
begin
if (not AlreadyHook) or (OldFunction = nil) or (NewFunction = nil) then
exit; Pid := GetCurrentProcessID;
hProc := OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid); VirtualProtectEx(hProcess, OldFunction,5,PAGE_EXECUTE_READWRITE,addr) ;// MessageBox(0,'写回地址','',0);
WriteProcessMemory(hProcess, OldFunction, @(Oldcode), 5, nCount);
AlreadyHook := FALSE; {表示退出HOOK}
VirtualProtectEx(hProcess, OldFunction,5,PAGE_EXECUTE_READ,addr) ; CloseHandle(hProc);
end;
给你个参考对照吧
我改成~ DllModule:=GetModuleHandle(PChar('kernel32.dll')); if DllModule=0 then DllModule:=LoadLibrary(PChar('kernel32.dll'));
_MyCreateProceA:=GetProcAddress(DllModule,PChar('CreateProcessInternalA'));
_MyCreateProceW:=GetProcAddress(DllModule,PChar('CreateProcessInternalW')); // 'CreateProcessInternalA'
@MyCreateProcessA := GetFunTrueAddress( _MyCreateProceA);
@MyCreateProcessW := GetFunTrueAddress(_MyCreateProceW);
ReplaceFunAddress(@MyCreateProcessA,@_MyCreateProcessInternalA);
ReplaceFunAddress(@MyCreateProcessW,@_MyCreateProcessInternalW);为什么就钩不上呢?
我有一个做好的
http://download.csdn.net/source/3351392
procedure DllEntry(dwResaon: DWORD);
begin
case dwResaon of
DLL_PROCESS_ATTACH: API_Hookup; //DLL载入
DLL_PROCESS_DETACH: Un_API_Hook; //DLL删除
end;
end;不能在这里HOOK在你的EXE中API_Hookup;就可以了