[C++] Eintrittspunkt/Basis-Addresse eines Programms finden.

12/16/2011 04:21 Pasukaru#1
#Edit:
[Only registered and activated users can see links. Click Here To Register...]

Hallo!
Hab mal angefangen mit memory read/write rum zu experimentieren, funktioniert soweit auch ganz gut.
Bei Solitär bereitet mir jedoch etwas probleme, sieht im CheatEngine folgendermaßen aus:
[Only registered and activated users can see links. Click Here To Register...]

Mit 'normalen' statischen addressen komm ich klar, aber hier weiß ich nich wie ich 'solitaire.exe+97074' in C++ handhaben soll.
Bräuchte also etwa sowas:

Code:
DWORD entryPoint = blablabla; 
//Wie bekomm ich den Einstiegspunkt von solitaire.exe hier rein, 
//so wie's im CE angezeigt wird? (0x0150ACE8)
DWORD offset = 0x2C; 
DWORD address = entryPoint+offset;
Danke schon mal im Voraus. :)
12/16/2011 18:32 HardCore.1337#2
[Only registered and activated users can see links. Click Here To Register...] <-- Link
12/16/2011 21:36 MrSm!th#3
kannst auch einfach direkt 0x400000 addieren und die absolute adresse nehmen.
12/16/2011 22:32 Ende!#4
Quote:
Originally Posted by MrSm!th View Post
kannst auch einfach direkt 0x400000 addieren und die absolute adresse nehmen.
Nur dann, wenn das Programm, welches er manipulieren will, kein ASLR verwendet und auch tatsächlich 0x400000 als ImageBase verwendet. Und ja: es gibt Spiele, die dort nicht die Standardwerte benutzen. WoW z.B..
12/17/2011 01:12 MrSm!th#5
Ist aber nicht die Regel und dann nimmt man halt die andere Base, ist ja nicht schwer herauszufinden.
Und eine dynamische Base haben die wenigsten Games.
12/17/2011 01:57 Pasukaru#6
Danke and HardCore.1337 und link, genau danach hab ich gesucht. :)

Hier der code, den ich jetzt hab - vielleicht hilfts später jemandem:

Code:
#include "stdafx.h" 
#include <windows.h> 
#include <TlHelp32.h> 
#include <iostream> 

using namespace std; 

DWORD dwGetModuleBaseAddress(DWORD dwProcessIdentifier, TCHAR *lpszModuleName) 
{ 
   HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessIdentifier); 
   DWORD dwModuleBaseAddress = 0; 
   if(hSnapshot != INVALID_HANDLE_VALUE) 
   { 
      MODULEENTRY32 ModuleEntry32 = {0}; 
      ModuleEntry32.dwSize = sizeof(MODULEENTRY32); 
      if(Module32First(hSnapshot, &ModuleEntry32)) 
      { 
         do 
         { 
            if(_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0) 
            { 
               dwModuleBaseAddress = (DWORD)ModuleEntry32.modBaseAddr; 
               break; 
            } 
         } 
         while(Module32Next(hSnapshot, &ModuleEntry32)); 
      } 
      CloseHandle(hSnapshot); 
   } 
   return dwModuleBaseAddress; 
} 

int main() 
{ 
   HWND window = FindWindow(0, _T("Solitaire")); 
   if( window == 0 ){ 
      printf("Window not found!\n"); 
      char f; 
      cin >> f; 
      return 0; 
   } 

   DWORD pID = 0; 
   GetWindowThreadProcessId(window, &pID); 
    
   DWORD baseAddr = dwGetModuleBaseAddress(pID, _T("solitaire.exe")); 
   DWORD staticOffset = 0x97074; 
    
   HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); 
    
   DWORD value; 
   DWORD numBytesRead; 
   ReadProcessMemory(handle, (LPCVOID)(baseAddr+staticOffset), &value, sizeof(DWORD), &numBytesRead); 
   value+=0x2C; 
   ReadProcessMemory(handle, (LPCVOID)value, &value, sizeof(DWORD), &numBytesRead); 
   value+=0x10; //Points offset 
   ReadProcessMemory(handle, (LPCVOID)value, &value, sizeof(DWORD), &numBytesRead); 
    
   CloseHandle(handle); 
   printf("Found value: %d", value); 

   char f; 
   cin >> f; 
   return 0; 
}
12/17/2011 12:03 Tyrar#7
würde nicht auch RtlImageNtHeader ne gute lösung bieten? ;)

PoC code:
Code:
; DWORD __stdcall GetImageBaseThread(LPVOID pModuleName)
call GetModuleHandleA
push eax
call RtlImageNtHeader
mov eax, [eax+24] ; eax=((PIMAGE_NT_HEADERS)eax)->OptionalHeader;
mov eax, [eax+28] ; eax=((IMAGE_OPTIONAL_HEADER)eax)->ImageBase;
ret
12/17/2011 13:52 Tyrar#8
Quote:
Originally Posted by link View Post
Wie jetzt?
GetModuleHandle liefert dir doch schon die ImageBase zurueck.
Ausserdem wuerde es halt nur im eigenen Adressraum funktionieren und man muesste den Code injizieren, um die korrekten Werte zu bekommen.
Daher geht es mit den TlHelp-Funktionen am sichersten und schoensten.
gut das war jetzt vielleicht nicht ein tolles beispiel ImageBase aus dem header zu lesen, aber man könnte so z.b. den entrypoint finden usw. das war der gedanke dahinter ;)

und ja wenn man keinen code injizieren will is das ne unschöne methode.. beschäftige mich momentan einfach ein wenig mehr mit den NtXX funktionen :)
12/17/2011 17:57 XxharCs#9
Quote:
Originally Posted by Pasukaru View Post
Hallo!
Hab mal angefangen mit memory read/write rum zu experimentieren, funktioniert soweit auch ganz gut.
Bei Solitär bereitet mir jedoch etwas probleme, sieht im CheatEngine folgendermaßen aus:
[Only registered and activated users can see links. Click Here To Register...]

Mit 'normalen' statischen addressen komm ich klar, aber hier weiß ich nich wie ich 'solitaire.exe+97074' in C++ handhaben soll.
Bei der .exe musst du statt der GetModuleHandle(0) den process schreiben, weil es so bei einer .dll aussieht.
Basepointer definierst als:
Code:
DWORD BasePointer = 0;
Code:
DWORD ImageBase = (DWORD)GetModuleHandle(0);
BasePointer = ImageBase + 0x00097074;
12/17/2011 20:34 MrSm!th#10
Quote:
Originally Posted by HeavyHacker View Post
gut das war jetzt vielleicht nicht ein tolles beispiel ImageBase aus dem header zu lesen, aber man könnte so z.b. den entrypoint finden usw. das war der gedanke dahinter ;)

und ja wenn man keinen code injizieren will is das ne unschöne methode.. beschäftige mich momentan einfach ein wenig mehr mit den NtXX funktionen :)
Nur ist das hier völlig irrelevant.