実行可能ファイルをリバースエンジニアリングから保護していますか?


210

私はC / C ++コードを逆アセンブリやリバースエンジニアリングから保護する方法を検討しています。通常、私は自分のコードでこの動作を自分で容認することは決してありません。しかし、私が取り組んでいる現在のプロトコルは、さまざまな人々のセキュリティのために、決して検査または理解されてはなりません。

今、これは私にとって新しい主題であり、インターネットはリバースエンジニアリング防止するために実際に機知に富んでいるのではなく、リバースエンジニアリングの方法に関する大量の情報を示しています

私がこれまでに考えたことのいくつかは次のとおりです。

  • コードインジェクション(実際の関数呼び出しの前後にダミー関数を呼び出す)
  • コードの難読化(バイナリの逆アセンブリを壊す)
  • 独自のスタートアップルーチンを記述する(デバッガーがバインドするのが難しい)

    void startup();  
    int _start()   
    {  
        startup( );  
        exit   (0)   
    }  
    void startup()  
    {  
        /* code here */  
    }
  • デバッガーのランタイムチェック(検出された場合は強制終了)

  • 機能トランポリン

     void trampoline(void (*fnptr)(), bool ping = false)  
     {  
       if(ping)  
         fnptr();  
       else  
         trampoline(fnptr, true);  
     }
  • 無意味な割り当てと割り当て解除(スタックは大幅に変更されます)

  • 無意味なダミー呼び出しとトランポリン(逆アセンブリ出力での大量のジャンプ)
  • 大量のキャスト(難読化された分解用)

これらは私が考えたことの一部ですが、適切な時間枠が与えられれば、コードアナリストがそれらをすべて回避または把握することができます。私が持っている他の選択肢はありますか?


172
「しかし、私が取り組んでいる現在のプロトコルは、さまざまな人々の安全のために、決して検査または理解されてはなりません。」-頑張ってください。
アンバー

62
アプリケーションのリバースエンジニアリングを困難にすることができます。他の人があなたのビットのかなりの部分を手に持っている限り、あなたはそれを不可能にすることはできません。特に生命が危機に瀕している場合は、完全なセキュリティを保証することに注意してください-配信できません。
Michael Petrotta

127
コンピュータがコードを理解できれば、人も理解できます。
オービットの軽量レース、

78
コードをオープンソースにしてください。リバースエンジニアリングを行う人はいません。
ユーザー不明

28
「あいまいさによるセキュリティは機能しませんでした。」
bot47 '06 / 06/26

回答:


151

アンバーが言ったことはまさに正しい。リバースエンジニアリングを難しくすることはできますが、防ぐことはできません。リバースエンジニアリングの防止に依存する「セキュリティ」を信頼してはなりません。

とはいえ、私が見たリバースエンジニアリングの最も優れた手法は、コードを難読化することではなく、コードがどのように機能するかを理解するために一般的に使用されるツールを壊すことに焦点を当てていました。逆アセンブラーやデバッガーなどを壊すための創造的な方法を見つけることは、恐ろしいスパゲッティコードの連なりを単に生成するよりも、どちらもより効果的であり、より知的に満足できる可能性があります。これは断固とした攻撃者をブロックすることは何もしませんが、Jランダムクラッカーが離れて、​​より簡単なものに取り掛かる可能性を高めます。


14
私はこれを理解し、Skypeのセキュリティについて説明したいくつかの論文を読み、Skypeがプロトコルを防止せずに保護する方法としてSkypeがすでに試みたのと同じ考えを熟考しています。Skypeの明らかな状況を考えると、十分に価値があると証明されたもの。
グラファイト

8
Skypeが最初に思い浮かんだ例なので、その方法をエミュレートすることを検討されていることをうれしく思います。
リケット

175

しかし、それらはすべて、適切な時間枠が与えられた場合、コード分析者によって回避および/または把握することができます。

実行可能なプログラムを人々に与えると、彼らは十分な時間をかけてそれをリバースエンジニアリングすることもできます。それがプログラムの性質です。バイナリを解読したい人が利用できるようになるとすぐに、最終的なリバースエンジニアリングを防ぐことはできません。結局、コンピュータはそれを実行するためにそれを解読することができなければなりません、そして、人間は単により遅いコンピュータです。


113
+1。Apple IIのコピー防止の栄光の日々、難読化ツールとクラッカー間の絶え間なく拡大する戦争、フロッピーディスクのステッピングモーターを使用したクレイジーなトリック、およびドキュメントに記載されていない6502の指示などについて読んでください。あまり精巧なものを実装するつもりはなく、結局すべてがクラックされてしまうためです。
ニモ

2
視覚的に、または逆アセンブラーを使用してリバースエンジニアリングを試みるよりも、シミュレーターを使用して視認性を向上させる方が簡単です。使用しているハードウェアにセキュリティが組み込まれていない場合、世界は平均して2日から2週間でリバースエンジニアリングを行い、出てくるほとんどすべてを打ち負かしています。これを作成して実装するのに2日以上かかる場合は、時間がかかりすぎています。
old_timer

5
今日、合理的に機能する唯一のDRMは、キーとインターネットサーバーの組み合わせであり、キーのインスタンスが一度に1つだけアクティブであることを確認します。
するThorbjörnRavnアンデルセン

2
@Rotsor:この種のインテリジェンスをアルゴリズムに(まだ)削減できていないため、コンピューターはそれを理解できません。物理的または技術的な障壁があるためではありません。人間は、コンピュータにできることは何でも(遅いですが)、理由もあるので、それを理解できます。
アダムロビンソン

