  | 
				
				Cheat Engine The Official Site of Cheat Engine   
				
 
				 | 
			 
		 
		 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		icarusdc How do I cheat?
  Reputation: 0
  Joined: 30 Mar 2016 Posts: 5
 
  | 
		
			
				 Posted: Mon May 21, 2018 7:56 pm    Post subject: [Delphi] AOB Scan | 
				       | 
			 
			
				
  | 
			 
			
				Hi,
 
I want to make a memory patcher with AOB scan.
 
 
So here it is my code:
 
 	  | Code: | 	 		  procedure ChangePrivilege(szPrivilege: PChar; fEnable: Boolean);
 
var
 
  NewState: TTokenPrivileges;
 
  luid: TLargeInteger;
 
  hToken: THandle;
 
  ReturnLength: DWord;
 
begin
 
  OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken);
 
  LookupPrivilegeValue(nil, szPrivilege, luid);
 
  NewState.PrivilegeCount := 1;
 
  NewState.Privileges[0].Luid := luid;
 
  if (fEnable) then
 
    NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
 
  else
 
    NewState.Privileges[0].Attributes := 0;
 
  AdjustTokenPrivileges(hToken, False, NewState, SizeOf(NewState), nil, ReturnLength);
 
  CloseHandle(hToken);
 
end;
 
 
function GetModuleBaseAddress(ProcessID: Cardinal; MName: String): Pointer;
 
var 
 
  Modules         : Array of HMODULE; 
 
  cbNeeded, i     : Cardinal;
 
  ModuleInfo      : TModuleInfo;
 
  ModuleName      : Array[0..MAX_PATH] of Char; 
 
  PHandle         : THandle; 
 
begin 
 
  Result := nil; 
 
  SetLength(Modules, 1024); 
 
  PHandle := OpenProcess(PROCESS_QUERY_INFORMATION + PROCESS_VM_READ, False, ProcessID); 
 
  if (PHandle <> 0) then 
 
  begin
 
    EnumProcessModules(PHandle, @Modules[0], 1024 * SizeOf(HMODULE), cbNeeded);
 
    SetLength(Modules, cbNeeded div SizeOf(HMODULE)); 
 
    for i := 0 to Length(Modules) - 1 do //Start the bucle 
 
    begin 
 
      GetModuleBaseName(PHandle, Modules[i], ModuleName, SizeOf(ModuleName));
 
      if AnsiCompareText(MName, ModuleName) = 0 then 
 
      begin 
 
        GetModuleInformation(PHandle, Modules[i], @ModuleInfo, SizeOf(ModuleInfo)); 
 
        Result := ModuleInfo.lpBaseOfDll;
 
        CloseHandle(PHandle); 
 
        Exit; 
 
      end; 
 
    end; 
 
  end; 
 
end;
 
 
function GetProcessID(Const ExeFileName: string; var ProcessId: integer): boolean;
 
var
 
  ContinueLoop: BOOL;
 
  FSnapshotHandle: THandle;
 
  FProcessEntry32: TProcessEntry32;
 
begin
 
  result := false;
 
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 
  FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
 
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
 
  while integer(ContinueLoop) <> 0 do begin
 
   if (StrIComp(PChar(ExtractFileName(FProcessEntry32.szExeFile)), PChar(ExeFileName)) = 0)
 
      or (StrIComp(FProcessEntry32.szExeFile, PChar(ExeFileName)) = 0)  then begin
 
      ProcessId:= FProcessEntry32.th32ProcessID;
 
      result := true;
 
      break;
 
   end;
 
   ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
 
  end;
 
  CloseHandle(FSnapshotHandle);
 
end;
 
 
function Match(pData: PByte; bMask: PByte; szMask: PChar): Boolean;
 
