PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit fputc bei Crypteranlauf



Deshoax
03.06.2009, 12:17
Hallo Leute, ich komm mit meinem Crypter nicht weiter. Ich bin grade dabei die Flags zu setzen aber da will das programm nicht mitspielen, ich weis nicht worans liegt.

Kann mir einer helfen?

Das ist die Main:
http://nopaste.free-hack.com/index.php?id=f4038d048b

Das ist die out_section_details.h:
http://nopaste.free-hack.com/index.php?id=ab7ea08ae2

Im mom funzt nur option 2, das abgleichen von Virtual Size mit der Raw Size funktioniert, aber dann setzt er die Flags nicht. Bin am verzweifeln :'(

EBFE
03.06.2009, 13:01
Allgemeiner Tipp: ließ doch die Exe zuerst komplett in einen Buffer und bearbeite sie darin. Dann schreibst du einfach den Buffer in einem Rutch wieder zurück. Die fgetc sind sehr unübersichtlich und wohl auch fehleranfällig ;)

Sonst: Flags setzt man i.R mit einem binary-or.
Zum Fehler: mit fputc schreibst du nur ein Zeichen/Byte rein. Int ist aber i.R etwas größer (üblicherweise 4 Bytes, wobei das je nach Plattform variieren kann);).
Entweder arbeitest du eben mit buffern oder schreibst die Zahl "komplett" rein mit fwrite:


unsigned int myint=6;
fwrite(&myint, 1, sizeof(int), fp);dasselbe gilt übrigens auch für deine VS-Abgleichfunktionen, da sie auch nur einmal fputc nutzen.

Statt den komischen Umwandlungen mit fgetc lässt sich übrigens auch fread nutzen:


unsigned int myint=0;
fread(&myint, 1, sizeof(int), fp);
printf("eingelesen: %d %x", myint,myint);
fclose(fp);(vielleicht nicht der schönste Stil, aber C mag/kann ich nicht wirklich und das soll nur ein Beispiel für die Nutzung sein ;) )

Deshoax
03.06.2009, 13:07
Hmm... wenn ich jetzt fwrite anstelle des fputc nutze, wird es funktionieren?
BTW: wenn ich jetz alles nochma umschreib is glaub ich viel arbeit aber ich setz mich dran. villt klappts ja dann wirklich besser.

Danke für die Antwort!

blackberry
03.06.2009, 13:11
Kleine Ergänzung:
gets(dateiname); (Zeile 18)
Würde zu einem Buffer-Overflow führen.

EDIT:
Anstelle dauernt mit fread und fgetc rumzuarbeiten könntest du auch die Datei in die einzelnen Strukturen einlesen.
(IMAGE_DOS_HEADER, IMAGE_NT_HEADERS, IMAGE_SECTION_HEADERS, ... --> in winnt.h; windows.h inkludieren)

EDIT2:
In nr_of_sections benutzt du folgenden Code um die Sectionzahl einzulesen:
nrofsections=fgetc(stream);
NumberOfSections ist jedoch WORD-groß (dh. short, dh. 2 Byte groß).
Wegen dem Litte-Endian macht das nichts, da du damit den Teil der 2 Bytes einliest, die den kleinsten Teil der Zahl darstellen, aber ganz korrekt ist diese Lösung natürlich nicht.

EDIT3:
Beispiel für die Benutzung von IMAGE_DOS_HEADER & Co.:

#include <stdio.h>
#include <windows.h> // für winnt.h


int main(void)
{
IMAGE_DOS_HEADER *idh;
IMAGE_NT_HEADERS *inh;
char *ptr;

// ptr zeigt nun auf den Anfang der in den Speicher geladenen Datei
ptr = datei_laden("whatever.exe");

// idh zeigt nun auf den DOS_HEADER der Datei im Speicher
idh = (IMAGE_DOS_HEADER) ptr;

// inh zeigt nun auf die NT_HEADERS der Datei im Speicher
inh = (IMAGE_NT_HEADERS) &ptr[idh->e_lfanew];

// NumberOfSections ausgeben
printf("NumberOfSections = %hd\n", inh->FileHeader->NumberOfSections);

// Neue Sectionzahl setzen:
inh->FileHeader->NumberOfSections = 0xDEADBEEF;

// Speicher zurückschreiben
datei_speichern(ptr, "whatever2.exe");

return 0;
}