3
その時点で、ユーザーが制御している環境でしか利用できない場合を除き、誰かがコンピューターをリバースエンジニアリングしようとします。
アンバー

41

Safe Net Sentinel(以前のAladdin)。ただし、注意点-それらのAPIは最低でも、ドキュメントも最低でもあり、どちらもSDKツールと比較して優れています。

私は長年ハードウェア保護方式(Sentinel HASP HL)を使用してきました。ソフトウェアの「ライセンス」として機能する独自のUSBキーフォブが必要です。SDKは実行可能ファイルとライブラリを暗号化して難読化し、アプリケーションのさまざまな機能をキーに書き込まれた機能に関連付けることができます。ライセンサーによってUSBキーが提供およびアクティブ化されていない場合、ソフトウェアは復号化できないため実行できません。Keyは、カスタマイズされたUSB通信プロトコル(私の知識の範囲外ですが、私はデバイスドライバーではありません)を使用して、仮想キーを構築したり、ランタイムラッパーとキー間の通信を改ざんしたりすることもできます。彼らのSDKは開発者にとってあまり使いやすくなく、保護の追加を自動ビルドプロセスに統合するのは非常に困難です(ただし可能です)。

HASP HL保護を実装する前は、製品からdotfuscatorの「保護」を取り除いた7人の既知の海賊がいました。HASPプロテクションをソフトウェアのメジャーアップデートと同時に追加しました。これにより、リアルタイムでビデオの重い計算を実行します。プロファイリングとベンチマークからわかるように、HASP HL保護は集中的な計算を約3%遅くするだけでした。そのソフトウェアが約5年前にリリースされて以来、製品の新しい海賊は1人も見つかりませんでした。それが保護するソフトウェアは、その市場セグメントで高い需要があり、クライアントは、リバースエンジニアリングを積極的に試みているいくつかの競合他社を認識しています(これまでのところ成功していません)。彼らが、ソフトウェア保護を破るサービスを宣伝しているロシアのいくつかのグループに助けを求めようとしたことは知っています。

最近、私たちは小規模なプロジェクトでソフトウェアライセンスソリューション(HASP SL)を試しました。これは、HL製品に既に慣れている場合は簡単に機能します。それは動作するようです。海賊事件は報告されていませんが、この製品は需要がはるかに少ないです。

もちろん、完璧な保護はあり得ません。誰かが十分にやる気があり、深刻な資金を消費する場合、HASPによって提供される保護策を回避できると私は確信しています。


19
モデレーターのメモ: この回答の下のコメントは、敵対的なノイズに脱線したため削除されました。
Tim Post

2
+1は経験ですが、完璧ではないことを繰り返し述べます。Maya(3D suite)はハードウェアドングル(HASPであるかどうかは不明)を使用していましたが、これは海賊を長期間にわたって阻止しませんでした。意志があるとき、方法があります。
Robert Fraser

1
AutoCADは、何度もクラックされた同様のシステムを使用しています。HASPやその他のHASPは、正直な人々を正直に保ち、偶然の海賊行為を防ぎます。次の数十億ドル規模の設計製品を構築する場合、常に対処するクラッカーがいます。そのすべては、収益の減少に関するものです。ソフトウェア保護を解読するのに、それを支払うだけの場合、何時間の労力が必要ですか。
RyanR 2011年

6
また、HASPで保護されたソフトウェアを使用したことのある人の観点からも話を聞きたいと思います。HASPは、エンドユーザーにとってお尻の痛みです。私はダラスのiButtonとアラジンHASPを扱ってきた、との両方があっ本当にバギー、そして切断してHASPを再接続する必要、ランダムに動作を停止にソフトウェアを引き起こしました。
偽の名前

4
また、HASPのセキュリティ対策はコードの難読化よりも安全であるとは限らないことに注意してください。リバースエンジニアリングには別の方法が必要ですが、リバースエンジニアリングすることは可能です-参照:flylogic.net/blog/?p=14 flylogic.net/blog/?p=16 flylogic.net/blog/?p=11
偽の名前

22

特に可変ワード長の命令セットでの最高の逆アセンブラートリックは、Cではなくアセンブラー/マシンコードにあります。たとえば、

CLC
BCC over
.byte 0x09
over:

逆アセンブラは、分岐先がマルチバイト命令の2番目のバイトであるという問題を解決する必要があります。ただし、命令セットシミュレータは問題ありません。計算されたアドレスへの分岐は、Cから発生する可能性があり、逆アセンブルを困難または不可能にします。命令セットシミュレータは問題ありません。シミュレーターを使用して分岐先を分類すると、分解プロセスに役立ちます。コンパイルされたコードは、逆アセンブラにとって比較的クリーンで簡単です。ですから、組み立てが必要だと思います。

Michael AbrashのZen of Assembly Languageの冒頭近くで、単純な逆逆アセンブラと反デバッガのトリックを示したと思います。8088/6にはプリフェッチキューがあり、次の命令またはいくつか前の命令を変更する命令がありました。シングルステップの場合は変更された命令を実行し、命令セットシミュレータがハードウェアを完全にシミュレートしなかった場合は、変更された命令を実行しました。正常に実行されている実際のハードウェアでは、実際の命令はすでにキューにあり、変更されたメモリ位置は、その一連の命令を再度実行しない限り、損傷を引き起こしません。パイプラインプロセッサが次の命令をフェッチするため、今日でもこのようなトリックを使用できます。または、ハードウェアに個別の命令とデータキャッシュがあることがわかっている場合、このコードをキャッシュラインに適切に配置すると、バイト数を先に変更できます。変更されたバイトは、命令キャッシュではなくデータキャッシュを通じて書き込まれます。適切なキャッシュシミュレータがなかった命令セットシミュレータは、適切に実行されません。ソフトウェアのみのソリューションでは、それほど遠くまでは行けないと思います。

