2012-04-14 3 views
0

私のシステムはfedoraです。何らかの理由から.1レコードの最後のフィールドは、ユニコード文字列です(qemuのゲストマシンからmemcpyコピーデータを使用します)。ユニコード文字列は、Windowsのregeditキー名です。ファイル内のユニコード文字列には異なるものが含まれています

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

ここには16進コードの一部があります: '|'を使用してください。分割された文字として。最初の6つのフィールドはASCII文字です。最後のフィールドはウィンドウの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

私はそれを解析し、dbを挿入するためにpythonを使用します。 UTF8はそれを知っていないバイトが含まれていてもよいUnicode文字列Becuase

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

:ここでは私が間違っていましたでしょう

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

を処理する方法です。 どのように最後のフィールドを正しく読み取ることができますか?

簡単に言うと、 utf-16エンコードファイルではなく、どのようにフィールドを正しくデータベースに挿入することができますユニコード文字列がありますか? Pythonはファイルを読み込み、1つのエンコーディングスタイルを使用します。原点のバイトを読み取ることはできますか?これらのバイトをユニコード文字列に結合することはできますか?

答えて

3

データファイルはテキストのみのファイルではありませんので、ファイルをバイナリとして開き、テキストフィールドを明示的にデコードします。元のバイナリデータだと思うものを取り戻すには、データをかなり操作しなければなりませんでした。最終的なフィールドのデータがTEXTではなくUTF-16でエンコードされたBLOBとして保存されていたことを除き、元のデータがsqlite3.exeのダンプになっているようです。

行による解析と '|'による分割は、 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

ありがとう非常にドロドロ

は、ここに私のテストです。私はちょうど家に帰ってきたので、明日テストします。私は2つの違いを見つけることができます。 1.モード 'b'の読み込み2最後のファイルがutf-16leの準備ができていたので、それをUnicode文字列にデコードします。ちなみに、あなたが書いたdata.dbファイルは "mssse.exN | OtepKnye3 | 404 | 4 | 0 | \ |文字列"です。問題は私がファイルのちょっとした部分をコピーしたことによると思います。 "**。exe | NtOpenKey | **"のようにする必要があります。 – jiamo

+0

はい、元の生データを持っている方が良いでしょう。少なくともリトルエンディアンの単語ではなく、バイトとしてダンプされている方がいいでしょう。あなたのデータをデスクランブルするための私の答えを更新しました。 –

+1

エントリレコーダーの最後に '\ n'を書かないと '\ n'を処理するのに問題があります。ファイルから行を読み取るにはどうすればいいですか? UnicodeDecodeError: 'utf16'コーデックはバイトをデコードできません( '\ n')。 132行目の0x0a:切り捨てられたデータ '2' 'eachline [-1] = eachline [-1] .strip( '\ n')'気象があるのは不思議です。 – jiamo

関連する問題