[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Searching memory.

Posted on 2006-11-24
12
Medium Priority
?
288 Views
Last Modified: 2010-04-05
Hi.

If i know the handle of a process,
how can i search for a specific value in memory (of the process) and write to it (change the value) ?

Thanks in advance.
0
Comment
Question by:CodedK
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
12 Comments
 
LVL 4

Expert Comment

by:tobjectpascal
ID: 18010246
function ReadProcMem(WindowCaption : String;Address : Pointer;Len : Integer) : String;
var
Wnd : Hwnd;
ph,pid : dword;
BytesRead : Cardinal;
begin
Result := '';
Wnd := FindWindow(nil,pchar(WindowCaption));
if Wnd = 0 then exit;
GetWindowThreadProcessID(Wnd, @pid);
ph := OpenProcess(PROCESS_ALL_ACCESS, false, pid);
SetLength(Result,Len);
ReadProcessMemory(ph, Address, pointer(Result), len, BytesRead);
CloseHandle(ph);
end;

//thats about it, you should call it like : ReadProcMem('Hi',Ptr($44444),12);


Const
  WindowTitle = 'Game Window'; // define the game's window name ;
  Address1 = $4ab3485f;      // define your address to poke   ;
  PokeValue1 = $32;          // define what value to write    ;
  NumberOfBytes1 = 1;        // define how many bytes to write
  Address2 = $4ab3485c;
  PokeValue2 = $11;
  NumberOfBytes2 = 3;

procedure TForm1.Button1Click(Sender: TObject); // when button is clicked ... ;
Var
 WindowName : integer;
  ProcessId : integer;
  ThreadId : integer;     // defining variable's types  ;
  buf : PChar;
  HandleWindow : Integer;
  write : cardinal ;
begin
 WindowName := FindWindow(nil,WindowTitle);
     If WindowName = 0 then  // check if the game is running;
                MessageDlg('The game must be running in the background. Run it now, and then try again.', mtwarning,[mbOK],0);
  ThreadId := GetWindowThreadProcessId(WindowName,@ProcessId);
  HandleWindow := OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId);
  GetMem(buf,1);
  buf^ := Chr(PokeValue1);
  WriteProcessMemory(HandleWindow,ptr(Address1),buf,NumberOfBytes1,write);
  FreeMem(buf);
  closehandle(HandleWindow);
end;

procedure TForm1.Button1Click(Sender: TObject);
Var
 Wnd : Hwnd;
 ph,pid : dword;
 BytesRead : Cardinal;
 Buffer: Array [0..255] of Char;
 Address: Integer;
Begin
 // Wnd := FindWindow(nil,pchar(WindowCaption));
 // if Wnd = 0 then exit;
   Wnd:=form1.Handle; //use self for now.
   GetWindowThreadProcessID(Wnd, @pid);
   ph := OpenProcess(PROCESS_ALL_ACCESS, false, pid);
   Address:=GetWindowLong(Wnd,GWL_HINSTANCE);
   BytesRead:=1;
   While BytesRead<>0 do
    Begin
      ReadProcessMemory(ph, Pointer(Address), @Buffer, SizeOf(Buffer), BytesRead);
      Richedit1.Lines.Add(Buffer);
      Inc(Address,Integer(BytesRead));
   //read into buffer and repeat.
    End;
   CloseHandle(ph);
end;

0
 
LVL 16

Author Comment

by:CodedK
ID: 18010540
Hi tobjectpascal. Thank you :)

Well some questions...

You say :  "you should call it like : ReadProcMem('Hi',Ptr($44444),12);"
I'll only know the value for example (6 lifes left)... value = 6
How can i call it ? >> 
ReadProcMem('Super Game',?????,6);"

The question about searching the memory space for the specific value stands.
And probably its going to take multiple searches to see if those values changed.
(creating a list & excluding addresses that dont have this value any more).

If i first check for '6' for example it will bring about 2000 results at least (imagine searching for 1).
I need a search method that will bring back the address.
0
 
LVL 16

Author Comment

by:CodedK
ID: 18010553
Is it possible to know where the address of this application in memory start and end and
search all the values inside ?
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 4

Accepted Solution

by:
Meldrachaun earned 2000 total points
ID: 18082596
Took some digging, but yes, there is a way to find the memory locations.  Unfortunately it's not simple.  The program isn't one big memory block you can search.  The exe, and each DLL that loads (including the windows API DLLs) are seperate modules that have their own address spaces.  Memory that is allocated onto the heap is also stored in a seperate place, so you have to find and search all the heap spaces as well.  If you know what area of memory you are looking for, you can narrow the search.

Here's some code to find each module's memory space.  Make sure to include SysUtils and the PSApi units.  This code assumes you have the ProcessID variable already set

var
  Output: DWORD;
  ProcessHandle: THandle;
  ModuleHandles: array[0..1023] of HMODULE;
  i, len: integer;
  info: _MODULEINFO;
  pinfo: LPMODULEINFO;
  start: pointer;
  size: cardinal;

begin
  ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or
                               PROCESS_VM_READ or PROCESS_VM_WRITE, false, ProcessID);
  if ProcessHandle = 0 then RaiseLastOSError;
  try
    if not EnumProcessModules(ProcessHandle, @ModuleHandles, sizeof(ModuleHandles), output) then
      RaiseLastOSError;
    len := (output div sizeof(HMODULE))-1;
    pinfo := @info;
    for i := 0 to len do
    begin
      if not GetModuleInformation(ProcessHandle, ModuleHandles[i], pinfo, sizeof(_MODULEINFO)) then
        RaiseLastOSError;
      start := info.lpBaseOfDll;
      size := info.SizeOfImage;
    // start is the starting memory address of the module
    // size if the number of bytes the module takes up
    // add code here to search memory, replace memory with desired data, etc.  

    end;

  finally
    CloseHandle(ProcessHandle);
  end;
end;

If you want to examine what each module is before you search it's memory, use the GetModuleBaseName or GetModuleFileName APIs.  

To get the heap info, use the GetProcessHeaps API, then use the  HeapLock, HeapWalk, and HeapUnlock APIs to search the heap, but I think the above code is what you're looking for.
0
 
LVL 16

Author Comment

by:CodedK
ID: 18099727
Meldrachaun thanks but i cant make it work.

I use it like this : ProcessID :=Form1.Handle;
RaiseLastOSError always raises an error.
0
 
LVL 4

Expert Comment

by:Meldrachaun
ID: 18100404
The process ID is not the same as a window handle.  If you are trying to test this on your current app, replace the

ProcessHandle := OpenProcess code above with

ProcessHandle := GetCurrentProcess;

You also should remove the

  CloseHandle(ProcessHandle);

code.  

OR - you can get the process ID from the Window handle using the GetWindowThreadProcessId

see http://msdn2.microsoft.com/en-us/library/ms633522.aspx
0
 
LVL 16

Author Comment

by:CodedK
ID: 18100654
I've tried
  ProcessID :=GetCurrentProcess;
  ProcessID := GetWindowThreadProcessId(Form1.Handle);
But i still get the errors...
0
 
LVL 4

Expert Comment

by:Meldrachaun
ID: 18110444
GetWindowThreadProcessID returns a handle to a thread.  To get the process ID, you pass the process ID as the second parameter.  I just tested it, and it worked for me like this:

GetWindowThreadProcessID(Form1.Handle, ProcessID);

I'm testing this on a Windows XP machine.
0
 
LVL 16

Author Comment

by:CodedK
ID: 18119026
Sorry for not posting earlier.
Well

I've tried this :

  ProcessID := GetWindowThreadProcessID(Form1.Handle, ProcessID);
  ShowMessage('Form PID : '+IntToStr(ProcessID));   /// Everyhting ok here...

  ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or
                               PROCESS_VM_READ or PROCESS_VM_WRITE, false, ProcessID);

  ShowMessage('Form HID : '+IntToStr(ProcessHandle)); // This is 0 ... it shouldn't be 0...
0
 
LVL 4

Expert Comment

by:Meldrachaun
ID: 18120701
Don't do

ProcessID := GetWindowThreadProcessID(Form1.Handle, ProcessID);

 Just do

GetWindowThreadProcessID(Form1.Handle, ProcessID);
0
 
LVL 16

Author Comment

by:CodedK
ID: 18122571
Thank you very much for your time & your help :)
0
 
LVL 4

Expert Comment

by:Meldrachaun
ID: 18127313
you're welcome.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question