EBFE
03.06.2009, 13:18
Hmm... wenn ich jetzt fwrite anstelle des fputc nutze, wird es funktionieren?Ich hab mein vorheriges Posting etwas editiert. Sonst: mit fputc schreibst du wie gesagt ein Zeichen/Byte rein. Die Zahl wird halt gecastet/"abgeschnitten". Wenn du unbedingt bei fputc bleiben willst, musst du dafür sorgen, dass auch die restlichen 3 Bytes des Integers mitgeschrieben werden:


unsigned int myint=0xdeadbeef;
fputc(myint,fp);
fputc(myint>>8,fp);
fputc(myint>>16,fp);
fputc(myint>>24,fp);

PS: auch wenn mein Code nicht so toll ausschaut - vor dem Posten teste ich diesen i.R immer ;)

Deshoax
03.06.2009, 13:20
warum, solange man keine dateinamen über 66 zeichen eingibt passiert doch nichts oder?

EDIT: Was bedeutet bei
fputc(myint >> 8,fp);
Die >> und die Zahl?

ist mir bisher noch nicht begegnet...

blackberry
03.06.2009, 13:42
warum, solange man keine dateinamen über 66 zeichen eingibt passiert doch nichts oder?

Nein, aber die Argumentation hat noch niemanden interessiert, der sich mit einem Buffer-Overflow in einem privilegierten Programm mehr Rechte auf einem System verschafft hat.

http://img189.imageshack.us/img189/7997/f54.png

EBFE
03.06.2009, 14:05
EDIT: Was bedeutet bei Zitat:
fputc(myint >> 8,fp);
Die >> und die Zahl?http://de.wikibooks.org/wiki/C-Programmierung:_Ausdr%C3%BCcke_und_Operatoren#Rech tsshift_.3E.3E

Verschiebt also die Bits um die angegebene Anzahl von Stellen:
Bsp: interne Darstellung eines Wertes:
01001 shift >> 1 ergibt 00100
01001 shift >> 3 ergibt 00001



Wofür das im Bsp benutzt wird: ein Int bei C auf einer üblichen Plattform (usw.) 4 Bytes groß.
0x80001000 sieht intern so aus:
Byte1:___Byte2:____Byte3:___Byte4:
10000000 00000000 00010000 00000000

da fputc nur 1 char=1Byte schreibt, wird die Zahl "abgeschnitten" und nur Byte Nummer 4 geschrieben.

ein Shift verschiebt nun die Bits um eine angegebene Anzahl von Stellen:
SHIFT >> 8
Ergebnis:
Byte1:___Byte2:____Byte3:___Byte4:
00000000 10000000 00000000 00010000
Die Bits sind also um 8 Stellen (größe eines Bytes) nach rechts gerückt.
wie man sieht, ist das Byte1 deshalb nun an Stelle von 2, Byte2 ist an Stelle von 3 gerückt und Byte3 an Stelle von Byte4
wenn man nun fputc ausführt, schreibt man das Byte Nummer 3 in die Datei (weil es nun an der vierten Stelle steht).

SHIFT >>16
Byte1:___Byte2:___Byte3:___Byte4:
00000000 00000000 10000000 00000000
Wurde also um 16 Stellen nach rechts verschoben, jetzt steht Byte1 an Stelle von 3 und Byte 2 an Stelle von 4.
nun würde man mit fputc das zweite Byte schreiben.

Und weil das sonst zu einfach wäre und um die nächtste Frage zu verhindern: ja, der Code schreibt zuerst Byte4 rein, dann Byte3 usw. In der Datei landen die Bytes also in der umgekehrten Reihenfolge: Byte4,Byte3,Byte2,Byte1
Grund dafür ist, dass auf den meisten Desktops eingesetzte CPUs die IA-32 nutzen (=Intelarchitektur-Standarddefinition, also das "Interface" der CPU, wird oft auch als 0x86 oder 0x386 bezeichnet, und ja AMD CPUs gehören auch dazu ;) ) und damit Little Endian Byte-Reihenfolge (http://de.wikipedia.org/wiki/Byte-Reihenfolge) einsetzen.

Nunja, ich hoffe, das war verständlich genug. Kann allerdings eine ausführliche Beschäftigung mit dem Thema nicht ersetzen, sofern du wirklich Low-Level mäßig programmieren möchtest ;)

Deshoax
03.06.2009, 16:43
Danke für die detailierte Antwort!
Jetz weis ich wesentlich mehr darüber ;)

hmm, ich seh auch langsam ein, das es villt besser wäre ein array zu nehmen nur fehlen mir im mom dafür die ideen. Von daaus werde ich erstma mit dem so weitermachen bis ich ein ergebnis hab und dieses ergebnis dann meinen helfern zukommen lassen ;)
MfG

Deshoax