上記は古く、よく知られています。現在のツールについては、それらがすでにそのようなことを回避しているかどうかを知るには十分ではありません。自己変更コードはデバッガを起動することができますが、人間は問題を絞り込み、自己変更コードを確認して回避できます。

以前は、ハッカーが何かを処理するのに約18か月かかりました(例:DVD)。現在、平均して2日から2週間(やる気がある場合)(ブルーレイ、iPhoneなど)です。つまり、セキュリティに数日以上費やすと、時間を無駄にしてしまう可能性があります。あなたが得る唯一の本当のセキュリティはハードウェアを介したものです(たとえば、命令は暗号化されており、チップ内部のプロセッサコアのみが実行直前に復号化され、復号化された命令が公開されません)。それはあなたに数日ではなく数ヶ月を買うかもしれません。

また、Kevin Mitnickの本「The Art of Deception」も読んでください。そのような人は、電話を取って、あなたまたは同僚に、それが会社の別の部分のマネージャーまたは別の同僚またはハードウェアエンジニアであると考えて、システムに秘密を渡させることができます。そして、あなたのセキュリティが吹き飛ばされます。セキュリティはテクノロジーの管理だけではなく、人間も管理する必要があります。


1
また、セキュリティホールを見つけるために、ソースコード(または逆アセンブルされたソースコード)にアクセスする必要はありません。これは、偶然か、ほとんどのホールがコード内の同じ問題(バッファオーバーフローなど)に起因するという事実を利用している可能性があります。
asmeurer

2
自己変更コードには大きな問題があります。最近のほとんどのOS /ハードウェアでは、非常に高い権限がないと実行できません。キャッシュの問題が発生する可能性があり、コードはスレッドセーフではありません。
マーティンジェームス

1
最近のx86プロセッサでは、このようなトリックはパフォーマンスに悪影響を及ぼすことがよくあります。複数の命令の一部として同じメモリ位置を使用すると、予測が誤っている分岐と同様の影響が生じる可能性があります。自己変更コードを使用すると、プロセッサはキャッシュラインを破棄して、命令とデータキャッシュ間の一貫性を維持します(変更したコードを変更するよりも頻繁に実行した場合でも、成功する可能性があります)。
jilles '06 / 06/26

2
私はこれに20年前に遭遇しました。何が起こったのかを理解するのに約30分かかりました。より長い保護が必要な場合は、あまり良くありません。
Bo Persson

1
「実際の命令はすでにキューにあり、変更されたメモリ位置は損傷を引き起こしません」その間に割り込みが発生し、命令パイプラインがフラッシュされ、新しいコードが見えるようになるまで。これで、難読化によって正当なユーザーにバグが発生しました。
Ben Voigt

21

たとえば、AESアルゴリズムを見てみましょう。これは非常に非常にパブリックなアルゴリズムであり、非常に安全です。どうして?2つの理由:多くの賢い人々によってレビューされており、「秘密」の部分はアルゴリズム自体ではありません。秘密の部分は、アルゴリズムへの入力の1つである鍵です。コード自体を秘密にするよりも、コードの外部にある生成された「秘密」を使用してプロトコルを設計する方がはるかに優れたアプローチです。コードは、あなたが何をしても常に解釈することができ、(理想的には)生成された秘密は、大規模な総当たり攻撃または盗難によってのみ危険にさらされます。

興味深い質問は、「なぜコードを難読化したいの」だと思います。攻撃者がアルゴリズムを解読するのを困難にしたいですか?彼らがあなたのコードの悪用可能なバグを見つけるのをより困難にするには?そもそもコードが解読できなければ、コードを難読化する必要はありません。問題の根本は、クラック可能なソフトウェアです。問題の根本を修正し、単に難読化しないでください。

また、コードを作成するのがより複雑になるほど、セキュリティバグを見つけるのが難しくなります。はい、それはハッカーにとって難しいことですが、バグも見つける必要があります。コードは数年後の保守が容易である必要があり、適切に記述された明確なコードでさえ保守が難しい場合があります。悪化させないでください。


3
常識的には+1:優れたシステムを設計できるだけで、なぜ自分自身を難しくするのか。
Necrolis、2011年

1
私がいつも言っているように、すべてをサーバー側に保持すると、より安全になります
liamzebedee

20

コードのリバースエンジニアリングを困難にすることをコード難読化と呼びます。

あなたが言及するテクニックのほとんどは、かなり簡単に回避できます。彼らはいくつかの役に立たないコードを追加することに集中しています。しかし、役に立たないコードは簡単に検出して削除できるため、クリーンなプログラムを使用できます。

効果的な難読化を行うには、プログラムの動作を、実行される不要なビットに依存させる必要があります。たとえば、これを行うのではなく、

a = useless_computation();
a = 42;

これを行う:

a = complicated_computation_that_uses_many_inputs_but_always_returns_42();

またはこれを行う代わりに:

if (running_under_a_debugger()) abort();
a = 42;

これrunning_under_a_debuggerを行います(コードがデバッガーの下で実行されているかどうかをテストする関数として簡単に識別できないようにする必要があります—有用な計算とデバッガーの検出を組み合わせる必要があります)。

a = 42 - running_under_a_debugger();

効果的な難読化は、コンパイルの段階で純粋にできることではありません。コンパイラーが実行できることは何でも、逆コンパイラーが実行できます。もちろん、逆コンパイラの負担を増やすことはできますが、それほど遠くまでは行きません。効果的な難読化手法は、存在する限り、1日目から難読化されたソースを作成することを含みます。コードを自己変更します。多数の入力から得られる計算されたジャンプでコードを散らかす。たとえば、単純な呼び出しの代わりに

