2012-04-14 3 views
0

Моя система fedora. По какой-то причине последнее поле одной записи: строка unicode (используйте memcpy копию данных с гостевой машины в qemu). Строка unicode - это имя ключа Windows regedit.строка unicode в файле содержит разные

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^@

Вот несколько шестнадцатеричных кода: используйте '|' как разделительный знак. Первые 6 полей были ascii sting. Последнее поле является строкой окна unicode (которая, я думаю, является кодом utf-16).

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

Я буду использовать python для его анализа и вставки в него db. Вот как я обрабатывать

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() 

я ошибалась:

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 строки Юникода может содержать байт utf8 не знает его. Как можно прочитать последнее поле правильно?

Просто сказать. Существует строка unicode, которая не является файлом кодировки utf-16. Как сделать поле правильно вставляемым в db? Python читает файл, используя один стиль кодировки. Могу ли я просто прочитать исходные байты. Соедините эти байты в строку юникода.

ответ

3

Ваш файл данных не является текстовым файлом, поэтому откройте файл как двоичный код и явно расшифруйте текстовые поля. Мне пришлось немного манипулировать данными, чтобы вернуть исходные двоичные данные. Похоже, что исходными данными, возможно, были дамп sqlite3.exe, похожий на мой окончательный результат ниже, за исключением того, что данные для окончательного поля были сохранены как BLOB с кодировкой UTF-16 вместо TEXT.

Обратите внимание, что разбор по строкам и расщепление на '|' могут возникнуть проблемы, если данные UTF-16 содержат байты, представляющие «\ n» или «|», но на этот раз я проигнорирую это.

Вот мой тест:

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') 

Выход:

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

Спасибо очень месиво. Когда я только вернусь домой, я буду тестировать завтра. Я могу найти две отличия. 1.read с режимом 'b' 2 Поскольку последняя поданная была готова к utf-16le, просто расшифруйте ее в строку unicode. Кстати, файл data.db, который вы пишете, это «mssse.exN | OtepKnye3 | 404 | 4 | 0 | \ | строка». Я думаю, что проблема была вызвана тем, что я просто скопировал небольшую часть файла. это должно быть как «**. exe | NtOpenKey | **». – jiamo

+0

Да, было бы лучше иметь исходные исходные данные или, по крайней мере, сбрасывать как байты, а не то, что, как я подозреваю, было малозначным. Я обновил свой ответ, чтобы дешифровать ваши данные. –

+1

У меня проблема с обработкой '\ n', если я не пишу '\ n' до конца записи recode. Как я могу прочитать строку из файла. Если я пишу '\ n', то: 1 не использовать 'eachline [-1] = eachline [-1] .strip ('\ n')' cause 'UnicodeDecodeError: 'utf16' кодек не может декодировать байт 0x0a в позиции 132: усеченные данные' 2 использовать 'eachline [-1] = eachline [-1] .strip ('\ n')' Интересно, что существует Погода, которая будет удалять байты внутри строки юникода. – jiamo

Смежные вопросы