📄 hook.pas
字号:
unit Hook;
{---------无影开发小组敬告:-------------------}
{ 外挂研究无罪,开放源码有理! }
{ 希望以此献给各位想研究外挂的朋友一窥外挂之容 }
{ 本代码只供研究之用,不得用于非法用途 }
interface
uses Windows, Messages, Dialogs, Sysutils,DisPack,SendPack,
WorkThread,WinSock2,MadCodeHook,GameCode,wgFace;
var
hNextHookProc : HHook;
procSaveExit : Pointer;
FirstPop : Boolean=false;
var WSASendOrigin:function(s:TSocket;lpBuffers:LPWSABUF;
dwBufferCount:dword;lpNumberOfBytesSent:LPDWORD;
dwFlags:DWORD;lpOverlapped:LPWSAOVERLAPPED;
lpCompletionROUTINE:LPWSAOVERLAPPED_COMPLETION_ROUTINE):integer;stdcall;
var WSARecvOrigin:function(s:TSocket;lpBuffers:LPWSABUF;
dwBufferCount:dword;lpNumberOfBytesRecvd:LPDWORD;
dwFlags:DWORD;lpOverlapped:LPWSAOVERLAPPED;
lpCompletionROUTINE:LPWSAOVERLAPPED_COMPLETION_ROUTINE):integer;stdcall;
var SocketOrigin:function(af:Integer;stype:Integer;protocol:Integer):TSocket;stdcall;
var WSASocketOrigin:function(af:Integer;stype:Integer;protocol:Integer;
lpProtocolInfo:LPWSAPROTOCOL_INFO;g:GROUP;dwFlags:dword):TSocket;stdcall;
function sethook: bool; export;
function hookproc(iCode: Integer; wParam: WPARAM; lParam: LPARAM):LRESULT; stdcall;
function endhook: bool; export;
procedure HotKeyHookExit; far;
function WSASendHook(s:TSocket;lpBuffers:LPWSABUF;
dwBufferCount:dword;lpNumberOfBytesSent:LPDWORD;
dwFlags:DWORD;lpOverlapped:LPWSAOVERLAPPED;
lpCompletionROUTINE:LPWSAOVERLAPPED_COMPLETION_ROUTINE):integer;stdcall;
function WSARecvHook(s:TSocket;lpBuffers:LPWSABUF;
dwBufferCount:dword;lpNumberOfBytesRecvd:LPDWORD;
dwFlags:DWORD;lpOverlapped:LPWSAOVERLAPPED;
lpCompletionROUTINE:LPWSAOVERLAPPED_COMPLETION_ROUTINE):integer;stdcall;
function SocketHook(af:Integer;stype:Integer;protocol:Integer):TSocket;stdcall;
function WSASocketHook(af:Integer;stype:Integer;protocol:Integer;
lpProtocolInfo:LPWSAPROTOCOL_INFO;g:GROUP;dwFlags:dword):TSocket;stdcall;
implementation
procedure IncPN(var N:Char);
begin
if N>='9' then
N:='1'
else
Inc(N);
end;
//----------------------------------------------------------
function SocketHook(af:Integer;stype:Integer;protocol:Integer):TSocket;stdcall;
var
s:TSocket;
begin
s:=SocketOrigin(af,stype,protocol);
GameSocket:=s;
SocketHook:=GameSocket;
DBGOut('Socket Create %d!',[GameSocket]);
end;
function WSASocketHook(af:Integer;stype:Integer;protocol:Integer;
lpProtocolInfo:LPWSAPROTOCOL_INFO;g:GROUP;dwFlags:dword):TSocket;stdcall;
var
s:TSocket;
begin
s:=WSASocketOrigin(af,stype,protocol,lpProtocolInfo,g,dwFlags);
GameSocket:=s;
WSASocketHook:=s;
DBGOut('WSASocket Create %d!',[GameSocket]);
end;
//----------------------------------------------------------
function WSASendHook(s:TSocket;lpBuffers:LPWSABUF;
dwBufferCount:dword;lpNumberOfBytesSent:LPDWORD;
dwFlags:DWORD;lpOverlapped:LPWSAOVERLAPPED;
lpCompletionROUTINE:LPWSAOVERLAPPED_COMPLETION_ROUTINE):integer;stdcall;
begin
//-------------------------------------------------------
//修改封包序号
if MyPN='0' then
MyPN:=lpBuffers.buf[1]
else
begin
lpBuffers.buf[1]:=MyPN;
IncPN(MyPN);
end;
//-------------------------------------------------------
DisPacketSend(lpBuffers.buf,lpBuffers.len);
WSASendHook:=WSASendOrigin(s,lpBuffers,dwBufferCount,
lpNumberOfBytesSent,dwFlags,lpOverlapped,lpCompletionROUTINE);
//初始化GameSocket
//DBGOut('Send Socket=%d',[s]);
if GameSocket<>s then
GameSocket:=s;
end;
//------------------------------------------------------
function MyOneRecv(Buf:PChar;Len:Integer):Integer;
begin
MyOneRecv:=1;
DisPacketRecv(@buf[0],Len);
end;
function MyRecv(Buf:PChar;Len:Integer):Integer;
var
OneLen:Integer;
i :Integer;
pHeader:PChar;
begin
i:=0;
pHeader:=Buf;
Onelen:=0;
MyRecv:=1;
while i<len do
begin
if ((Buf[i]='*') or (Buf[i]='#')) then
begin
OneLen:=0;
pHeader:=@Buf[i];
end;
if Buf[i]='!' then
begin
MyOneRecv(pHeader,OneLen);
OneLen:=0;
pHeader:=@Buf[i];
end;
inc(OneLen);
inc(i);
end;
end;
//------------------------------------------------------
function WSARecvHook(s:TSocket;lpBuffers:LPWSABUF;
dwBufferCount:dword;lpNumberOfBytesRecvd:LPDWORD;
dwFlags:DWORD;lpOverlapped:LPWSAOVERLAPPED;
lpCompletionROUTINE:LPWSAOVERLAPPED_COMPLETION_ROUTINE):integer;stdcall;
begin
WSARecvHook:=WSARecvOrigin(s,lpBuffers,dwBufferCount,
lpNumberOfBytesRecvd,dwFlags,lpOverlapped,lpCompletionROUTINE);
MyRecv(lpBuffers.buf,lpNumberOfBytesRecvd^);
if GameSocket<>s then
GameSocket:=s;
end;
//----------------------------------------------------------
function HookProc(iCode: integer; wParam: wParam; lParam: lParam):
LResult; stdcall;
var
hwnd: dword;
AppRect: TRect;
title: pchar;
begin
//DBGOut('iCode=%d,wparam=%d,lparam=%d',[iCode,wparam,lparam]);
result := 0;
title := '';
if iCode < 0 then
begin
CallNextHookEx(hnexthookproc, iCode, wParam, lParam);
result := 0;
Exit;
end;
if ((lParam and $80000000) = 0) and (wParam = $6A) then
begin
hwnd := getforegroundwindow;
try
GetMem(title, 255);
getwindowtext(hwnd, title, 255);
if PopForm<>nil then PopForm.Show else
begin
if title='《神迹》公测版' then
begin
GameWindow:=hwnd;
GameWindow2:=hwnd;
PopForm:=TPopForm.CreateParented(hwnd);
GetWindowRect(hwnd, AppRect);
PopForm.Caption:='神迹之光0.141(免费测试版)';
PopForm.Show;
WorkThread.WThread.Resume;
end;
end;
finally
FreeMem(title);
end;
result := 1;
end;
end;
function sethook: bool; export;
begin
result := false;
if hnexthookproc <> 0 then
exit;
hNextHookProc := SetWindowsHookEx(WH_KEYBOARD, hookproc, HInstance, 0);
Result := hNextHookProc <> 0;
end;
procedure hotkeyhookexit;
begin
if hNextHookProc <> 0 then
endHook;
ExitProc := procSaveExit;
end;
function endhook: bool; export;
begin
if hNextHookProc <> 0 then
begin
UnhookWindowshookEx(hNextHookProc); // 解除 Keyboard Hook
hNextHookProc := 0;
end;
Result := hNextHookProc = 0;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -