📄 hook.pas
字号:
unit hook;
interface
uses
SysUtils,ClassEs,Windows,Winsock2;
type
TCode = packed record
one : byte;
NewProc : pointer;
three : array[0..2] of byte;
end;
PJmpCode = ^TJmpCode;
TJmpCode = Packed record
Address : pointer;
OldCode : array [0..7] of byte;
NewCode : TCode;
end;
function mySend(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
function myRecv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
procedure HookAPI();
procedure UnHookAPI();
function sethook: bool; export;
function endhook: bool; export;
procedure ExitDll;
var
idhook : HHook;
SaveExitProc : Pointer;
hProcess : Cardinal;
// WSASendJmpCode : TJmpCode;
// WSARecvJmpCode : TJmpCode;
SendJmpCode : TJmpCode;
RecvJmpCode : TJmpCode;
implementation
uses GamePacket,DllForm;
//----------------------------------HOOKAPI----------------------------------
function mySend(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
lpNumWrite : dword;
begin
GameSocket := s; //给sokcet赋值 初始化
mySendData(@buf, len); //发送处理
WriteProcessMemory(hProcess, SendJmpCode.Address, @SendJmpCode.OldCode, sizeof(SendJmpCode.OldCode), lpNumWrite);
result := send(s, Buf, len, flags);
WriteProcessMemory(hProcess, SendJmpCode.Address, @SendJmpCode.NewCode, sizeof(SendJmpCode.NewCode), lpNumWrite);
end;
function myRecv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
lpNumWrite : dword;
begin
GameSocket := s; //给sokcet赋值 初始化
WriteProcessMemory(hProcess, RecvJmpCode.Address, @RecvJmpCode.OldCode, sizeof(RecvJmpCode.OldCode), lpNumWrite);
result := recv(s, Buf, len, flags);
WriteProcessMemory(hProcess, RecvJmpCode.Address, @RecvJmpCode.NewCode, sizeof(RecvJmpCode.NewCode), lpNumWrite);
myRecvData(@buf, len); //收包处理
end;
{
function myWSASend(s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD;
var lpNumberOfBytesSent : DWORD; dwFlags : DWORD;lpOverlapped : LPWSAOVERLAPPED;
lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE ): Integer; stdcall;
var
lpNumWrite : dword;
begin
GameSocket := s; //给sokcet赋值 初始化
mySendData(lpBuffers.buf, lpNumberOfBytesSent); //发送处理
WriteProcessMemory(hProcess, WSASendJmpCode.Address, @WSASendJmpCode.OldCode, sizeof(WSASendJmpCode.OldCode), lpNumWrite);
result := WSASend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionROUTINE);
WriteProcessMemory(hProcess, WSASendJmpCode.Address, @WSASendJmpCode.NewCode, sizeof(WSASendJmpCode.NewCode), lpNumWrite);
end;
function myWSARecv(s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD;
var lpNumberOfBytesRecvd : DWORD; var lpFlags : DWORD;lpOverlapped : LPWSAOVERLAPPED;
lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall;
var
lpNumWrite : dword;
begin
GameSocket := s; //给sokcet赋值 初始化
WriteProcessMemory(hProcess, WSARecvJmpCode.Address, @WSARecvJmpCode.OldCode, sizeof(WSARecvJmpCode.OldCode), lpNumWrite);
result := WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionROUTINE);
WriteProcessMemory(hProcess, WSARecvJmpCode.Address, @WSARecvJmpCode.NewCode, sizeof(WSARecvJmpCode.NewCode), lpNumWrite);
myRecvData(lpBuffers.buf, lpNumberOfBytesRecvd); //收包处理
end;
}
procedure HookAPI();
var
hModule : Cardinal;
lpNumWrite : dword;
begin
hProcess := GetCurrentProcess(); {
hModule := LoadLibrary('WS2_32.dll');
if (hModule <> 0) then
begin
WSASendJmpCode.Address := GetProcAddress(hModule, 'WSASend');
CopyMemory(@WSASendJmpCode.OldCode, WSASendJmpCode.Address,8); //读前8个字节
//自已定义跳转到自已的api函数地址..下面构造汇编代码 (共长8个字节)
WSASendJmpCode.NewCode.one := $B8;
WSASendJmpCode.NewCode.NewProc := @myWSASend;
WSASendJmpCode.NewCode.three[0] := $FF;
WSASendJmpCode.NewCode.three[1] := $E0;
WSASendJmpCode.NewCode.three[2] := $90; //这一字节没有用.充数而已 90 = nop
//以上翻译成汇编代码应该是 mov eax,@myMessageBox jmp eax (直接jmp涉及到计算问题,超复杂)
WSARecvJmpCode.Address := GetProcAddress(hModule, 'WSARecv');
CopyMemory(@WSARecvJmpCode.OldCode, WSARecvJmpCode.Address,8);
WSARecvJmpCode.NewCode.one := $B8;
WSARecvJmpCode.NewCode.NewProc := @myWSARecv;
WSARecvJmpCode.NewCode.three[0] := $FF;
WSARecvJmpCode.NewCode.three[1] := $E0;
WSARecvJmpCode.NewCode.three[2] := $90;
//WriteProcessMemory(hProcess, WSASendJmpCode.Address, @WSASendJmpCode.NewCode, sizeof(WSASendJmpCode.NewCode), lpNumWrite);
//WriteProcessMemory(hProcess, WSARecvJmpCode.Address, @WSARecvJmpCode.NewCode, sizeof(WSARecvJmpCode.NewCode), lpNumWrite);
FreeLibrary(hModule);
end; }
hModule := LoadLibrary('wsock32.dll');
if (hModule <> 0) then
begin
SendJmpCode.Address := GetProcAddress(hModule, 'send');
CopyMemory(@SendJmpCode.OldCode, SendJmpCode.Address,8); //读前8个字节
SendJmpCode.NewCode.one := $B8;
SendJmpCode.NewCode.NewProc := @mySend;
SendJmpCode.NewCode.three[0] := $FF;
SendJmpCode.NewCode.three[1] := $E0;
SendJmpCode.NewCode.three[2] := $90;
RecvJmpCode.Address := GetProcAddress(hModule, 'recv');
CopyMemory(@RecvJmpCode.OldCode, RecvJmpCode.Address,8); //读前8个字节
RecvJmpCode.NewCode.one := $B8;
RecvJmpCode.NewCode.NewProc := @myRecv;
RecvJmpCode.NewCode.three[0] := $FF;
RecvJmpCode.NewCode.three[1] := $E0;
RecvJmpCode.NewCode.three[2] := $90;
WriteProcessMemory(hProcess, SendJmpCode.Address, @SendJmpCode.NewCode, sizeof(SendJmpCode.NewCode), lpNumWrite);
WriteProcessMemory(hProcess, RecvJmpCode.Address, @RecvJmpCode.NewCode, sizeof(RecvJmpCode.NewCode), lpNumWrite);
FreeLibrary(hModule);
end;
end;
procedure UnHookAPI();
var
lpNumWrite : dword;
begin
//WriteProcessMemory(hProcess, WSASendJmpCode.Address, @WSASendJmpCode.OldCode, sizeof(WSASendJmpCode.OldCode), lpNumWrite);
//WriteProcessMemory(hProcess, WSARecvJmpCode.Address, @WSARecvJmpCode.OldCode, sizeof(WSARecvJmpCode.OldCode), lpNumWrite);
WriteProcessMemory(hProcess, SendJmpCode.Address, @SendJmpCode.OldCode, sizeof(SendJmpCode.OldCode), lpNumWrite);
WriteProcessMemory(hProcess, RecvJmpCode.Address, @RecvJmpCode.OldCode, sizeof(RecvJmpCode.OldCode), lpNumWrite);
end;
//---------------------------------HOOK------------------------------------
procedure keyboradproc(nCode: Integer; wParam: WPARAM; lParam: LPARAM); stdcall;
var
hwnd : dword;
ClassName : Pchar;
begin
if nCode < 0 then
begin
CallNextHookEx(idhook, nCode, wParam, lParam);
exit;
end;
if ((lParam and $80000000) = 0) and (wParam = VK_PAUSE) then // pause 键
begin
hwnd := GetForeGroundWindow();
GetMem(ClassName, 255);
GetClassName(hwnd, ClassName, 255);
if StrComp(ClassName,'TFrmM') = 0 then
begin
if DllForm1 <> nil then
begin
DllForm1.Show;
exit;
end;
try
DllForm1 := TDllForm1.CreateParented(hwnd);
DllForm1.Show;
HookAPI();
except
DllForm1.Free;
DllForm1 := nil;
exit;
end;
end;
FreeMem(ClassName);
end;
end;
function sethook(): bool;
begin
if idhook <> 0 then
begin
result := false;
exit;
end;
idhook := SetWindowsHookEx(WH_KEYBOARD, @KeyBoradProc, hinstance, 0);
result := idhook <> 0 ;
end;
function endhook(): bool;
begin
UnHookAPI();
if DllForm1 <> nil then
begin
DllForm1.Free;
DllForm1 := nil;
end;
if idhook <> 0 then
begin
UnHookWindowsHookEx(idhook);
idhook := 0;
end;
result := true;
end;
//------------------------------------------------------------------------------
procedure ExitDll; //不知道怎么搞的..dll退出时这一段不会执行
begin
endhook();
if DllForm1 <> nil then
begin
DllForm1.Destroy;
DllForm1.Free;
DllForm1 := nil;
end;
ExitProc := SaveExitProc; // 恢复退出指针
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -