PE Infektion

Aehm ja, so ungefaehr. Ist zwar nicht zu 100% richtig, das ganze ist ein klein wenig komplexer, aber falsch ist es auch nicht.
 
Das bedeutet, dass wenn ich den EP auf meinen angehängten Code setze, die CPU über alle Sections hinwegliest wie wenn es nur Funktionen wären, bis sie zu meinem angehängten Code mit dem neuen EP gelangt, und dann mit der Ausführung anfängt, richtig??
Die CPU "liest" nichts ein und überlegt es sich auch nicht, dass es nur Funktionen sind - nach dem WindowsPE Loader die Exe in den Speicher geladen hat, ließt er den EntryPoint Wert aus und setzt den EIP Register auf diesen Wert. Damit beginnt die Ausführung des Codes auch erst an dieser Stelle.
http://de.wikipedia.org/wiki/EIP#Spezialregister
Sorry, aber ich frag mich ernsthaft, ob du auch etwas anderes als die Forenbeiträge hier liest? Wie wäre es mit einem Asm-Buch ? Denn hier werden Sachen z.T zum 4 mal wiederholt und irgendwie habe ich immer mehr den Eindruck, dass du versuchst die ganzen Grundlagen hier aus den Postings zu herauszulesen. Das wird so nicht wirklich funktionieren.
 
RE: Ep

Ah..jetzt hab ichs verstanden...

D.h., dass die "Befehle" vor dem EP nur beispielsweise Funktionen sind, welche noch nichts ausführen ,da sie erst aufgerufen werden müssen (was dann im Codeabschnitt nach dem EP passiert, oder?), oder?

Das bedeutet, dass wenn ich den EP auf meinen angehängten Code setze, die CPU über alle Sections hinwegliest wie wenn es nur Funktionen wären, bis sie zu meinem angehängten Code mit dem neuen EP gelangt, und dann mit der Ausführung anfängt, richtig??

Grüße
Gapa
Ich glaube du hast das Prinzip nicht verstanden. Du siehst das ganze noch viel zu sehr als Hochsprache an. ASM ist vom Grundsatz her viel simpler aufgebaut, als z.b. C++. Das macht dann einfach den Code viel komplexer. Es gibt keine eigentlichen Funktionen...

Und das der Code auch nur ein Bytehaufen ist, und einfach nach und nach abgearbeitet wird. Egal wohin der EP zeigt.
 
Als was würdest du denn add, mov, etc. bezeichnen, wenn nicht als Funktion?
Sie unterscheiden sich etwas von den Funktionen der Hochsprachen, aber das Prinzip ist eigentlich sehr ähnlich.
 
add, mov und konsorten sind nicht wirklich mit funktionen gleichzusetzen. Funktionen in Hochsprachen bestehen aus einigen (manchmal tausenden) Prozessorbefehlen, wogegen add, mov, etc eben diese Prozessorbefehle darstellen. Als chemisches Analogon könnte man add, mov und so weiter mit Atomen gleichsetzen und Funktionen mit Molekülen. Funktionen sind unendlich komplizierter und leistungsfähiger als ihre einzelnen Bestandteile.
 
Code einbetten

Hallo (hoffentlich bald das letzte mal in diesem Thread^^),

ich denke, dass mir xrayns Link zur msdn - Doku dazu das letzte Verständnis vermittelt hat.

Ich habe mir nun zwei Programme erstellt (Wirt.exe / Anhängsel.exe) und die wichtigen Infos aus ihnen ausgelesen:

Wirt.exe
Code:
.386
.model flat,stdcall 
option casemap:none 
include \masm32\include\windows.inc 
include \masm32\include\kernel32.inc 
includelib \masm32\lib\kernel32.lib 
include \masm32\include\user32.inc 
includelib \masm32\lib\user32.lib  

.data 
MsgBoxCaption  db "Wirt",0 
MsgBoxText       db "Ich bin der Wirt",0  

.code 
start: 
invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, NULL 
invoke ExitProcess, NULL 
end start

Anhängsel.exe
Code:
.386
.model flat,stdcall 
option casemap:none 
include \masm32\include\windows.inc 
include \masm32\include\kernel32.inc 
includelib \masm32\lib\kernel32.lib 
include \masm32\include\user32.inc 
includelib \masm32\lib\user32.lib  

.data 
MsgBoxCaption  db "Anhaengsel",0 
MsgBoxText       db "Ich bin das Anhaengsel",0  