some_function();

これを行うと、ビットの予想される正確なレイアウトがわかりますsome_data_structure

goto (md5sum(&some_data_structure, 42) & 0xffffffff) + MAGIC_CONSTANT;

難読化を真剣に考えている場合は、計画に数か月を追加してください。難読化は安くはありません。そして、人々があなたのコードをリバースエンジニアリングすることを避けるための最善の方法は、彼らが気にならないようにそれを役に立たなくすることであると考えてください。これは単純な経済的考慮事項です。彼らにとっての価値がコストよりも大きい場合、リバースエンジニアリングを行います。ただし、コストを上げるとコストも大幅に上がるので、値を下げてみてください。

今、私はことを言ったことを難読化が困難で、高価な、私はあなたを伝えるつもりだ、それはとにかくあなたのためではありません。あなたが書く

私が取り組んでいる現在のプロトコルは、さまざまな人々のセキュリティのために、決して検査または理解されてはなりません

それは赤い旗を上げる。これは非常に貧弱な記録を持つ、あいまいさによるセキュリティです。プロトコルのセキュリティがプロトコルを知らない人に依存している場合、あなたはすでに負けています。

推奨読書:


1
@ギレス、それはあなたの声明であり、非常に強いので、立証責任はあなたにあります。ただし、簡単な例を示します。2+2コンパイラーによってに簡略化できます4が、逆コンパイラーはそれを元に戻すことができません2+2(実際にそうだった場合はどうなり1+3ますか?)。
Rotsor

7
@Rotsor 42+2は観測上同等であるため、この目的でも同じです。つまり、プログラムが何をしているかを理解するためです。はい、もちろん、逆コンパイラはソースコードを再構築することはできませんが、それは無関係です。このQ&Aは、動作(つまり、アルゴリズム、より正確にはプロトコル)の再構築に関するものです。
Gilles「SO-邪悪なことをやめなさい」

1
動作を再構築するために何もする必要はありません。あなたはすでにプログラムを持っています!何が通常必要なのは(2を交換するようにそれでプロトコルと変更何かを理解することである2+23と、または交換+とします*)。
Rotsor

1
動作的に同等なプログラムをすべて同じと見なすと、コンパイラはインデンティ変換のみを実行するため、コンパイラは何もできません。デコンパイラーもまた、アイデンティティの変換なので、その場合も役に立ちません。ただし、そうしない場合、2+2-> 4は、コンパイラーによって実行される不可逆変換の有効な例です。それが理解をより簡単にするか、より難しくするかどうかは別の議論です。
Rotsor

2
@ギレス私はあなたの類推をアップルで拡張することはできません。構造的に異なるが行動的に同等なアップルは想像できないからです。:)
Rotsor

13

多くの場合、製品がリバースエンジニアリングされることへの恐れは見当違いです。はい、リバースエンジニアリングできます。しかし、それが短期間で非常に有名になるので、ハッカーは逆転する価値があると気づくでしょう。それ ?(この仕事は、コードの実質的な行のための短い時間の活動ではありません)。

それが本当にお金を稼ぐ人になるなら、あなたは特許や著作権などの法的な方法を使ってそれを保護するのに十分なお金を集めているはずです。

私見、あなたが取るつもりの基本的な予防策を取り、それを解放してください。それがリバースエンジニアリングのポイントになり、本当に良い仕事をしたということになれば、あなた自身がそれを克服するより良い方法を見つけるでしょう。幸運を。


1
つまり、これは実行可能で適用可能な答えですが、保護と数百万の収入を得て他の人にあなたの製品を保護してもらうという境界線は非常に長いものです。
グラファイト

12

http://en.wikipedia.org/wiki/Security_by_obscurity#Arguments_againstをお読みください。他の人もおそらく、あいまいさによるセキュリティが悪いことである理由のより良い情報源を提供することができると確信しています。

最新の暗号化技術を使用して、システムをオープンにすることは完全に可能であり(オープンである必要はないと言っているわけではありません)、暗号化アルゴリズムが実行されない限り、完全なセキュリティを維持できます。そこに穴が開いており(適切なものを選択した場合はそうではない)、秘密鍵/パスワードは秘密のままであり、コードにセキュリティホールがありません(これはあなたが心配すべきことです)。


2
私はこれに同意します。概念的または設計上の問題があると思います。秘密鍵と公開鍵のペアソリューションを持つアナログはありますか?秘密鍵を漏らすことはありません。安全なクライアントが秘密鍵を処理する所有者に残ります。安全なコードをコンピューターから切り離して、結果のみをユーザーに返すことはできますか?
ディズリー

8

2013年7月以降、Amit Sahaiの元の研究から拍車をかけたと思われる、暗号的に堅牢な難読化(区別不能難読化)に対する関心が新たに高まっています。

このQuanta Magazineの記事とそのIEEE Spectrumの記事で、いくつかの蒸留された情報を見つけることができます。

現在、この手法を利用するために必要なリソースの量は実用的ではありませんが、AFAICTコンセンサスは将来についてはかなり楽観的です。

私はこれを非常にさりげなく言いますが、難読化テクノロジを本能的に却下することに慣れているすべての人にとって、これは異なります。それが本当に機能していて実用的であることが証明されている場合、これは確かにメジャーであり、難読化だけではありません。


7

自分に知らせるために、コード難読化に関する学術文献を読んでください。アリゾナ大学のクリスチャンコルバーグは、この分野で評判の高い学者です。ハーバード大学のサリル・バダンもいくつかの良い仕事をしました。

