Hunt it down every patch, but it's easy to find. Open up WoW with IDA and type in "TlsIndex" in the "Names" window. Double click the variable to follow it to its location, then copy the offset it's stored at. Takes a total of about 3 seconds.
.. yes IDA is powerfull toy
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.
I've got a question, why do you delphi guys always write data to buffers instead of building a function that returns a value?
It's always better to have your function return some values than writing them to a buffer, because It'll make your functions easier to understand and it'll help other people to port the hole stuff into another programming language, since references and pointer symbols are different in every programming language.
Ps: Delphi sucks please start using another language and this code looks alot like greymans proof of concept code, so I can't give you +rep sorry.
heh ... your Delphi phobia is imba
And yes, it's based on Greyman's code, as I wrote above. His code didn't work, it's only proof-of-concept .. try to compile it
And +rep .. heh, I don't need your +rep
ok, i must be an idiot, can`t get the example file to compile, can someone send me the file in a project(zip) or link a download location. i always have problems with copying code from the website.
ok, i must be an idiot, can`t get the example file to compile, can someone send me the file in a project(zip) or link a download location. i always have problems with copying code from the website.
Thanks.
probably because you arnt using a compiler for the actual launguage. There is no one compiler for everything (to my knowledge). Also, you may be missing some of the headers. Trying looking through them to see if they included any headers that arnt standard (which means they probably made or leeched them).
hm, i looked at my source code, and I saw the numbers with $ are missing, maybe it's impossible include it into code section here in forum... i'll try to fix it, when i come home ...
BUT : if you use my code, it ONLY shows player's info !!! No mobs, no gameobjects ... because of
Code:
if (WoWObject.GUID = FPlayerGUID) then
begin
...
Read the code, don't Copy&Paste and compile ;-) Now you can simply modify my code and voila, it shows all gameobjects for you now ;-)
Bookmarks