背景
- UltraHDR の調査中に画像ファイルのメタデータを確認する必要が生じた
- 今までは VS Code の Hex Editor を使っていたが、もっと拡張性のあるツールを使わないと解析が厳しかった
- Chat GPT 先生にバイナリエディタについて相談したところ、ImHex を勧められたので実際に使ってみた
目的
結論
- ImHex は大変便利なバイナリエディタであった
- Pattern editor でデータの取得、および取得したデータを使った計算ができるのは大変助かった
- ImHex の Pattern editor で解析をしている様子を図1 に示す。
- 一方で ImHex はとても多機能なバイナリエディタであり、使いこなすには修練が必要だと感じた
詳細
解析対象の紹介
今回、筆者が解析したのは UltraHDR形式の JPEG ファイルの Application Segment の ISO 21496-1 の Gain Map のメタデータである。
筆者は ISO 21496-1 を購入するほどのモチベーションはなかったため、メタデータの構造に関しては libultrahdr のソースコードから判断した。下記リンクのコードのuseCommonDenominator == false
かつchannelCount == 3
が筆者が解析したいメタデータの内容である。
上記のソースコードから ImHex で扱えるように構造体を作った結果が以下となる*1。s32
やu32
などの型の定義については Pattern Language の Data Types の項目を参照(Pattern Language は ImHex 用に開発された専用言語である)。
// 1チャンネル分(useCommonDenominator == false のときの並び) struct ChannelFrac { s32 gainMapMinN; // streamWriteS32 u32 gainMapMinD; // streamWriteU32 s32 gainMapMaxN; // streamWriteS32 u32 gainMapMaxD; // streamWriteU32 u32 gainMapGammaN; // streamWriteU32 u32 gainMapGammaD; // streamWriteU32 s32 baseOffsetN; // streamWriteS32 u32 baseOffsetD; // streamWriteU32 s32 alternateOffsetN; // streamWriteS32 u32 alternateOffsetD; // streamWriteU32 }; // ヘッダ+本体(useCommonDenominator == false / channelCount == 3 固定) struct GainmapMetadata { // ヘッダ u16 min_version; // streamWriteU16 u16 writer_version; // streamWriteU16 u8 flags; // streamWriteU8(bit3 は 0 の想定) // 共通分母を使わない経路(順序に注意) u32 baseHdrHeadroomN; // streamWriteU32 u32 baseHdrHeadroomD; // streamWriteU32 u32 alternateHdrHeadroomN; // streamWriteU32 u32 alternateHdrHeadroomD; // streamWriteU32 // 3 チャンネル分 ChannelFrac channels[3]; };
ImHex の Pattern editor を使ったメタデータの抽出
ImHex の画面右側には Pattern editor という画面がある。Pattern editor 内に構造体を定義して、構造体の先頭アドレスを指定すると Pattern editor に構造体の情報が表示される。言葉だけだとわかりづらいので、実際に作業をした様子を図2 の ①~③ に示す。
先頭アドレスは ImHex の Find タブを使って調べた。Find タブはメニューバーの View -> Find で表示できる。
UltraHDR の ISO 21496-1 のメタデータは、以下のソースコードを見るとkIsoNameSpace.c_str()
の後に続いていることが分かる。これは"urn:iso:std:iso:ts:21496:-1"
という文字列で定義されているので、この文字列を Find タブで検索した*2。
ImHex の Pattern editor を使った簡単な計算の実施
Pattern editor では構造体の定義だけでなく、バイナリから取得したデータを使った簡単な計算も可能である。
Gain Map のメタデータは Numerator と Denominator に分かれて格納されているため、実際の値を知るには割り算が必要だったが、Pattern editor の機能を使って簡単に計算することができた。各種パラメータの値を計算、表示している様子を図3 の ①~③ に示す。
感想
凄く便利だった。ドキュメントを見ると非常に多機能であり、バイナリ解析を日常的に行う人は凄く重宝するのだと感じた。
筆者はバイナリ解析はそんなに頻繁にやらないので、すぐに使い方を忘れてしまいそうで心配である(というのもあって記事を書いた)。
参考資料
[1] Pattern Language, "Data Types", https://docs.werwolv.net/pattern-language/core-language/data-types