2012-04-14 6 views
0

Mein System ist Fedora. Aus irgendeinem Grund. Das letzte Feld eines Datensatzes ist ein Unicode-String (verwenden Sie memcpy kopieren Daten von einem Gastcomputer in qemu). Die Unicode-Zeichenfolge ist der Windows regedit-Schlüsselname.Unicode-Zeichenfolge in Datei enthalten unterschiedliche

smss.exe|NtOpenKey|304|4|4|0|\^@R^@e^@g^@i^@s^@t^@r^@y^@\^@M^@a^@c^@h^@i^@n^@e^@\^@S^@y^@s^@t^@e^@m^@\^@C^@u^@r^@r^@e^@n^@t^@C^@o^@n^@t^@r^@o^@l^@S^@e^@t^@\^@C^@o^@n^@t^@r^@o^@l^@\^@S^@e^@s^@s^@i^@o^@n^@ ^@M^@a^@n^@a^@g^@e^@r^@ smss.exe|NtClose|304|4|4|0|System|NtOpenKey|4|0|2147484532|0|\^@R^@e^@g^@i^@s^@t^@r^@y^@\^@M^@a^@c^@h^@i^@n^@e^@\^@S^@y^@s^@t^@e^@m^@\^@C^@u^@r^@r^@e^@n^@t^@C^@o^@n^@t^@r^@o^@l^@S^@e^@t^@ services.exe|NtOpenKey|680|624|636|0|\^@R^@E^@G^@I^@S^@T^@R^@Y^@\^@M^@A^@C^@H^@I^@N^@E^@\^@S^@y^@s^@t^@e^@m^@\^@C^@u^@r^@r^@e^@n^@t^@C^@o^@n^@t^@r^@o^@l^@S^@e^@t^@\^@S^@e^@r^@v^@i^@c^@e^@s^@

Hier ist ein Teil des Hex-Codes: Verwenden Sie '|' als Split-Char. Die ersten 6 Felder waren ascii sting. Das letzte Feld ist ein Fenster Unicode-String (was ich denke, es ist utf-16-Code).

0000000 6d73 7373 652e 6578 4e7c 4f74 6570 4b6e
0000010 7965 337c 3430 347c 347c 307c 5c7c 5200
0000020 6500 6700 6900 7300 7400 7200 7900 5c00
0000030 4d00 6100 6300 6800 6900 6e00 6500 5c00
0000040 5300 7900 7300 7400 6500 6d00 5c00 4300
0000050 7500 7200 7200 6500 6e00 7400 4300 6f00
0000060 6e00 7400 7200 6f00 6c00 5300 6500 7400
0000070 5c00 4300 6f00 6e00 7400 7200 6f00 6c00
0000080 5c00 5300 6500 7300 7300 6900 6f00 6e00
0000090 2000 4d00 6100 6e00 6100 6700 6500 7200

Ich werde Python verwenden, um es zu analysieren und es eine db einzufügen. Hier ist, wie ich

def parsecreate(filename): 
    sourcefile = codecs.open("data.db",mode="r",encoding='utf-8') 
    cx = sqlite3.connect("sqlite.db") 
    cu = cx.cursor() 
    cu.execute("create table data(id integer primary key,command text, ntfunc text, pid text, ppid text, handle text, roothandle text, genevalue text)") 
    eachline = [] 
    for lines in sourcefile: 
     eachline = lines.split('|') 
     eachline[-1] = eachline[-1].strip('\n') 
     eachline[-1] = eachline[-1].decode('utf-8') 

     cu.execute("insert into data(command,ntfunc,pid,ppid,handle,roothandle,genevalue) values(?,?,?,?,?,?,?)",(eachline[0],eachline[1],eachline[2],eachline[3],eachline[4],eachline[5],eachline[-1])) 

    cx.commit() 
    cx.close() 

Griff bekam ich falsch wird:

File "./parse1.py", line 18, in parsecreate for lines in sourcefile: File "/usr/lib/python2.7/codecs.py", line 684, in next return self.reader.next() File "/usr/lib/python2.7/codecs.py", line 615, in next line = self.readline() File "/usr/lib/python2.7/codecs.py", line 530, in readline data = self.read(readsize, firstline=True) File "/usr/lib/python2.7/codecs.py", line 477, in read newchars, decodedbytes = self.decode(data, self.errors) UnicodeDecodeError: 'utf8' codec can't decode byte 0xd0 in position 51: invalid continuation byte

Becuase der Unicode-String enthalten ein Byte die UTF-8 nicht wissen es. Wie kann das letzte Feld richtig gelesen werden?

Einfach zu sagen. Es gibt eine Unicode-Zeichenfolge in keiner utf-16-Encodedatei. Wie kann das Feld korrekt in die db eingefügt werden? Python liest eine Datei mit einem Kodierungsstil. Kann ich nur Ursprungsbytes lesen. Kombiniere diese Bytes zu einer Unicode-Zeichenkette.

