RNC ProPackの5年間の逆コンパイル

友人の皆さん、ご挨拶!













この記事では、 AmigaOSからの実行可能ファイルのうち、 46 KBの反転に数年間取り組んだ方法を説明します。AmigaOSから多くのことを学び、多くのさまざまなテクノロジーを試し、最終的には目標を達成しました- 逆コンパイルされたMotorola M68000アセンブリコードをCコードに変換します誰でも使用できます







背景



RNC ProPack (Rob Rorthen Compression)などがあります。 これはかつて非常に一般的なデータパッカーです。 彼は、 MS-DOSSega Genesis / Mega DriveGame BoySNESSony Playstation 、および場合によっては他のプラットフォーム向けのゲームを詰め込みました。 実際、 Sega Mega Driveのおかげで私はパッカーの研究を始めました。







参照によるLHA-アーカイブには、 AmigaOSおよびMS-DOSの実行可能ファイルが含まれています。これは、64ビットオペレーティングシステムで動作する現代の現実では、それほど大きくはありませんが、ユーティリティの通常の使用に対する障害です。







はい、 ソースがあり、RNC解凍バージョン1の機能していると言われていますが、実際には、曲がって動作し、圧縮が悪化し、他のいくつかの悪いことがあります。そのため、この部分は使いたくありませんでした。







もちろん、あらゆる種類のDOSBoxesWinUAEがありますが、実際にはどういうわけか非常に面倒です。







真実の探求



まず第一に、著者を見つけ、彼に連絡し、現代の現実に移植しやすい既製のソースを見つけようとしました。 しかし、著者は見つけるのがかなり難しいことがわかりました。 ロブ・ノーゼンは現在中年の祖父であり、彼はもはやソースを持っていません、そして、 Aminetからのそのリンクは彼がコンパイルさえしなかったプログラムでアーカイブにつながります(著者によると、ソースは純粋なアセンブラーであり、他のすべては彼のものではありませんでした)。







UPD。







祖父を見つけた方法
最初はウェイバックマシンで彼との古いインタビューでした。 しかし、そこからの石鹸はもはやアクティブではありませんでした。 次に、Northen Computingドメイン自体をGoogleで検索し、 rob @をドメインにドッキングして、書き込みを試みました。アルゴリズムの作成者の石鹸を手に入れました。


私が理解しているように、パッカーのソースコードはゲーム開発者にお金で提供されました。 MS-DOS用のRNC ProPackにはいくつかの異なるバージョンがあり、実行可能ファイルプロテクターの異なるバージョンがパックされていました。 AmigaOSのバージョンもパッケージ化されました( RNC ProPack自体によって)。







アプローチ回数



最初に、このジャンクのデバッグを開始しようとしました。 その時(まあ、約5年前) MS-DOSが私に近かったので、私はそれから始めて、 IDA Proを使い、実行ファイルを分析し、誰にも触れずに静かにすべてをすることにしました。 。







最初の問題:ファイルはMS-DOSで実行可能なファイルのある種のパッカーによって保護されていました。 最近のPEアナライザー( PEIDExeinfo PE )のほとんどは、dosの希少性をどうするかわかりませんでした。 したがって、彼らはそれに応えて黙っていました。













Detect It Easyのみが役に立ちました:













正確な方法は覚えていませんが、デバッガをオンにしたDOSBoxを使用して、 なんとかWWPackを解凍できました













しかし、 IDABorland C ++シグネチャは、ほとんどの標準ライブラリ関数を認識したくありませんでした(私が理解しているように、通常のfopen呼び出しの上に、名前を受け取らないラッパー関数がありました)。 それから、私は自分でFlare-utils IDAを使用して署名を収集することにしました。 それは少し助けた。







とにかく、私が望んでいた方法ではありません...私は便利さ、ソースコード、動的コードデバッグを望みました...

さて、 IDA Proはセグメント、セレクター、16ビットコードで動作するようです...はい。 しかし、最初に、標準配信にはデバッガがありません。 次に、 その時点で利用可能な唯一のデバッガプラグインIlfakはその後SDKの参照として全員に追加しました):







#define DEBUGGER_ID_X86_DOSBOX_EMULATOR 10 ///< Dosbox MS-DOS emulator
      
      





...それは非常に曲がって動作し、ハングします。デバッガーヒントは、 DWORD PTR DS:[EAX+58h]



などのような相対アドレスの間違った宛先アドレスを指します。







書き直すことにしましたMS-DOSアプリケーションをデバッグする場合、このバージョンをすべての人にお勧めします。







しかし、このオプションを使用して、これは同じではないことに気付きました...利便性が向上しましたが、目標も遠くにあります。







2度目に判明した場合はどうなりますか?



今回、しばらくして、私はamitoolsのような素晴らしいプロジェクト、特にそのコンポーネントの1つであるvamosについて聞きました。







これはpythonのような独立したAmigaOSエミュレーターです(覚えているなら、2番目の実行可能ファイルはそれ専用でした)。 M68kプロセッサのエミュレータとして、 Musashiが使用されています。







それは素晴らしいアイデアのように思えました。 Pythonコードをプルし、内部で必要なコードを実行するIDA用のデバッガープラグインを作成します。 しかし、私はその時点で組み込みPythonを理解できませんでした。 実際にpython自体は、実際には知りませんでした/適用しませんでした。

したがって、一緒に成長しませんでした。







