Zitat von
Keksdose
1. Warum stürzt das irgend wann ab? also wie bei einer Endlosschleife "has stopped working"
2. Was fang ich denn damit an? Kann ich auch meinen eigenen Code da reinschmuggeln oder so?
1)keine Kristallkugel anwesend . Ist nur rudimentärer Beispielcode, ohne Fehlerprüfungen.
2)Threadstarter wollte speicher anderer Programme auslesen. Und anfangen kann man damit schon einiges. Unter anderem auch eigenen Code/Daten schreiben (Stichwort:Codeinjection, memory patching).
Zitat von
SleiZer
Wenn ich jetzt von der Addresse 0 start hört er aber nicht mehr auf zulaufen.
Er läuft bis zu einem Access Violation.
Kann man vor dem Access Violation auch anhalten oder muss ich den Access Violation unterdrücken, damit das Programm nicht abstürtzt?
Du kannst nicht ALLES auslesen. Wie schon gesagt, es werden nicht die geamten 4 GB belegt. Viele Bereiche sind erstmal frei und werden erst auf eine Anforderung des Programms zugewiesen (z.B über VirtualAlloc bzw über C-Runtime DLL mit malloc - kommt allerdings auf die konkrete C-Runtime Bibliothek an)[1]. Vor dem Auslesen solltest du also erstmal mit VirtualQueryEx prüfen, wie groß der Bereich ist und welche Flags er hat.
Wenn der Speicher eine MEM_FREE Markierung besitzt, hat es keinen Sinn, diesen auszulesen . Dann geht man zum nächsten Speicherblock.
Btw: Ne AccessViolation kommt in dem Fall sowieso nicht vom auslesen (da liefert ReadProcessMemory eine 0 zurück), sondern weil ich im Beispielcode die
"bytes" als unsigned deklariert hab. Wenn 0 Bytes eingelesen wurde, stand in der FOR-schleife praktisch for(i=0;i<0xFFFFFFFE;i++). Das ist der Nachteil, wenn man mal schnell eine hübsche Ausgabe basteln will. Mit einem Debugger allerdings sehr schnell zu finden - und mit dem sollte man sich sowieso anfreunden, wenn man sich mit Low-Level Sachen (Speicherauslesen, Manipulieren usw) beschäfitgen möchte
korrektes Beispiel:
Code:
#include <windows.h>
#include <stdio.h>
#define PROCESS_ID_MANUAL 1168
int dump(void* hProcess,void *base,int size)
{
unsigned char* buff= malloc(size);
int bytes=0;
int result=ReadProcessMemory(hProcess,base,buff,size,&bytes);
if (result!=0)
printf("konnte 0x%X Bytes einlesen von 0x%0.8X\n",bytes,base);
else
{
printf("konnte 0x%0.8X NICHT auslesen\n",base);
free(buff);
return 0;
}
int i;
for (i=1;i<bytes-1 && i<size-1;i++)
{
printf("%0.2X ",buff[i-1]);
if ((i%16==0)) printf("\n"); /*Zeilenumbruch alle 16 Bytes*/
}
free(buff);
return 0;
}
int main()
{
unsigned char puffer[256];
void *pressid;
void *startip;
pressid= OpenProcess(PROCESS_VM_READ,1,PROCESS_ID_MANUAL);
dump(pressid,(void*)0x1000,50);
dump(pressid,(void*)0x400000,50);
dump (pressid,(void*)0x600000,50);
dump (pressid,(void*)0x80000000,50); /*sollte nix ausgeben,
da OS reserviert*/
return 0;
}
ausgabe (bei mir zumindest):
Code:
konnte 0x00001000 NICHT auslesen
konnte 0x32 Bytes einlesen von 0x00400000
4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00
B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
konnte 0x32 Bytes einlesen von 0x00600000
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
konnte 0x80000000 NICHT auslesen
Schöner wäre es allerdings wie erwähnt, mit VirtualQueryEx erstmal abzufragen, was Sache ist. Denn die meisten kleineren Programme belegen nur paar MB des RAMs. Man braucht also nicht stur alle 4GB durchzuklappern und zu dumpen (was dann auch recht langsam wäre).
PS/OT: GCC -Wall wird ein paar Warnungen ausspucken weil bei den APIs ich recht gnadenlos caste. Allerdings hatte ich keine Lust in den Defs/Headern zu wühlen und richtige typedefs zu suchen - das sollte schließlich nur ein Beispiel sein . Außerdem kann ich C nicht wirklich - erinnert mich zu sehr an C++, um sich damit rumzuplagen