code von exe an code von anderen exe hängen? (c++)

Ich hab neulich von file viren gelesen. Die hängen sich ja bekanntlich in andere exe oder com dateien. jetzt hab ich mich gefragt wie man das mit c++ machen kann? jetzt bitte nicht denken ich will mir nen virus progn dafür bin ich viel zu dumm es interessiert mich einfach nur.
 
Da ich mich jetzt ne woche damit rumgeschlagen habe (ressourcen) ist es eigentlich kein problem mehr einen joiner/binder) zu schreiben.

Und son "Jede .exe File verseuch Virus" sollte auch kein problem sein,
ich schreibe mal die rohe theorie:


compiler/linker in den virus als ressourcen packen (mit headern etc pp was man brauch)
dann einer .exe die als infektion (böser code) dient.
dann funktion die die .exe'n sucht und dann immer son standard projekt compiliert
bsp: firefox.exe wird esetzt mit nem projekt wo der virus/infektion mit firefox gebunden wurde

also jedes mal die exe mit bösen code als ressourcen in eine neues programm packen und wenn man dann zB. mal firefox startet, wird firefox + der virus drinne gestartet (was auch immer der virus kann/macht.


Naja, is jetzt plumpe Theorie, ist auch wohl besser so, wir wollen ja net das jemand unfug macht^^


//Edit: mir fällt ein, nen icon "changer" ist auch sehr einfach realisierbar, einfach nen programm, was ne .exe laden kann und nen definiertes icon in die ressourcen packt und einfach die .exe startet.


mfg
 
Ich gehe mal von normalen Windows Executables aus.
Diese liegen im Portable Executable Format vor.
http://de.wikipedia.org/wiki/Portable_Executable
Nunja, die Erklärung in der deutschen Wikipedia ist recht klein.
Für eine genaue Beschreibung kommt man um google nicht herum - z.B von MS selbst,
http://www.x86.org/ftp/manuals/tools/pe.pdf
Tutorial von Iczelion und wohl vieles mehr.

Das Format beschreibt im Prinzip alles, was nötig ist - wo in der Datei der Code liegt, wo die Daten, wo die Ressourcen, wo der Codeanfang ist, welche externen Funktionen die Executable nutzt. Um zusätzlichen Code hinzuzufügen gibt es durchaus mehrere Wege.
Um die folgende Erklärung zu verstehen, kommt man nicht drum herum, sich vorher ein wenig in den PE-Format einzulesen ;)

Um eigenen Code einzufügen, müssen wir
1)Platz dafür schaffen
z.B in dem wir eine zusätzliche Section anhängen oder die letzte Section erweitern
2)den Entry Point Wert ("Codeanfangsadresse") auf unseren Code umbiegen und erst dann den alten Wert aufrufen (somit wird unser Code zuerst ausgeführt).
3)den Code schreiben,alle von uns geänderten Werte korrekt neu berechnen.


Also zuerst die nötigen Werte auslesen/anpassen - dafür muss man den PE-Header suchen:
Am Anfang der Exe gibt es noch die "Altlasten" - aus Kompatibilitätsgründen ein DOS-Exe-Header (um unter DOS die schöne Meldung "This program can not be run in DOS mode" auszugeben).
erst an Position 0x03C ist die Adresse des "neuen" Headers (PE) angegeben.
Geht man zu dieser Adresse, sieht man die zwei Buchstaben "PE".
Weitere Angaben sind relativ zu dieser Adresse (als PE+0x geschrieben)

In PE + 0x28 befindet sich der Entry Point
Dieser Wert (als RVA) gibt an, an welcher Adresse der "echte" Code anfängt.
Um die Codeadresse im laufenden Programm anzuspringen, müssen wir allerdings die VA kennen - und diese berechnet sich aus Imagebase + RVA Angabe.
Imagebase können wir an: PE+0x34 auslesen.
also OEP (original entry point)=Wert an [PE+0x34]+Wert an[PE+28]
zu diesem Wert muss unser Code irgendwann mal springen, sonst läuft die normale Andwendung nicht ;)


Um Platz zu schaffen, kann man die letzte Section vergörßern:

in PE+6 befindet sich die Anzahl der Sections (als WORD)
in PE+0xF8 findet man ein Section-Array vor.
Die Einträge sind 0x28 Byte groß und so aufgebaut:
Code:
+0 8byte ANSI name 
+8 dword virtual size
+C dword virtual address (an rva to where it should bee mapped)
10 dword sizeofrawdata 
14 dword pointerToRawData (file based offset)
18 dword pointerToRelocations
1C dword PointerToLinenumbers
20 word NumberOfRelocations
22 word NumberOfLineNumbers
24 dword Characteristics
Den Array Eintrag zu der letzten Section findet man also an:
Last_Sectinon_Info_begin = Wert an[PE+0xF8] + (SectionAnzahl-1)*0x28
Wir brauchen: virtual size, virtual address und sizeofraw data - diese Werte müssen wir anpassen.
also
Wert an [Last_section_info_begin+0x8]=alter Wert+code_size
Wert an [Last_section_info_begin+0x10]=alter Wert+code_size
und virtual_address_wert_für_später= [last_section_info_begin+0xC]