私はこの文献に遅れをとっていますが、私が知っている本質的な考えは、実行するコードを攻撃者に見られないようにすることはできないが実行されないコードでそれを囲むことができ、コストがかかるということです。コードのどのフラグメントが実行され、どのフラグメントが実行されていないかを発見するための攻撃者の指数時間(最もよく知られている手法を使用)。


7

プログラムの難読化と1回限りのプログラム呼ばれる最近の論文があります。アプリケーションの保護に真剣に取り組んでいる場合。一般に、このペーパーでは、シンプルでユニバーサルなハードウェアを使用することによる理論的に不可能であるという結果を取り上げています。

追加のハードウェアを必要とする余裕がない場合は、同じ機能と同じサイズのすべてのプログラムの中で、理論的に可能な限りの難読化「On best-possible obfuscation」についての別のペーパーもあります。ただし、この論文では、情報理論的に可能な限り最良のものが多項式階層の崩壊を意味することを示しています。

これらの論文は、これらの結果があなたのニーズに合わない場合、少なくとも関連文献を歩くのに十分な書誌的リードを与えるはずです。

更新:区別が困難な難読化と呼ばれる難読化の新しい概念により、不可能性の結果を軽減できる(論文)


6

誰かがバイナリを反転する時間を費やしたい場合、それらを停止するためにあなたができることは絶対にありません。あなたは適度に難しい場合でも作ることができますが、それはそれについてです。これについて本当に知りたい場合は、http://www.hex-rays.com/idapro/のコピーを入手して、いくつかのバイナリを分解してください

CPUがコードを実行する必要があるという事実は、元に戻すことです。CPUはマシンコードのみを実行し、プログラマーはマシンコードを読み取ることができます。

とはいえ、別の方法で解決できる別の問題が発生している可能性があります。何を守ろうとしているの?問題によっては、暗号化を使用して製品を保護することができます。


6

適切なオプションを選択できるようにするには、次の点を考慮する必要があります。

  1. 「新しいユーザー」が支払いを望まず、ソフトウェアを使用する可能性はありますか?
  2. 既存の顧客が持っているよりも多くのライセンスを必要とする可能性はありますか?
  3. 潜在的なユーザーはいくら支払ってもよいですか?
  4. ユーザー/同時ユーザー/ワークステーション/会社ごとにライセンスを付与しますか?
  5. あなたのソフトウェアが役立つためにトレーニング/カスタマイズが必要ですか?

質問5の回答が「はい」の場合、違法コピーの心配はありません。とにかく役に立たないでしょう。

質問1の答えが「はい」の場合、最初に価格設定について考えます(質問3を参照)。

質問2に「はい」と答えた場合、「従量制」モデルが適している可能性があります。

私の経験から、次の理由により、従量課金制+カスタマイズとトレーニングがソフトウェアの最良の保護です。

  • 新規ユーザーは価格モデルに惹かれます(ほとんど使用されない->わずかな支払い)
  • 「匿名ユーザー」はほとんどいません。トレーニングとカスタマイズが必要だからです。
  • ソフトウェアの制限が潜在的な顧客を怖がらせません。
  • 既存の顧客からのお金の継続的な流れがあります。
  • 長期的なビジネス関係のため、顧客から開発に関する貴重なフィードバックを得ることができます。

DRMまたは難読化の導入を考える前に、これらの点を考え、それがソフトウェアに適用可能かどうかを考えるかもしれません。


非常に良いアドバイスです(そして私はそれを支持しました)が、それはこの特定の質問に実際に対処するものではありません
モーグはモニカを復活させます

5

仮想マシンの保護されたコードは、最初はリバースエンジニアリングが不可能であるように見えました。テミダパッカー

しかし、それはもはや安全ではありません。そして、コードをどのようにパックしても、ロードされた実行可能ファイルのメモリダンプを常に実行し、IDA Proのような逆アセンブラでそれを逆アセンブルできます。

IDA Proには、Cソースコードトランスフォーマーへの気の利いたアセンブリコードも付属していますが、生成されたコードは、ポインター/アドレスの数学的な混乱に似ています。


5

サイコロはありません。コードを逆アセンブルから保護することはできません。あなたができることは、ビジネスロジックのためにサーバーを設定し、アプリにそれを提供するためにウェブサービスを使用することです。もちろん、このシナリオは常に可能であるとは限りません。


8
よく言われているように、人々がコードを分解しないようにする唯一の方法は、コードに物理的にアクセスできないようにすることです。つまり、アプリケーションをSAASとして排他的に提供し、リモートクライアントからリクエストを受け取り、処理されたデータを返します。サーバーをアリゲーターの溝と5mの電気かみそりワイヤーに囲まれた地下バンカーのロックされた部屋に置き、10mの鉄筋コンクリートでカバーする前にキーを捨てて、トンを設置することを忘れないでください。ネットワークを介した侵入を防ぐためのソフトウェアシステムの。
2011年

6
私はあなたのサーバーを維持するための契約を取得することはありません願っています
コリン・ピカード

5

リバースエンジニアリングを回避するには、コードをユーザーに提供しないでください。とは言っても、オンラインアプリケーションを使用することをお勧めします。


これが本当の解決策です...つまり、独自のVPSマシン上の独自のサーバーに王冠を置き、クライアント(ブラウザーまたはAPIクライアント)からこのサーバーへのAPI呼び出しのみを公開します
Scott Stensland

5

おそらく、最良の代替策は仮想化を使用することであり、バイパスが必要な別のレベルの間接化/難読化が導入されますが、SSpokeの回答で述べたように、この手法も100%安全ではありません。


