Anfängerfragen zu OllyDbg

Hallo Leute,

ich beschäftige mich seit kurzem mit Assembler und versuche mit Hilfe von OllyDbg die Programmabläufe eines z.B. in C geschriebenen Programmes zu verstehen. Das Problem ist, dass immer scheinbar eine ganze Menge Bibliotheken in mein Programm eingelinkt werden, ohne dass ich das sehen kann. So wird der Maschinencode immer sehr groß und ich brauche ewig, bis ich an meinen eigenen Code komme.

Gibt es vielleicht eine Möglichkeit, ein Programm von Olly überwachen zu lassen und an genau der Stelle anzuhalten, an der ein bestimmter Wert (z.B. ASCII) im Stack vorkommt?

Vielen Dank!

Chrisimo
 
Rechtsklick im CPU Window -> Search for -> All referenced text strings

Im folgenden fenster kannst du dann Breakpoints an Instruktionen setzen, die auf einen ASCII/Unicode String zugreifen.
 
Danke, aber ich glaube, das hat mir nicht weitergeholfen. Hier mal mein Test-Programm:

Code:
int runprog() {
        char c1[2];
        char test12[20]="Hallo2";
        exit(0);
        }


int main() {
        int test=1;
        runprog();
        exit(0);
        }

Ist es nicht so, dass bei dem Aufruf der Funktion "runprog" Speicher auf dem Stack angelegt wird und im Zuge der Funktion der Wert "Hallo2" auf den Stack geschrieben wird?

Ich kann im Code-Segment des Speichers keine Verweise auf "Hallo2" finden. In dem Bereich links unten allerdings schon. Gehört das zum Heap? Oder was zeigt dieser bereich an (Spalten: Address,HEX Dump,ASCII)?

Meine Deutung der Bereiche:

Links oben (Address,Hex Dump,Disassembly,Comment): Code-Segment - 00401000-00407FFF
Links unten (Address,Hex Dump, ASCII): Heap - 0040A000-0040BFF8
Rechts oben (Prozessorregister - das einzig eindeutige :))
Rechts unten (Address,Value.Comment): Stack - 0012E000-0012FFFC
Wobei das ja eigentlich unlogisch wäre - der Stack sollte doch am Ende des Speichers stehen und zum Anfang hin größer werden, währenddessen der Heap nach dem Code und BSS Segment kommen sollte und zum Ende hin größer werden sollte - oder nicht?


Ah, hab' eine Möglichkeit gefunden: Breakpoint - Memory On Access
 
Zuge der Funktion der Wert "Hallo2" auf den Stack geschrieben wird?
Was der Compiler letzendlich daraus macht, weiß niemand so genau. Allerdings: gerade C Programme sind normalerweise recht angenehm zu debuggern. Bist Du sicher, dass Du keine Debug-Version hast? Welchen Compiler nutzt Du (obwohl das dann eher in den Codingbreich hingehören würde)?

Was Deine Aufteilung angeht:
Links oben: Dein Debugfenster (CPU Windows). Alles was mit dem "ausführen des Codes" zu tun hat, sollte hier erledigt werden. Hier sieht man den analysierten Code und kann ihn manipulieren.
links unten: einfach der Dump an sich - also ein Speicherausszug. Im Debugfenster kann man nämlich je nach anweisung "Follow in Dump->Memory address" etc auswählen und der Speicherbereich wird angezeigt. Also nicht nur HEAP.

Hast Du den Tipp von v01d ausgeführt? Damit solltest Du eine "Übersicht" aller Anweisungen enthalten, die irgendwie auf den String referenzieren.
 
Ja, ich hab das Fenster aufgerufen, da scheinen aber nur Strings enthalten zu sein, die im Programmcode eingebaut sind - keine Variablen.

Ich habe es mit zwei Compilern probiert.

1. Der von Visual Studio.NET 2005
2. gcc

Der MS Compiler legt eine EXE-Datei mit 44.xxx Bytes an, der gcc eine mit 97.xxx Bytes.

Gibt's ne Möglichkeit, dass man nur die Sachen kompiliert kriegt, die auch im eigenen Programmcode stehen? Solange ich nur Variablen definiere und fülle müssen doch nicht so umfangreiche Bibliotheken eingebunden werden, wie das scheinbar geschieht, oder?

Ich hab sonst nur Erfahrung mit VB6 und VB.NET.
 
Ein C-Programm besteht nicht nur aus dem Code, der in der Datei steht. Es muss auch vom Compiler eine Art Rahmen um den Code gebildet werden. Das sieht man daran, dass die Funktion main() auch nicht direkt am Anfang des Codes steht sondern dort meistens erst Funktionen wie GetCommandLine aufgerufen werden und erst später deine main()-Funktion.
Meine VC++-Version(6.0) verarbeitet solchen Code soweit ich mich erinnern kann so:
Irgendwo im Programm steht der String "hallo2" und zu Beginn der Funktion bei der der String auf dem Stack liegt wird der Platz reserviert und "hallo2" auf den Stack kopiert.

Dass man keine Referenz zu dem String sieht, liegt daran, dass der Compiler(zumindest meine Version) bis zu einer bestimmten Stringlänge die DWORDs des Strings einzeln kopiert und erst bei längeren Strings die rep movs-Anweisung verwendet. Dann taucht der String auch unter den Referenzen auf.

