Python 3 Bytestring ausgeben

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

1.
Wie kann ich Folgendes unter Python 3 als Bytestring ausgeben?

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)
2.
Und wie klappt das gleiche damit?

Code: Alles auswählen

import struct
eip = 0x004013ee
print("A"*14 + struct.pack("<L",eip)
Unter Python 2 klappt das anstandslos - für Python 3 suche ich schon seit Stunden vergeblich nach einer Lösung :(
Vielen Dank für eure Hilfe!


Anmerkung: Habe mein ursprüngliches Thema geschlossen, da die Fragestellung dort zunächst noch eine andere war.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ad 1: Ich wuerde es mit Bytestrings statt unicode versuchen: `b"..."`
lunar

Um Bytes direkt auszugeben, kannst Du nicht "print" verwenden, sondern musst auf "sys.stdout.buffer.write()" zurückgreifen. "print()" arbeitet ebenso wie "sys.stdout" mit Zeichenketten, nicht mit Bytes.
omnidan
User
Beiträge: 12
Registriert: Donnerstag 6. Januar 2011, 15:32

Code: Alles auswählen

Python 3
import sys
ausgabe = b"\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" 
sys.stdout.buffer.write(ausgabe)

0000000: fffe d900 1e00 5e00 3100 1425 3100 8825  ......^.1..%1..%
0000010: 3100 5425 3100 ca00 ea00 4600 0d00 0a00  1.T%1.....F.....
0000020: 9125 0400 0225 0100 ec00 0e00 9325 0d00  .%...%.......%..
0000030: 0a00 5025 c700 3100 1425 3100 8825 9125  ..P%..1..%1..%.%
0000040: 0100 5025 c700 de00 a600 a000 a000 a000  ..P%............
0000050: 4800 6500 6c00 6c00 6f00 2c00 2000 7700  H.e.l.l.o.,. .w.
0000060: 6f00 7200 6c00 6400 2100 2300 0d00 0a00  o.r.l.d.!.#.....
ist leider von dem was ich eigentlich haben will sehr verschieden:(

Code: Alles auswählen

Python 2
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)

0000000: eb1e 5e31 c031 db31 c931 d288 460d b004  ..^1.1.1.1..F...
0000010: b301 8d0e b20d cd80 31c0 31db b001 cd80  ........1.1.....
0000020: e8dd ffff ff48 656c 6c6f 2c20 776f 726c  .....Hello, worl
0000030: 6421 230a                                d!#.
Wie kann das sein? Bzw. wie bekomm ich die Ausgabe von Python 2 unter Python 3 hin? Hätte ja eigentlich gedacht, dass Versionswechsel mehr Vor- als Nachteile bringen ;)
lunar

@omnidan: Die gezeigten Beispiele liefern – wie nicht anders zu erwarten – abgesehen von einem Zeilenumbruch am Ende identische Ausgaben. Zeige also bitte den Quelltext, mit dem Du tatsächlich unterschiedliche Ausgaben erhältst, inklusive der Art, wie Du den Quelltext aufrufst.

Ansonsten bleibt es eben bei den üblichen Allgemeinplätzen: Du musst Dir im Klaren darüber sein, mit welchem Typ Du gerade arbeitest. Zeichenketten sind etwas anders als Bytefolgen und müssen demnach auch anders verarbeitet werden. In Python 2 ist dieser Unterschied dank der impliziten Konvertierungen nur versteckt, beachtet werden muss er trotzdem, ansonsten funktionieren die resultierenden Programme nur auf gut Glück. Es ist also ein Vorteil, dass Python 3 streng zwischen diesen Typen trennt, denn das vermeidet viele Fehler, auch wenn es am Anfang etwas umständlich ist.
omnidan
User
Beiträge: 12
Registriert: Donnerstag 6. Januar 2011, 15:32

Hmmm....also ich sehe in den von mir vorgestellten Beispielen schon deutliche Unterschiede:
Meine dargestellte Python-2-Ausgabe unter OS X enthält genau die von mir gewünschten Bytes, während Python 3 unter Windows eine vielzahl von Füllzeichen, Zeilenumbrüchen etc. einfügt.

Aufgerufen werden sie genau wie dargestellt. Um das Ergebnis hier zeigen zu können hab ich die Ausgabe allerdings in eine Datei umgeleitet, diese mit dem Hex-Editor geöffnet und das Ergebnis hier gepostet:

Code: Alles auswählen

python exploit.py > input
lunar

@omnidan: Du kannst ruhig davon ausgehen, dass ich das auf meinem Linux-System selbst ausprobiert habe:

Code: Alles auswählen

from __future__ import print_function
import sys

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

if sys.version_info[0] == 3:
    print('Python 3', file=sys.stderr)
    sys.stdout.buffer.write(s)
else:
    print('Python 2', file=sys.stderr)
    print(s, end='')

Code: Alles auswählen

$ python2 foo.py > python2.dat
Python 2
$ python3 foo.py > python3.dat 
Python 3
$ diff python2.dat python3.dat
Wie gesagt: Identische Ausgabe. Deswegen ja auch meine Frage nach Deinem exakten Vorgehen, denn offensichtlich gibt es etwas, was aus den von Dir zusammen gestellten Beispielen nicht hervorgeht.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich habe es auch auf meinem System mit Python 3 probiert und mit xxd angeschaut - und da kommt genau das von dir gewünschte raus.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
omnidan
User
Beiträge: 12
Registriert: Donnerstag 6. Januar 2011, 15:32

Vielen lieben Dank schonmal, dass ihr euch soviel Mühe macht!

Also: Unter OS X/Linux habt ihr recht! Es kommt auch mit meinem Python 3-Skript die identische Ausgabe raus. Unter Windows XP (Powershell 2.0, Python 3.2b2) bekomme ich jedoch oben dargestellte Ausgabe :-( Obwohl der Aufruf in der Powershell exakt gleich ist:

Code: Alles auswählen

PS C:\df> python ex4.py > input
PS C:\df> ls input


    Verzeichnis: C:\df


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        07.01.2011     14:53        112 input
Man erkennt bereits hier, dass das Ergebnis mehr als doppelt so groß ist :(
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Am besten bastels du ein minimales Beispiel zusammen, welchen den Fehler reproduzierst und postest den Code hier. Sonst endet es wahrscheinlich in einer Rumraterei, was nicht besonders produktiv ist.

Sebastian
Das Leben ist wie ein Tennisball.
omnidan
User
Beiträge: 12
Registriert: Donnerstag 6. Januar 2011, 15:32

Ok, man brate mir einen Storch!

Wenn ich das Skript unter der normalen Windows-Konsole aufrufe bekomme ich auch das richtige Ergebnis! Das Problem scheint ausschließlich in der Verwendung von PowerShell zu liegen - das gibts doch nicht! Vielen Dank für eure Hilfe - werde jetzt mal ein Powershell-Forum quälen ;)
Antworten