重要なのは、そのようなものは存在しないため、最終的な保護を受けることができず、それがあったとしても長続きしないことです。つまり、そもそもそれは最終的な保護ではありませんでした。

どんな人が組み立てても、分解することができます。

通常、(適切な)分解は(少し以上)多くの場合困難な作業であるため、対戦相手より熟練している必要があります。

REから何かを保護する場合は、少なくともREで使用される一般的な手法を知っている必要があります。

したがって、言葉

インターネットは、リバースエンジニアリングを防止するのに実際に役立つわけではなく、リバースエンジニアリングの方法に関する大量の情報を示しています

あなたの態度が悪い。保護を使用または埋め込むには、それを破る方法を知っている必要があるとは言っていませんが、賢く使用するには、その弱点と落とし穴を知っている必要があります。あなたはそれを理解する必要あります。

(誤った方法で保護を使用しているソフトウェアの例があり、そのような保護は実質的に存在しません。漠然と話すのを避けるために、私はインターネットで簡単に説明されている例を挙げましょう:CD-ROM v4のOxford English Dictionary Second Edition。次のページでのSecuROMの使用の失敗:16、32、または64ビットのWindows環境でのCD-ROM上のOxford English Dictionary(OED):ハードディスクのインストール、バグ、ワープロマクロ、ネットワーク、フォント、およびなど

すべてに時間がかかります。

あなたがこのテーマに不慣れで、REに適切に取り組むための月または数年がない場合は、他の人が作成した利用可能なソリューションを使用してください。ここでの問題は明白であり、すでに存在しているため、100%安全ではないことは既にわかっていますが、独自の新しい保護を作成しても、保護されているという誤った感覚しか得られません。リバースエンジニアリングと保護(ただし、少なくとも現時点ではそうではありません)。

ソフトウェア保護のポイントは、初心者を怖がらせ、一般的なREを失速させ、経験豊富なREがアプリケーションの中心に(できれば興味深い)旅を終えた後、笑顔を見せることです。

商談では、可能な限り競争を遅らせることがすべてであると言うかもしれません。

(Black Hat 2006に表示されたPhilippe BiondiとFabrice DesclauxによるSkypeでのSilver Needleの素晴らしいプレゼンテーションをご覧ください)。


REについてはいろいろなことがわかっているので、読み始めてください。:)

仮想化について説明したので、EXETOOLS FORUMの 1つの例示的なスレッドへのリンクを示します。最高のソフトウェアプロテクター:ThemidaまたはEnigma Protector?。それは、さらなる検索に少し役立つかもしれません。


4

どのコードもハッキングできないとは思いませんが、誰かがそれを試してみたいと思う人にとっては、報奨は素晴らしいものである必要があります。

あなたがすべきことは次のようなものがあると言いました:

  • 可能な限り最高の最適化レベルを使用します(リバースエンジニアリングは、アセンブリシーケンスを取得することだけでなく、コードを理解し、Cなどの高水準言語に移植することも含みます)。高度に最適化されたコードは従うべきb --- hです。
  • 必要以上に大きなデータ型を持たないようにして、構造を密にしてください。公式コードリリース間で構造体メンバーを再配置します。構造体のビットフィールドを並べ替えることもできます。
  • 変更してはならない特定の値の存在を確認できます(著作権メッセージが一例です)。バイトベクトルに「vwxyz」が含まれている場合は、「abcde」を含む別のバイトベクトルを作成して、違いを比較できます。それを実行する関数には、ベクトルへのポインターを渡すべきではありませんが、他のモジュールで(擬似Cコード) "char * p1 =&string1 [539];"として定義された外部ポインターを使用します。および「char p2 =&string2 [-11731];」。そうすれば、2つの文字列を正確に指すポインタはなくなります。次に、比較コードで「(p1-539 + i)-*(p2 + 11731 + i)== some value」について比較します。クラッカーは、誰もそれを参照しているようには見えないので、string1を変更しても安全だと考えます。予想外の場所でテストを埋めます。

アセンブリコードを自分でハックして、何が簡単で何が難しいかを確認してください。コードをリバースエンジニアリングし、デバッグをより困難にするために実験できるアイデアがポップアップ表示されます。


2
あなたの最初のポイントは意味がありません、最適化されたコードは残骸をカットします、これは簡単に元に戻すことができます(私は経験から話します)。スリッドポイントも時間の浪費であり、メモリアクセスブレークポイントを実行する方法を知っている彼の知識に値するリバースエンジニアです。これは...おそらく少し長く「ルーキー」は作成することができます何よりも最後のAへのthats becuase、おそらく最高のシステムを自分で設計しないことである理由であるが、あることをまだ持っている私たちのサードパーティのライブラリ「割れた」
Necrolis

主題については何もわからないようですので、コードを自分で書くのではなく、ソフトウェア開発のニーズに応じて、あなたなどの専門家に相談する必要があります。
Olof Forshell、2011年

4

多くの人がすでに言ったように:通常のCPUでは、実行を止めることはできません。遅延させるだけです。私の古い暗号の先生が私に言ったように:あなたは完全な暗号化を必要としないので、コードを解読することは利益よりももっと高価でなければなりません。難読化についても同じことが言えます。