Jetzt kann man also den OEP in seinen Code einarbeiten und den Code dann ans Ende der Datei schreiben. Nun müssen noch der EntryPoint und der SizeofImage-Wert korrigiert werden:
Da wir den Code in die letzte Section hineingeschrieben haben (praktisch angehangen), sollte er beim Laden im Speicher auch als "angehangen" erscheinen. Wir finden ihn also "hinter" dem normalen Code - andersherum gesagt:
neuer_entry_point_wert = virtual_address_der_letzten_section+alte_virtual size_der_letzten_section (siehe etwas weiter oben).

Und SizeofImage (an PE+0x50) = alter Wert + code_size.

Ich gebe zwar keine Garantie, dass ich nicht etwas vergessen habe ;) - aber in etwa so sollte es laufen.
Das ist aber noch lange nicht alles - der injizierte Code muss die obigen Funktionen irgendwie umsetzen und anderseits adressunabhängig sein. Normalerweise werden für alle grundlegenden Operationen (Dateien suchen/öffnen) Betriebssystemfunktionen benutzt (WinAPI). Man kann aber diese nicht wie sonst in dem Injektionscode verwenden, da der Code dann nicht mehr adressunabhängig wäre (und irgenwelche Libs sollte man auch gleich vergessen, da diese ihre Funktionen letzendlich auch nur über WinAPI umsetzen ;) ).

Da wird man sich etwas einfallen lassen müssen um an die APIs zu kommen. Z.B in dem die Funktionen des Wirtprogrammes genutzt werden (dazu müssen vor der Infektion die Imports abgeklappert werden).

Oder den Speicher nach Kernel32.dll scannen (bietet Grundfunktionen "LoadLibrary" und "GetProcAddress", mit diesen können alle anderen API Adressen schnell und unkompliziert ermittelt werden können).Dabei müssen natürlich die ganzen internen Unterschiede zwischen den Winversionen (9.x/ME,NT/2k/2k3,XP SP1/XP SP2) beachtet werden.

Wie man sieht, ist die eigentliche Infektion der einfachste Teil ;)

Ein anderer Weg eigenen Code einzurbingen wäre einfach eine DLL in die Importtabelle des "Wirts" hinzuzufügen - es sollte zwar nicht immer klappen (manchmal ist kein Platz mehr da), dafür kann die DLL ganz bequem in Delphi/C++/VB(?) usw. erstellt werden - der Code muss nicht, wie bei dem "direkten" Weg, adressunabhängig sein.

Im Anhang eine kompakte Übersicht übers PE-Format
 
also für mich hört sich des alles en bissel kompliziert an. ich hab mich jetzt mal selber noch en bissel damit beschäftigt. ich bin jetzt so weit das ich die exe die ich anhängen will mit nem hexeditor oeffne und dann in den c++ quellcode einfüg. dann öffne ich die exe wo's angehaengt werde soll mit fopen und schreib's dann mit fwrite rein.
Code:
FILE *fp;
Code:
fopen("datei","ab");
Code:
fwrite(HexCode[2000000],1,1,"datei");
das einzige prb was ich jetzt noch hab is das fwrite "const void" als ersten parameter will und "HexCode" ein unsigned array is
 
das einzige prb was ich jetzt noch hab is das fwrite "const void" als ersten parameter will und "HexCode" ein unsigned array is
eigentlich sollte es so gehen:
http://www.cplusplus.com/reference/clibrary/cstdio/fwrite.html
also
Code:
  pFile = fopen ( "datei" , "ab" );
  fwrite (HexCode , sizeof(buffer[0]) , sizeof(buffer) , pFile );
  fclose (pFile);
Nicht dass ich C kann oder auch nur mag ;)
Allerdings denke ich, dass Du noch Grundlagen von C++ lernen solltest. Insbesondere bei diesem Thema wirst Du nicht um Pointeroperationen/Dateimanipulation herumkommen können.
 
oh man es hat doch noch geklappt war ein scheiß fehler hab nicht aufgepasst :rolleyes:
ich kann allerding nichts an ne exe anhängen sondern nur den inhalt von der exe überschreiben. aber des is auch egal auf jeden fall geht des jetzt so weit (undich kann c++ schon weitestgehend bin grad an winapi dran. so ien blackout wo man nicht weiter weiß hat ja jeder mal 2 stunden nach dem post hat ich meinen fehler entdeckt)
 
IMHO wird aber ein Trojaner oder Virus oder was auch immer probieren einen "vernünftigen" PE Loader zu bauen der auch das Icon,... übernehmen kann und CRC Routinen umläuft.
 
@CDW:

Wow,

tolle Beschreibung! Übersichtlich und doch ausführlich.

Eine Frage hätte ich aber noch:

Kann man auch Code als Thread laufen lassen?

und: Wenn ich, wie du weiter unten in deinem Beitrag vorgeschlagen hast, eine dll hinzufüge, wie wird diese dann geladen? bzw kann ich sie, wie oben erwähnt als Thread laufen lassen?

Gibts da viell Probleme mit der Firewall?