begin
 
  while (szMask^ <> #0) do
 
  begin
 
    if (szMask^ = 'x') and (pData^ <> bMask^) then
 
    begin
 
      Result := false;
 
      exit;
 
    end;
 
    Inc(szMask);
 
    Inc(pData);
 
    Inc(bMask);
 
  end;
 
  Result:= (szMask^ = #0);
 
end;
 
 
function FindPattern(dwAddress, dwLen : Cardinal; bMask : PBYTE; szMask : PCHAR) : Cardinal;
 
var
 
i : Cardinal;
 
begin
 
  Result:= 0;
 
  for i := 0 to dwLen-1 do
 
    if(Match(PBYTE(dwAddress + i), bMask, szMask)) then
 
    begin
 
      Result := Cardinal((dwAddress + i));
 
      break;
 
    end;
 
end;
 
procedure TForm1.bGetAOBScanClick(Sender: TObject);
 
const
 
  test2: array [0 .. 9] of byte = ($FF,$92,$C8,$00,$00,$00,$84,$C0,$74,$0C);
 
var
 
  i: Cardinal;
 
  dwLen: Cardinal;
 
  szMask: PCHAR;
 
  bMask: PBYTE;
 
  Addr: cardinal;
 
  Address: Cardinal;
 
  ProcessID : integer;
 
  pi : Process_Information;
 
  x:dword;
 
  targetname:string;
 
  datamask:pchar;
 
  datadwlen:cardinal;
 
begin
 
targetname:='test.exe';
 
datadwlen:=$000251000;
 
datamask:='xxxxxxxxxx';
 
ChangePrivilege('SeDebugPrivilege', True);
 
  if GetProcessID(targetname, ProcessID) then
 
  begin
 
  eProcessID.Text:=inttostr(processid);
 
  Address := Integer(GetModuleBaseAddress(ProcessID, targetname));
 
  Pi.hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_ALL_ACCESS or PROCESS_VM_OPERATION, false, ProcessID);
 
  ReadProcessMemory(pi.hProcess, Ptr(Address), @Address,datadwlen, x);
 
  i := address;
 
  dwLen := datadwlen;
 
  bMask:= @test2;
 
  szMask := datamask;
 
  Addr:= FindPattern(i, dwLen, bMask, szMask);
 
  eAOBScan.Text:=(IntToHex(Addr,8));
 
  end else
 
  begin
 
  showmessage(targetname+' Not Found');
 
  end;
 
end;
 
 | 	  
 
 
but it only scan AOB in my patcher. not the target (test.exe).
 
any suggestion how to scan in other process?
 
 
 
Salam.
 | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Dark Byte Site Admin
  Reputation: 470
  Joined: 09 May 2003 Posts: 25807 Location: The netherlands
  | 
		
			
				 Posted: Tue May 22, 2018 1:16 am    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				use virtualqueryEx to get a range of memory regions , then use readprocessmemory on the readable ones, and scan that
 
 
Also, your readprocessmemory call is wrong, it needs an addres in the target process and an address in your process. You just give it your process each time, and the same one at that
 _________________
 Do not ask me about online cheats. I don't know any and wont help finding them.
 
 
Like my help? Join me on Patreon so i can keep helping  | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		icarusdc How do I cheat?
  Reputation: 0
  Joined: 30 Mar 2016 Posts: 5
 
  | 
		
			
				 Posted: Thu May 24, 2018 1:53 am    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				Hi,
 
thanks for your reply.
 
So I found the source like this that include VirtualQueryEx like you said.
 
 
 	  | Code: | 	 		  procedure TForm1.Button2Click(Sender: TObject);
 
const
 
  test2: array [0 .. 9] of byte = ($FF,$92,$C8,$00,$00,$00,$84,$C0,$74,$0C);
 
var
 
  ProcessID:cardinal;
 
  Addr, BytesRead: cardinal;
 
  ProcessHandle: THandle;
 
  Mbi: TMemoryBasicInformation;
 
  i: Cardinal;
 
  Buf: PChar;
 
  value:cardinal;
 
  targetname:string;
 
begin
 
targetname:='Test.exe';
 
ChangePrivilege('SeDebugPrivilege', True);
 
  if GetProcessID(targetname, ProcessID) then
 
  Value := 69696969;
 
  ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_ALL_ACCESS or PROCESS_VM_OPERATION, false, ProcessID);
 
    if ProcessHandle <> 0 then
 
      try
 
        Addr := 0;
 
          while VirtualQueryEx(ProcessHandle, Pointer(Addr), Mbi, SizeOf(Mbi)) <> 0 do
 
            begin
 
              if (Mbi.State = MEM_COMMIT) and not ((Mbi.Protect and PAGE_GUARD) = PAGE_GUARD) then
 
                begin
 
                  GetMem(Buf, Mbi.RegionSize);
 
                    try
 
                      if ReadProcessMemory(ProcessHandle, Mbi.BaseAddress, Buf, Mbi.RegionSize, BytesRead) then
 
                        begin
 
                          for i := 0 to BytesRead - SizeOf(Value) do
 
                            begin
 
                              if PDWord(@Buf[i])^ = Value then
 
                              Memo1.Lines.Add('$' + IntToHex(Integer(Cardinal(Mbi.BaseAddress) + i), 8));
 
                            end;
 
                        end
 
                      else
 
                    finally
 
                      FreeMem(Buf);
 
                    end;
 
                end;
 
              Addr := Addr + Mbi.RegionSize;
 
            end;
 
      finally
 
        CloseHandle(ProcessHandle);
 
      end;
 
end; | 	  
 
 
But the problem is how to use array of byte?
 
Value is cardinal and it only has 8 bytes length.
 
and test at constant has 10 bytes.
 
and also how to use mask xxx??xxx like that.
 | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
  | 
   
 
		 |