Anders ist es z.B. bei masm, wo auch, wenn keine zusätzlichen Bibliotheken eingebunden wurden, auch nur der Code, den man geschrieben hat in der Datei steht.
 
Ja, mit masm habe ich auch ein Test-Programm erstellt, welches wirklich nur die Befehle enthält, die in meinem Code stehen. Aber was dort möglich ist, sollte doch auch unter c++ möglich sein oder nicht? Letztendlich kann doch auch C++ zumindest theoretisch die Daten einfach in Maschinencode umwandeln. Funktionen wie aus der kernel32.dll und ntdll.dll, die in meinem kompilierten C-Programm aufgerufen werden, sind ja nicht zwingend erforderlich. Also muss man die doch irgendwie rausnehmen können...? So ist nämlich auch ein so kleines Programm für einen Anfänger wie mich relativ unübersichtlich :)
 
probier mal, mit deinem compiler/linker eine .com datei zu produzieren.
stichwort TINY object model
bei meinem linker muss man dazu den switch /TINY angeben (digital mars). dadurch wird eine .com datei erzeugt, die auf dem besagten tiny object model aufbaut. allerdings wird dabei ein 16-bit-programm erzeugt. keine ahnung ob dich das stört... auf jeden fall können 16bit-programme garkeine winapis oder andere dlls benutzen, wodurch du dann auch wirklich nur einfache programme rausbekommst

hoffe ich konnte helfen..
mfgJacky
 
für reines C habe ich mit LCC32 gute Erfahrungen gemacht - gcc mit DJGPP (also unter windows) produziert größere Executables, mit denen Olly auch noch nichts anfangen kann. MSVC++ macht dagegen viel zu viel unnötiges Zeug rein.

Achte beim lcc nur darauf, dass das ganze Debug-Zeug wirklich außen vor bleibt. Also 10KB für ein HelloWorld in C sind schon die Obergrenze.

auf jeden fall können 16bit-programme garkeine winapis
16-Bit mag Olly gar nicht, weil sie im Win-Emulator ablaufen ;)
Außerdem bin ich mir relativ unsicher, ob die gängigen Compiler überhaupt noch 16-bit Code produzieren können. Für MASM z.B musste ich mir auch eine ältere Link.exe besorgen und bei C/C++ sieht man diese Frage doch ab und zu in den Foren rumgeistern (denn es müssten dann auch die Libs im entpsrechendem Format vorliegen), weil manche Leute noch für DOSe etwas schreiben müssen.
 
Danke für den Tipp, ich werd's mal mit lcc probieren. Das mit den 16-Bit Programmen habe ich auch schon gemerkt. Die werden alle unter ntvwm gestartet, auch wenn man sie über Olly aufruft. COM-Dateien kann man in Olly gar nicht aufrufen.
Ich habe aber mittlerweile auch noch einen anderen Debugger gefunden (IDA Pro), mit dem man z.B. den Disassemblierten Code seiner Anwendung sehen kann (und zwar nur den eigenen - wenn man das möchte - da ist für jeden Import ein extra Disassembly aufzurufen), dann entsprechende Breakpoints setzen und den Speicher zur Laufzeit dumpen kann. Das ist zwar nur eine Demo-Version, funktioniert aber trotzdem (ist zeitlich begrenzt - nach ca. 10 Minuten beendet sich das Programm) ganz gut.

Ich werde auch da mal schauen, ob man den Speicher überwachen kann und einen Breakpoint auf ein bestimmtes Ereignis setzen kann, das erst zur Laufzeit eintritt (z.B. die Eingabe eines Benutzernamens).

Jedenfalls erstmal vielen Dank für Eure Antworten.

Gruß,
Chrisimo
 
Original von Chrisimo
Danke für den Tipp, ich werd's mal mit lcc probieren. Das mit den 16-Bit Programmen habe ich auch schon gemerkt. Die werden alle unter ntvwm gestartet, auch wenn man sie über Olly aufruft. COM-Dateien kann man in Olly gar nicht aufrufen.
Ich habe aber mittlerweile auch noch einen anderen Debugger gefunden (IDA Pro), mit dem man z.B. den Disassemblierten Code seiner Anwendung sehen kann (und zwar nur den eigenen - wenn man das möchte - da ist für jeden Import ein extra Disassembly aufzurufen), dann entsprechende Breakpoints setzen und den Speicher zur Laufzeit dumpen kann. Das ist zwar nur eine Demo-Version, funktioniert aber trotzdem (ist zeitlich begrenzt - nach ca. 10 Minuten beendet sich das Programm) ganz gut.

Ich werde auch da mal schauen, ob man den Speicher überwachen kann und einen Breakpoint auf ein bestimmtes Ereignis setzen kann, das erst zur Laufzeit eintritt (z.B. die Eingabe eines Benutzernamens).

Jedenfalls erstmal vielen Dank für Eure Antworten.

Gruß,
Chrisimo

Es gibt IDA 4.3 auch kostenlos und ohne Beschränkungen, jedoch ist da kein Debugger enthalten, aber ich finde den Disassembler doch sehr nützlich:
http://www.themel.com/ida.html
 
Zurück
Oben