.code 
start: 
invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, NULL 
invoke ExitProcess, NULL 
end start

Im HexEditor habe ich nun die wichtigen Daten ausgelesen:
- ImageBase (Wirt.exe)
- SizeOfImage (Wirt.exe)
- NumberOfSections (Wirt.exe)
- OEP
- VirtualSize (letzte Section) (Wirt.exe)
- VirtualAdress (letzte Section) (Wirt.exe)
- SizeOfRawData (letzte Section) (Wirt.exe)
- VirtualSize aller Sections (Anhängsel.exe)

Wenn ich nun alle VirtualSizes der Sections von Anhängsel.exe addiere, dann habe ich ja die Größe des einzufügenden Codes, richtig?

Nun habe ich die 4 wichtigen Werte in Wirt.exe angepasst:

1. OEP = VA der letzten Section + VS der letzten Section
2. SizeOfImage = SizeOfImage + VirtualSize aller Sections von Anhängsel.exe
3. VirtualSize (letzte Section) = VirtualSize + VirtualSize aller Sec. von Anhängsel.exe
4. SizeOfRawData = SizeOfRawData + VirtualSize aller Sec. von Anhängsel.exe

Da nun alle Vorkehrungen getroffen waren, habe ich den einzufügenden Code ab PointerToRawData der 1. Section (also Anfang 1. Section) bis zum Dateiende kopiert und einfach an Wirt.exe angehängt.

Meine Fragen:

1.
Habe ich nun einen Fehler gemacht oder stimmt das alles so??

2.
Wenn ich nun ans Ende meines Codes den JMP-Befehl zum eigentlichen EP schreiben will: JMP 00401000
dann kommt die Fehlermeldung, dass ich nur zu Labels springen kann, nicht jedoch zu Adressen...was mache ich nun?

