逆コンパイラCodeReverseを作る
■ このスレッドは過去ログ倉庫に格納されています
CodeReverseは、片山博文MZが開発している、Windows用の逆アセンブラ兼ダンプツールです。
最終的には「リバーシブルな」逆コンパイラを目指しています。
CodeReverse公式サイト
http://katahiromz.web.fc2.com/codereverse/
GitHubレポジトリはこちら
https://github.com/katahiromz/CodeReverse パッと思いつくのは
・アドレスにラベルを割り付ける
・関数を切り分ける
・スタックフレームから関数引数・ローカル変数・戻り値を切り出す
・if/for/switchを抽出して構文化する
・DLLからロードされるシンボルを置き換える
解説しているサイトとかあるかは調べてないので知らん
どうせ defineされた定数をマクロ名に戻せないとか
構造体復元が難しいとかあるから大したことはできん このスレッドは天才チンパンジー「アイちゃん」が
言語訓練のために立てたものです。
アイと研究員とのやり取りに利用するスレッドなので、
関係者以外は書きこまないで下さい。
京都大学霊長類研究所 ネタスレはマ板でやれよ。
> Cの逆コンパイラはどこまで実現可能か
アフィサイト晒してんじゃねーよ。 内容もちょい微妙だし。
まず、アセンブリから C/C++ へのトランスレータは簡単だろ?
そっからどの程度 C/C++ らしい表現にするかが問題なんだろ?
何から手を付けてどういう順番でやるつもりなの。 まずは関数の切り分け(手元では入り口を解析する形でほぼ完了)。次は関数情報とスタックフレームの解析。
そして中間表現の定義と中間表現への変換。さらに構文解析と型情報の処理。
トランスレータって言ってもそんなに簡単じゃない。
リソースのダンプでいいのないか(オープンなの)? 関数には__cdecl、__stdcall、__pascal、__fastcall、単純ジャンプ関数の五種類あるんだけど、これをどうやって判別するかという問題がある。
遅延ロード情報の取り込みもしたい。ソース希望。 OllyDbgじゃダメなんか
分かってる人には充分だろ ネタスレではありません。私は本気です。明日、OllyDbgのソースをDLしてみます。
CodeReverseは、NASMのコードを一部拝借しています。
多分、構文解析用のインクルードファイルが必要になると思います。
MinGWから頂くかも知れません。ライセンスはどうするか? アイコンのデザイン、洒落てるでしょ? >>11
> MinGWから頂くかも知れません。ライセンスはどうするか? アイコンのデザイン、洒落てるでしょ?
MinGWのソース使ったら、配布するときのライセンスはGPLになると思う。
一部パブリックドメインらしいけれど。 アムロの親父みたいに俺の親父もボケてしまった。
たしかに昔はある分野で日本一の技能をもってた。俺の目標は親父だった。
今は硬い世界の殻に閉じこもってしまって、もはや日常会話しか通じない。 うーむ、今のところこの世にまともなC/C++の逆コンパイラが
存在しない事を考えても片山程度の技術力で作れるとは思えんが・・・ ヘッダファイルもプリプロセッサも要るから、単純にMinGWに寄生する形にします。
バージョンアップの度にいちいちでっかいファイルをダウンロードさせるのも不憫だから。
ライセンスはGPLになる予定です。 つーか、片山GUIはどうした?予想通り挫折したのか?
そんなんじゃ逆コンパイラなんてもっと無理だろ 自動車の命はエンジンでしょ。GUIは後で自由に作れるから。 >>19
そういう問題じゃねーだろw
お前にはモノを最後まで作り上げる能力が無いって事だ
あれだけWin32APIやMFCに代わるGUIを作るって豪語してたろ
多分お前はこの逆コンパイラも作れないし、後になってもGUIも作れんよ まあ一人で色々作ってたら未完成になることは多い。
そういう未完星人の同類なら、GUI作りくらい協力してやってもいい。
だが残念だがそれは無理だ。なぜなら彼が作っている物は俺よりしょぼい。
もはや彼が俺に「あなたのプロジェクトに協力させて下さい」と頼まなければいけないレベルなのだ。
残念である。世の中は不条理に満ちている。 まあ誰もが出来ないと思ってるよ
グラフィックライブラリもこれを最後に音沙汰なしだしな
975 名前:片山博文MZパンク ◆0lBZNi.Q7evd [sage] 投稿日:2013/03/21(木) 03:21:59.90
MZC2順調に開発中。。。 順調に開発中クソワロタwww
どこが順調なんだよwww CUIの有り難みがわからない人とは話しが合わないっす。
CUIにパイプラインをつなげてGUIを作るなんてお茶の子さいさいっす。
俺はサイドビジネスで忙しいから、空いた時間で作ってるっす。
CUIの使い方も知らない人はうざいから消えてね。 ふーむ、CUIのありがたみがわかってる人間がなんでわざわざ
二番煎じのGUIを作ろうと思ったのか。しかもオリジナルより劣化してる。
更には、お茶の子さいさいと言いながら、いまだに何の成果物も出せないのはこれいかに。
>>23のレスからもう半年も経過しているが。 俺は貴様らよりも自由じゃないから。夜遊びはできないし、インターネットに
つなげてもらえないし。パソコンの使用時間は制限されてるし。
この書き込みも見張りに見つからないように携帯から書き込んでいるところ。 こりゃアカンで。ちょっと期待してたらどうやら>>1の人格・人間性に
相当の問題アリやな。 クロスワードギバーというパズル作成ソフトで結構反響あった。MZ KeyLoggerもわりと人気あるし。 そうそう幅広くニッチなところ狙ってけ。おまえはわけのわからんものを大量に発明して東京都知事選に変態枠で出馬するようなタイプなんだ。 × 大量に発明して
○ 大量に「発明するぞ」というだけ言って >>32
当選は枠があるけど出馬は出たきゃ出れるんじゃなかったっけ? エクスポート名の@の右の数字は引数全体のサイズだよね? で、__stdcallの引数全部のサイズが命令retの第一オペランドの値だよね?
そして、スタックフレームはebpとespの値の増減を調べないとわからないんだよね? >>9は間違いね。__pascalなんてないし、64ビットに言及がないし、単純ジャンプ関数って何じゃそれ >>35-36
Win32 べったりの話? 何にも知らないんだね。
DEF ファイルを使った DLL からのエクスポート
で検索してご覧、MSDN 内のページが引っかかるから。
悪いけど、主要な(少なくともターゲットとする)コンパイラやアセンブラやリンカのマニュアルを読んでから質問してくれる?
ていうかブログでやってくんない? ブッブー、defファイルではなく__stdcall,__fastcall関数のmanglingの話でした。
manglingされたシンボル名から元の名前を求めるのは大変みたいですね。 >>43
まぁだがコンパイラ毎ではあるもののマングリングは明確な規則で行われてるわけで…
それを難しいとか言ってるようではC/C++コードへの復元とか夢のまた夢だわな。
呼び出し規約と関数内のレジスタ利用方法の規約ゴッチャにしてる辺りも残念すぎる。 v0.0.1にバージョンアップしました。
関数の切り分けができるようになりました。
課題1:DisAsmメソッドの中で各関数の種類(FUNCTIONTYPE)を確定させる。
また、各関数の引数全部のサイズを求める。関数内関数の対処。 全パターンぶんデマングルしてみてうまくデマングルできたやつを採用すればいいんじゃない g++の場合は、プログラムc++filtで解読できるようです。
gccの場合はわからない。
VCの場合はdbghelp.dllのUnDecorateSymbolName関数で。
UnDecorateSymbolName function
http://msdn.microsoft.com/en-us/library/ms681400(v=VS.85).aspx 正直ね、片山さんのその技術力で
逆コンパイラじゃなくて
C#とD言語を上手く改良したような実用できる言語作ってほしい
逆コンパイラの都合のいい言語みたいな感じでもいいから。
そしたら実装も楽になるかもよ。
これ作るついでにやってみてくれないかな? ネイティブC#みたいな位置づけのさ。
D言語だと正直不安定すぎて使えなさすぎなのよ Microsoft C は、シリアル番号をオブジェクトファイルに
埋め込んでるってうわさ話があったな... >>53
そんな速攻で検証できそうなことをわざわざするかなぁ……? 課題2:アドレスからスタック状態集合への写像
課題3:コンパイラの種類を判定するコード
課題4:アセンブリ命令が何を参照し、何を変更するかの情報
課題5:データ型の管理方法
これらに関して知ってることがあれば俺に教えて下さい。 次のリリースは、pimplで読みやすいコードになる予定。
今までの人工知能研究の全てを注ぎ込んで、頑張りますのでご声援を。 コントロールパスというのがよくわからん。単純にプロファイルするとループで無限長になってしまうよな。
掛け算と割り算のキャリーとオーバーフロー条件の違いもよくわからん。 v0.0.2にバージョンアップ。
コードの整理。insn*.datファイル、mzc2mini.{h,cpp}ファイルの追加。
関数内関数の対処。 insnはinstructionの略でアセンブリの命令のこと。
次は、コントロールパスとスタック状態の取得に挑戦します。 サイドビジネスで疲れてMPがない
妙なバグがまだ取れてない
頑張るしかないか コントロールパスの組み合わせが無限になるバグが修正できない。
ループは排除したのに。 無限大じゃなかったけど、コントロールパスが768通りって多すぎないか? コントロールパスよりもCFGの方が重要だとわかった。目標が間違ってた。 型情報がない状態で、レジスタとスタックの使用状況がわからないと、
関数の呼び出し規約や引数は分析できませんね。
insn16.dat/insn32.dat/insn64.datファイルに書かれているような
中間表現によって、アセンブリとC言語ソースをつなげようと
考えています。 そりゃそうだ。リバースエンジニアリングってのはどちらかといえば破壊行為だし。
この板の連中はおまえの想像以上に生産的(破壊的の反対)なんだよ。 それ以前に「どうせ無理だろ……」と多勢が思っていることもあるだろうね コンパイラが多すぎて全部はソースに変換できないって分ってからなぁ・・・
そしてコテ的に>>76 彼でも1〜2年で限定用途なら可能だろうし
5〜10年も頑張れば実用レベルのが出来るんじゃないかな?ただそれだけ頑張った見返りがあるか疑問だが。 >>74
興味ありますよ頑張ってください応援してます しばらくスクリーンセーバーの開発に時間を割くことにします。GUIはwxを採用します。 MZC使えよバカ、作った人にも使われないなんてよっぽどだな(笑) 馬鹿がまた飽きたのかwww
こいつ本当に何一つ最後まで作れないなw 仕事の合間にLinuxのスクリーンセーバーをWindowsに移植したら、海外から何件か要望が来た。
要望の多い方を優先する方針。すまない。何ならGitHubで開発に参加してくれると助かるのだが…。 まあ簡単な方から片付けていくのが効率的人生の鉄則ではある。 クッソワロス、やっぱり最初に言った通り途中で挫折したw
ちなみに、こいつが途中で他のを優先すると言って
また開発に戻った例は無いぞw スクリーンセーバーの移植が終わったので、CodeReverseの開発を再開します。 Windows 系の .exe .dll を逆コンパイルするので分りやすいコードを吐いてくれるのは
今って何が高性能?
C#ぐらいの言語っぽいのだと分りやすいんだけど 機械語からの逆コンパイルは大抵ろくなコードが出てこない。
マトモなコードになるのは中間言語からの逆コンパイルくらいだな。
.NETやJavaやActionScriptやHSPの中間言語は結構普通の逆コンパイル結果が得られる。 逆コンパイルで出てきたコードを書き換えてコンパイルしようという訳じゃないんだ。
機器のログを表示するソフトのデータ読み込みにバグがあるみたいで
自分で表示用データを出せるプログラム作ろうとしたら一部計算式が分らない
三角関数だろうけど >>103
だから中間言語使った実行ファイルなら逆コンパイルも実用になるけど、
機械語使った実行ファイルの逆コンパイラはなかなか実用にならんよ。
たぶん逆アセンブラがなんだかんだ一番実用的だと思うぞ。
その.exeや.dllが中間言語使ってる実行ファイルかどうかは知らん。
.NETあたりだと逆コンパイルも楽だから.NETだといいね。 アセンブラは機械語と一対一に対応しているとよく言われるけど、
実際は対応していない。
同じアセンブリでも配置によって複数の機械語から特定のコードを選択
しなければならないプロセッサはよくありがち。
いろいろ面倒だよ。 >>103
ログ読み取りに不透明要素を持ちこむな 本末転倒にもほどがある >575 名前:片山博文MZコスモ ◆T6xkBnTXz7B0 :2013/12/31(火) 22:44:07.54
>2013年の実績:
>クロスワードギバーを完成。
>XScreenSaverの200個以上のスクリーンセーバーをWindowsに移植。
>逆アセンブラを途中まで作成。
いつのまにか逆アセンブラにグレードダウン(笑)
なんというか、「〜をダウンロードした」とか「〜を勉強中」など
どうでもいいことは大声で宣伝するが、重要なことは何も言わないとか・・・ ネタギレです…しばらく保守になります。
この停滞状態が我慢できなければGitHubでPull requestしてね 都合が悪くなると名無しで発言するんだな、発言の内容からして本人であることは明白なんだが 無駄にはならんと思うが、つまみ食い気分で買うにはちとお高いよ アマゾンギフト券2000円を買ったぞ
中古のドラゴンブック買うぞーー! ドラゴンブック、1000円くらいの中古を買っちゃった!!!!!
さあ、ドラゴンと戦うぞ!!! 「コンパイラI原理・技法・ツール」が家に届いたぞー
戦闘開始! コンパイラ「ロバwwwwwwwwwwwwwwwwwwww」 RE: Bison Windows m4 problems
bison: cannot open file `data/m4sugar/m4sugar.m4': No such file or directory
https://lists.gnu.org/archive/html/help-bison/2010-03/msg00015.html
空白を含むC:\Program Filesにインストールしちゃ駄目らしい。やり直し。 これも必要
set BISON_PKGDATADIR=C:\GnuWin32\share\bison 報告。ドラゴン本第三章まで読了。左再帰を右再帰に直す方法を学習した。
フロントエンド、フェーズなどの用語を習得した。
GNU Win32 Bison(Yacc)+Flex(Lex)のインストールに成功した。
引き続きBison+Flexの使い方を勉強する。 あれ、逆コンパイラじゃなかったの?
フロントエンドよりバックエンドの方が重要だろう
俺が知らないうちに方針が変わったのかな どうでもいい。アホは自由だけが取り柄、好きにすればいいじゃない。 bison+flexで作ったパーサーを2つ以上取り込むことができないから、Cはダメだな、C++にしよう ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/cdecl-2.5.tar.gz
ここにcdeclというプログラムのソースがある。これを分析する。 最近はPEGを使うのが流行りなのか? ちょっくら調べてみるか パーサジェネレータの勉強を兼ねて電卓を作ってます。 bison/flexのパーサーが複数使えないって
片山はマニュアルが理解できないのか Windowsではまだmodern Bison++(3+)は入手できない。
それにC++に関してはまだ実験的らしい。
すぐに使えなくなりそうなコードは書きたくない。
だからANTLR3を使うことにした。 Type [q or Q] to quit
> 871263948761872364871623946182973164+8761928734912634183412379461874234
Result is: 880025877496784999055036325644847398
> s=92183019827349179203471
s := 92183019827349179203471
Result is: 92183019827349179203471
> sin(s)%100.3
Result is: 0.7484296692622107891527456053804399259219719456829430374497200718368
9079690554390091960884209113407122218168687650754654152155867
> __extension__とか__builtin*とか処理が多いなあ。 ANTLRでFOLLOW_set_in_問題が発生した。これも使えないのか。。。 bison-3.0.2をビルドしようとしたが失敗。
CaperとPEGを試してみる。。。 Caperは生成に時間がかかる(Core i5で10分)。しかもできるものが非常にでかい。 Cパーサのプロトタイプができたよ!!!!
http://katahiromz.web.fc2.com/mathai/cparser2.zip
storage class関連の文法の見直し、並びにT_TYPEDEF_NAME,
T_TYPEDEF_NAME_FIRST, T_TAGNAMEなどの特殊なトークンが必要だった。
それにしてもCaperは時間がかかりすぎ。。。やっぱりBisonが最強かなと思い始める。。。 >>145
あんた偽物だろ。
片山先生ならなぜ時間がかかるかまで調べて教えてくれるはず。 さあ、caparの高速化に挑戦するぞ。開発環境はMinGW+MSYS。
まずは、計測。
$ time ./caper.exe -c++ cparser.cpg cparser.hpp
real 7m50.856s
user 0m0.015s
sys 0m0.000s
7分50秒もかかっていることがわかる。
g++のコマンドラインに-pgをつけてビルドすると、
関数の処理時間などをプロファイルするCaperの出来上がり。
$ ./caper -c++ cparser.cpg cparser.hpp
を実行すると、ファイルgmon.outが作成される。さらに
$ gprof caper.exe gmon.out > gmon.log
と入力すると、人間にも読めるgmon.logができる。
...(中略)...
その結果、
real 0m31.862s
user 0m0.000s
sys 0m0.031s
となり、30秒程度で処理できるようになった。めでたしめでたし。
http://katahiromz.web.fc2.com/mathai/qcaper.zip @jonigataさんのCaperが劇的に高速化されたらしいぞ!!!
github.com/jonigata/caper 汗から関数を切り出すのはできた。汗コードから関数の引数の個数を判定する方法がわからない。
最近汗やってないな。。。 雑用とか色々有って忙しいんだよな。
C2EXEの作者でも降臨して手伝ってくれないかなあ〜。多分連絡取れないんだろうな。 最適化なんてどうでもいいから、早くASTを構築しろって上司に怒鳴られた。
すなおに実装してみるか こうして見返してみると馬鹿なコード書いてるのがわかるな。。。
書き直そう。 github.com/katahiromz/CodeReverse
更新しました。パースルーチンを追加。コードの近代化。
ライセンスをThe BSD 2-Clause Licenseに変更。
さあ、どんどん作るぞ!!! x86アセンブリから関数の引数のサイズを求める方法がわからない。知ってる人、教えてよ そういうのはプロジェクト立ち上げる前に解決しとくと子だろ 途中何も読んでないから的外れ言ってたらすまんこまんこ
引数はPUSH最後からPUSHで行って、最後にリターンアドレスをPUSHして関数をcallする
arg3
arg2
arg1
retaddr
引数が4バイトで3つの場合、呼び出し直後のスタックはこうなる 関数呼び出し規約の違いは引数の分のスタック処理を誰が責任持つかの違い
__stdcallは呼び出された関数が最後にスタックを整理して返る
__cdeclは呼び出し側がpushした分だけスタックを整理する
__fastcallはcallする前にpushじゃなくて最大2つまでレジスタに値をぶっ込んでからcallする
__thiscallはcallの直前にecxにthisポインタを入れてから呼び出すが、スタック処理は_規定では_stdcallと同じ
関数内でecxにあれこれしてローカル変数っぽいのを弄ってたらなんかしらのクラス決定
__cdeclを指定されたり可変個引数だったりするメンバ関数は、thisポインタを最後にスタックに積んだ気がする __fastcall調べたなら「スタック処理を誰が責任持つかの違い」じゃ無いことは自明だろがアホ
あとx64だとかなり様変わりする ごめんニワカなんだすまんこまんこ
__fastcallは3つ以上引数取るときには3つめ以降の責任は__stdcallと同じだったはず
x64はほとんどレジスタで引数やりとりするんだっけ?全く詳しくないが 「引数の渡し方からしてそもそも違う」のに「誰が責任持つかの違い」に限定しなきゃいかん理由は何なんだ。 型システムは70%くらいできた。
アセンブリから呼び出し規約と引数のサイズを推定するオートマトンを作らないといけない。
頑張るぜ。 Amazonでドラゴンブック二冊目買おうかな
データフローを勉強したいんで ビットフィールド、サポート出来そう。
次はオートマトンに取り組むぞ!!! 【関数呼び出しコード分析における注意点】
☆呼び出しの際、スタックを解放せずに再利用されることがある。
☆呼び出し先のアドレスがレジスタに格納されて呼び出しに使われることがある。
☆また、条件によって場合分けされて呼び出し先の異なるアドレスがレジスタに格納されて呼び出しに使われることがある。 レベル0.機械語コード。
レベル1.アセンブリのみのコード。
レベル2.関数に切り分けられたアセンブリコード。
レベル3.レジスタとスタックの直接的操作を含む中間表現コード。
レベル4.レジスタとスタックの直接的操作を含まない中間表現コード。
レベル5.C言語のコード。
#こんな感じかな? レベル3.レジスタとスタックの直接的操作を含む型なしの中間表現コード。
レベル4.レジスタとスタックの直接的操作を含まない型付きの中間表現コード。 命令セットの中間表現はテキストとして与えられる(insn*.dat)。
よって、中間表現の設計とパーサとASTが必要。
中間表現はC言語のサブセットの拡張とする。 gccは余分にスタックフレーム確保してる。。。何でだろ? 実現出来てもwatcom cの吐いたバイナリで面白いことになる予感 コンパイラが関数だとすると、逆コンパイラは逆関数である。
逆なんだよ、逆。コンパイラのコード生成に対しては、逆コンパイラのコード分析が対応する。 __stdcallが一番簡単。__stdcallのときに限ってretの引数があって、それが関数の引数リストのサイズ。
__stdcallでないときはretに引数がなく、呼び出し側が引数スタックを解放する。
__cdeclか__fastcallか__thiscallの判断はレジスタの使用や関数呼び出しの状況を統計するしか方法はない。
スタックやレジスタやヒープの型情報とデータと式などを統合して扱う仕組みが必要。 統計しなくても理詰めで解けるケースを想定できんのか
//どっちみち可変長引数は詰むけどな ある関数内で呼び出すターゲット関数のスタック引数サイズは、スタックフレームマイナススタックポインタ以下の値を取りうる。
関数内でターゲット関数の呼び出しが1回のみで他にスタック操作をしていないなら、そのときのスタック引数サイズは確定する。
ターゲット関数内のレジスタとスタックの使用状況から、スタック引数サイズの下限がわかる。
可変長引数の場合は、スタック引数サイズは下限以上の値になる。 ということは、スタックフレームイコールスタックポインタの場合はターゲット関数の
スタック引数サイズはゼロで確定で、ターゲット関数に対する統計は不要という訳か? 1.関数のスタック引数サイズとローカル領域を確定し、スタック操作を仮想化する。
2.コードを基本ブロックに分け、分岐を仮想化する。
3.オペランドに型を付けて型推論を行う。
4.データフロー解析を行い、中間表現へ変換。オペランドを式に抽象化する。
5.読みやすいように最適化しながら、コード生成を行う。
6.AStyleを使ってコードを整形する。 x86のintrinsicのまとまった情報が欲しいけど見付からない 符号付きか符号なしか分からない型をxsignedで表す。
未知の型はunknown%d_tという型を付ける。未知の型について型の属性を解析していく。
例えば、即値xが非ゼロで上位ワードがゼロならポインタでなく整数である。
callの引数は間違いなく関数ポインタである。 ということは、intrinsicのアセンブリパターンをほとんど全部調べて、
パターンマッチングでパターンごとに中間表現に置き換えていく必要があるんやで。
パターンデータを用意するのが大変やで、しかし。 pattern {
(アセンブリのテンプレート)
} code {
(中間表現)
}
こんな感じのテキストデータを事前に読み込んで、それ(置き換え規則)を使って
パターンマッチを行い、中間表現への置き換えをする。
テンプレートには$1,$2,$3,...などの引数が書ける。 パターンが足りず変換し損なうか、パターンが意図しない場所にマッチして変換し損なうか、
マッチ候補の組み合わせ探索量が爆発して尋常じゃなく遅くなる、て未来が見えそうだね。 最適化されたバイナリとか全く考えて無さそうだな
変換できなかったらインラインアセンブリのソースに変換します! ならかっこいいw >>199
それ言い出すとインラインアセンブリだらけになっちゃうだろ! ループ展開とか、再起がgoto文になってたりすると見にくそう >>197
コンパイラの癖が変わったら破たんするな。 >>203
コンパイラのバージョンとコンパイルオプションの組み合わせごとにパターンセット作るんじゃね?
手作業だと余裕で死ねる。 頻出形だけカバーできればいいだろ
どうせ大事なのはその先なんだし はーひふーへほー!!!
片山被告のせいで俺まで職場で悪役扱いだずぇ!
まゆげが無くても父親が殺人者でも関係ねぇ!
俺はコンピュータテクノロジーの心臓部に弾丸を撃ち込んで歴史を塗り替えてみせる!
俺様は諦めない!がはははっひゃっ! ばいばいきーん! 最終チェックが終わったら次は64bitのパターンだな。
7月15日までに結果を出さねば。 jmp を for にできるようになったら呼んでくれ v0.1.5!
https://github.com/katahiromz/CodeReverse
パターンファイルasmpat32.dat, asmpat64.datを追加しました。
ソースが読みやすくなりましたので、興味がある方はじっくりご覧下さい。
>>210 それはまだ先のこと。 たいした成果がないとスポンサーからの今年の研究費がお預けになる予感。。。開発を急がないと。。。
GitHubにてPull Repuest歓迎。アドバイス・批評歓迎。功績・貢献にはアマゾンギフト券かWebMoneyでお応えします。 うひょー、ひらがな電卓のお陰で研究費ゲットだぜぇ! もう少しひらがな電卓を頑張るずぇっ! >>214
ニートですが研究費とかいうものはどうやったら貰えるのですか? GitHubで星が1つ付いた。頑張らないといけないのだが、時間がない。 こんな嘘ばかりのスレ取り消せ。
クソボケが 、アホクソボケカスが。
根性無しのカスの集まりが。
どうせ何もできんのやろが?
カスはカスらしく黙っとらんかい!クソボケ!
何なんじゃアホが。この根性無しのクズが。
クソボケクズ。クズの集まりじゃねえか。
ポンコツのクソドアホが。ボンクラだろがてめえら。
はっきり言っといてやるよ。 てめえらなんか、何一つ怖くないわ、
このクズ以下のポンコツボンクラが。 データフローの表現の問題が未解決。アイデアが見つかるまで時間が掛かりそうです。 dag (directed acyclic graph): 閉路のない有向グラフ。「グラフ理論」を参照。
基本ブロック (basic block): 途中で停止したり、分岐したりしない、連続した文の並び。
流れグラフ: 基本ブロックを制御の流れに従って矢印で結んだもの。
「基本ブロックのdag表現」とは、次のようなdag:
1.葉のラベルは一意な識別子。
2.内部節点のラベルは演算子。
3.さらに節点に識別子の並びのラベルを付けることができる。 内部節点で正しいと思う
http://imd.naist.jp/~miyazaki/doshisha/data-algo/ad-3.pdf
・内部節点(internal node) 子を持つ節
・外部節点(external node) 葉(leaf) 子を持たない節 『節点』に『内部』があると思っているのか?日本語からやり直せよチョソ >>241
残念。節点なんだけど丸で描かれてその中にラベルがあるんだな、これが。
現在、インシデント解決待ち。 今、リファクタリングとDBのサニタイズしてるとこ。いくつかサイズの間違いを見つけた。
構造体のサイズを正確に得るには、アライメントを考慮せねば。 A「では、進捗報告を」
B「アライメントの扱いに案外手こずり、まだDBのサニタイズが終わっていません」
A「時間が掛かりすぎだ!いつになったらできるんだ!(机を叩く)」
B「申し訳ございません。」
A「アライメントの規則性を分析して早くサニタイズしなさい」
B「御意」 型情報のload/saveを可能にしなきゃ。
定数の"typed value"計算を可能にしなきゃ。 今、typed valueの実装をやってるけど、型によって場合分けが
必要だから、「場合分けの化け物」になっちゃうんだよな。
関数型ならもっとスマートに書けそうだが。。。 マクロから一部の定数を抜き出すのを実装してみた。
定数全部を抽出するには、
マクロの展開とパースとtyped valueの実装が必要みたいだ。
https://github.com/katahiromz/DoWonders typed valueを実装してみた。サニタイズ失敗。
typed value実装のどこかに間違いがあるようだ。
https://github.com/katahiromz/DoWonders A「では、進捗報告を」
B「後はマクロ展開を実装すれば、次のステージに進めます。」
A「それはできるのか?」
B「今、QZというハッカーにマクロ展開実装を依頼していますが、
返答がありません。何とか自力でできないか模索している処です」
A「来週の日曜日までに急いでやれ。頼んだぞ」 俺の興味がどこにあるかお前はよく知っているはずだが?
あの証明は飛躍があるから埋めておけ参考書もそうならその参考書は捨てたほうがいい 宿題スレを荒らしてたのは俺じゃねーぜ。勘違いするな、Qzさん 反応を待たずにレスをして何を焦っているのかな?www before: 宿題スレを荒らしてたのは俺じゃねーぜ。勘違いするな、Qzさん
v
after:あの宿題はQzが居なくてもできるよ
ウリのすぐバレる嘘ニダwww Qzさんだって下品な発言はしないし、大体お前のようにすぐバレる嘘をつくほどマヌケじゃない。 マクロ展開ができた。サニタイズは時間切れ。
バグがまだたくさんあるものと思われる。
https://github.com/katahiromz/DoWonders マクロ定数が正しく読み込めなければ、Win32 APIとは言えないので、
何とかがんばっているところ。 47氏は崇拝されていたが、片山は軽蔑される
人格上の問題なのではないか? こいつがあちことで出没するとスレが過疎るからやめてほしい 約束のdeadlineは五月一日。それまでにWonders API Webを完成しないといけない。 今、複合値とデータのバイナリーダンプのサポートに取り組
んでいるところ。明日、リリースの予定。 Wonders API
http://katahiromz.esy.es/wonders/
予告どおり「複合値」をサポート。変数のバイナリーダンプも可能。 Wonders API
http://katahiromz.esy.es/wonders/
まずは、Windows APIをPHPとPythonとRubyへ移植する。 Wonders APIをCodeReverseに取り込んで、CodeReverseのCパース箇所を破棄だ。
これでCodeReverseで型情報が使える。
GWにネットカフェが空いてないから、更新が遅くなるかも。 CPUレジスターや仮想的なアドレス空間の任意の抽象的な場所にアクセスするための全射なアドレスを文字列で表現する。
expressed address、略してexpr_addr。
expr_addrを解決すると未知の値、シンボル、もしくは具体的な値が得られる。
また、expr_addrから型の集合への写像を作ることができる。 値の集合とシンボルの集合と型の集合が存在する。
値やシンボルはその格納場所(storage)によって類別できる。
格納場所は、スタック、ヒープ、レジスター、実行可能コード領域、その他のデータ領域などが挙げられる。
expr_addrから値やシンボルへの写像が存在する。
expr_addrから格納場所への写像が存在する。 では、expr_addrの具体的な定義を決めよう。
(ea.1) expr_addrが数値ならばexpr_addrはexpr_addrが表す値の仮想アドレスを指し示す。
(ea.2) expr_addrがレジスターの名前ならばexpr_addrはそのレジスターの値が表す仮想アドレスを指す。
(ea.3) expr_addrが__cr.xxx[yy]といった文字列ならば、__cr.の後のxxxはストレージの名前であり、expr_addrはストレージxxxの(yy+1)バイト目を指し示す。
ここに、yyはexpr_addrである。
(ea.4) expr_addrに演算子+,-,*が含まれていれば、普通にexpr_addr上で足し算、引き算、掛け算を行う。 x86/x64のスタックは逆向きに成長するから、__cr.stackは特別扱いしなければならない。 >>295は間違い。昔はメモリーをけちるのが常だったが、
今となっては、スタックサイズ100KBくらいけちる必要はない。
たとえ失敗してもスタックサイズが可変ならば、やり直せばいい。 コンパイラーなら型情報と構文に基づいてレジスター割り付けを行って、アセンブリを出力する。
逆コンパイラーはアセンブリから、オペランドと仮想アドレスに仮想的な値と
型を割り付け、それらを定数・変数・実引数・仮引数に抽象化し、式と構文を構築し、ソースを出力する。 callの引数は関数アドレスであるから、それがAPI関数であれば、実引数や戻り値に型情報を付加できる。
代入においては同一の値になるオペランドが現れる。このとき、型も同一になる可能性が高い。
このようにオペランドや仮想アドレスやレジスターに型情報を再帰的に付加していく。 仮想アドレス空間の状態は、プログラムの進行に従って遷移していく。
状態が変わる様子を再現するには、仮想マシンを作って動かしてみるのが、一番合理的だ。 仮想マシンを動かすなら、アセンブリか中間言語のどちらのレイヤーで動かすべきか?
中間言語で動かすならば、アセンブリの情報をほとんどすべて中間言語に移行しなければならない。 両方のレイヤーでやれってか? なら、2種類の仮想マシンを作らにゃあかんべえ。んだんだ。 要件定義をよく考えると、中間言語パーサーは不必要と判断した。 いや、中間言語パーサーは必要。パーサーがなければ、アセンブリのでっかいアーキテクチャを
ハードコーディングしなきゃいけなくなる。恐らく中間言語はアトリビュートベースになる。 中間言語では、新しい値ができるたびに明示的にそのインスタンスを宣言する。
インスタンスは型情報、入出力に関する情報、値やアドレスを表す式などの属性を持つ。 アーキテクチャを中間言語のデータで表現しないといけない。
中間言語の設計も完成していないのに。。。! たぶん、値を宣言してそれらに変数を割り当ててくという考え方は間違ってない。
これでうまく行きそうだ。 https://github.com/katahiromz/CodeReverse
ファイルarch_x32.datを追加した。
このファイルにx86アセンブリから中間コードへの変換方法を記述する。
不完全。 我に力と自由時間を与えたまえ!(画面がパパっと2回点滅) トップにarch_x86.dat/arch_x64.datという二つのファイルを用意したから、
これを元にして、アセンブリを中間言語に逐次翻訳する。
翻訳方法は、基本的にパターンマッチを基本とする。 翻訳の戦略について。
まず、前述の翻訳辞書データを読み込み、パースする。
次に全体を走査して、邪魔者を消す。nopやmov ax,axやlea eax,[eax]の
ような、人間にとって無意味な命令を全部取り除く。
さらに全体を走査して、技巧的な命令を「標準語」に直す。
さらにさらに逐次的にパターンマッチしたものを次々と翻訳していく。
この戦略がうまく行けば、アセンブリはすべて中間言語に翻訳される。 https://github.com/katahiromz/CodeReverse
流れグラフができた。リーダーのみ、ラベルを出力するようにした。
CR_ICode32, CR_ICode64を追加した。中間言語の定義とパースに移る。 こういう翻訳処理の過程は、「ステージ」という考え方でとらえるとわかりやすい。
たとえば、ステージ0が逆アセンブルしていない状態。
ステージ1が逆アセンブルした状態。ステージ2が中間言語に翻訳された状態。
ステージ0→ステージ1→ステージ2→...
逆アセンブルしていないコードが現れた場合などでは、その部分ではステージを戻って処理しないといけない。 https://github.com/katahiromz/CodeReverse
>>316の考え方に基づいて、CR_DecompInfo32::GetFuncStageを追加した。
DisAsm32の前処理をPrepareForDisAsm32に分離した。 本格的なプログラム言語の設計は初めてだが、やれることはやってみよう。 アドレッシングの複雑性を乗り越えてオペランドをパターンマッチするんだ!!! https://github.com/katahiromz/CodeReverse
Coding.cppにCrParamPatternMatchを追加した。
CrParamPatternMatchはパラメーターの抽象化されたコードの
パターンマッチを行う重要な関数だ。
>>320 仮想化のため。 https://github.com/katahiromz/CodeReverse
CodeReverse.hをCommon.hに改名。Testing.cppを追加。
Testing.cppで$0, $1, ...のパターンマッチを実証。
中間言語の名前がiCodeに決まった。これからiCodeを具体的に設計する。 Java to C++ converter面白そう
ちょっと中断して読んでみるよ GitHubにマルチ環境の要望があるが、アーキテクチャを仮想化・プラグイン化するのは面倒くさ。
Windows .exe以外のフォーマット知らないし。LinuxやMacって何? 今はexploitが欲しいだけ。 分かったよ、勉強すりゃあいいんだろ? でも真夜中は監視役が居るからダメ。
パソコンはインターネットにつながってないし、家の構造が昭和時代だからな。
本当は24時間パソコンしたいんだ。 昔LightConeとかいう基地外がいたが片山とよく似ているな
スレと関係ない雑談や脈絡もない妄言とか。 何か、forkやstarが増えてきたぞ。。。
やらないとまずいかな。。。 逆コンパイルって解が無数にあるから
例えばナイーブな逆コンパイルは、Cでアセンブラをエミュレーションすることだし
他にもインライン展開されたコードは展開後として逆コンパイルするのか
展開前として逆コンパイルするのかとか
だからなんらかの人間にとっての読みやすさを定義して
無数の解の中でなるべく読みやすい解をどれか一つ選ぶっていう風にするのが
方向性だと思った VeySicKの開発が一段落ついたのでCodeReverseの開発を再開するよ。
ひとまずゼロからCコンパイラを作ってみる。 こんなことなら、大学でコンパイラの作り方を勉強しとけばよかった。 きつねさんのLLVMをAmazonで買ったよ! (もちろん中古) LLVMと.NETを組み合わせて何か面白いことをやれって言われてる。 いずれにしても、だれかが教師になって、読みやすいコードを出力するための
教育を行わないとまともな逆コンパイラは完成しない。
さらには教育にはコミュニケーションが必要。 逆コンパイルを数学的に考えると、
ソースコードからコンパイル結果への変換器「コンパイラ」の逆変換器を
求める問題になる。教育を行うなら、ソースコードと、実際にコンパイルした結果の対応を
学習させることになる。その対応は情報量が少ないことが望ましい。 大きな変換器はより小さな変換器に分解される。
LLVMの言葉で言えば、変換器はpassであり、コンパイルはpassの合成である。
であるから、これから必要な作業は、1つひとつのpassの逆変換器を
求めることである。 病気は我が精神を思索の森に誘ってくれる。
健全であれば気付かない事象にも出会うことができる。
今年のうちに逆コンパイラを作らねばならない。
たとえそれが世界を滅ぼす魔法でも完成させなければならない。
ボスの命令は絶対だ。 clangのソースを読み始めたよ。
CMakeの使い方を勉強しないといけない。
examplesのPrintFunctionNamesを改造してみようっと。 CMakeをインストール。CMakeの基本的な使い方を覚えた。
llvmを仮想Ubuntuにapt-getでインストールして、ターンエンドだ。 CMakeの使い方を勉強しながらテンプレートプロジェクトをいくつか
作成して、きつねさんを参考にLLVMのコマンドを何度か試してターンエンドだ。 <llvm/IR/Type.h> 型
<llvm/IR/TypeBuilder.h> 型構築器
<llvm/IR/Constant.h> <llvm/IR/Constants.h> 定数
<llvm/IR/IRBuilder.h> IR構築器
<llvm/IR/Module.h> モジュール
<llvm/IR/Function.h> 関数
<llvm/IR/BasicBlock.h> 基本ブロック
<llvm/ADT/StringRef.h> 文字列参照
<llvm/ADT/StringMap.h> 文字列マップ
<llvm/MC/MCExpr.h> MC表現
<llvm/MC/MCInst.h> MC命令
<llvm/MC/MCValue.h> MC値
<llvm/MC/MCAssembler.h> MCアセンブラ
<llvm/MC/MCDisassembler.h> MC逆アセンブラ
<llvm/Support/MemoryBuffer.h> メモリバッファ
<llvm/Support/ErrorOr.h> エラーまたは
<llvm/Support/raw_ostream.h> 生出力ストリーム DraperさんのFractureを解析してみるみる。。。 きつねさんの本は少々古く、最新版ではコマンドラインとヘッダーが
多少変わっているようだ。最新版に合わせないといけない。
また、MinGWでは動かない機能もあるようだ。 $ opt -help > help.txt
多種多様なPassがあるぞ。まずはこれを解析してみるか。
MinGWで動かなかった分はCygwinで試すぞ。 最新の仮想Ubuntu32bitと64bitをVMwareにインストール。
さらにclang-3.7とllvm-3.7をそれぞれにインストールして
俺のターンは終わりだ。 LLVMは型情報を完全には保持していないようだ。
Win32ではLONGとINTは同じサイズだが、それらのポインタ型は厳格に区別される。
しかしLLVM IRではどちらもi32となる。
つまり、LLVMやClangで構造体を読み込みその型をダンプしたとしても、
コンパイルできる代物にはならない。これでは逆コンパイラには
役に立たないのではないか? ここまで何か間違いがあれば、ご指摘願う。 Clangでは区別できてるんだから、LLVM IRよりも上位で保持しているはず。ならば、Clangで
構造体などの型情報をLLVM IRの上位でどのように扱っているかを調査しないといけないぞ。 だいぶ解析が進んで来た。
おそらくキーワードは
clang::CompilerInstance,clang::Sema,clang::ASTContext,clang::Type
だろう。clangも大変再利用しやすい模範的なデザインになっており、
これらを組み合わせればclangの改造版が比較的容易に作れると思われる。 Clang-tutorialのmakefileのllvm-configをllvm-config-3.6に変えてメイクしてみた。
tutorial1.o: 関数 `main' 内:
/mnt/hgfs/cc/LLVM/Clang-tutorial/tutorial1.cpp:53: `llvm::sys::getDefaultTargetTriple()' に対する定義されていない参照です
なぜだ。。。分からぬ。 いくら優れたライブラリでも、動かないと意味ない。。。
最新版をビルドしないといけないのか。。。
LLVMとClangのビルド、めっちゃ時間かかりそう。。。 仮想Ubuntuのディスク容量不足でビルド失敗。35GBくらいは必要か。
最初からやり直し。VMwareよりもVirtualBoxの方が使い易そうだ。 VirtualBox上の仮想UbuntuでLLVM+Clangのビルドに成功した。
これでまずはスタートラインに立てた。可能ならば後で公開する。 仮想環境のためか、ビルドに五日間かかった。電気代は高い請求額が来るだろう。
現在のオッズは低いが地道に頑張る。 Ubuntu 14.04.4 LTS (64-bit)をインストール。ディスク容量50GB以上・メモリ2GB以上。
端末およびGhest Additions(仮想の場合のみ) インストール。
メモリが少ないときは、次のようにスワップ確保。
$ sudo dd if=/dev/zero of=/swap bs=400M count=16
$ sudo mkswap /swap
$ sudo swapon /swap
$ sudo gedit /etc/fstab
「/swap swap swap defaults 0 0」の行を最後に追加。
$ cat /proc/swaps
$ sudo apt update
$ sudo apt install build-essential
$ sudo apt install linux-headers-$(uname -r)
$ sudo apt install make
$ sudo apt install automake
$ sudo apt install cmake
$ sudo apt install subversion
$ sudo apt install gdb
$ sudo apt install perl
$ sudo apt install libtool
$ sudo apt install libncurses5-dev
$ sudo apt install valgrind
$ sudo apt install zlib1g-dev
$ sudo apt install libedit-dev
$ sudo apt install texinfo
$ sudo apt install python
$ sudo apt upgrade $ cd ~
$ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
$ cd llvm/tools
$ svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
$ cd ../projects
$ svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
$ svn co http://llvm.org/svn/llvm-project/openmp/trunk openmp
$ svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx
$ svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi
//$ svn co http://llvm.org/svn/llvm-project/test-suite/trunk test-suite
//$ sudo apt uninstall llvm clang llvm-3.6 clang-3.6 llvm-3.7 clang-3.7
$ cd ~
$ mkdir llvm-build
$ cd llvm-build
$ cmake -G "Unix Makefiles" ../llvm
$ make -j1 >>361
訂正。ビルド&インストール成功のためにはディスクは100GB以上、
メモリーは8GB以上必要と思われる。
メモリーが充分あればスワップはデフォルトでOK。
ビルド時間を短くしたければ実機でのビルド推奨。 EXEファイル全般でやろうとしているの?
まずバイナリがどの開発環境で作ったのかを固定しないと。
どちらにしろ、理論上絶望的だから逆アセンブルはできても逆コンパイルは無理だよ。
JavaのクラスファイルもJavaでコンパイルされていたら逆コンパイラでほぼ完璧なソースをだせるけども、
LLJVMを使ったC言語がソースのLLVMからJavaクラスファイルに変換した物は逆コンパイルしても、何やっているのかよく分からない回りくどいJavaソースしか出て来ない。
同じJavaクラスファイルという中間言語形式であっても、開発言語が違えば逆コンパイルは期待通りのものにはならない。
それでもJavaやC#の中間言語ファイルは情報をいっぱい持っているから逆コンパイルしやすい。
EXEで実用的な逆コンパイラとか無理無理。
時間の無駄。他のことしたほうがいいよ。
絶対にできないから。 >>364
勝算は5%ほどある。型情報抽出と型推論を実現する策略を練っているところだ。
LVMでディスクを100GBに拡張。LLVM+Clangインストール成功。
VirtualBox仮想アプライアンスのエクスポートを完了して、俺のターンエンドだ。 >>365
LLVMを逆コンパイルするソフトを作ろうとしているの? IMEの開発が正式に決まった。逆コンパイラの開発は、
IMEの開発が終わるまでお預けとなる。しばしお待ちを。 匿名通信(Tor、i2p等)ができるファイル共有ソフトBitComet(ビットコメット)みたいな、
BitTorrentがオープンソースで開発されています
言語は何でも大丈夫だそうなので、P2P書きたい!って人居ませんか?
Covenantの作者(Lyrise)がそういう人と話したいそうなので、よろしければツイートお願いします
https://twitter.com/Lyrise_al
ちなみにオイラはCovenantの完成が待ち遠しいプログラミングできないアスペルガーw
The Covenant Project
概要
Covenantは、純粋P2Pのファイル共有ソフトです
目的
インターネットにおける権力による抑圧を排除することが最終的な目標です。 そのためにCovenantでは、中央に依存しない、高効率で検索能力の高いファイル共有の機能をユーザーに提供します
特徴
Covenant = Bittorrent + Abstract Network + DHT + (Search = WoT + PoW)
接続は抽象化されているので、I2P, Tor, TCP, Proxy, その他を利用可能です
DHTにはKademlia + コネクションプールを使用します
UPnPによってポートを解放することができますが、Port0でも利用可能です(接続数は少なくなります)
検索リクエスト、アップロード、ダウンロードなどのすべての通信はDHT的に分散され、特定のサーバーに依存しません
1@ RECという優れた逆コンパイラがあるので、CodeReverseにはもはや存在価値がない。
よって、このスレは 糸冬 了 し ま す 。
皆様、有難う御座いました。再利用可。
◆◆◆スレッド終了◆◆◆ ■ このスレッドは過去ログ倉庫に格納されています