mfg

EDIT: Weil du gesagt hast manchmal ist kein Platz mehr da für eine dll, kann man sich den nicht verschaffen?
 
und: Wenn ich, wie du weiter unten in deinem Beitrag vorgeschlagen hast, eine dll hinzufüge, wie wird diese dann geladen? bzw kann ich sie, wie oben erwähnt als Thread laufen lassen?
Such mal nach IID King. Damit kann man Funktionen aus einer DLL der Exe hinzufügen.
Du brauchst in der DLL irgendeine "dummy" Funktion zu exportieren.
IID King fügt dann die Funktion der DLL (und somit die DLL selbst) zu den Imports hinzu.
Das Programm an sich muss die Funktion gar nicht aufrufen - bei Exestart wird die DLL von Windows PE-Loader geladen (dieser Loader ruft automatisch die DLL-Main auf).

Klar kannst Du Deinen eigenen Code dann (in der DLL) als Thread starten - der Code (aus der DLL Main) muss aber auf jedenfall zeitig returnen, sonst "hängt" das Programm.
Hier hatte ich mal ein Beispiel:
http://www.hackerboard.de/attachment.php?attachmentid=2373
Code:
LibMain proc hInstDLL:DWORD, arg:DWORD, reserviert:DWORD
         

        .if arg == DLL_PROCESS_ATTACH
            invoke CreateThread,0,0,addr Thread,addr BytesWritten,NULL,addr ThreadID
           
           
            mov eax,1
            ret 
       .elseif arg==DLL_PROCESS_DETACH
       	
           mov eax,1
        
        .endif

        ret

LibMain Endp
ist zwar masm, aber ich denke dass das Prinzip verständlich ist :)
 
Hallo,

danke für die Antwort!

Hmm wie meinst du das?

Ich hatte eig an Code gedacht der parallel zur EXE läuft also praktisch ein eigenständiges parallel laufendes Programm

Gibt es irgendwo n Bsp etc (Material oder so), das zeigt wie ich das automatisiere?
Also ohne externes Programm? (ich meine das was IID King macht)

Btw: Kann sich eine exe Datei dagegen schützen so manipuliert zu werden?

mfg
 
Original von Mo
Hallo,

danke für die Antwort!

Hmm wie meinst du das?

Ich hatte eig an Code gedacht der parallel zur EXE läuft also praktisch ein eigenständiges parallel laufendes Programm
dafür ist CreateThread gedacht. Sonst würde die Exe hängen bleiben.

Gibt es irgendwo n Bsp etc (Material oder so), das zeigt wie ich das automatisiere?
Also ohne externes Programm? (ich meine das was IID King macht)
also zur Laufzeit: DLL-Injection. Ansonsten müsste man sich was zusammenbasteln, entweder einen Code hineinschreiben, der die DLL lädt (z.B in die DOS-Stub) oder Imports erweitern.
Btw: Kann sich eine exe Datei dagegen schützen so manipuliert zu werden?
Ja, CRC des Exefiles oder Laufzeitprüfungen. Das sieht man öfters, wenn die Exe gepackt ist - z. B PECompact gibt bei einer Exemodifizierung die Meldung "Virus hat Exe modifiziert bla" (oder so ähnlich) aus.
mfg[/quote]
 
Hallo sry, ich steh etwas auf der Leitung,

dieser Thread wird aber in der dll gestartet, dh doch der ganze Prozess wartet bis die dll-main returned oder?

oder wird einfach die Funktion per CreateRemoteThread gestartet?

Sry wenn ich nerve, nur bin etwas verwirrt^^

mfg
 
Sorry, hatte mich im Vorpost etwas verquotet und es irgendwie nicht bemerkt.

dieser Thread wird aber in der dll gestartet, dh doch der ganze Prozess wartet bis die dll-main returned oder?
Du startest den Thread per CreateThread. Dadurch läuft dieser "parallel" und CreateThread return sofort nach der Threaderstellung. Die "Parallelität" ist ja der Sinn von Threads ;)
CreateThread
* During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.
* Only one thread in a process can be in a DLL initialization or detach routine at a time.
* ExitProcess does not return until no threads are in their DLL initialization or detach routines.
.

Erstelle am besten also eine "nackte" DLL (kein COM oder ähnliches), mit der es sich testen lässt:
http://www.egocrew.de/board/thread....readview=0&hilight=&hilightuser=0&sid=&page=1
Code:
DWORD WINAPI TestThread(LPVOID lParam)
{
	MessageBox(NULL,"Thread läuft und wurde durch die dll gestartet","",MB_OK);
	return 0;
}



BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
	HANDLE hthread;
	DWORD threadid;
	if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
		MessageBox(NULL,"dll process attach","",MB_OK);
		hthread = CreateThread(NULL,NULL,TestThread,NULL,NULL,&threadid);
		
    }
	
	else if (ul_reason_for_call == DLL_PROCESS_DETACH)
	{
		MessageBox(NULL,"dll process detach","",MB_OK);
	}
	else
	{
		MessageBox(NULL,"was anderes","",MB_OK);
	}

    return TRUE;
}
 
Zurück
Oben