【Ethernet】車載ネットワーク その8【BLFファイル⑧】

車載ネットワーク

バックナンバーはこちら。
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解凍後のファイルも解析が必要。

バックナンバーはこちら。

コメント

タイトルとURLをコピーしました