Seite 1 von 1
[Problem] Asm und OllyDbg
Verfasst: 20.11.2006 16:26
von Thorium
Hi,
ich hoffe hier ist jemand der sich ein wenig mit Assembler auskennt und OllyDbg nutzt. Ich habe da nämlich ein Problem. Ich will eine Fremdsoftware direkt im Asm-Code patchen. Mit OllyDbg kein Problem allerdings assembliert Olly eine Anweisung nicht so wie ich will:
Es geht um den Push-Befehl.
Ich will eine Win-Api-Funktion aufrufen und muss dafür Parameter auf den Stack pushen, soweit so gut. Wenn ich aber als Parameter eine sehr kleine Zahl auf den Stack pushen will z.b. 0, dann assembliert mir OllyDbg ein Push was 1 einziges Byte auf den Stack pusht. Bekanntlicherweise erwarten Win-Api-Funktionen aber immer DoubleWords. Ich hab das jetzt so gelöst, das ich eax erst mit der Zahl fülle und dann eax pushe. Aber da hab ich natürlich einen Befehl mehr als ich eigentlich bräuchte.
Also um auf den Punkt zu kommen: Wie sage ich OllyDbg das er mir ein "push 00000000" auch wirklich als DoubleWord-Push assembliert?
Verfasst: 20.11.2006 16:59
von Tafkadasom2k5
Ich habe jetzt nicht besonders die Ahnung von ASM, aber in anderen Sprachen kann man Zahlen konvertieren, indem man den Bezeichner in Klammern oder so davor schreibt...
Java- (so würde man zum Beispiel dem Fehler entgehen, dass Java über den Präzisionsverlust meckert)
Gr33tz
Tafkadasom2k5
Verfasst: 20.11.2006 17:05
von Thorium
Hm naja, die Idee ist ja nicht schlecht aber OllyDbg will mir das so nicht assemblieren. Im Thread "Schnellere Sprachen" hab ich das gefunden:
Aber das assembliert OllyDbg net, bei dieser Schreibweise glaubt er das ich indirekt adressieren will. Will ich ja aber garnet.

Verfasst: 20.11.2006 17:18
von Eric
Ganz einfach, es gibt kein push, das nur ein Byte auf den Stack packt,
aber es gibt eine Kurzform, die verwendet wird, wenn die Zahl in ein Byte passt,
die aber trotzdem 4Byte auf den Stack packt.
(Es gibt auch noch ein Push für 16bit, aber das wird von Olly meines Wissens
nach anders dargestellt.)
Und falls du das Problem haben solltest, dass beim Patchen eine Lücke entsteht,
die lassen sich mit NOP auffüllen.
Verfasst: 20.11.2006 17:24
von Thorium
Eric hat geschrieben:Ganz einfach, es gibt kein push, das nur ein Byte auf den Stack packt,
aber es gibt eine Kurzform, die verwendet wird, wenn die Zahl in ein Byte passt,
die aber trotzdem 4Byte auf den Stack packt.
Ah super, thx. Dachte der würde nur 1 Byte pushen. So is das wenn man Amateur ist und keine Ahnung hat. Vielen Dank, bin nun wieder um einen Wissensbaustein reicher.

Verfasst: 20.11.2006 18:13
von Helle
Man kann durchaus nur 2 Byte auf den Stack pushen:
Code: Alles auswählen
Global X4.l
!mov [v_X4],esp
Debug X4 ;Stackpointer vor den Operationen
!push word(23) ;Opcode : 66681700
!mov [v_X4],esp
Debug X4 ;Stackpointer nach pushen eines Words nur -2!
!push dword(23) ;Opcode : 6817000000
!mov [v_X4],esp
Debug X4 ;Stackpointer nach pushen eines Double-Words hier -4!
Da hilft nur den Opcode zu manipulieren, aber der muss in der Länge stimmen! Auffüllen kann man ja, aber kürzen...
Gruss
Helle

