Code:
unit MemoryReader;
interface
uses Windows,
JwaNative, JwaWinBase,JwaWinType, JwaWinNT,
PCex, tlhelp32;
type TPlayerData = record
HP, MaxHP : dword;
SP, MaxSP : dword;
x, y, z : single;
HROT, VROT : single;
Target : Int64;
end;
type TPlayerInfo = record
PlayerBase : dword;
ptrPlayerX : dword;
ptrPlayerY : dword;
ptrPlayerZ : dword;
ptrPLayerHROT : dword;
ptrPLayerVROT : dword;
end;
var
FWoWProcessHandle : THandle;
FWoWWindowHandle : THandle;
FWoWProcessID : THandle;
FPtrObjectBase : dword;
FPlayerGUID : Int64;
FPlayerInfo : TPlayerInfo;
FPlayerData : TPlayerData;
function CaptureWow: boolean;
function GetWoWBaseInfo : boolean;
function GetPlayerInfo : boolean;
function GetPlayerData : boolean;
implementation
type
TWoWObject = record
DontCare1: Integer;
DontCare2: Integer;
UnitData: Integer;
DontCare4: Integer;
DontCare5: Integer;
ObjectType: Integer;
DontCare7: Integer;
DontCare8: Integer;
DontCare9: Integer;
DontCare10: Integer;
DontCare11: Integer;
DontCare12: Integer;
GUID: Int64;
DontCare13: Integer;
NextPtr: Integer;
end;
function CaptureWow;
begin
Result := false;
NTSetPrivilege(SE_DEBUG_NAME,True);
FWoWWindowHandle := FindWindow(nil,'World of Warcraft');
if isWindow(FWoWWindowHandle) then
begin
GetWindowThreadProcessID(FWoWWindowHandle, @FWoWProcessID);
if FWoWProcessID = 0 then Exit
else
begin
FWoWProcessHandle := OpenProcess(PROCESS_ALL_ACCESS,False, FWoWProcessID);
if FWowProcessHandle = 0 then Exit;
Result := true;
end;
end
else Exit;
end;
function GetWoWBaseInfo: Boolean;
const
TLS_INDEX: Pointer = Pointer();
var
// TLS stuff
TLS_Slot: DWord;
TLS_Offset: DWord;
TargetTLS_Slot: DWord;
// Threads
ThreadHandle: Integer;
ThreadEntry: TThreadEntry32;
ThreadQueryResult: DWord;
BytesRead: DWord;
SnapHandle: THandle;
BasicInformation: TThreadBasicInformation;
BaseObjectPtr: DWord;
TmpPointer : Dword;
begin
FPtrObjectBase := 0;
FPlayerGUID := 0;
Result := false;
// find TLS_Slot
if not ReadProcessMemory(FWoWProcessHandle, TLS_INDEX, @TLS_Slot,
SizeOf(TLS_Slot), @BytesRead)
then Exit;
SnapHandle := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (SnapHandle <> INVALID_HANDLE_VALUE) then
begin
ThreadEntry.dwSize := SizeOf(ThreadEntry);
// Search all threads
if (Thread32First(SnapHandle, ThreadEntry)) then
repeat
try
// Choose WoW threads
if ThreadEntry.th32OwnerProcessID = FWoWProcessID then
begin
ThreadHandle := OpenThread(THREAD_QUERY_INFORMATION, False, ThreadEntry.th32ThreadID);
Sleep(100);
if ThreadHandle <> 0 then
try
// Look for information about thread
ThreadQueryResult := NtQueryInformationThread(ThreadHandle, THREADBASICINFORMATION,
@BasicInformation, SizeOf(BasicInformation), @BytesRead);
if ThreadQueryResult = 0 then
begin
TmpPointer := Cardinal(BasicInformation.TebBaseAddress);
TmpPointer := TmpPointer + $2C;
if not ReadProcessMemory(FWoWProcessHandle, Pointer(TmpPointer), @TLS_Offset,
SizeOf(TLS_Offset), @BytesRead) then
Continue;
if (TLS_Offset <> 0) then
begin
if not ReadProcessMemory(FWoWProcessHandle,
Pointer(TLS_Offset + (TLS_Slot * 4)), @TargetTLS_Slot,
SizeOf(TargetTLS_Slot), @BytesRead) then
Continue;
if not ReadProcessMemory(FWoWProcessHandle,
Pointer(TargetTLS_Slot + 8), @BaseObjectPtr,
SizeOf(BaseObjectPtr), @BytesRead) then
Continue;
if not ReadProcessMemory(FWoWProcessHandle,
Pointer(TargetTLS_Slot + 16), @FPlayerGUID, SizeOf(GUID),
@BytesRead) then
Continue;
if (BaseObjectPtr <> 0) then
begin
FPtrObjectBase := BaseObjectPtr;
Result := True;
Exit;
end;
end;
end;
finally
CloseHandle(ThreadHandle);
end;
end;
finally
ThreadEntry.dwSize := SizeOf(ThreadEntry);
end;
until (not Thread32Next(SnapHandle, ThreadEntry));
end;
CloseHandle(SnapHandle);
CloseHandle(FWoWProcessHandle);
end;
function GetPlayerInfo :boolean;
var ObjectPointer : dword;
CurrentObject : Dword;
BytesRead : DWord;
WoWObject : TWoWObject;
begin
Result := false;
ObjectPointer := FPtrObjectBase + ;
if not ReadProcessMemory(FWoWProcessHandle, Ptr(ObjectPointer), @CurrentObject,
SizeOf(CurrentObject), @BytesRead) then Exit;
while (CurrentObject <> 0) and (Integer(CurrentObject) and 1 = 0) and (Integer(CurrentObject) <> $1c) do
begin
if not ReadProcessMemory(FWoWProcessHandle, Ptr(CurrentObject), @WoWObject,
SizeOf(TWowObject), @BytesRead) then Exit;
if (WoWObject.GUID = FPlayerGUID) then
begin
with FPlayerInfo do
begin
PlayerBase := CurrentObject;
ptrPlayerX := PlayerBase + ;
ptrPlayerY := PlayerBase + ;
ptrPlayerZ := PlayerBase + ;
ptrPlayerHROT := PlayerBase + ;
ptrPlayerVROT := PlayerBase + ;
end;
Result := true;
end;
CurrentObject := WoWObject.NextPtr;
end;
end;
function GetPlayerData;
var dword_var : dword;
single_var : single;
guid_var : int64;
BytesRead : dword;
ptrTmp : dword;
begin
Result := false;
// coords
if not (ReadProcessMemory(FWoWProcessHandle, Ptr(FPlayerInfo.ptrPlayerX) ,
@single_var, 4, @BytesRead)) then Exit;
FPlayerData.X := single_var;
if not (ReadProcessMemory(FWoWProcessHandle, Ptr(FPlayerInfo.ptrPlayerY) ,
@single_var, 4, @BytesRead)) then Exit;
FPlayerData.Y := single_var;
if not (ReadProcessMemory(FWoWProcessHandle, Ptr(FPlayerInfo.ptrPlayerZ) ,
@single_var, 4, @BytesRead)) then Exit;
FPlayerData.Z := single_var;
if not (ReadProcessMemory(FWoWProcessHandle, Ptr(FPlayerInfo.ptrPlayerHROT) ,
@single_var, 4, @BytesRead)) then Exit;
FPlayerData.HROT := single_var;
if not (ReadProcessMemory(FWoWProcessHandle, Ptr(FPlayerInfo.ptrPlayerVROT) ,
@single_var, 4, @BytesRead)) then Exit;
FPlayerData.VROT := single_var;
// staty
if not (ReadProcessMemory(FWoWProcessHandle, Ptr(FPlayerInfo.PlayerBase + $08) ,
@ptrTmp, 4, @BytesRead)) then Exit;
if not (ReadProcessMemory(FWoWProcessHandle, Ptr(ptrTmp + $5C) ,
@dword_var, 4, @BytesRead)) then Exit;
FplayerData.SP := dword_var;
if not (ReadProcessMemory(FWoWProcessHandle, Ptr(ptrTmp + $74) ,
@dword_var, 4, @BytesRead)) then Exit;
FplayerData.MaxSP := dword_var;
if not (ReadProcessMemory(FWoWProcessHandle, Ptr(ptrTmp + $58) ,
@dword_var, 4, @BytesRead)) then Exit;
FplayerData.HP := dword_var;
if not (ReadProcessMemory(FWoWProcessHandle, Ptr(ptrTmp + $70) ,
@dword_var, 4, @BytesRead)) then Exit;
FplayerData.MaxHP := dword_var;
if not (ReadProcessMemory(FWoWProcessHandle, Ptr(ptrTmp + $40) ,
@guid_var, SizeOf(Int64), @BytesRead)) then Exit;
FplayerData.Target := guid_var;
Result := true;
end;
end.
To be continued ...