はじめに
私がvarintsに出会ったのは何年も前、殺人と放火の捜査でiPhone 3GSをデジタルフォレンジック検査したときだった。 それまでは、私のフォレンジック作業は主にフィーチャーフォン、特にBREWを実行しているCDMAデバイスを対象としていた。各テキストメッセージは、一貫したオフセットとメッセージの長さを示すわかりやすい16進数値で、独自のファイルに保存されていた。それは予測可能で、慣れ親しんだプロセスだった。
しかし、iPhoneはまったく新しい挑戦に私を導いてくれた。メッセージは個々のファイルとしてではなく、データベース内のレコードとして保存されるようになったのだ。フィーチャーフォンのシンプルさとは異なり、メッセージ文字列の長さは明確な16進数値で定義されていなかった。その代わりに、私はSQLiteデータベースをナビゲートし、レコードのペイロードを解析することを学んだ。ここで私は varints-可変長整数-コンパクトで効率的なデータの符号化方法である。バリントを理解することは、データベースの構造を解明し、重要な証拠を抽出する上で非常に重要だった。この事件では、バリントを使いこなすことで、最終的に放火と殺人の罪で被告を有罪にするための証拠となる発見をすることができた。
バリントはSQLiteデータベースの基本コンポーネントで、セル、レコード、特定のフィールドの長さを定義する整数の効率的なエンコーディングを可能にします。デジタル・フォレンジックの実務家にとって、データベースファイル内の重要な情報を明らかにするためには、バリントの解読が不可欠です。これらのコンパクトな整数は、テーブル構造のマッピング、レコードのペイロードの特定、削除されたデータや隠されたデータの復元において重要な役割を果たします。
このブログ記事では、SQLiteフォレンジックにおいてバリントが果たす重要な役割について説明します。私の VarInt電卓デコードプロセスを簡素化するために私が設計したツールであるVarintsのチュートリアルを通じて、この知識を捜査に応用することができます。SQLiteデータベース・エントリーの解析から削除されたレコードの再構築まで、バリントを理解することは、すべてのフォレンジック調査者がツールキットに備えておくべきスキルです。
バリントを理解するバリントを見抜き、解読する
SQLiteとデジタル・フォレンジックをより深く理解するために必要なスキルの1つは、次のことを理解することです。 可変長整数 (varints).これらのコンパクトな数値はSQLiteデータベースのいたるところにあり、できるだけ少ないバイト数で値を格納することで、システムの省スペース化に役立っています。しかし、何を探せばいいのかわからないと、これを発見して解読するのは難しいかもしれません。順を追って説明しましょう。
バリントとは?
varintは数値を格納する特殊な方法で、数値のサイズによって使用されるバイト数が決まります。固定長の整数(例えば4バイトや8バイト)とは異なり、varintは1バイトから9バイトまで小さくすることができます。この柔軟性により、varintはスペース効率に優れていますが、解釈の難易度も高くなります。
バリントはどこにいるのか?
SQLiteデータベースでは、エンコードにvarintが使用されます:
- データベースページのセルまたはレコードの長さ。
- レコードを一意に識別する行ID。
- レコードのペイロード内のデータの長さ。
- その他、データベース構造に関連する様々な値。
バリントを読む鍵マーカービット
varintを読み取る際にまず知っておかなければならないのは、その長さを把握する方法である。varint の各バイトには マーカビット (最上位ビット、またはMSB)は、同じvarintの一部である別のバイトが右側にあるかどうかを示します:
- マーカービットが1の場合次のバイトもvarintの一部である。
- マーカービットが0の場合これでバリントは終わりです。
バリントの長さを解読する2つの方法
varintの長さを知るには2つの方法がある:長い方法(2進数を使う)と簡単な方法(16進数を使う)だ。両方について説明しよう。
長い道のりバイナリーの使用
- varintの最初のバイトから始める。
- バイトを2進数に変換する。最上位ビット(一番左のビット)を見る。
- ビットが1の場合、右側のバイトはvarintの一部である。
- ビットが0であれば、終了に達している。
- MSBが0のバイトが見つかるまで、各バイトについてこの作業を繰り返す。
例
- バイト:
0xC2
→ バイナリ:11000010 → MSB:1 → 続ける。 - バイト:
0x7F
→ バイナリ:01111111 → MSB:0 → ここでストップ。
簡単な方法左ニブルを使う
- 左のニブル(バイトの最初の16進数)を見てください。
- 左ニブルが8以上(8、9、A、B、C、D、E、F)の場合、次のバイトはvarintの一部となる。
- 左のニブルが7以下(0から7)なら、varintの終端に達している。
なぜこれが有効なのか: 左ニブルが8以上はMSBが1であることを意味し、左ニブルが7以下はMSBが0であることを意味する。
例
- バイト:
0xC2
→ 左ニブルC(8より大きい) → 続ける。 - バイト:
0x7F
→ 左ニブル:7(8未満) → ここでストップ。

細胞長におけるバリントの理解:実例
バリントはSQLiteで セル データベースのページにある。これらのセルには、テーブルからテーブル・レコードまで、あらゆるものが格納される可能性があり、セルの最初のバイトによって、そのセルの大きさがわかる。この長さインジケータはそれ自体が varint であり、長さは 1 バイトから 9 バイトの範囲である。
実際の例WALファイル
この例では、セルに メッセージテーブル.セルの最初のバイトは 0x81
2バイトのvarintを示す。
- 内訳
- バイト1:
0x81
→ バイナリ:10000001 → マーカービット:1 → 継続 - バイト2:
0x07
→ バイナリ: 00000111 → マーカービット0 → ストップ
- バイト1:
デコードバリント
ここで、varintをデコードする必要がある。単純に値を 0x8107
を整数に変換すると、誤って33,031という巨大な計算をしてしまう。
なぜですか?
マーカービットはvarintの実際の値には寄与しない。varintを正しくデコードするには、次のようにする必要がある。 マーカービットを剥がす そして、バイナリ表現の意味のある部分だけを解釈する。その方法はこうだ:
- デコード
- マーカービットを削除する:0000001と0000111。
- 2つのセプテットを組み合わせる:00000000 10000111 → 10進数:135.
- セルの長さは135バイトである(varintとROWIDを除く)。
バリント計算機による効率化
について バリント計算機 を使うと、このプロセスが簡単になる。16進数値(例:8107)を入力すると、varintをすばやくデコードできます。上記の例では、電卓は135を返し、長さを確認します。

レコードヘッダーのバリントのデコード
SQLiteでは、レコードヘッダはvarintを使って定義します:
- 長さ: どれだけのデータを読むか。
- タイプ データの解釈方法(整数、文字列、BLOBなど)。

例文字列の長さ
レコードヘッダのvarintをデコードしてみよう:- バリント
0x25
- 左ニブル:2(8未満)→1バイトvarint。
- 10進数:37。
- ペイロード: 文字列の長さ = 12 バイト (+97444455667)。

閉会の辞
バリントを理解し解読することは、SQLiteデータベースを扱うデジタル・フォレンジック調査員にとって基礎となるスキルです。これらのコンパクトな整数は、データベース構造を解釈し、セルサイズを決定し、データを効率的に復元するための鍵となります。
Varint Calculatorのようなツールがあれば、そのプロセスはより身近なものとなり、フォレンジックの専門家はデジタル証拠に隠された真実の解明に集中することができます。バリントを使いこなすことは技術的なスキル以上のものであり、捜査結果に直接影響を与える重要な能力なのです。
バリント計算機のダウンロードはこちらから: