@ss_site

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

オブジェクト生成物の確認方法とは

Q&A

Closed

はじめまして底辺技術者です。
働いていると、正解が分からないことに翻弄されます。

例えばです。
ソースコードを書き換えたとして、
編集前後で動作が変わっていないことを確認したいとき、コンパイル・リンクした生成物(オブジェクトファイル)が一致すれば、動作が変わらないことが確認できたと言えると思います。

そのオブジェクトファイルの一つに、バイナリファイルがあります(※1,2)が、これが大抵うまく一致してくれませんでした。

本当にソースコードの動きが変わらない場合でも、一致が確認できないことがあります。
ネットでは「32ビット以上のマイコンだと日付情報を埋め込みがちだから」とか、「コンパイラによりけり」とかでオブジェクト生成物が一致しないという情報が出てきました。ただ、こういった一致しない原因に関する情報はしばしば出てくるのですが、バイナリファイルの見方やこういう文字コードはこういう情報が入ってるかもといった具体例はあまり見かけません。

このオブジェクトファイルが一致することが確認できると、
ソースコード編集前後で動作が変わっていないことが確認できて評価に有用である。や、開発環境の構築手段として、生成物が一致することを確認することが有用である。といったことが言えます。

生成物に差分が生まれたときはどのようにして、日付のみ差分であることなど述べるとよいのでしょうか。
コンパイラや機械語のしくみを理解するしかないのでしょうか。
こういった事柄にとどまらず、日々正解をつかめずにいます。

※1 バイナリデータとは「テキストデータ(文字だけのデータ)以外のデータ」
https://wa3.i-3-i.info/word1147.html

※2 バイナリ比較の意義とは
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11236273851?__ysp=44OQ44Kk44OK44Oq44OV44Kh44Kk44Or44CA5q%2BU6LyD

文章力は壊滅的なためご容赦ください。

Ps.たくさんのご回答ありがとうございました。
質問文章もかなり読みづらい文章で、てっきり壁打ちになると思っていましたため、回答いただいていて少々驚いています。解決に至ったわけではないですが、自身の至らなさと諸事情でクローズしようと思います。ありがとうございました。

1 likes

4Answer

私ならデコンパイル後のコードが一致すればオブジェクトファイルが多少変わっても問題なしと判断すると思う。人間だもの。

2Like

Comments

  1. @ss_site

    Questioner

    デコンパイル…初めて聞きました。
    世の中にはそういった手法もあるのですね。
    ツールやソフトを使ったことがありません;
    メモリから無理やり書き起こしたコードを用いて適正か評価するとは凄いですね。
    調べてみましたが、なにが正しそうか読み取るのが逆に難しそうです。

    そもそもコンパイラを詳しく理解していないため、時間を要しそうです。
    ご回答ありがとうございました。
    (以下は参考に読んでみました。リンクべた貼りで申し訳ないです。
    https://rightcode.co.jp/blog/information-technology/c-language-gdb-decompile-vernam-cipher-decryption
    https://corgi-lab.com/programming/c-lang/reverse-assemble/
    http://www5d.biglobe.ne.jp/~noocyte/Programming/Decompile.html#CDecompilerPossiblity)

  2. なにが正しそうか読み取る

    細かい読取はしません。バイナリの比較で差分があっても、同じ環境でデコンパイルしたソース同士の比較一致をみれば明白と判断。

    無理やり書き起こしたコード

    コンパイルの逆をやっているだけなので変数名とかは適当になりますが、
    バイナリを見るより人間的です。
    各CPU向けのコンパイラに対する学習コストも不要です。
    ただ、商用商品にかけるとリバースエンジニアリングになるのでご注意ください。

参考記事:
https://jpdscore.github.io/blog/vs/identity-of-build-artifacts-from-identical-source/

(生じないはずの)差分が出た場合、バイナリ比較をしてみると勉強になると思います。

コンパイルオプションで逃げ切れるならそれがベスト、できないのであれば、まあ、割り切るしかないと思います。ソースコードのdiffでもって担保したりとか。

ただ実開発において、バイナリが変わらないような微修正って、そんなに多くないと思います。よって、本件に多大なる工数を掛けるのはやめたほうがいいかなと。。。

1Like

Comments

  1. @ss_site

    Questioner

    まさに、参考記事に上げていただいた記事を拝読しました。
    >差分が出た場合、バイナリ比較をしてみると勉強になると思います。
    ご教授ありがとうございます。バイナリ比較で差分が生じた場合の具体例は環境によるので、どこかに載っているわけではなさそうですね。
    makeの命令を根気強く追いかけたり、コンパイラの環境を比較したりして整えるほどしか言いようがないのかもしれません。

    特に身の回りでも、以下の部分が議論されます。(記事から引用)
     >1.ビルド環境 (OS や Visual Studio など) の移行を行うので、移行前後の成果物を比較してビルド環境に問題がないことを保証したい
     >2. ビルド毎に得られる成果物をバイナリ比較することでそれらが同等であるかを確認し、再テストや再リリースの要否を判断したい

    記事の中では以下のように前置きの結論がある上で、「ソースコードやリンクされるオブジェクト類が同一であれば、同じビルド ツールによって生成されるビルド成果物の動作や機能に相違が生じるようなことは通常ありません。」と括られていました。(記事を要約)
     1.ビルド成果物は同一にならない可能性がある。
      同一になったとしてもビルド環境に問題がないことの保証にもならない。
     2.同一のビルド成果物を得るための環境や、前提条件と、ビルド成果物に相違が生じる要因やビルドツールの対応状況について理解することが重要。

    >ただ実開発において、バイナリが変わらないような微修正って、そんなに多くないと思います。
    コードを整える程度の微修正を行った場合を想定していました。
    ご回答ありがとうございました。

例えばです。
ソースコードを書き換えたとして、
編集前後で動作が変わっていないことを確認したいとき、コンパイル・リンクした生成物(オブジェクトファイル)が一致すれば、動作が変わらないことが確認できたと言えると思います。

商業でいちいちバイナリの比較なんてする人いないと思います.
コンパイラっていうのはほんっっっとに低レイヤー向けにソースを変換する以上そんなもんの評価は現実的に不可能なので,世の人はふつうテストを書きます.
プログラムに期待する動作ってほとんどの場合は事前に規定があると思いますので,その通りに動くかどうか検証用のソースコードを書くわけです.
テストが何者なのかは検索すれば大量に出てきますので割愛します.

1Like

Comments

  1. @ss_site

    Questioner

    >商業でいちいちバイナリの比較なんてする人いないと思います.
    >コンパイラっていうのはほんっっっとに低レイヤー向けにソースを変換する以上そんなもんの評価は現実的に不可能なので,世の人はふつうテストを書きます.
    ご回答ありがとうございました。
    バイナリ比較といった言葉をたびたび耳にしていたため、商業で比較することない、ふつうはテストといったご意見に目から鱗でした。
    言語がCのため、低レイヤに位置しているといえるかもしれません。
    私自身は技術力がかなり疎く、テストするにも何事にも時間を何倍もかけてしまうので、効率的な評価方法を探しておりました。

コンパイラの生成物にはタイムスタンプやソースのファイルパスが含まれることがあり、入力が同じでも生成物が一致しないことは往々にしてあります。一例として、 C/C++ コンパイラにおいて生成物に影響する要因が以下のブログで紹介されています。

ソースコードが同じとき、他の不定な要因を固定するか排除して、複数回ビルドしても同じ生成物が作られるようにすることを reproducible builds あるいは deterministic builds といい、言語やコンパイラごとに異なる手法が知られています。概要は以下のサイトにまとまっています。

なお、 reproducible builds は同じソースコードに対して同じ生成物ができることを保証したいときに使えますが、ご質問のようにコードを変えても挙動が同じなら同じ生成物を作りたいというときにはうまくいかない気がします。挙動が変わらないことを保証するにはテストのほうが向いています。

1Like

Comments

  1. @ss_site

    Questioner

    >コンパイラの生成物にはタイムスタンプやソースのファイルパスが含まれることがあり、入力が同じでも生成物が一致しないことは往々にしてあります。
    そのようです。

    ご紹介いただいたブログ読みましたが、今の私には難しく厳しい内容でした。
    せっかくいただいたのに申し訳ありません。
    ひとまず、「reproducible builds あるいは deterministic builds」といい、
    和訳分では、決定的ビルド、再現可能ビルド、密閉ビルド、と表現できるのですね。
    リファレンスのご紹介もありがとうございました。
    コンパイラについて強くならないといけないかもしれません。
    ご回答ありがとうございました。

Your answer might help someone💌