しかし、3つの追加の注記:

  1. リバースエンジニアリングを不可能にすることが可能である、しかし(これは非常に非常に大きいが、ある)、あなたは、従来のCPU上でそれを行う傾けます。ハードウェアの開発も多く、FPGAがよく使われています。たとえば、Virtex 5 FXにはPowerPC CPUが搭載されており、APUを使用してハードウェアに独自のCPUオペコードを実装できます。この機能を使用して、外部または他のソフトウェアからアクセスできないPowerPCの命令を実際に復号化したり、ハードウェアでコマンドを実行したりすることもできます。FPGAにはコンフィギュレーションビットストリーム用のAES暗号化が組み込まれているため、リバースエンジニアリングを行うことができませんでした(誰かがなんとかAESを壊した場合を除いて、他の問題があると思います...)。これにより、ハードウェアIPのベンダーも作業を保護します。

  2. あなたはプロトコルから話します。どのようなプロトコルであるかは言いませんが、それがネットワークプロトコルである場合は、少なくともネットワークスニッフィングから保護する必要があります。これは確かに暗号化によって行うことができます。ただし、ソフトウェアの所有者から暗号化/暗号化を保護したい場合は、難読化に戻ります。

  3. プログラムをデバッグできない/実行できないようにしてください。デバッグのある種の検出を使用して、それを適用してみてください。たとえば、マジック定数にデバッグレジスタの内容を追加する数式に使用してください。プログラムが正常に実行されている場合と同じようにデバッグモードでプログラムを検索すると、計算、操作、またはその他の処理が完全に正しく行われなくなります。例:コピープロテクションが非常に厄介なエコゲームをいくつか知っています(コピープロテクションを望まないことは知っていますが、同様です):盗まれたバージョンは、30分のゲームプレイ後にマイニングされたリソースを変更し、突然1つだけになりました資源。海賊はちょうどそれを解読しました(すなわち、それをリバースエンジニアリングしました)-それが実行されるかどうかをチェックし、voliaがそれをリリースしました。このようなわずかな動作の変化は、特に検出が非常に困難です。すぐには検出されず、遅れるだけの場合。

それで最後に私は提案します:あなたのソフトウェアをリバースエンジニアリングする人々の利益を推定し、これをある時間に翻訳し(例えば、最も安いインドの給与を使用することにより)、リバースエンジニアリングを時間のかかるものにして、それが大きくなるようにします。


3

ほとんどの人が言うことに反して、直感と個人的な経験に基づいて、暗号的に安全なプログラムの難読化が一般的に不可能であると証明されているとは思いません。

これは、私の要点を示すために完全に難読化されたプログラムステートメントの1つの例です。

printf("1677741794\n");

それが実際に何をしているのかを推測することはできません

printf("%d\n", 0xBAADF00D ^ 0xDEADBEEF);

このテーマに関する興味深い論文があり、これはいくつかの不可能な結果を​​証明しています。「難読化プログラムの(不可能な)可能性について」と呼ばれています

この論文は、プログラムを実装する機能と区別できないようにする難読化は不可能であることを証明していますが、より弱い方法で定義された難読化はまだ可能です!


7
1.あなたの例はここでは関係ありません。表示する2つのプログラムは動作的に同等であり、この質問はプログラムの動作を理解することであり、ソースコードを再構築することではありません(明らかに、これは不可能です)。2.この論文は理論的な論文です。完全な難読化プログラムを作成することは不可能ですが、完全な逆コンパイラを作成することも不可能です(完全なプログラムアナライザを作成することと同じ理由で)。実際には、それは軍拡競争です:誰がより良い(解)難読化者を書くことができます。
Gilles「SO-邪悪なことをやめよう」

1
@Gilles、(正しい)解読の結果は、常に動作的に難読化されたコードと同等になります。それがどのように問題の重要性を損なうのかわかりません。
Rotsor

また、軍拡競争についても、これは誰が研究にもっと投資するかではなく、誰が正しいかについてです。誰かが本当にひどく望んでいるからといって、正しい数学的証明が失敗することはありません。
Rotsor

1
さて、多分あなたは実際の軍拡競争について正しいです。これは誤解したようです。:)私はある種の暗号的に安全な難読化が可能であることを願っています。
Rotsor

難読化の興味深いケースについては、スマートカードを試してください。問題は、攻撃者が物理的にアクセスできることです(ホワイトボックス難読化)。応答の一部は、物理的な手段でアクセスを制限することです(攻撃者は秘密鍵を直接読み取ることはできません)。しかし、ソフトウェアの難読化も役割を果たし、主にDPAのような攻撃が有用な結果をもたらさないようにします。申し訳ありませんが、申し訳ありません。私の回答の例は、そのドメインで使用されている手法から漠然とヒントを得ています。
Gilles「SO-邪悪なことをやめなさい」

3

あいまいさによるセキュリティは、私たち2人よりもはるかに賢い人々によって実証されているように機能しません。顧客の通信プロトコルを保護する必要がある場合は、オープンで完全に専門家によって精査された最良のコードを使用することが道徳的に義務付けられています。

これは、人々がコードを検査できる状況のためのものです。アプリケーションを組み込みマイクロプロセッサーで実行する場合は、シーリング機能を備えたものを選択できます。これにより、コードを検査したり、実行中に現在の使用状況のような些細なパラメーターを監視することができなくなります。(ハードウェア侵入技術を除き、チップを慎重に解体し、高度な機器を使用して個々のトランジスタの電流を検査します。)

私はx86のリバースエンジニアリングアセンブラーの作成者です。冷たい驚きの準備ができているなら、私にあなたの最善の努力の結果を送ってください。(私のウェブサイトを通じて私に連絡してください。)答えに出会ったことのある人は、かなりのハードルを私に与えるでしょう。洗練されたリバースエンジニアリングコードがどのように機能するかを確認したい場合は、リバースエンジニアリングの課題があるWebサイトを研究する必要があります。