Sorry, aber ich frag mich ernsthaft, ob du auch etwas anderes als die Forenbeiträge hier liest? Wie wäre es mit einem Asm-Buch ? Denn hier werden Sachen z.T zum 4 mal wiederholt und irgendwie habe ich immer mehr den Eindruck, dass du versuchst die ganzen Grundlagen hier aus den Postings zu herauszulesen. Das wird so nicht wirklich funktionieren.
Ich hoffe du kannst wenigstens ein bisschen erkennen, dass ich Eigeninitiative zeige...
Ich habe mich wirklich ausführlichst mit den meisten hier geposteten Links auseinandergesetzt und versucht, logische Schlüsse daraus zu ziehen. Aber es ist doch manchmal wirklich enttäuschend nachher zu erkennen, dass man alles falsch verstanden hat... :(
Wie du siehst habe ich mich nun daran versucht und HOFFE, HOFFE wirklich darauf, dass ich diesmal nichts falsch gemacht habe!! Ich bitte nun nur noch um Hilfe bis ich dieses "Projekt" (besser: Hürde) endlich hinter mich gebracht habe!

Viele Grüße
Gapa
 
Nein so klappt das nicht. Man kann nicht einfach 2 Datei zusammenpacken.

http://vx.netlux.org/src_view.php?file=anthrax_iac.zip

Lies den Sourcecode, der ist einfach zu verstehen, da der Virus nichts besonderes kann und google nach PE infection, virus source usw. Es gibt im Netz genug Sourcecode, Beispiele und Erklaerungen, sodass man das auch so lernt, sollte schaffbar sein, ich hab es auch auf diesen Weg hinbekommen.
 
...

Hallo,

sorry aber aus diesem Link werde ich überhaupt nicht schlau...
Der Virus ist ja ne Millionen Zeilen lang.

Warum geht das mit dem Infizieren nicht so wie ich es beschrieben habe?

Grüße
Gapa
 
von "Anhängsel.exe"
invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, NULL

Wie soll denn die Adresse von MessageBoxA in die IAT von "Anhängsel.exe" kommen, wenn sie nicht vom PE-Loader ausgefuellt wird?!

Der Virus ist ja ne Millionen Zeilen lang.
Ja so ne PE-infection ist halt was anderes als 2 Dateien zusammenfuegen!

Letzter Link und Post, ich habe auch langesam das Gefuehl, dass du dir die Grundlagen mit den Thread aneignen willst. Alles was du wissen wilst/musst, steht irgendwo im Internet und ist per Goolge auffindbar!
http://www.codeproject.com/KB/system/inject2exe.aspx
 
@farhaven
Ich habe nie gesagt, dass eine Assembler Funktion (auch Prozessorbefehl) dasselbe ist wie eine Funktion der Hochsprache, aber Prozessorbefehle können ebenfalls als Funktionen bezeichnet werden. Die Funktionen in der Hochsprache wurden sogar auf dem Prinzip der ASM-Funktionen aufgebaut und sie lassen sich auch deshalb mit einer hochsprache sehr einfach nachmachen, auch wenn dann natürlich mehrere Prozessorfunktionen benutzt werden müssen um die selbe Funktionsweise in der Hochsprache zu erhalten.
 
PE Infection

Hallo mal wieder,

also ich habe mich nun auf jeder erdenklichen Internetseite über das Thema PE-Format, PE-Infection etc. erkundigt und kann nun fast das komplette PE-Format auswendig!!

Ich werde nun (so wie mein aktueller Wissensstand ist) in einzelnen Schritten erläutern, wie man 2 kompilierte EXE mit nur einem HexEditor zur Hilfe ineinander fügt:

1. Wirt.exe im HexEditor öffnen
2. PE auslesen (an 0x03c)
3. Anzahl Sections auslesen (an PE + 0x6)
4. EntryPoint auslesen ( PE + 0x28 )
5. Image-Base auslesen (PE + 0x34)
6. OEP ausrechnen (Image-Base + EP)
7. SizeOfImage auslesen
8. Letztes Section-Table-Array suchen, und:
- VirtualSize (DWORD)
- VirtualAdress (DWORD)
- SizeOfRawData (DWORD)
auslesen

9. Anhang.exe im HexEditor öffnen
10. Größe von Anhang.exe ermitteln:
- Section-Table auslesen
- Alle VirtualSizes addieren
11. Wirt.exe modifizieren:
- SizeOfImage = SizeOfImage + Größe von Anhang.exe
- VirtualSize (letzte Section) = VirtualSize + Größe von Anhang.exe
- SizeOfRawData (letzte Section) = VirtualSize + Größe von Anhang.exe (gerundet, so dass Alignment im OptionalHeader durch den Wert teilbar ist)
- OEP = VirtualAdress (letzte Section) + Größe von Anhang.exe
- Characteristics (letzte Section) auf executable setzen

12. Alle Sections von Anhang.exe im Hexeditor markieren, kopieren und an die letzte Section von Wirt.exe anhängen


Hier nochmal zusammengefasst alle Werte, die im Hexeditor ausgelesen / modifiziert werden müssen:

Auslesen:
Wirt.exe
- PE
- AnzahlSections
- EP
- ImageBase
- SizeOfImage
- SectionArray der letzten Section:
> VS
> VA
> SizeOfRawData

Anhang.exe
- VS aller Sections

Modifizieren:
Wirt.exe
- EP
- SizeOfImage
- SectionArray der letzten Section:
>VS
>SizeOfRawData
>Characteristics


Das soll nur den "Injektionsvorgang" schildern, das Suchen nach API-Funktionen kommt später (sobald dieses Problem hier aus dem Weg ist!!).

Könnt ihr mir nun bitte sagen, ob (wenn ja, was?) ich vergessen habe und was falsch ist so wie ich es beschrieben habe??

Und (das soll nun wirklich nicht unhöflich klingen!!) bitte postet nicht einfach wieder einen weiteren Link der mir nicht exakt eine Antwort auf mein Problem liefert (ich wäre ja froh wenn gar kein Link mehr gepostet werden würde, sondern einfach schlicht dieses Thema zufriedenstellend abgeschlossen werden kann nach dieser Ewigkeit!).

Ich wäre WIRKLICH FROH über eine Antwort, die mich zum langersehnten Ziel bringen würde!!

Viele Grüße
Gapa
 
RE: PE Infection

Original von Gapa
Ich werde nun (so wie mein aktueller Wissensstand ist) in einzelnen Schritten erläutern, wie man 2 kompilierte EXE mit nur einem HexEditor zur Hilfe ineinander fügt
<--- bevor du dich da vertust (und das tut sehr man schnell), würde ich einen PE-Editor (PE-Tools oder LordPE) nehmen - zumindest um eine "Gegenprobe" zu haben.

9. Anhang.exe im HexEditor öffnen
10. Größe von Anhang.exe ermitteln:
- Section-Table auslesen
damit bekommst du nur die "virtual Size" der Sectionen heraus!
D.h wenn du Code aus einem Hexeditor herauskopierst, brauchst du auch die physikal Size (SizeOfRawData).

11. Wirt.exe modifizieren:
- SizeOfImage = SizeOfImage + Größe von Anhang.exe
nicht vergessen, den Wert zu alignen:
SizeOfImage
The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of SectionAlignment.
Wenn die Linker unterschiedliche SectionAlignments verwendet haben (also vom Wirt und Anhang.exe) könnte man sonst Probleme bekommen.

- SizeOfRawData (letzte Section) = VirtualSize + Größe von Anhang.exe (gerundet, so dass Alignment im OptionalHeader durch den Wert teilbar ist)
also: wenn du SizeOfRawData == VirtualSize setzt, musst du auch vorher schauen, dass du die Bytes zu diesem Wert auffüllst. Denn SizeOfRawData kann durchaus kleiner/größer (in 99% kleiner) sein.
Den Wert SizeOfRawDate setzt man normalerweise dem VirtualSize Wert gleich, wenn man einen Speicherdump erstellt (sprich, laufendes Programm dumpt) - da wurden die Bytes beim laden schon automatisch aufgefüllt.

In deinem Fall: wenn man im Hexeditor arbeitet, muss man darauf achten, wie groß SizeOfRawData ist. du könntest stattdessen versuchen:
SizeOfRawData=SizeOfRawData+physikalische Größe des angehängten Codes.

- OEP = VirtualAdress (letzte Section) + Größe von Anhang.exe
nicht vergessen - dann muss deine "main" bzw. Codeanfang auch ganz am Anfang der Anhang.exe sein. Hat man in MASM/TASM/FASM "automatisch".
- Characteristics (letzte Section) auf executable setzen
jep, aber ohne die anderen zu überschreiben ;).
je nach dem was dein Code macht (daten lesen,schreiben) noch "write"/"read" setzen.
Alternativ diesen Wert reinschreiben:0xE0000020 (das ist eine "fertige" Bitmaske, die besagt: Executeable,writeable,readable).