また、パッカーの実行可能ファイル自体はエミュレーターでうまく機能しませんでした。同じファイルを繰り返しパックしようとしましたが、一部のAmigaOSシステムコールはまったく機能しませんでした。







デバッガーに埋め込むために、 Cで vamosを書き直そうとしました。 しかし、 python2cのようなクールな逆コンパイラはありません。手で書き直すのにすぐに疲れました。 事件は絶望的だった。







私はWinUAEを介してデバッグさえ試みました、 UaeIDAを書きましたデバッガーモジュールのサーバー部分の彼自身のコードを組み込み、デバッグを試みて、バグを報告します。 問題は多少なりとも受け入れられるようになったようです。 しかし、 WinUAE自体の不可解なバグ(および、デバッガーを担当するソースの一部を混乱させることに対する著者の不本意)が、やがて行き止まりになりました。







今では間違いなく出てきます



私が最後に力を集めたとき、これらのすべての愚かな試みが望ましい結果に至らず、別のAmiga CruncherImploder-WinImploderCでその時間までに書き直した後、私は再びAmitoolsオプションに戻ることにしました。







プロジェクトはいくつかのバグを修正しているようで、プロジェクトのアセンブリは簡素化されています...したがって、開始が与えられました! その結果、フランケンシュタイン: Amitools_dbgを入手しました 。 デバッガーモジュール起動するIDAから-dbgフラグを使用してpython- partを起動します。...出来上がり -アプリケーションへのエントリポイントにいます。 そして、デバッグもできます!







システムAPI呼び出しのみが、次の形式の逆アセンブラーの行でした。

JSR -$3A(a6)



、ここでa6はシステムライブラリのベース、および-$ 3AはAPI呼び出しのオフセットです。







インターネットで大騒ぎして、ReSourceのようなかつて関連したプロジェクトを見つけました 。 このプログラムが含まれるアーカイブはインターネット上にあり、 WinUAEで実行できます。 そのため、各ライブラリのオフセットを示すfd-ファイルが含まれていましたAmitoolsにはこれらのfdファイル用のパーサーがあり、私はそれを自分用に取りました。 その結果、私のデバッガーもそのようなシステムコールを認識し、APIコールのラッパーを識別するのに役立ちました。







これまでの数年間、誰かがAmigaOS実行可能ファイルを取得するために使用していたCコンパイラ、つまり古代バージョンのSAS / Cをほぼ把握することができました。 しかし、配信からIDAに libファイルを設定する試みは成功しなかったので、私は自分の手でそれを行いました(はい、私が望んでいたような風水ではありませんが、何もしませんでした)。







ソースコード



誰かがトピックに含まれていない場合、 C -nyでアセンブラコードを取得して書き換えることはできません。











さまざまなニュアンス:変数の名前、関数、構造体のフィールド。 そして、それはまだきれいでした。 したがって、これらすべてに名前を付けることも非常に時間がかかります。

どうですか?







 #pragma pack(push, 1) typedef struct huftable_s { uint32 l1; // +0 uint16 l2; // +4 uint32 l3; // +6 uint16 bit_depth; // +A } huftable_t; #pragma pack(pop) typedef struct vars_s { uint16 max_matches; uint16 enc_key; uint32 pack_block_size; uint16 dict_size; uint32 method; uint32 pus_mode; uint32 input_size; uint32 file_size; // inner uint32 bytes_left; uint32 packed_size; uint32 processed_size; uint32 v7; uint32 pack_block_pos; uint16 pack_token, bit_count, v11; uint16 last_min_offset; uint32 v17; uint32 pack_block_left_size; uint16 match_count; uint16 match_offset; uint32 v20, v21; uint32 bit_buffer; uint32 unpacked_size; uint32 rnc_data_size; uint16 unpacked_crc, unpacked_crc_real; uint16 packed_crc; uint32 leeway; uint32 chunks_count; uint8 *mem1; uint8 *pack_block_start; uint8 *pack_block_max; uint8 *pack_block_end; uint16 *mem2; uint16 *mem3; uint16 *mem4; uint16 *mem5; uint8 *decoded; uint8 *window; uint32 read_start_offset, write_start_offset; uint8 *input, *output, *temp; uint32 input_offset, output_offset, temp_offset; uint8 tmp_crc_data[2048]; huftable_t raw_table[16]; huftable_t pos_table[16]; huftable_t len_table[16]; } vars_t;
      
      





私にとってはひどく見えます。 しかし、現在、コードは機能しています...将来的には、このコードで他の何かを修正するかもしれません。







はい、見回した後にバグがあり、いくつかのテストを行いました。 どこか<



<=



である必要があり、定数はそれほど適合していません。 しかし、今ではすべてを修正したようです。







もちろん、このパッカーでMS-DOSアプリケーション、 AmigaOSアプリケーションのパッケージを書き換えたわけではありません(そのような機能がありました)。 アルゴリズム自体が欲しかった。







結論



最も一般的なこと:何かを達成したい場合は、それを試してみてください。恐れることはありません。 ステップバイステップでそれを取る。 そして、あなたはそれをやった。







AmigaOS binarのIDBファイルへのリンク:

https://mega.nz/#!3Z1TBA6J!ZOOfQf4Jmp_I704yYynzMVI_3To3etMjqRC2eF9b0Jg







RNC Propackソースhttps : //github.com/lab313ru/rnc_propack_source








All Articles