あなたの質問はいくつかの説明を使用することができます。コンピュータコードがリバースエンジニアリングに適している場合、どのようにプロトコルを秘密に保つと思いますか?私のプロトコルがRSA暗号化メッセージ(公開鍵を含む)の送信である場合、プロトコルを秘密にしておくことで何が得られますか?すべての実際的な目的のために、検査官は一連のランダムなビットに直面します。

Groetjes Albert


3

従来のリバースエンジニアリング手法は、逆アセンブラを使用してコードに関する質問に答えるスマートエージェントの能力に依存しています。強力な安全性が必要な場合は、エージェントがそのような答えを得ることをおそらく証明できないことをしなければなりません。

これは、一般に解決できない停止プログラム(「プログラムXは停止するか?」)に依存することで実行できます。推論するのが難しいプログラムをプログラムに追加すると、プログラムの推論が難しくなります。このようなプログラムは、切り離すよりも簡単に作成できます。推論の難易度が異なるコードをプログラムに追加することもできます。有力な候補は、エイリアス(「ポインタ」)を推論するプログラムです。

Collbergほかには、これらのトピックについて説明し、コードについての推論を非常に困難にするさまざまな「不透明な」述語を定義する論文(「安価で回復力がありステルスな不透明構造の製造」)があります。

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.39.1946&rep=rep1&type=pdf

Collbergの特定のメソッドがプロダクションコードに適用されるのを見たことはありません。特にCまたはC ++ソースコードは対象外です。

DashO Java難読化ツールも同様のアイデアを使用しているようです。 http://www.cs.arizona.edu/~collberg/Teaching/620/2008/Assignments/tools/DashO/


2

コードを非表示にすることについて覚えておくべき最初の事柄:コードのすべてを非表示にする必要はありません。

最終目標は:ほとんどのソフトウェアプログラムのための私の最終目標は、私のプログラム内の特定の機能のオンとオフになります別のライセンスを販売する能力です。

最高のテクニック:WordPressが提供するようなフックとフィルターのシステムで構築することは、対戦相手を混乱させようとする場合の絶対最良の方法であることがわかりました。これにより、実際にコードを暗号化せずに、特定のトリガーの関連付けを暗号化できます。

これを行う理由は、可能な限り最小限のコードを暗号化する必要があるためです。

あなたのクラッカーを知ってください:これを知ってください:コードをクラックする主な理由は、ライセンスの悪意のある配布によるものではなく、実際にはコードを変更する必要があり、無料のコピーを配布する必要がないからです。

はじめに:暗号化する少量のコードを脇に置いて、残りのコードを1つのファイルに詰め込み、複雑さと理解を深める必要があります。

暗号化の準備:私のシステムではレイヤーで暗号化しますが、これも非常に複雑な手順になるため、暗号化プロセスを担当する別のプログラムを作成します。

ステップ1:すべてにbase64名を使用して難読化します。完了したら、難読化されたコードをbase64し、後でこのコードの復号化と実行に使用される一時ファイルに保存します。理にかなっていますか?

これを何度も繰り返すことになるので、繰り返します。base64文字列を作成し、復号化してレンダリングする変数として別のファイルに保存します。

ステップ2:この一時ファイルを文字列として読み取り、難読化してから、base64で保存し、それを2番目の一時ファイルに保存します。この一時ファイルを使用して、エンドユーザーに解読してレンダリングします。

ステップ3:ステップ2を必要なだけ繰り返します。復号化エラーなしでこれを適切に機能させると、対戦相手の地雷で構築を開始することになります。

LAND MINE ONE:絶対的な秘密が通知されているという事実を守りたいと思うでしょう。そのため、レイヤー2のクラッカー試行セキュリティ警告メールシステムを組み込みます。これは、何か問題が発生した場合に相手の詳細を通知するために起動されます。

LAND MINE TWO:依存関係。対戦相手がレイヤー1、レイヤー3または4または5を使わずに実行できるようにしたくなく、実際にそれが設計されたプログラムも必要ありません。そのため、レイヤー1内に、プログラムが存在しない場合にアクティブになる何らかの種類のkillスクリプト、または他のレイヤーを含めるようにしてください。

あなたは自分の地雷だと思いつくことができ、それを楽しんでいると確信しています。

覚えておくべきこと:実際にコードをbase64する代わりに暗号化することができます。そうすれば、単純なbase64でプログラムを解読できなくなります。

報酬:これは実際にはあなたとあなたの対戦相手の間の共生関係である可能性があることを覚えておいてください。私は常にレイヤー1の内側にコメントを配置します。このコメントはクラッカーを祝福し、あなたから現金報酬を受け取るために使用するプロモーションコードを提供します。

偏見を伴わずに現金報酬を有意なものにします。私は通常$ 500のようなものを言います。あなたの男が最初にコードを解読した場合、彼にお金を払い、彼の友達になります。もし彼があなたの友達なら、あなたのソフトウェアを配布するつもりはありません。彼にそれをどうやってやったのか、そしてあなたがどのように改善できるかを彼に尋ねてください!

幸運を!


4
あなたも質問を読みましたか?海賊行為から身を守る方法を尋ねたことはありません。アプリケーションは無料です。セキュリティの性質上、保護する必要があるのは、使用されている基本的なプロトコルです。
グラファイト

2

誰かがCodeMorthを試したことがあります:http : //www.sourceformat.com/code-obfuscator.htm?またはThemida:http ://www.oreans.com/themida_features.php ?

後でより有望に見えます。


私が最初にお勧めすることは、商用の難読化ツールの使用を絶対に避けることです!難読化ツールをクラックすると、難読化されたすべてのアプリケーションをクラックできるからです。
窒化ガリウム2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.