Anhang.exe
- VS aller Sections
wie erwähnt: wenn du mit Hexeditor kopieren willst, brauchst du auch die physicalische Größe.

Also kurz zusammengefasst:
- SectionArray der letzten Section:
>VS =alter VS+VS der eingefügten Sections aus der Anhang.exe + algigning Checken
>SizeOfRawData = alter SoRData+SORData der eingefügten Sections+ Aligning Checken
>Characteristics

Der Rest sieht ok aus.
Nicht vergessen auf little Endian zu achten. Wie gesagt, nach der modifizierung einfach mal im LordPE öffnen und schauen, ob die Werte so sind, wie du die haben wolltest.

Als Tipp: schreibe die Anhang.exe erstmal in Masm. Wenn du den Code dann so assemblierst und linkst:
e:\masm32\bin\ml /c /coff /nologo program.asm
E:\masm32\bin\Link /NOLOGO /SUBSYSTEM:WINDOWS /MERGE:.rdata=.text /MERGE:.data=.text /section:.text program.obj /section:.text,RWE
erhälst du schon mal eine Exe mit nur einer Section.Sollte weniger Probleme geben (und weniger zu berechnen sein ;) )
 
Hallo,

Ha! Das hört sich doch schon mal gut an!! Endlich mal ein Schritt vorwärts :D

Jetzt habe ich nur noch ein Problemchen (wahrscheinlich ist es gar kein Problem, sondern nur eine Vermutung auf die ich Bestätigung suche^^).

Mit "Alignment" sind schon die Rundungen gemeint, oder? Da gibt es ja so ein FileAlignment, welches ja immer ein Mehrfaches von SizeOfRawData ist, sprich: Man kann FileAlginment durch SizeOfRawData dividieren.
Und das ist bei SizeOfImage etwa genau so?

Das bedeutet also, ich muss nur schauen, ob sich SizeOfImage von Wirt.exe durch alle SizeOfRawDatas von Anhang.exe addiert teilen lässt, oder? Und wenn das nicht der Fall sein sollte, muss ich dann SizeOfImage angleichen oder muss ich SizeOfRawData angleichen? Ich werde wohl wahrscheinlich SizeOfImage auf die nächsthöhere Zahl runden müssen, durch die man die Anhang.exe-SizeOfRawDatas teilen kann, oder?
Meine Frage hier ist nur: aufrunden oder abrunden??
Wenn ich abrunden würde, dann könnte es doch passieren, dass SizeOfImage zu klein wird.

