バックナンバーはこちら。
https://www.simulationroom999.com/blog/In-vehicle-network-backnumber/
はじめに
Vector社BLFの中のオブジェクト抜き出しとzlib解凍のPythonコードの話。
登場人物
博識フクロウのフクさん
イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん
イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
BLFの中のオブジェクト抜き出しとzlib解凍のPythonコード
フクさん
じゃ、早速だけど、作ってきたPythonコードを見せるよ。
import zlib
import sys
def alignment_chk(size):
alignment = 0
if size % 4 != 0:
alignment = 4 - size % 4
return size + alignment
def blf_unzlib(inputBLF, outputBIN):
# BLFの全データ取得
f = open(inputBLF, 'rb')
blf_data = f.read()
f.close()
# 解凍済みデータ保存先ファイル
f2 = open(outputBIN, 'wb')
filesize = len(blf_data)
decompress_data = b''
compress_data = b''
# 先頭ヘッダからサイズ抽出
offset = blf_data[4] + blf_data[5]*0x100
cnt = 0 # 経過表示用カウンタ
while True:
if offset >= filesize:
# offsetがデータ終端に到達
break
# zlibパッケージヘッダ抽出
obj_size = blf_data[offset+8] + blf_data[offset+9]*0x100 + blf_data[offset+10]*0x10000 + blf_data[offset+11]*0x1000000
compress_data = blf_data[offset+0x20:offset+obj_size]
decompress_data = zlib.decompress(compress_data)
f2.write(decompress_data)
offset += obj_size
if offset+4 >= filesize:
break;
# Signature LOBJの探索
i = 0
while True:
tmp = str.format( "%c%c%c%c" % (blf_data[offset + i + 0], blf_data[offset + i + 1], blf_data[offset + i + 2], blf_data[offset + i + 3]) )
if tmp == 'LOBJ':
break
elif i >= 4:
print('LOBJ not found!')
exit()
break
else:
i += 1
offset += i
# 経過表示用
if cnt % 100 == 0:
print(offset)
cnt += 1
f2.close()
if __name__=='__main__':
inputBLF = 'test.blf'
outputBIN = 'test.bin'
args = sys.argv
# コマンドライン引数がある場合は、引数優先
if len(args) >= 3:
inputBLF = args[1]
outputBIN = args[2]
print("BLF=%s,output=%s" % (inputBLF,outputBIN))
blf_unzlib(inputBLF,outputBIN)
実行方法
フクさん
実行方法はいたってシンプルで、以下。
> python blf_unzlib [入力BLF] [出力BIN]
フクさん
引数無しのデフォルトでは、test.blfを読んで、test.binを出力するって動きになる。
Pythonコード解説
太郎くん
いやー思ったよりもボリュームあるなー。
もっとシンプルになるかと思ったんだけど。
フクさん
zlibのところはシンプルなんだけどねー。
規模が大きくなってる原因はblfの各オブジェクトヘッダの解析だね。
あとは、SignatureのOLBJの探索のところかな。
オブジェクトヘッダに埋まっているオブジェクトサイズ分Jumpした後に、
LOBJという文字れるとを探してる感じ。
とはいえ、同じことをC言語でやるともっと複雑になるから、
かなりシンプルなコードになっていると思った方が良いかも。
太郎くん
確かに配列の切り出しとかはC言語だとちょっと手間だもんねー。
フクさん
次回はこれで出来たzlib解凍済みのバイナリファイルを解析する感じかな。
まとめ
フクさん
まとめだよ。
- BLFのオブジェクト抽出とzlib解凍のPythonコードを書いた。
- オブジェクト抽出に起因するコードが支配的。
- zlib解凍後のファイルも解析が必要。
バックナンバーはこちら。
コメント