Memory Chain read in Delphi only ?

03/31/2013 15:25 Afro-Head#1
Excuse the maybe nubish question :o
but can i ReadProcessMemory with Delphi on chains only or can i also read Pointer's ?

Im using for learning Bot coding the Prophet Bot autoit source.
The coder here set up a pointer struct first:
Quote:
Global $OFFSET_PLAYERBASE[4], $CFG_OFFSET_PLAYERBASE = "PlayerBase_OffSet", $CFG_OFFSET_PLAYERSTRUCT1 = "PLAYERSTRUCT1_OffSet", $CFG_OFFSET_PLAYERSTRUCT2 = "PLAYERSTRUCT2_OffSet"
$OFFSET_PLAYERBASE[1] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_PLAYERSTRUCT1, "28")
$OFFSET_PLAYERBASE[2] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_PLAYERSTRUCT2, "32")
$OFFSET_PLAYERBASE[3] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_PLAYERBASE, "136")
and read out the Playerbase with a single pointer read:
Quote:
Global $PLAYER_DATA_BASE = _MemoryPointerRead($APP_BASE_ADDRESS, $PROCESS_INFORMATION, $OFFSET_PLAYERBASE)
In Delphi i use this ReadProcessMemory chain to get the Playerbase:
Quote:
// player database
ReadProcessMemory(GameHandle, ptr(BaseAdress), @eax, 4, Wert); //BASE
ReadProcessMemory(GameHandle, ptr(eax + 28), @eax, 4, Wert);
ReadProcessMemory(GameHandle, ptr(eax + 32), @eax, 4, Wert);
ReadProcessMemory(GameHandle, ptr(eax + 136), @PLBASE, 4, Wert); //Pointer global People Base
So four lines of Code in Delphi and one Line of Code in a poorer programming Language :confused:

Anybody can enlight me please :o
04/03/2013 23:29 Interest07#2
It's because you call a function in the 'poorer' language that does exactly that, read a chain of pointers.
04/04/2013 09:19 Sᴡoosh#3
I somehow forgot to answer this, thanks interest for bumping...

This pointer chain reading stuff isn't what you want if you like speed. I did this at first also, until a wise old crazy man enlightend me. You want to read structwise, each time reading n bytes, n being the value of your highest offset. This way you can actually read, for example, complete character struct in 4 lines of code. After that, you'd simply reference offsets locally in your struct.

TL;DR : Chains suck for performance, use structs. If you really want, write a chain method that supports writing to struct at final offset.
04/04/2013 11:48 Interest07#4
Quote:
Originally Posted by Sᴡoosh View Post
I somehow forgot to answer this, thanks interest for bumping...

This pointer chain reading stuff isn't what you want if you like speed. I did this at first also, until a wise old crazy man enlightend me. You want to read structwise, each time reading n bytes, n being the value of your highest offset. This way you can actually read, for example, complete character struct in 4 lines of code. After that, you'd simply reference offsets locally in your struct.

TL;DR : Chains suck for performance, use structs. If you really want, write a chain method that supports writing to struct at final offset.
Indeed, or in the very least when reading a lot of values from for example the player struct, only read in the player pointer once. Then read all the offsets from that pointer, instead of going through the entire chain every single time.
04/06/2013 01:32 Afro-Head#5
Thank you two for the helpfull answers :handsdown:
I use now some functions to ChainReadInt, ChainReadInt32, ChainReadString...ChainWriteInt etc.

Like this one:
Code:
function ChainReadString(addr: DWORD; MaxCharCount: integer): string;
var
  BytesCountOfRead, Size: NativeUInt;
  sValue: array [0..255] of WideChar;
begin
  result := '';
  if (MaxCharCount > 0) and (addr+4 < $FFFFFFFF) then
  try
    Size := SizeOf(sValue);
    if Size > (MaxCharCount * 2) then
     Size := MaxCharCount * 2;
    ZeroMemory(@sValue[0], SizeOf(sValue));
    ReadProcessMemory(hProcess, ptr(addr), @sValue[0], Size, BytesCountOfRead);
    Result := Copy(WideCharToString(sValue), 1, MaxCharCount);
  except
    result := '';
  end;
end;
Works fine and the light shines bright :)
05/13/2013 21:12 Alikarbam#6
Have a look on my source code [Only registered and activated users can see links. Click Here To Register...], it's may be help you. To be more Specific on TPlayer (CPlayer.pas) class procedure.