Und was ich auch gelesen habe, ist, dass VS die orginale Größe des Codes ist, und SizeOfRawData die gerundete -> dann muss SizeOfRawData aber doch größer sein als VS, nicht kleiner, sonst gäbe es ja Platzprobleme. Wieso schreibst du dann, dass SizeOfRawData zu 99% kleiner ist?

Also hier noch einmal alle Werte, die modifiziert werden müssen:
SizeOfImage = SizeOfImage + alle SizeOfRawDatas der Sections von Anhang.exe
OEP = VA der letzten Section + alle SizeOfRawDatas der Sections von Anhang.exe
Letzte Section:
- VS = VS + alle VS der Sections von Anhang.exe (+ Aligning checken ??)
- SizeOfRawData = SizeOfRawData + alle SizeOfRawDatas der Sections von Anhang.exe (+ Aligning checken ??)
- Characterstics = 0xE0000020

Also mir fehlt jetzt nur noch die Antwort auf die Frage mit dem Aligning checken:
- Was genau ist damit gemeint (runden - auf - ab) ?
- Bezieht sich das nur auf SizeOfImage

Wenn sonst alles ok ist, dann bin ich ja schon mal sehr zufrieden!
Viele Grüße
Gapa
 
Mit "Alignment" sind schon die Rundungen gemeint, oder? Da gibt es ja so ein FileAlignment, welches ja immer ein Mehrfaches von SizeOfRawData ist, sprich: Man kann FileAlginment durch SizeOfRawData dividieren.
Andersrum. SizeOfRawData "richtet" sich nach FileAlignment Wert. FileAlignment besagt, dass die Größe ein Vielfaches von diesem Wert sein muss. Bsp:
FileAlignment=512. SizeOfRawData kann nun 512,1024,1536,2048 usw. sein.
SizeOfImage muss nun einen Wert haben, der ein Vielfaches von SectionAlignment ist.
D.h nichts teilen, sondern nur schauen, dass es ein Vielfaches von SectionAlignment ist.
Afaik verwenden die meisten Linker für SectionAlignment den Defaultwert von 4096, so dass man sich den Check auch sparen kann (denn vor dem Hinzufügen ist SizeOfImage ja aligned - also ein Mehrfaches von 4096, wenn man nun VS einer Section hinzuaddiert, die auch schon an 4096 ausgerichtet war, ist der neue Wert "automatisch" aligned.
Meine Frage hier ist nur: aufrunden oder abrunden??
natürlich auf, die Erklärung warum hast du ja schon selbst gegeben ;)


Und was ich auch gelesen habe, ist, dass VS die orginale Größe des Codes ist, und SizeOfRawData die gerundete
VS ist die Größe der Section im Speicher. "Raw" ist die Größe in der Datei. Wenn VS>SizeOfRawData, wird die Differenz im Speicher mit 00 ausgefüllt. Wenn SizeOfRawData>VS, wird ein Teil der Daten "abgeschnitten" - also nicht geladen.
Zitat von pecoffv8.doc
VirtualSize
The total size of the section when loaded into memory. If this value is greater than SizeOfRawData, the section is zero-padded. This field is valid only for executable images and should be set to zero for object files.
d.h es kann physikalisch sogar 0 sein und der Speicher wird dann so zusagen erst beim laden der Exe reserviert.

Also hier noch einmal alle Werte, die modifiziert werden müssen:
SizeOfImage = SizeOfImage + alle SizeOfRawDatas der Sections von Anhang.exe
OEP = VA der letzten Section + alle SizeOfRawDatas der Sections von Anhang.exe
Letzte Section:
- VS = VS + alle VS der Sections von Anhang.exe (+ Aligning checken ??)
- SizeOfRawData = SizeOfRawData + alle SizeOfRawDatas der Sections von Anhang.exe (+ Aligning checken ??)
- Characterstics = 0xE0000020
Du bringst "virtuelle" und "physikalische" Werte durcheinander:
SizeOfImage=SizeOfImage+VS der hinzugefügten Sections+Align
Beim OEP verstehe ich nicht, wie du darauf kommst. Wo genau der EntryPoint ist, kommt auf den Code an. Wenn man MASM programmiert, hat man diesen direkt am Anfang (sieht man auch in Olly immer).
Wenn man nun zur letzten Section Code hnzufügt und dieser ab der erster Stelle ausgeführt werden soll, ergibt sich der neue EntryPoint Wert für den Wirt aus:

