Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: Cannot read memory pointers.



Permlink Replies: 11 - Last Post: Jan 31, 2017 8:57 AM Last Post By: Brandon Staggs
Maciek Maciejow...

Posts: 8
Registered: 2/23/17
Cannot read memory pointers.
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 23, 2017 3:39 AM
Hello.

I think this forum is my last hope. I really hope you will help me.
I am trying to make an application that would be reading values from another file.
Unfortunately, but since addresses are not static I have to work with pointers.
The thing is that it's very difficult and I didn't find any advises anywhere.
Let me show you my code:
[code]
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
Timer1: TTimer;
Edit1: TEdit;
Label1: TLabel;
Label2: TLabel;
Edit2: TEdit;
Button1: TButton;
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
PID, ThID : integer;
PH : integer;
Offset : integer;

const
POINTER1 = $003410E0;
offset1 = $b8;
offset2 = $8;
offset3 = $750;
offset4 = $0;
offset5 = $798;

implementation

{$R *.dfm}

function ReadMemInteger(Address: Cardinal): Cardinal; //Read adress:value
var
ProcId: Cardinal;
tProc: THandle;
NBR: Cardinal;
value:integer;
begin
GetWindowThreadProcessId(FindWindow(Nil, 'GameClient'), @ProcId);
tProc:= OpenProcess(PROCESS_ALL_ACCESS, False, ProcId);
ReadProcessMemory(tProc, Ptr(Address), @value, 8, NBR);
CloseHandle(tProc);
Result:=value;
end;

function ReadDouble(Address: string): Double;
var
value: Double;
TibiaH : integer;
NBR :dword;
begin
TibiaH := FindWindow('GameClient', nil);
Thid := GetWindowThreadProcessId(TibiaH, @PID);
PH := OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
ReadProcessMemory(PID, Ptr(StrToInt(Address)), @Value, 8, NBR);
Result:=value;
end;


procedure TForm1.Timer1Timer(Sender: TObject);
var
addr:integer;
begin
if FindWindow(Nil, 'GameClient') = 0 then
showmessage('open client')
else
begin
addr:=(ReadMemInteger(POINTER1)+(offset1)+(offset2)+(offset3)+(offset4)+(offset5));
Edit1.Text :='$'+inttohex(addr,8);
label1.caption :=(inttostr(ReadMemInteger(addr)));
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
addr:integer;
begin
addr:=(ReadMemInteger(POINTER1)+(offset1)+(offset2)+(offset3)+(offset4)+(offset5));
Edit2.Text :='$'+inttohex(addr,8);
label2.caption :=(FloatToStr(ReadMemInteger(addr)));
end;
end. [/code]

I was trying to do it in many different ways.
Let me now show you how it looks in cheat engine:
[img]https://zapodaj.net/images/bfc37421e1001.jpg[/img]

Thank you.

Alex Belo

Posts: 626
Registered: 10/8/06
Re: Cannot read memory pointers.
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 23, 2017 7:51 AM   in response to: Maciek Maciejow... in response to: Maciek Maciejow...
Maciek Maciejowski wrote:

The thing is that it's very difficult
...
I was trying to do it in many different ways.

And ... I see no question in your post. What's the problem?

--
Alex
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Cannot read memory pointers.
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 23, 2017 12:47 PM   in response to: Maciek Maciejow... in response to: Maciek Maciejow...
Hello,

1. As Alex wrote: your question is not too clear. But I have a guess
what you want.

2. this is a non-technical forum, a better place to ask would be either
the .RTL forum or the compiler one.

3. A possible solution for your wish to be able to manipulare arbitrary
bytes in a file might be to use a TFileStream, which can read files
byte by byte and random access is possible as well. You will only
work with indexes instead of real pointers.

Greetings

Markus
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Cannot read memory pointers.
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 23, 2017 2:39 PM   in response to: Markus Humm in response to: Markus Humm
Markus wrote:

1. As Alex wrote: your question is not too clear. But I have
a guess what you want.

What makes you think Maciek is trying to read data from a file? It is clear
from the shown code that he is trying to read data from another running process
instead.

--
Remy Lebeau (TeamB)
Uffe Kousgaard

Posts: 218
Registered: 2/7/00
Re: Cannot read memory pointers.
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 26, 2017 3:50 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

Markus wrote:

1. As Alex wrote: your question is not too clear. But I have
a guess what you want.

What makes you think Maciek is trying to read data from a file? It
is clear from the shown code that he is trying to read data from
another running process instead.

This statement from him:

I am trying to make an application that would be reading values from
another file.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Cannot read memory pointers.
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 23, 2017 3:09 PM   in response to: Maciek Maciejow... in response to: Maciek Maciejow...
Maciek wrote:

I am trying to make an application that would be reading values from
another file.
Unfortunately, but since addresses are not static I have to work with
pointers.

And what is the actual problem you are having with it?

The thing is that it's very difficult