Antwort

3

Ihre Datendatei ist keine reine Textdatei. Öffnen Sie die Datei daher als Binärdatei, und dekodieren Sie die Textfelder explizit. Ich musste die Daten ziemlich manipulieren, um die ursprünglichen binären Daten wiederherzustellen. Es sieht so aus, als ob die ursprünglichen Daten ein sqlite3.exe Speicherabzug ähnlich wie meine endgültige Ausgabe unten waren, außer dass die Daten für das letzte Feld als ein UTF-16-codiertes BLOB anstelle von TEXT gespeichert wurden.

Beachten Sie, dass die Analyse nach Zeilen und Teilen mit '|' kann Probleme auftreten, wenn die UTF-16-Daten die Bytes enthalten, die '\ n' oder '|' darstellen, aber ich werde das jetzt ignorieren.

Hier ist mein Test:

from binascii import unhexlify 
import sqlite3 

data = unhexlify('''\ 
6d73 7373 652e 6578 4e7c 4f74 6570 4b6e 
7965 337c 3430 347c 347c 307c 5c7c 5200 
6500 6700 6900 7300 7400 7200 7900 5c00 
4d00 6100 6300 6800 6900 6e00 6500 5c00 
5300 7900 7300 7400 6500 6d00 5c00 4300 
7500 7200 7200 6500 6e00 7400 4300 6f00 
6e00 7400 7200 6f00 6c00 5300 6500 7400 
5c00 4300 6f00 6e00 7400 7200 6f00 6c00 
5c00 5300 6500 7300 7300 6900 6f00 6e00 
2000 4d00 6100 6e00 6100 6700 6500 7200'''.replace(' ','').replace('\n','')) 

# OP's data dump must have been decoded from the original data 
# as little-endian words, and is missing a final 0x00 byte. 
# Byte-swapping and adding missing zero byte to get back what 
# was likely the original binary data. 
data = ''.join(a+b for a,b in zip(data[1::2],data[::2])) + '\x00' 

with open('data.db','wb') as f: 
    f.write(data) 

def parsecreate(filename): 
    with open(filename,'rb') as sourcefile: 
     with sqlite3.connect("sqlite.db") as cx: 
      cu = cx.cursor() 
      cu.execute("create table data(id integer primary key,command text, ntfunc text, pid text, ppid text, handle text, roothandle text, genevalue text)") 
      eachline = [] 
      for line in sourcefile: 
       eachline = line.split('|') 
       eachline[-1] = eachline[-1].decode('utf-16le') 
       cu.execute("insert into data(command,ntfunc,pid,ppid,handle,roothandle,genevalue) values(?,?,?,?,?,?,?)",(eachline[0],eachline[1],eachline[2],eachline[3],eachline[4],eachline[5],eachline[-1])) 

parsecreate('data.db') 

Ausgang:

C:\>sqlite3 sqlite.db 
SQLite version 3.7.9 2011-11-01 00:52:41 
Enter ".help" for instructions 
Enter SQL statements terminated with a ";" 
sqlite> select * from data; 
1|smss.exe|NtOpenKey|304|4|4|0|\Registry\Machine\System\CurrentControlSet\Control\Session Manager 
+0

Danke sehr Brei. Da ich gerade nach Hause komme, werde ich morgen testen. Ich kann zwei Unterschiede finden. 1.read mit Modus 'b' 2 Weil letzten abgelegt war ein utf-16le, entschlüsseln Sie es einfach Unicode-String. Die Datei data.db, die Sie schreiben, ist übrigens "mssse.exN | OtepKnye3 | 404 | 4 | 0 | \ | eine Zeichenkette" .Ich denke, das Problem wurde dadurch verursacht, dass ich nur einen kleinen Teil der Datei kopiere. Es sollte wie "**. exe | NtOpenKey | **" sein. – jiamo

+0

Ja, es wäre besser, die originalen Rohdaten zu haben, oder zumindest als Bytes auszugeben, anstatt wie ich vermutete, Little-Endian-Wörter. Ich habe meine Antwort aktualisiert, um Ihre Daten zu entschlüsseln. –

+1

Ich habe ein Problem mit dem '\ n', wenn ich kein '\ n' am Ende eines Eintrags schreibe. Wie kann ich eine Zeile aus der Datei lesen? Wenn ich ein '\ n' schreibe, dann: 1 benutze nicht 'eachline [-1] = eachline [-1] .strip (' \ n ') 'Ursache' UnicodeDecodeError:' utf16 'Codec kann Byte nicht dekodieren 0x0a in Position 132: abgeschnittene Daten' 2 benutze 'eachline [-1] = eachline [-1] .strip ('\ n')' Ich frage mich, ob es eine Möglichkeit gibt, ein Byte innerhalb der Unicode-Zeichenkette zu löschen. – jiamo

Verwandte Themen