VA der letzten Section+alter SizeOfRawData Wert. Warum hier SizeOfRawData verwendet wird? Der Wert sagt ja praktisch, wo die Section in der Datei nun endet - da man den Code im Hexeditor ans Ende der Section kopiert braucht man sich nur an diese Angaben zu halten.

Also mir fehlt jetzt nur noch die Antwort auf die Frage mit dem Aligning checken:
- Was genau ist damit gemeint (runden - auf - ab) ?
- Bezieht sich das nur auf SizeOfImage
Aufrunden.
Bezieht sich auf SizeOfImage, SizeOfRawData, StartAdresse der Sections (sofern man neue anlegt).
 
Hallöle,

***Editiert***

Ich habe nun herausgefunden, dass es an dem MessageBox-API-Funktionsaufruf lag, dass mein Anhang.exe nicht funktioniert hat!

Ich habe Anhang.exe wie folgt umgeschrieben:
Code:
.386
.model flat,stdcall
.code
start:
MOV EAX, 00401000
JMP EAX
end start
Es funktioniert!! Hoffe ich zumindest! Denn ich weiß nun nicht, ob er meinen Anhang.exe überhaupt ausgeführt hat oder ob er einfach nur das Hauptprogramm ausgeführt hat^^

Deshalb nun gleich die nächste Frage:
WIE ist es möglich, API-Funktionen benutzen zu können (im Anhang.exe) ??

Viele Grüße
Gapa
 
um zu testen ob es funktionier, kann man einen Debugger nutzen (bei dem ganzen Injectionskram ist es sowieso Pflicht) ;)
API:
am einfachsten ist erstmal, im Debugger nachzuschauen, wo die API Adressen des Wirts hinterlegt sind.
Meistens stehts in so einem Format (ollydbg):
Code:
00402EBB   .  FF15 14504000 CALL DWORD PTR DS:[<&kernel32.CreateFile>; \CreateFileA
Naja, Olly löst die Sachen schon automatisch auf und zeigt dann die Zielfunktionen an, aber wenn man auf die Zeile doppelklickt oder (wenn die Zeile markiert ist), Leertaste betätigt, erscheints es "as is" -
Code:
CALL DWORD PTR DS:[405014]
also in diesem Fall geht der indirekte Call auf 405014. Die Adresse der API steht also in 405014.
d.h man kann nun im Injectionscode erstmal schreiben:
Code:
386
.model flat,stdcall
.code
start:

push 0
push 0
push 0
push 0
call  DWORD PTR [405014] <- oder welcher Wert das in der Wirt exe auch sein mag.
MOV EAX, 00401000
JMP EAX
end start
um auch mal einen Text ausgeben zu können, muss man ein wenig Tricksen - die API erwartet ja Adressen der Strings. Die Adressen kennt man aber erstmal nicht, da der code injeziert wird und sich dadurch alles ändert. Also behilft man sich mit einem delta-call:
Code:
386
.model flat,stdcall
.code
start:
jmp code_   
    Message db "Hi",0
  code_:
       call delta
	delta:	
        ;Stackherrichten
	pop ebp <--- nun in EBP die adresse von delta - label
       mov eax,ebp
       sub eax,(delta-Message)
      push 0
     push 0
     push eax
     push 0
     call dword ptr [herausgefundene API adresse]
MOV EAX, 00401000
JMP EAX
end start
kleine Erklärung warum das in etwa so funktioniert:
beim Call wird die Rücksprungadresse auf dem Stack abgelegt.
wenn man nun statt mit einem RET zurückzukehren, die Adresse vom Stack holt, hat man die "aktuelle" Position im Code (und zwar die Position von "delta"). Nun muss man von dieser Position einen bestimten Wert abziehen und hat die Position des Strings.
Den "bestimmten Wert" lässt man einfach den Assembler ausrechnen, indem man schreibt (LABEL1-LABEL2) <-- der Assembler ersetzt bei der Assemblierung die Labelnamen durch Adressen, berechnet das Ergebnis und schreibt dieses in die Anweisung.

"call delta" funktioniert deshalb, weil dies ein "direkter" Call ist - dabei wird nicht die Zieladresse, sondern der Abstand von der Aktuellen zur Zieladresse angegeben.
Man schreibt zwar meistens CALL LABEL/FUNKTION - vom Assembler wird es dann trotzdem als CALL 0000020 (falls der Abstand=20 ist) übersetzt.
D.h diese Form des Calls ist nicht an feste Adressen gebunden und kann im adressunabhängigem Code benutzt werden.

Alternativ kann man es auch selber ausrechnen: ein direkter Call "label" ist 5 Bytes groß.Unsere Nachricht ist nochmal 3 Bytes groß. Also muss man von der Delta-Adresse 8 abziehen und bekommt die Adresse des Strings raus.
Somit schreibt man dann
Code:
 call delta
	delta:	
	pop ebp <--- nun in EBP die adresse von delta - label
       mov eax,ebp
       sub eax,8
      push 0
     push 0
     push eax
     push 0
     call dword ptr [herausgefundene API adresse]
allerdings ist es einfacher, die Adresse durch Labels berechnen zu lassen ;)
 