As it should be. If this were easy, everyone would do it.

const
POINTER1 = $003410E0;
offset1 = $b8;
offset2 = $8;
offset3 = $750;
offset4 = $0;
offset5 = $798;

Are you sure the values you are working with don't change over time? I can
understand offsets likely staying the same, but the starting address is likely
to change.

function ReadMemInteger(Address: Cardinal): Cardinal; //Read adress:value

You are not doing ANY error checking on the API functions you call. FindWindow()
can fail. OpenProcess() can fail. ReadProcessMemory() can fail. Always
check for errors. For instance, OpenProcess() may fail because you are asking
for too many permissions that you are not likely to have access to. ReadProcessMemory()
may fail because you are asking it to read 8 bytes of data into a 4 byte
variable.

Try something more like this instead:

procedure ReadMemFromProcess(PID: DWORD; Address: DWORD_PTR; Buffer: Pointer; 
BufSize: DWORD);
var
  tProc: THandle;
  NBR: SIZE_T;
  value: Integer;
begin
  tProc := OpenProcess(PROCESS_VM_READ, False, PID);
  if tProc = 0 then RaiseLastOSError;
  try
    if not ReadProcessMemory(tProc, Ptr(Address), Buffer, BufSize, NBR) then
      RaiseLastOSError;
  finally
    CloseHandle(tProc);
  end;
end;
 
procedure ReadMemFromWindow(Wnd: HWND; Address: DWORD_PTR; Buffer: Pointer; 
BufSize: DWORD);
var
  ProcId: DWORD;
begin
  GetWindowThreadProcessId(Wnd, @ProcId);
  ReadMemFromProcess(ProcId, Buffer, BufSize);
end;
 
function ReadMemIntegerFromWindow(Wnd: HWND; Address: DWORD_PTR): Integer;
begin
  ReadMemFromWindow(Wnd, Address, @Result, SizeOf(Integer));
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Wnd: HWND;
  addr: DWORD_PTR;
begin
  Wnd := FindWindow(nil, 'GameClient');
  if Wnd = 0 then
    ShowMessage('open client')
  else 
  begin
    ReadMemFromWindow(Wnd, POINTER1, @addr, sizeof(addr));
    Inc(addr, offset1 + offset2 + offset3 + offset4 + offset5);
    Edit1.Text := '$' + IntToHex(addr, 8);
    Label1.Caption := IntToStr(ReadMemIntegerFromWindow(Wnd, addr));
  end;
end;


I was trying to do it in many different ways.

Trying to do WHAT exactly?

--
Remy Lebeau (TeamB)
Luigi Sandon

Posts: 74
Registered: 2/22/08
Re: Cannot read memory pointers.
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 26, 2017 1:41 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
offsets likely staying the same, but the starting address is likely
to change.

In any system and software with Address Space Layout Randomization enabled, I'd expect any address to change enough... the OP is playing with fire without spending the time first to understand what he's doing. There's a good chance its code will be identified by an antimalware software. While there could be good reason to read another process memory, there are also many other bad ones. Even if there's already plenty of documentation around, I'm not keen on helping sorcerer's apprentices unless I know who they are really...
Maciek Maciejow...

Posts: 8
Registered: 2/23/17
Re: Cannot read memory pointers.
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 27, 2017 4:46 PM   in response to: Luigi Sandon in response to: Luigi Sandon
Hello again.
I didn't write anything for a while, because I was out of home for last few days.
After checking the thread and this code:

 unit Unit1;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
const
POINTER1 = $003410E0;
offset1 = $b8;
offset2 = $8;
offset3 = $750;
offset4 = $0;
offset5 = $798;
 
 
 
implementation
 
{$R *.dfm}
 
procedure ReadMemFromProcess(PID: DWORD; Address: DWORD_PTR; Buffer: Pointer;
BufSize: DWORD);
var
  tProc: THandle;
  NBR: SIZE_T;
  value: Integer;
begin
  tProc := OpenProcess(PROCESS_VM_READ, False, PID);
  if tProc = 0 then RaiseLastOSError;
  try
    if not ReadProcessMemory(tProc, Ptr(Address), Buffer, BufSize, NBR) then
      RaiseLastOSError;
  finally
    CloseHandle(tProc);
  end;
end;
 
procedure ReadMemFromWindow(Wnd: HWND; Address: DWORD_PTR; Buffer: Pointer;
BufSize: DWORD);
var
  ProcId: DWORD;
begin
  GetWindowThreadProcessId(Wnd, @ProcId);
  ReadMemFromProcess(ProcID, Address, Buffer, BufSize);
end;
 
function ReadMemIntegerFromWindow(Wnd: HWND; Address: DWORD_PTR): Integer;
begin
  ReadMemFromWindow(Wnd, Address, @Result, SizeOf(Integer));
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Wnd: HWND;
  addr: DWORD_PTR;