Verfasst: 20.11.2006 18:28
von Eric
Wie gesagt, es gibt ein push für 16bit, wie ich aber gerade festgestellt hab,
wird es von Olly nicht als Push word, sondern nur als Push dargestellt.
16 und 32bit Push unterscheiden sich nur durch ein Präfix.
Code: Alles auswählen
68 00000000 PUSH 0 ;normales 32bit Push.
6A 00 PUSH 0 ;kompaktes 32bit Push.
66:68 0000 PUSH 0 ;normales 16bit Push.
Verfasst: 20.11.2006 19:19
von Thorium
Helle hat geschrieben:Man kann durchaus nur 2 Byte auf den Stack pushen:
Da hilft nur den Opcode zu manipulieren, aber der muss in der Länge stimmen! Auffüllen kann man ja, aber kürzen...
Jo stimmt, das Problem hab ich aber zum gottseidank net. Ich patche kein Push sondern habe mein eigenes eingefügt. Also ich hab alten Code rausgeschmissen und dafür neuen Code eingefügt. Hab eine Prozedur komplett neu geschrieben. Die hat eine verschlüsselte Ressource geladen und entschlüsselt. Ich wollte aber das die Daten aus einer Datei, die nicht verschlüsselt ist geladen werden. Funzt auch einwandfrei, sind nur ein paar API-Aufrufe.
Es handelt sich dabei um das Spiel Sacred Underworld. Ich will das die Global.res von der Platte geladen wird. Da stehen alle Texte drinnen, die im Spiel erscheinen. Dadurch das die Datei nun von der Festplatte geladen wird und nicht aus einer binären Ressource der .exe, kann man nun endlich die Texte im Spiel verändern. Wieder einen Schritt weiter in Sachen Modding.
Hier mal mein Code:
Bin für Hinweise und Verbesserungsvorschläge sehr dankbar, da ich absoluter Assembler-Anfänger bin. Die Prüfung ob die Datei überhaupt geladen werden konnte, kommt noch.
Code: Alles auswählen
mov ebx,ecx ;Speicheradresse der Global.res für spätere Verwendung sichern
;CreateFile aufrufen um die Global.res zu öffnen
push 0 ;hTemplateFile (nix)
push 0 ;dwFlagsAndAttributes (nix)
push 3 ;dwCreationDisposition (OPEN_EXISTING)
push 0 ;lpSecurityAttributes (nix)
push 0 ;dwShareMode (kein Sharing der Datei)
push 80000000 ;dwDesiredAccess (GENERIC_READ)
push 0012FE38 ;lpFileName (Pointer zum Global.res-Pfad)
call [0088E244] ;Kernel32.CreateFile
mov ebp,eax ;Filehandle sichern
;Größe der Global.res per GetFileSize bestimmen
push 0 ;lpFileSizeHigh (nix)
push ebp ;hFile (Filehandle)
call [0088E1D8] ;Kernel32.GetFileSize
mov esi,eax ;Dateigröße sichern
;Sacred-Prozedur aufrufen um Speicher für die Global.res zu allokieren
push esi ;nSize (benötigte Speichermenge)
call 008485E2 ;Speicher allokieren
mov [ebx],eax ;Speicheradresse in Variable sichern
;ReadFile aufrufen um die Global.res in den Speicher zu laden
push 0 ;lpOverlapped (nix)
push 0012FE44 ;lpNumberOfBytesRead (Pointer zur Variable)
push esi ;nNumberOfBytesToRead (Größe der Global.res)
mov eax,[ebx] ;Speicheradresse für Global.res nach eax hohlen
push eax ;lpBuffer (Adresse wo die Global.res hingeladen werden soll)
push ebp ;hFile (Filehandle)
call [0088E1D4] ;Kernel32.ReadFile
;CloseHandle aufrufen
push ebp ;hObject (Filehandle)
call [0088E24C] ;Kernel32.CloseHandle