Wow!
Super! Das macht ja sogar Sinn!! :D Ich denke langsam habe ich den Dreh raus!!

Das mit den APIs wird auch denke ich nicht so das Problem (um jedoch mal den Mund nicht zu voll zu nehmen^^), was mich mehr schockt ist eine Entdeckung, welche ich gerade beim Debuggen meiner infizierten Wirt.exe im Olly gemacht habe:
Ich hatte vergessen, den EP umzuleiten und er zeigte noch auf das Hauptprogramm -> deshalb funktionierte alles!! Als ich ihn dann umlenkte, kamen die üblichen Fehlermeldungen wieder X(

Ich würde dir jetzt mal die Daten für die 2 Dateien geben und dich bitten, mal nachzurechnen und die von mir bereitgestellten modifizierten Daten zu überprüfen bzw. zu ergänzen (das soll nur eine BITTE sein und ich wäre dir sehr verbunden!):

Wirt.exe:
Code:
.386 
.model flat,stdcall 
option casemap:none 
include \masm32\include\windows.inc 
include \masm32\include\kernel32.inc 
includelib \masm32\lib\kernel32.lib 
include \masm32\include\user32.inc 
includelib \masm32\lib\user32.lib  
.data 
MsgBoxCaption  db "Wirt",0 
MsgBoxText       db "Gut",0  
.code 
start: 
invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, NULL 
invoke ExitProcess, NULL 
end start
SizeOfImage : 00004000
ImageBase : 00400000
EntryPoint : 00001000
Orginal EntryPoint : 00401000
FileAlignment : 00000200
SectionAlignment : 00001000
NumberSections : 0003
Section 1:
- VA : 00001000
- VS : 00000026
- SiOfRaDa : 00000200
Section 2:
- VA : 00002000
- VS : 00000092
- SiOfRaDa : 00000200
Section 3:
- VA : 00003000
- VS : 00000009
- SiOfRaDa : 00000200
- Characteristics : C0000040



Anhang.exe
Code:
.386 
.model flat,stdcall  
.code 
start: 
MOV EAX, 00401000 
JMP EAX end start
SizeOfImage : 00002000
ImageBase : 00400000
EntryPoint : 00001000
Orginal EntryPoint : 00401000
FileAlignment : 00000200
SectionAlignment : 00001000
NumberSections : 0001
Section 1:
- VA : 00001000
- VS : 00000007
- SiOfRaDa : 00000200



Und hier die modifizierten Werte in Wirt.exe (so wie sie eig. sein sollten, aber so läuft das Programm nicht!!):


SizeOfImage : 00004007
ImageBase : 00400000
EntryPoint : 00003200
Orginal EntryPoint : 00403200
FileAlignment : 00000400 <-----muss ja mind. 400 sein, da die letzte Section ja nun 400 Bytes groß ist
SectionAlignment : 00001000 <---- wie soll das jemals mit SizeOfImage übereinstimmen??????
NumberSections : 0003
Section 1:
- VA : 00001000
- VS : 00000026
- SiOfRaDa : 00000200
Section 2:
- VA : 00002000
- VS : 00000092
- SiOfRaDa : 00000200
Section 3:
- VA : 00003000
- VS : 00000010
- SiOfRaDa : 00000400
- Characteristics : E0000020



Könntest du CDW anhand der vorliegenden Daten (grün) überprüfen, ob die daraus geschlossenen modifizierten Daten (rot) alle stimmen??

Viele Grüße
Gapa
 
Original von Gapa

Code:
.386 
.model flat,stdcall  
.code 
start: 
MOV EAX, 00401000 <--- hier fehlt ein h für Hexadezimal, er spring sonst zu 0x6xxirgendwas
JMP EAX end start

Und hier die modifizierten Werte in Wirt.exe (so wie sie eig. sein sollten, aber so läuft das Programm nicht!!):


SizeOfImage : 00004007 <-- aufrunden auf den nächsten Wert =0x5000


FileAlignment : 00000400 <-----muss ja mind. 400 sein, da die letzte Section ja nun 400 Bytes groß ist
FileAlignment ist der "Richtwert" - den sollte man nicht ändern!

SectionAlignment : 00001000 <---- wie soll das jemals mit SizeOfImage übereinstimmen??????
in dem man die aktuelle ImageSize berechnet (bei dir z.b 0x4007) und
bis zum nächsten, durch 0x1000 teilbaren Wert auffüllt = 0x5000




NumberSections : 0003
Section 1:
- VA : 00001000
- VS : 00000026
- SiOfRaDa : 00000200
Section 2:
- VA : 00002000
- VS : 00000092
- SiOfRaDa : 00000200
Section 3:
- VA : 00003000
- VS : 00000010
<--- hier VS mindestens auf den alten SizeOfRawData+Größe des eingefügten Codes ändern - sonst lädt der PE-Loader auch nur 10 Bytes aus dieser Section. Also neuer Wert wäre: 0x000207, oder gleich 0x0000400 (falls man insgesamt 200 Bytes rüberkopiert hat hat). Wenn dieser Wert > tatsächlich vorhandene Bytes, ist es nicht so schlimm, da der Rest mit 00 aufgefüllt wird.



Häng doch einfach die Exen an, damit man schauen kann, wo der Fehler liegt.
 
PE Infection

Hallo CDW,

ok ich habe es mal versucht, SizeOfImage auf 5000 aufzurunden, aber dann lässt sich das Programm gar nicht mehr öffnen, sondern es kommt eine Fehlermeldung, dass das Programm keine gültige Win32-Anwendung sei!
Ist ja eig auch logisch, da SizeOfImage ja nun viel größer ist als es sein sollte - > welche Werte muss ich dann noch erhöhen um alles wieder ins Gleichgewicht zu bringen??

Und warum setzt LordPE den SizeOfImageWert immer automatisch sogar noch kleiner als der ursprüngliche? wenn ich Wirt.exe das erste Mal mit LordPE öffne, dann ist der SizeOfImage-Wert 00004000 -> füge ich nun Code hinzu (also vergrößere die Section mit LordPE), dann setzt er SizeOfImage sogar zurück auf ähm glaube 00003400...aber wieso??

>>>>EDIT:<<<<

Hat sich erledigt :D
Ich hatte dein Kommentar zu meinem JMP-Befehl überlesen....Der einzige Fehler war das "h" :D :D

Aber dennoch würde ich gern wissen, wieso er das mit dem SizOfImage so macht und 00005000 nicht zulässt...

Viele Grüße
Gapa

Viele Grüße
Gapa
 
ok ich habe es mal versucht, SizeOfImage auf 5000 aufzurunden
ok, ich hab mich verrechnet ;)
der Wert ist ja schon aufgerundet - und die Gesamtgröße, auch mit hinzugefügtem Code bleibt unter 4000.
Zu LordPE: der setzt den Wert auf "letzte Section VA+VS+Headersize(1000)". Eigentlich nicht ganz korrekt - aber (das wäre ein weiterer Punkt) der PE-Loader ist z.T sehr fehlertolerant. Das sieht man insbesondere bei einigen Protectoren - diese nutzen es aus und schreiben z.T sehr extravagante Werte rein wie riesige VS Werte, falsche CodeSize Werte usw. (Zweck: Debugger/Disassembler verwirren). Die Fehlertoleranz hat natürlich auch viele Nachteile (von der Disassemblersiete aus) - man kann z.B die Werte wie BaseOfCode und SizeOfCode nicht nutzen, um herauszufinden, wie der Codebreich ist (die Werte werden scheinbar gar nicht ausgewertet - man kann in BaseOfCode auch 0xffffffff eintragen - es passiert nichts).

D.h auch wenn es so funktioniert - solltest trotzdem die FileAligning Werte nicht antasten und die VS korrekt setzen ;)

PS: hier mal ein Beispiel (im PE Header von Wirt.exe rumgespielt - siehe im LordPE (insbesondere die Directory Einträge):
Olly lagt beim durchsteppen (ok, bei dieser Codemenge merkt man es nicht wirklich :) )
IDA 4.9 hängt sich beim laden auf - aber die Exe läuft trotzdem.
 
Zurück
Oben