begin
  Wnd := FindWindow(nil, 'Client');
  if Wnd = 0 then
    ShowMessage('open client')
  else
  begin
    ReadMemFromWindow(Wnd, POINTER1, @addr, sizeof(addr));
    Inc(addr, offset1 + offset2 + offset3 + offset4 + offset5);
    Edit1.Text := '$' + IntToHex(addr, 8);
    Label1.Caption := IntToStr(ReadMemIntegerFromWindow(Wnd, addr));
  end;
end;
 
end.


I have an error which is "code 299" and it's writing that Only part of a ReadProcessMemory or WriteProcessMemory request was completed, so the label1.caption is not getting changed.

Edited by: Maciek Maciejowski on Jan 27, 2017 4:47 PM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Cannot read memory pointers. [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 27, 2017 5:09 PM   in response to: Maciek Maciejow... in response to: Maciek Maciejow...
Maciek wrote:

I have an error which is "code 299"

That is ERROR_PARTIAL_COPY.

and it's writing that Only part of a ReadProcessMemory or
WriteProcessMemory request was completed, so the
label1.caption is not getting changed.

From some previous answers I posted on StackOverflow:

http://stackoverflow.com/a/4457745/65863

ReadProcessMemory would return FALSE and GetLastError would return ERROR_PARTIAL_COPY
**when the copy hits a page fault**. This is a common scenario in dumpers,
which have to work on a potentially corrupted process so they can't be sure
if the requested area is valid or not (the pointer they chased to get the
start address could be corrupted and point to la-la-land), but they would
still like to copy as much as possible into the dump.

http://stackoverflow.com/a/34648230/65863

Reading reserved uncommitted memory is not very useful, and is the likely
culprit of your error:

http://stackoverflow.com/a/4457745/65863

"ReadProcessMemory would return FALSE and GetLastError would return ERROR_PARTIAL_COPY
when the copy hits a page fault."

Working Set
https://msdn.microsoft.com/en-us/library/windows/desktop/cc441804.aspx

"When a process references pageable memory that is not currently in its working
set, a page fault occurs."

ReadProcessMemory() can't read data from a memory page that has the PAGE_GUARD
flag, or is not in the process's current working set.

And a likely reason for hitting one of these conditions might be that you
are simply trying to read from the wrong memory address to begin with.

--
Remy Lebeau (TeamB)
Maciek Maciejow...

Posts: 8
Registered: 2/23/17
Re: Cannot read memory pointers. [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 28, 2017 7:02 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Yeah, but the thing is that when I was working on static addresses everything was fine. Client is not protected by any game guards.
I am also able to do the same thing (read value from this pointer) in autoit, but just because autoit is shit I am trying to work in delphi. When I will be able to read these pointers I will be able to do rest (whatever I want to do). The problem is "just" with pointers.

Before it was like:

const
Player_HP = $6C4848;
Player_MaxHP = $6C4844;
 
function MemReadInteger(Address: Cardinal): Cardinal;       //Read adress:value
var
ProcId: Cardinal;
tProc: THandle;
NBR: Size_T;
value:integer;
begin
    GetWindowThreadProcessId(FindWindow('Game Client',Nil), @ProcId);
    tProc:= OpenProcess(PROCESS_ALL_ACCESS, False, ProcId);
    ReadProcessMemory(tProc, Ptr(Address), @value, 4, NBR);
    CloseHandle(tProc);
    Result:=value;
end;
 
 
var
HP1:integer;
HP2:integer;
HPd:double;
i:integer;
begin
Randomize;
i := RandomRange(-SpinEdit2.Value, SpinEdit2.Value);
HP1:=memreadinteger(Player_MaxHP);
HP2:=memreadinteger(Player_HP);
Hpd:= HP2/HP1*100;
if ((HP2/HP1*100) + (i))  < HPs.value then
 
begin
  Say(Spell.Text);
  Form2.LOGS.Items.Add('Healed with : ' + (inttostr(HP2) + ' ' + 'HP' + ' '+ '(' + (FloatToStr(round(HPd))) + '%' + ')') + '.');
  end;
end;

I want to do the same thing, but I am forced to work with dynamic addresses, so I need to learn how to read pointers. The problem is that there aren't any tutorials on the internet.
Maciek Maciejow...

Posts: 8
Registered: 2/23/17
Re: Cannot read memory pointers.
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 31, 2017 8:51 AM   in response to: Maciek Maciejow... in response to: Maciek Maciejow...
refresh
Brandon Staggs

Posts: 683
Registered: 3/3/01
Re: Cannot read memory pointers.
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 31, 2017 8:57 AM   in response to: Maciek Maciejow... in response to: Maciek Maciejow...
"Maciek Maciejowski" wrote on Tue, 31 Jan 2017 08:51:14 -0800:

refresh

You didn't respond to any of the questions people asked. They were
trying to help.

--
Brandon Staggs
StudyLamp Software LLC
http://www.studylamp.com
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02