📄 lm.~dpr
字号:
library LM;
{ Important note about DLL memory management: ShareMem must be the
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
Windows,SysUtils,Messages,
Classes;
const
//**********************自定义消息负责接受客户端发来的消息******************//
WM_GETMAXBLOODADDR=WM_USER+100;
WM_GETNPCLISTADDR=WM_USER+101;
WM_AOTOMOVE=WM_USER+102;
//*********************自定义消息结束***************************************//
SaveMaxXueAddr:Integer=$4EB476; //把获得的最大血基址放到这里
SaveNpcListAddr:Integer=$4EB47B; //把固定NPC列表基址放在这里
MaxXueAddrCall:Integer=$4EB45C; //需要HOOK的血地址
type
ZuoBiao_STR=record
x:Single;
z:Single;
y:Single;
end;
PZuoBiao_STR=^ZuoBiao_STR;
var
hHk: HHOOK=0;
NpcListAddr:Integer=0;
IsDoMaxXueAddr:Integer=0;
{$R *.res}
Function HookProc(nCode:Integer;WParam:WPARAM;LParam:LPARAM):LRESULT;stdcall;forward;
procedure AoToXunLu(Tarx,TarY:Integer);stdcall;forward;
procedure HookMaxXueProc;stdcall;forward;
procedure OpenNpcListPoint;stdcall;forward;
procedure InjectJmpCode(ADDRS,ADDRD:DWORD);stdcall;forward;
Function StartHook(lpHwnd:HWND;aHandle:THandle):HHOOK;stdcall;
var
hThread: Cardinal;
hmod: Pointer;
begin
hmod:=NIL;
hThread :=GetWindowThreadProcessId(lpHwnd,hmod);
if lpHwnd<>0 then
begin
hHk :=SetWindowsHookEx(WH_CALLWNDPROC,@HookProc,hInstance,hThread);
end;
result:=hHk;
end;
Function EndHook:Boolean;stdcall;
begin
if hHk<>0 then
begin
//移除挂钩
UnHookWindowsHookEx(hHk);
hHk :=0;
Result :=true;
end
else
Result :=false;
end;
//******************HOOK函数****************************//
Function HookProc(nCode:Integer;WParam:WPARAM;LParam:LPARAM):LRESULT;stdcall;
var
pCWP:^CWPSTRUCT;
begin
if nCode=HC_ACTION then
begin
pCWP:=Pointer(LParam);
if pCWP.message=WM_AOTOMOVE then
AoToXunLu(pCWP.WParam,pCWP.LParam);
if pCWP.message =WM_GETMAXBLOODADDR then
InjectJmpCode(MaxXueAddrCall,DWORD(@HookMaxXueProc));
if pCWP.message =WM_GETNPCLISTADDR then
OpenNpcListPoint;
end;
Result:= CallNextHookEx(WH_CALLWNDPROC,nCode,WParam,LParam);
end;
procedure InjectJmpCode(ADDRS,ADDRD:DWORD);stdcall;
var
tOldPoint:Cardinal;
begin
VirtualProtect(Pointer(ADDRS),$5,PAGE_READWRITE,tOldPoint);
VirtualProtect(Pointer(SaveMaxXueAddr),$4,PAGE_READWRITE,tOldPoint);
VirtualProtect(Pointer(SaveNpcListAddr),$4,PAGE_READWRITE,tOldPoint);
PWORD(ADDRS)^:=$E8;
PDWORD(ADDRS+$1)^:=ADDRD-ADDRS-$5;
end;
procedure HuiFuOldJmp(ADDRS,ADDRD:DWORD);stdcall; //恢复被HOOK的地址
begin
PWORD(ADDRS)^:=$E8;
PDWORD(ADDRS+$1)^:=ADDRD-ADDRS-$5;
end;
procedure HookMaxXueProc;stdcall;
var
Addr:Pointer;
begin
Addr:=Pointer($4EB960);
if IsDoMaxXueAddr=0 then
begin
asm
pushad
MOV EAX, DWORD PTR [SaveMaxXueAddr]
mov DWORD PTR [EAX],ecx
Call Addr
popad
end;
IsDoMaxXueAddr:=1;
end;
if IsDoMaxXueAddr=1 then //恢复原来的函数JMP
begin
HuiFuOldJmp(MaxXueAddrCall,DWORD(Addr));
asm
Call Addr
end;
end;
end;
procedure AoToXunLu(Tarx,TarY:Integer);stdcall;
var
Address:Pointer;
ZuoBiao:ZuoBiao_STR;
begin
Address:=Pointer($4302C0);
ZuoBiao.x :=TarX;
ZuoBiao.z :=0.0;
ZuoBiao.Y :=TarY;
asm
pushad
lea eax,ZuoBiao
push eax
mov ecx,dword ptr[$833C5C]
call Address
popad
end;
end;
procedure OpenNpcListPoint;stdcall;
var
Address:pointer;
begin
Address:=Pointer($6046D0);
asm
pushad
Call Address
push $716520
mov edx,dword ptr[eax]
mov ecx,eax
call dword ptr[edx+$7C] //打开列表框
mov NpcListAddr,eax
mov edx,dword ptr[SaveNpcListAddr]
mov DWORD PTR [edx],eax
popad
end;
end;
exports
StartHook,EndHook;
begin
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -