解析講義Q&A集

講師:Lear教官


Lear教官によるデータ解析講義のQ&A集です。もどる場合はブラウザの機能で戻ってください。

  1. データ構造とは?

    ここで説明上、データ構造と言いましたが説明するのは至難の技なので具体的にどんな感じのことを行っているか説明して雰囲気だけつかんで下さい。
    最初に行ったのは「開発表制作に不必要なデータを洗い出して解析範囲を狭める」です。
    解析範囲を絞ればその分、解析効率は上がりますからね。
    例えば、都市名やスタッフロール、搭載兵器関連とおぼしきデータであろうと思われる部分は基本的には開発表になんの関係も無いのでそこら辺は解析しても意味がありません。
    そして、残った部分に対してトライ&エラーやその他、考えられる方法で解析を行い、その結果、無関係な部分をさらにそぎ落として行きます。
    これの繰り返しです。
    そして、無駄な部分とはいえ、少し解析が進むとこのデータを作り出したプログラマの癖と言うか、ゲーム制作上の手法として「こうしてるだろう」というものが見えてきます。
    今回は「全てのデータが4バイト単位でできている」ってのがそれに当たります。
    さらに、なぜ4バイト単位かまで予測が付けば、その先の解析の大きなヒントとなります。
    すなわち、「本当に全部4バイトか」、「もっと時間をかけて疑うべきか」とかですね。

  2. データの格納方法(構造?)はある程度一般化されているものなのか、それともプログラマによってバラバラなのか?

    C言語で開発を行っている場合、ある程度、自由な大きさの任意な適当なデータサイズを構造体という概念で容易く扱えるので一般化はされていません。
    ただ、構造体と言う概念でデータを格納しているだろうという予測が的中していれば解析の手がかりの1つとなります。
    ADPDATA.DLLの場合、兵器データが0x2A0バイト(672バイト)と0x174バイト(372バイト)単位で生成されていますが、この固まりが構造体です。
    まあ、データ集合の固まり具合が構造体と言えるでしょうか。

  3. 教官殿は「全体の流れを掴む」とおっしゃってますが、それはバイナリエディタのASCII文字を眺めているとつかめるものなのでしょうか?

    1.に重複しますが、ようは全てが一回の解析で判明することはほとんどありません。
    あとは、不要な部分を取り除いて、必要を思われる部分だけを見渡してさらに見直してみる・・・の繰り返しです。
    時には必要な部分までも削ってしまうこともあります。
    解析できる前に行き詰まったら、今までの考察が正しかったのか疑わねばなりません。
    考察する部分が無くなればトライ&エラーで新たな情報を取得して再考察します。
    そんな感じです。

  4. LHAのロジックで暗号化されたデータは、なんらかのLHAユーティリティで復号できるのか?

    普通はできません。
    LHAやgzipがLZ法+Huffmanで圧縮していてもLHAで圧縮したものがgzipで展開できないことと同じで、あくまでも同じなのは理論であり実装法は別です。
    LHAを直接使用しているなら話は別ですがね。
    圧縮理論の推定が正しければそれを紐解くことはそんなに難しいことではありません。
    ただし、プロのプログラマでも普段からLZ法等を暗記しているのではなくて、LZ法やその他の理論があることと、それを解説している書籍を持っていて、いざ使うときにそれらを参考にするのが普通です。 全てを知り得ているわけではなくて、ある何かを調べる手立てを持ち合せていて重要な部分は解説書に任せておけば良いのです。

  5. XORってなんですか?

    eXclusive OR(排他的論理和)をこう略します。
    さて応用数学ですね。
    高校レベルってどこまでやってましたっけ?
    工学系の学科へ大学進学された方は知らないとヤバイですね。
    AND、OR、NOTは分かりますか?
    AND
    論理積
    2つの命題A、Bがともに真(1)である時のみ真である論理関数。
    OR
    論理和
    2つの命題A、Bのどちらかまたはその両方が真であるとき真である論理関数。
    NOT
    否定
    命題Aが真(1)の時は偽(0)に、偽(0)の時は真(1)を表す論理関数。
    XOR
    排他的論理和
    2つの命題A、Bがともに真であるか、ともに偽であるとき真である論理関数。
    NANDNOT ANDの略、ANDの結果をNOTする。
    NORNOT ORの略、ORの結果をNOTする。

    とりあえず真理値表でも書いておきますか。
    AandBAorBnotAnotBAxorBAnandBAnorB

     例えば
      A=本来のデータ
      B=暗号化するキーコード
      C=AxorB
    
    Cが暗号化されたデータとなるわけです。
    C値からAを得るにはBが判別すれば逆算できます。
    暗号化時にBを可変にすると更に暗号化されます。

  6. チェックサムってなんですか?
     例題:以下のデータを1バイト単位で加算し、その結果の下位1バイ
        トをこのデータのチェックサムと定義すると。
    
     データ1:0x12345678
     データ2:0x1023984F
    
    計算式:0x12

    0x34

    0x56

    0x78

    0x10

    0x23

    0x98
    0x4F
    −−−−−−−−−−

    0x022E

    チェックサム値は0x2E

    ここで、これをセーブデータと仮定すると途中の値を変更すると、チェックサム値が同じでない値になる確立は256分の255で、偽データを見破ることができます。
    元々は通信データのデータ化けチェック等に用いているが、改ざんデータチェックにも使える。

  7. あるデータが不必要なデータであると推定できたのはなぜ?

    たぶん、深読みにハマっていらっしゃいます。
    私の様な本職がプログラマでも他人のデータを一読して「これは・・・だ!!」などと断言できる訳ではありません(そういうことも偶にはありますが、ほとんど無いです)。
    前回書いた通り、明らかに必要のないデータは、先ず目で見て判断が付く範囲です。
    日本語表示可能なバイナリーエディタで見れば、都市名やスタッフロールは直ぐにでも分かります。
    また、ビジュアルC++でDLLを作ると、データとデータの間にムダなブランクを作るらしく、0x00や0xFFダケで埋められた範囲は除外する項目となると同時にあるデータと次のデータの区分をする指針になります。
    後は解析したい内容(今回は開発関連)に注目して、残ったデータの一部を少しづつ書き換えていって、その結果がどう反映されるor反映されないかで「この辺は無関係らしい」とか「この辺は関係ありそうだ、もう少しこのあたりに重点を置いて見るか」などとやって行くわけです。

  8. 解析するためには、どんなツールが必要なのでしょう?

    基本的に必要な要素を考えましょう。
          A)バイナリーでは人間には読めませんのでバイナリーデータを数字に
            変換して読める様にするためのツールが先ず必要です。
            いわゆる、dump(ダンプ)ツールと言われるのがこれですね。
    
          B)dumpデータを更に読みやすくするために数値データを文字デー
            タと仮定した場合、それを文字として変換してくれるツールがある
            と便利です。
    
          C)バイナリーデータを低レベルで簡単に加工でいるエディターがある
            と便利です。
    
          D)2つのファイルの相違を抜き出せる比較ツールがあると良いでしょ
            う。
            これはUnixやDOSのコマンドでも存在します。
    
          E)思いついたキーワードをデータの中から検索してくれるツールがあ
            ると便利です。
            これは、アリ物のツールで有ったかな?
    
    上記ABC、3要素を合わせ持つのが日本語表示可能なバイナリーエディターです。
    ただし、日本語表示可能なバイナリーエディターは必ずしも万能ではありません。日本語とは言いましたが日本語文字コードは複数あります。
    JIS、SJIS、EUC、UNICODE、半角カナ文字、機種依存文字。
    全コードを表示してくれる日本語表示可能なバイナリーエディタなんてたぶん無いでしょう。
    また、2バイト文字と1バイト文字が混在すると表示がおかしくなるツールも珍しくありません。
    ツールだけに頼る解析は解析限界もしれています。
    したがって解析をどこまで行うかによってはこれでは対処できないこともあります。
    また、解析にかかる時間も、ツールだけに頼るとムダが多くなることもあります。
    この限界を超える解析をしたければ自分で必要なツールをそろえるしかありません。
    一番の近道はC言語等をおぼえて、必要なデータは自分で抜き出せてたり、自分の思うように変換できたりできるように自分でツールを作ってしまう事です。
    急がば回れですね。
    別に、アリ物のツールを使うなとは言ってません。
    アリ物のツールの限界を越える方法は自分でツールを作るしか無いって事です。
    少数のデータ変更だけならバイナリーエディタで事は済みますが、インテリジェントに膨大な量のデータを編集したい場合はエディターでちくちく変えていくことはかなりの苦痛です。
    また、タイプミスで全ての努力が無になることは珍しくも無いでしょうし、それを承知で行うことはかなりの忍耐力の消費をともないます。
    それと比較すれば、C言語等で簡単な専用のツールを作り出す方が明らかに寛容です。
    バイナリーエディタによるデータの書換えはあくまでも低レベルであることを認識していなければなりません。

  9. Lear教官が解析している時の作業風景はどんな感じなのでしょう?

    メモは取ります。
    紙の時もありますし、画面上にエディタを開いて書いて置くこともあります。
    作業の2/4は考えてます。
    1/4は自作ツールのデバックや機能変更です。
    1/4はトライ&エラーです。
    仕事場の空き時間にやってますので機材には事欠きません。
    目の前には20インチモニター2台にPC2台(1台は私物)とWS(ワークステーション)が1台が繋がってます。
    3台ともLANで接続されているのでファイルのやり取りも簡易です。
    キーボードは同じものを前後に2つ、その内、キーボード切替え機で1つにしたいです。
    マウスは右がWS、左がPC。
    そう、私は左手でもマウスが使えます、ちゃんと設定は左効き用に変えてます。

  10. LZ法+Huffmanで圧縮されたデータは、どうやって戻すのですか?

    「圧縮理論の推定が正しければそれを紐解くことはそんなに難しいことではありません」とは書きましたし、ウソではありませんが、プログラマ達はもっと手抜きな事が多いです。
    圧縮理論うんぬんの前に同じ圧縮を使い回す事が多々あり、しかもその道では誰もが知っている「例題をそのまま」ってのが良くあって、圧縮理論を追いかけたことは・・・・あったかな?・・・・あったよな?
    LZ法の場合、LZ77とLZ78と言う有名どころでは2種類あるのですが、実装の簡易さでLZ77ばかり使われてる様です。
    私はそれほど解析はやってない?のでサンプルにはなりませんが聞くところによるとLZ78を見たこと言う話をお目に掛かったことが無く、私も見てません。。
    LZ77とLZ78に関しては「Cによるアルゴリズム辞典」に例が載ってます。
    手抜きな場合はこのサンプルそのままで圧縮されていることすらあります。

    さてLZ法はこの辺で逃げといてHuffmanどうしよう。
    目の前に「データ圧縮ハンドブック」があるんだけど、Huffmanダケでもけっこうなページあるな。
    Shannon−Fano法とか二分復号木とか分かればかなりはしょれるんだけどそうは行かないみたいだし・・・。

    そもそも、ここまでくるまでに越えなきゃならないハードルは結構ある(例えば高級言語が使えるようになるとか)のと、この段階まで来れば自ずと自分で調べて、理解しない限り使えないのでパスしま〜す。
    #ああ、逃げた。
    #お願いです、撃たないで下さい・・・ギャー・・・。

  11. なぜ他の論理演算でなくXORを使うのでしょう?

    やっぱ、そこに来ますか。
    論理回路とはなんぞやと軽く説明しておきます。
    先ず、論理回路の内、AND,OR,NOTは基本中の基本だと心して下さい。
    実はXORはAND,OR,NOTの簡単な組み合せなのです。
    AxorB =
       (Aand(notB))or((notA)andB)
    または
       (AorB)and(not(AandB)
    
    良く、このCPU(とかMemoryとか・・・いろいろ)は???万ゲートとか言いますが、このゲートってやつがAND、OR、NOT(+NAND、NOR、XOR)と言われる基本論理回路の大ざっぱな数を差しています。
    コンピュータが0と1の組み合せでできていると言うのもこの辺でイメージできるでしょ?
    つまり、コンピュータの中身はこれの組み合せでできています。
    この話をすると、ではどうやってメモリーは記憶を行っているのかとか出てきそうですが・・・情報量1ビット(つまり0か1)を記憶する回は例えばFlipFlopと言われる回路でできているとか・・・・止めよう。
    深みにはまりそうだ、質問が来たら考えよう。
    まあ、「コンピュータの中身はこれの組み合せでできている」だけおぼえておいて下さい。

    で、基本的論理回は基本なので、CPUのアセンブラ命令に実装するのが簡単、高速、安上り(アセンブラ1命令に対して少ないゲート数で実現−>だから速い)です。
    しかも、種々と便利なんです(この辺は説明するのが難しいんだけど)。
    でもって、何でXORかというと。
    1.AND、ORではデータを元に戻せない
    2.NOTは単純すぎて元のデータがあっさり分かってしまう。
    3.XORはNOTほど単純ではなく、ちょっとだけ複雑でしかも高速
    だからです。

    ただし、XORをかける1回あたりの大きさがあまり大きい(1バイトを越える)とXORの臭いが読み取れる事があるので、通常1バイト単位でかけますが・・・それを何で?と言われるとかなり説明が長くなるので今回はここでカット。

  12. データはどうやって抜き出すのか?

    >バイナリエディタからカットして、テキストエディタにペーストし、整
     形するなんてことではあるわけないですよね。一体どのような方法で、
     あの膨大な兵器データをお作りになったのでしょう。

    この回答は簡単です。
    半自動的にHTMLファイルを作るところまで行うツールを作りました。
    流石に、エディタでカット&ペーストだと不正確で完成もやばそうなのは直ぐに推論できますから力技は即放棄しました。
    使用言語はCでOSはUnix、WindowsでやるとWindowの設定とかやんないと表示すらできないのでパス。
    DOS上のCは今は無いので不可。
    男はだまってGNUでしょう。(ウソ)
    全てを1回でかたずけることもできますが作業は2回に別けました。
    1. DLLから兵器名を引っぱり出してそれだけのデータベース(テキスト)を作成。
    2. DLLと名前データベースからデータを引き出してHTMLを作る。
    1.の段階ではまだ日本語兵器名とかも残ってたのですが、HTMLにもあるように機種依存文字とか日本語兵器名が無い兵器の対処が大変なのでバッサリ削除です。
    兵器名は逆さに登録されているので順序は引っ繰り返しました。
    兵器名のズレは力技で治しました。
    これは、この方が速いと判断したためです。
    だから、DLLが変ると使えません。

    2.で問題なのがSJISコード。
    通常、SJISではソ連の「ソ」とか図表の「表」の時がfprintf関数では書けません。
    理由はSJIS、2バイト文字の2バイト目が0x5Cでこれは1バイト文字の「\」=「¥」と重なるのですがこの文字はprintf系関数の制御文字とバッティングするからです。
    『SJISの危ない文字の羅列一覧』
          ― ソ Ы 噂 浬 欺 圭 構
          蚕 十 申 曾 箪 貼 能 表
          暴 予 禄 兔 喀 媾 彌 拿
          杤 歃 濬 畚 秉 綵 臀 藹
          觸 軆 鐔 饅 鷭
    
    全てEUCとかで書けば良いのですが、DLLの中身はSJISだったので文字の比較はSJISにしなければなりません。
    つまり、プログラム内に文字コードが複数存在したりします。
    これでは間抜けなので文字コード変換関数なり、外部コマンドなりを使う予定でしたが、完成速度優先で、データやプログラムをSJIS系とEUC系に分離して対処。
    こう書くと、カッコイイプログラム書いてる見たいですがソースは・・・・ダサイな。
    文字にだまされては行けません。
    C言語を書ける人なら、誰でも書けるレベルの簡単なプログラムです。

SiteTop
(c) ロドリゲス学級OB会 All rights reserved. 1997-2003Last Modified 2003/11/05 02:48:03