How to Read Memory from 64bit Programm with 32bit Programm (delphi) menu

User Tag List

Results 1 to 1 of 1
  1. #1
    gemy79's Avatar Member
    Reputation
    13
    Join Date
    Jul 2008
    Posts
    23
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    How to Read Memory from 64bit Programm with 32bit Programm (delphi)

    Hello

    finally i found a solution to read memory from a 64bit Application like World of Warcraft or League of Legends using a 32 bit Programm. This also includes a solution to find the Module Base Adress of any 64 bit Programm which you will need to add the Base Pointer (from cheat engine) to find a variable.


    This example read the amount of Gold from league of legends. If you want to try it, you have to change the processId (in my case it was dec 3672 (league of legends)).I also used a Timer, Memofield and a Button on the Form. Compiled using Delphi 10 Seattle. Code explanation below


    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, Vcl.ExtCtrls;
    
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        Timer1: TTimer;
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
    
      type
     NTSTATUS = Integer;
    
     PROCESS_BASIC_INFORMATION = packed record
       Reserved1: UINT64;
       PebBaseAddress: UINT64;
       Reserved2: array [0 .. 1] of UINT64;
       UniqueProcessId: UINT64;
       Reserved3: UINT64;
     end;
    
     PPROCESS_BASIC_INFORMATION = ^PROCESS_BASIC_INFORMATION;
    
     TNtQueryInformationProcess = function(ProcessHandle: THANDLE; ProcessInformationClass: ULONG; ProcessInformation: Pointer; ProcessInformationLength: ULONG; ReturnLength: Pointer): NTSTATUS; stdcall;
     TNtReadVirtualMemory = function(ProcessHandle: THANDLE; BaseAddress: UINT64; Buffer: Pointer; BufferLength: UINT64; ReturnLength: Pointer): NTSTATUS; stdcall;
    
    
     
    
      private
        { Private-Deklarationen }
      public
    var
     NtQueryInformationProcess: TNtQueryInformationProcess;
     NtReadVirtualMemory: TNtReadVirtualMemory;
       { Public-Deklarationen }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    
    function AddCurrentProcessPrivilege(PrivilegeName: WideString): Boolean;
    var
     TokenHandle: THandle;
     TokenPrivileges: TTokenPrivileges;
     ReturnLength: Cardinal;
    begin
     Result := False;
     if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, TokenHandle) then
     begin
       try
         LookupPrivilegeValueW(nil, PWideChar(PrivilegeName), TokenPrivileges.Privileges[0].Luid);
         TokenPrivileges.PrivilegeCount := 1;
         TokenPrivileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
         if AdjustTokenPrivileges(TokenHandle, False, TokenPrivileges, 0, nil, ReturnLength) then
           Result := True;
       finally
         CloseHandle(TokenHandle);
       end;
     end;
    end;
    
    
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    if Form1.Timer1.Enabled=True
       then
       begin
        Form1.Button1.Caption:='start';
        Form1.Timer1.Enabled:=False;
       end else
       begin
         Form1.Button1.Caption:='stop';
         Form1.Timer1.Enabled:=True;
       end;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
     hLibrary: HMODULE;
     ProcessHandle: THandle;
     PBI: PROCESS_BASIC_INFORMATION;
     ReturnLength: UINT64;
     i: ULONG;
     Buffer : cardinal;
    begin
     AddCurrentProcessPrivilege('SeDebugPrivilege');
    
     hLibrary := LoadLibrary('ntdll.dll');
     if hLibrary <> 0 then
     begin
         @NtQueryInformationProcess := GetProcAddress(hLibrary, 'NtWow64QueryInformationProcess64');
         @NtReadVirtualMemory := GetProcAddress(hLibrary, 'NtWow64ReadVirtualMemory64');
     end;
    
     ProcessHandle:= OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, True, 3672);  
     if NtQueryInformationProcess(ProcessHandle, 0, @PBI, SizeOf(PBI), nil) = 0 then
     begin
       if NtReadVirtualMemory(ProcessHandle, PBI.PebBaseAddress + $10, @Buffer, 4, @ReturnLength) = 0 then
       begin
    
          if NtReadVirtualMemory(ProcessHandle, Buffer+$169C294 , @Buffer, 4, @ReturnLength) = 0 then
         begin
           if NtReadVirtualMemory(ProcessHandle, Buffer+$48, @buffer, 4, @ReturnLength) = 0 then
           begin
             if NtReadVirtualMemory(ProcessHandle, Buffer+$44, @buffer, 4, @ReturnLength) = 0 then
             form1.Memo1.Clear;
             form1.memo1.text:= form1.memo1.text+ inttostr(buffer)+#13#10;
           end;
         end;
       end;
     end;
     CloseHandle(ProcessHandle);
    end;


    I found out if i add $10 to the PBI.PebBaseAdress i will get the Programm entry point which i need to add to the BaseAdress from CheatEngine. If you found a Base Pointer in Cheat engine its like :"League of legends.exe"+169C294 +$48 +$44. (value for gold)

    In 32 bit programms it was no Problem to Read with:

    Code:
    function GetModuleBaseAddress(PHandle: Thandle; MName: String): Pointer;
    var
          Modules         : Array of HMODULE;
          cbNeeded, i     : Cardinal;
          ModuleInfo      : TModuleInfo;
          ModuleName      : Array[0..MAX_PATH] of Char;
         // Melong : LongBool;
        begin
          Result := nil;
          SetLength(Modules, 1024);
          //cbNeeded := 0;
          if (PHandle <> 0) then
          begin
            try
             EnumProcessModules(PHandle, @Modules[0], 1024 * SizeOf(HMODULE),cbNeeded);
            except
              Exit;
            end;
            SetLength(Modules, cbNeeded div SizeOf(HMODULE)); //Setting the number of modules
           if (Length(Modules) > 0) then
           begin
            for i := 0 to Length(Modules) - 1 do //Start the loop
            begin
              try
                GetModuleBaseName(PHandle, Modules[i], ModuleName, SizeOf(ModuleName));
                if (Pos(MName, ModuleName) > 0) then
                begin
                  GetModuleInformation(PHandle, Modules[i], @MoDuleInfo, SizeOf(ModuleInfo));
                  Result := ModuleInfo.lpBaseOfDll;
                  Exit;
                end;
              Except
              end;
            end;
           end;
          end;

    but this does not work for 64 bit programms. More and more programms like world of warcraft are only avaliable in 64 bit in the next time, so you can use this new code.
    Last edited by gemy79; 06-25-2017 at 03:15 PM.

    How to Read Memory from 64bit Programm with 32bit Programm (delphi)

Similar Threads

  1. Replies: 1
    Last Post: 07-28-2015, 03:53 PM
  2. reading memory from elite dangerouss
    By moe in forum Programming
    Replies: 2
    Last Post: 12-26-2014, 12:22 AM
  3. How to make your Server from the Noobpack from 711 public with Hamachi
    By Rimodo in forum WoW EMU Guides & Tutorials
    Replies: 31
    Last Post: 02-24-2013, 07:19 AM
  4. How to Read Combat log or Chat log? with program?
    By riki in forum World of Warcraft General
    Replies: 0
    Last Post: 08-06-2008, 02:41 PM
  5. [c++] problem with reading memory
    By Lucani in forum WoW Memory Editing
    Replies: 3
    Last Post: 05-08-2008, 03:41 AM
All times are GMT -5. The time now is 07:58 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search