ブラックボックスを攻撃したす。 仮想化および倉曎されたコヌドのリバヌス゚ンゞニアリング





自分の゜フトりェアをリバヌス゚ンゞニアリングから保護するこずはかなり叀い問題であり、か぀お倚くのシェアりェア開発者の心を苊しめただけでなく、それを苊しめたした。 通垞、このような目的にはトレッドが䜿甚されたすが、トレッドがどんなに急募配であっ​​おも、垞にトレッドを切断しおクラックする人がいたす。 しかし最近、プロテクタヌはコヌド倉曎技術突然倉異ず仮想化の䜿甚を開始したした。これにより、元のアルゎリズムのブラックボックスのような混乱を䜜るこずができたす。 実際、珟代の商甚プロテクタヌによる実行可胜コヌドの仮想化ず突然倉異は䞇胜薬であるず確信しおいる人々がいたす。 セキュリティの苊い䟡栌を知っおいる人は、完党な保護のヒントを神話やマヌケティングのおずぎ話ずしお感じる可胜性が高いため、セキュリティガヌドがこのような声明にかなり笑い、反察するこずは明らかです。 この蚘事では、商甚プロテクタヌのブラックボックスずその攻撃の可胜性を探るずいう私自身の経隓ずビゞョンに぀いおお話したす。 このような技術の䞍利な点を理解するこずで、実際にそれらをより合理的か぀効果的に適甚するか、たったく適甚しないかを願っおいたす。



0x00。 コヌド保護メカニズムの分析


たず、調査するテクノロゞヌを定矩したしょう。



1.ミュヌテヌションは、オリゞナルのプログラムアルゎリズムに違反するこずなく、制埡フロヌの元のグラフが远加の頂点、分岐、ガベヌゞ呜什、サむクルによっお補完されるコヌド難読化方法です。 倚くの堎合、゜ヌス呜什は同じゞョブを実行する他の呜什のサブセットに倉換されたす。



2.仮想化は、アルゎリズムの元の呜什がプロテクタヌによっお生成された仮想マシンの呜什に倉換されるコヌド難読化方法です。 元のアルゎリズムの代わりに、実行時に䞭間呜什を枡しおそれらを解釈する仮想マシンに入るコヌドが埋め蟌たれおいたす。



䞡方の方法は、実行可胜コヌドの静的および動的分析の䞡方を耇雑にし、倚くの堎合、プロテクタヌは方法の組み合わせを蚱可したす。



蚘事の埌半で、 VMProtectずSafengineの 2぀のプロテクタヌの無料デモバヌゞョンを怜蚎したす。これらは、難読化の䞡方の方法を倉曎、仮想化、および組み合わせるこずを可胜にしたす。



ミュヌテヌションおよびコヌド仮想化テクノロゞヌを適甚するために、プロテクタヌは次の方法を提䟛したす。



1.開発段階で、特別なマヌカヌSDKを䜿甚

゜フトりェア開発者は、゜ヌスコヌドでトレッドSDKの特別な機胜を䜿甚しお保護されたコヌドのフラグメントをマヌクし、コンパむル埌、トレッドのむンストヌル段階でこれらのセクションを怜出、切り取り、難読化したす。



int main () { VMProtectMutate("Critical_code_mut"); ... // critical code here VMProtectEnd(); return 0; }
      
      



VMProtectマヌカヌで゜ヌスコヌドをマヌクする䟋



2.保護の段階で、デバッグファむルを䜿甚

トレッドのむンストヌル䞭に盎接、デバッグファむルpdb、mapが読み取られ、それに基づいおアプリケヌションオブゞェクトのマップが決定されたす。 次に、開発者は、保護する機胜ずその方法を遞択したす。その埌、それらは完党にコヌドから切り離されお凊理されたす。



保護されたコヌドが切断されるのはなぜですか 実際、コヌドが垌釈されるず、そのサむズが倧幅に増加するため、元のセグメントに新しい呜什を収めるこずができないため、コヌドはトレッドメモリの独自のセクションにカットされたす。





実行可胜関数コヌドの簡略化された突然倉異スキヌムvoid Test{printf "Hello"; }



0x01。 プロテクタヌの長所ず短所


もちろん、突然倉異の明らかな利点は、アルゎリズムの芖芚的調査が䞍可胜であるこずです。 研究者の前に、䞀芋するず、スパゲッティの山が付いたプレヌトがありたす。これは手で分解するこずは非垞に難しく、たさに珟代の保護者が賭けおいるものです。



同様に重芁なのは、デバッグ察策、パッチ適甚察策、フック察策、突然倉異などのさたざたな手法の組み合わせです。 䞀緒に、これはすべお分析プロセスの耇雑化に぀ながりたすが、それらを停止したせん。



そのような技術の欠点も十分です。 1぀目はパフォヌマンスの䜎䞋です。これは、倉曎されたコヌドが数癟たたは数千倍も増加するためです。 これは仮想化にも適甚されたす。原則ずしお、仮想マシンは倉曎されたコヌドよりもはるかに重いです。 䞡方のアプロヌチを組み合わせるず、コヌドが肥倧化したす。 さらに、オヌバヌヘッドコストは垞にこのような難読化を正圓化するものではありたせん。倉異技術の䜿甚は、プログラム実行の元のグラフの埩元を耇雑にするこずを目的ずしおいたす。



プリミティブ関数をトレヌスする䟋を次に瀺したす。



 void test() { printf("This is protected message #1\n"); printf("This is protected message #2\n"); }
      
      





突然倉異前

トレヌスログ
 メむン00405A2A CALL 004059F0 ESP = 0018FEE0
メむン004059F0 PUSH EBP ESP = 0018FEDC
メむン004059F1 MOV EBP、ESP EBP = 0018FEDC
メむン004059F3 SUB ESP、40 ESP = 0018FE9C
メむン004059F6 PUSH EBX ESP = 0018FE98
メむン004059F7 PUSH ESI ESP = 0018FE94
メむン004059F8 PUSH EDI ESP = 0018FE90
メむン004059F9プッシュオフセット0040ED10 ESP = 0018FE8C
メむン004059FE CALL DWORD PTR DS[<MSVCR100D.printf>] EAX = 00000012、ECX = 84CB6CA9、EDX = 7418F4B8
メむン00405A04 ESPの远加、4 ESP = 0018FE90
メむン00405A07プッシュオフセット0040ECF8 ESP = 0018FE8C
 main 00405A0C CALL DWORD PTR DS[<MSVCR100D.printf>] EAX = 00000014
メむン00405A12 ADD ESP、4 ESP = 0018FE90
メむン00405A15 POP EDI ESP = 0018FE94
メむン00405A16 POP ESI ESP = 0018FE98
メむン00405A17 POP EBX ESP = 0018FE9C
メむン00405A18 MOV ESP、EBP ESP = 0018FEDC
メむン00405A1A POP EBP ESP = 0018FEE0、EBP = 0018FF30
メむン00405A1B RETN ESP = 0018FEE4 


Safengineプロテクタヌによる突然倉異埌

トレヌスログ
 メむン00405A2A CALL 004059F0 ESP = 0018FEE0
メむン004059F0 JMP 004C9C6A
メむン004C9C6A JMP 004C8391
メむン004C8391 CALL 004C82D6 ESP = 0018FEDC
メむン004C82D6 LEA ESP、[ESP + 2] ESP = 0018FEDE
メむン004C82DA LEA ESP、[ESP + 2] ESP = 0018FEE0
メむン004C82DE PUSH EBP ESP = 0018FEDC
メむン004C82DF NEG BP EBP = 001800D0
メむン004C82E2 JMP 004C812E
メむン004C812E MOV EBP、ESP EBP = 0018FEDC
メむン004C8130 STC
メむン004C8131 SUB ESP、40 ESP = 0018FE9C
メむン004C8134 CALL 004C8006 ESP = 0018FE98
メむン004C8006 JMPショヌト004C7F96
メむン004C7F96 LEA ESP、[ESP + 4] ESP = 0018FE9C
メむン004C7F9A PUSH EBX ESP = 0018FE98
メむン004C7F9B CALL 004C7F80 ESP = 0018FE94
メむン004C7F80 LEA ESP、[ESP + 4] ESP = 0018FE98
メむン004C7F84 PUSH ESI ESP = 0018FE94
メむン004C7F85 JMP SHORT 004C7FB6
メむン004C7FB6 PUSH EDI ESP = 0018FE90
メむン004C7FB7 PUSH 0040ED10 ESP = 0018FE8C
 main 004C7FBC CALL DWORD PTR DS[40E19C] EAX = 00000012、ECX = 93D2AD8F、EDX = 7418F4B8
メむン004C7FC2 JMP SHORT 004C7FA0
メむン004C7FA0 STC
メむン004C7FA1 JMP SHORT 004C7FDA
メむン004C7FDA ADD ESP、4 ESP = 0018FE90
メむン004C7FDD CALL 004C7FC4 ESP = 0018FE8C
メむン004C7FC4 LEA ESP、[ESP + 4] ESP = 0018FE90
メむン004C7FC8 PUSH 0040ECF8 ESP = 0018FE8C
 main 004C7FCD CALL 004C7FE2 ESP = 0018FE88
メむン004C7FE2 MOV BYTE PTR SS[ESP]、CH
メむン004C7FE5 JMP SHORT 004C7FEB
メむン004C7FEB LEA ESP、[ESP + 4] ESP = 0018FE8C
 main 004C7FEF CALL DWORD PTR DS[40E19C] EAX = 00000014
メむン004C7FF5 SETPE BH EBX = 7EFD0100
メむン004C7FF8 XCHG BL、BH EBX = 7EFD0001
メむン004C7FFA INC EBX EBX = 7EFD0002
メむン004C7FFB JMPショヌト004C805A
メむン004C805A ESPの远加、4 ESP = 0018FE90
メむン004C805D POP EDI ESP = 0018FE94
メむン004C805E MOV ESI、4B536EDD ESI = 4B536EDD
メむン004C8063 MOV SI、WORD PTR SS[ESP] ESI = 4B530000
メむン004C8067 JMPショヌト004C801E
メむン004C801E LEA EBX、[CDDFCA2F] EBX = CDDFCA2F
メむン004C8024 POP ESI ESP = 0018FE98、ESI = 00000000
メむン004C8025 CALL 004C8008 ESP = 0018FE94
 main 004C8008 POP WORD PTR SS[ESP] ESP = 0018FE96
メむン004C800C MOV BX、WORD PTR SS[ESP + 1] EBX = CDDF0000
メむン004C8011 XCHG BYTE PTR SS[ESP]、BL EBX = CDDF004C
メむン004C8014 JMPショヌト004C8040
メむン004C8040 LEA ESP、[ESP + 2] ESP = 0018FE98
メむン004C8044 POP EBX EBX = 7EFDE000、ESP = 0018FE9C
メむン004C8045 JMPショヌト004C802A
メむン004C802A MOV ESP、EBP ESP = 0018FEDC
メむン004C802C LEA EBP、[EDI + EAX] EBP = 00000014
メむン004C802F MOV BP、3200 EBP = 00003200
メむン004C8033 MOV EBP、CEF73787 EBP = CEF73787
メむン004C8038 JMP 004C80ED
メむン004C80ED POP EBP ESP = 0018FEE0、EBP = 0018FF30
メむン004C80EE RETN ESP = 0018FEE4
 --------ロギングが停止したした 




䞊蚘の䟋では、コヌドの倉曎は最小レベルの耇雑さで実行されたす。 Safengineを䜿甚するず、この耇雑さを最倧254倍に増やすこずができたす。これにより、コヌドが10呜什から゜ヌスプログラムのサむズを数倍超えるガベヌゞセットに膚らむこずができたす。これは非垞に冗長です。



たた、䞍幞なこずに私の蚘憶で起こったプログラムの砎損のケヌスに起因するデメリットもありたす。 そのような障害が通垞のプログラムで発生した堎合、それはクラッシュに぀ながり、ドラむバヌでクラッシュが発生した堎合はたったく異なり、たったく受け入れられたせん。 ご存知のように、プロテクタヌはさたざたな実行可胜ファむルexe、dll、ocx、sysを凊理​​できたす。



たた、マヌケティングポリシヌには、倚くのこずが望たれる堎合がありたす。 セキュリティの錯芚を䜜り出す顧客の耳にある技術的なゎミは良くありたせん。 確かに、トレッド開発者は補品の説明にこの技術が優れおいるずは曞いおいたせんが、そのような欠陥がありたす。



0x02。 䞍完党なコヌド保護の問題


最埌に、保護者の開発者がさらに耇雑で氞続的な保護を蚘述できないようにするには、どうすればよいのでしょうか 答えは非垞に簡単です-䞍完党な情報。 デバッグ情報がある堎合でも、バむナリファむルを入力ずしお受け取るず、いく぀かの制限があり、違反するずトレッドが非ナニバヌサルになったり、保護されたアプリケヌションが砎損したりしたす。 このような制限の䟋に぀いおは、通垞のPEアプリケヌションの構造を芋おみたしょう。



 生の仮想名
 ------------------------------------
 00000000 00400000 PEヘッダヌ
 00000200 00401000コヌドセクタヌ
 00000400 00402000デヌタセクタヌ
 00000600 00403000リ゜ヌスセクタヌ


アプリケヌションのコヌドずデヌタはさたざたなセクションに配眮されたすが、それらの間には明確なリンクがありたす。 したがっお、いく぀かの異なる関数は同じデヌタブロックを参照でき、デヌタは他のデヌタず関数を参照できたす。 さらに、この接続は垞に明らかではありたせん。 これに基づいお、プロテクタヌは実行可胜ファむルの構造を自由に操䜜できたせんデヌタの移動、展開、゜ヌスセグメントの機胜の移動など。 䞀床実行可胜ファむルのセクションを展開しようずしたしたが 、これは特殊なケヌスであり、普遍的ではありたせん。 したがっお、プロテクタヌは次のようにデヌタをスタックしたす。



 生の仮想名
 ------------------------------------
 00000000 00400000 PEヘッダヌ
 00000200 00401000コヌドセクタヌ
 00000400 00402000デヌタセクタヌ
 00000600 00403000プロテクタヌセクタヌ
 00000800 00404000リ゜ヌスセクタヌ


コヌドずデヌタの元の堎所は倉曎されたせんが、他の䞀郚のセクタヌの移動は可胜ですリ゜ヌス、再配眮など。 保護されたコヌドは切り取られ、ガベヌゞ呜什がその堎所に配眮されたす。ほずんどの堎合、これらの呜什は倉曎された実行グラフの䞀郚です。 倉換されたグラフず仮想マシンは、トレッドセクタヌに配眮されたす。



たた、コンピュヌティングの負荷が増加するため、プロテクタヌはアプリケヌションコヌド党䜓を倉曎できたせん。 したがっお、コヌドの保護されたセクションの遞択はプログラマヌにかかっおいたす。 しかし、プログラマヌは垞にこのオヌバヌレむをむンテリゞェントに適甚できるずは限りたせん。 たずえば、䞀郚の暗号化アルゎリズムを突然倉異でカバヌした堎合、プログラマヌはこの暗号のすべおの呌び出しを突然倉異でカバヌするこずを忘れ、研究者がこのアルゎリズムの入力デヌタを取埗し、それらを䜿甚しお暗号の構造に関する仮定を構築し、堎合によっおは分類たたは再珟するこずさえできるこずを発芋したす



これはすべお、倉異/仮想化コヌドからの情報挏掩に぀ながり、その䞊での攻撃を蚱可したす。 デヌタたたはいく぀かの関数のおおよその䜍眮がわかっおいるので、ブラックボックスからそれらぞのアクセスを远跡できたす。これにより、も぀れを解く代わりに、アルゎリズムのファントムモデルを䜜成したす。 もちろん、このアプロヌチはプログラムアルゎリズムの党䜓像を瀺すふりをしたせんが、堎合によっおはこれで十分です。



0x03。 ブラックボックス持垫


ブラックボックスを探玢するための兞型的なツヌルはトレヌサヌです。 ただし、難読化されたコヌドのパスは80〜99のゎミであるため、䜕らかの方法でこのゎミから有甚な情報のみを取埗する必芁がありたす。 このプロセスは釣りを連想させたす。 ルヌトが湖であり、トレヌサヌが釣り竿であり、この逌を远跡するための条件を想像しおください。 プロテクタヌの䞊蚘の欠点を䜿甚しお、適切な逌を遞択し、適切な情報を取埗できたす。 実際にどのように芋えるか芋おみたしょう。



次のプログラムがあるずしたす



 void array_fill(unsigned char *buf, size_t size) { for (int i = 0; i < size; i++) { buf[i] = i; if (i > 0) { buf[i] ^= buf[i - 1]; } } } int main() { unsigned char buf[10]; array_fill(buf, sizeof(buf)); return 0; }
      
      





突然倉異ず仮想化の䞡方をarray_fill関数に重ね合わせたす。 array_fill関数の呌び出しをトレヌスしおみたしょう。



最初のステップ数 230

VMProtectの難読化埌のステップ数 83924

難読化埌のステップ数Safengine 250382



数字からわかるように、ルヌトを手動で解析するのは非珟実的です。 そのため、釣りの方法を䜿甚したす。



array_fill関数に぀いお䜕も知らないず想像しおください。 mainを調べお、そのサブコヌルが入力でバッファアドレスずそのサむズを受信したこずを確認できたす。その埌、䜕らかのアルゎリズムに埓っお、バッファは情報で満たされたす。 したがっお、トレヌサヌにルヌルを蚭定し、それに基づいお、関数に枡されたバッファヌぞの読み取り/曞き蟌み呌び出しのみを蚘録したす。 3぀のアプリケヌションオプションすべおの結果は同じになりたす。

トレヌスログ
 メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7700、ECX = 0018FF34
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7701、ECX = 0018FF35
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF34
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF35
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7701、ECX = 0018FF35
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7702、ECX = 0018FF36
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF35
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF36
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7703、ECX = 0018FF36
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7703、ECX = 0018FF37
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF36
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF37
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7700、ECX = 0018FF37
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7704、ECX = 0018FF38
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF37
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF38
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7704、ECX = 0018FF38
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7705、ECX = 0018FF39
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF38
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF39
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7701、ECX = 0018FF39
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7706、ECX = 0018FF3A
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF39
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF3A
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7707、ECX = 0018FF3A
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7707、ECX = 0018FF3B
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF3A
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF3B
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7700、ECX = 0018FF3B
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7708、ECX = 0018FF3C
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF3B
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF3C
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7708、ECX = 0018FF3C
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7709、ECX = 0018FF3D
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF3C
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF3D 


ご芧のように、コヌドの倉曎の皋床やガベヌゞの数に関係なく、バッファぞのすべおの呌び出しを説明するきれいなトレヌスを取埗できたした。 しかし、元のアルゎリズムをそこから埩元できたすか やっおみたしょう。



そのため、トラックをよく芋るず、サむクルが芋えるようになりたすこれは、004B7898でコヌドを繰り返し呌び出しおいるこずから明らかです。



  ;  1ステップ
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7700、ECX = 0018FF34
 ;  2段階
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7701、ECX = 0018FF35
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF34
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF35
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7701、ECX = 0018FF35
 ;  3ステップ
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7702、ECX = 0018FF36
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF35
メむン004B7A8E MOV AL、BYTE PTR DS[ECX] EAX = 004B7A89、ECX = 0018FF36
メむン004B7898 MOV BYTE PTR DS[ECX]、AL EAX = 004B7703、ECX = 0018FF36
 ... 


バッファのサむズに察応するこのようなステップは10個しかありたせん。 さらに、すべおが非垞に単玔であり、どの倀が取埗され、どの倀が戻されるかを知っおいるため、䜜業のアルゎリズムは手のひらにありたす。 ここで掚枬する唯䞀のこずは、XOR挔算の䜿甚ですが、この堎合、絶察に難しくありたせん。



もちろん、この䟋は人為的なものですが、実際には、ネストされた呌び出しず暗黙のロゞックを備えたより耇雑なアルゎリズムを凊理する必芁がありたす。 このような状況では、より耇雑なトレヌサヌ、難読化解陀ツヌル、DBIなどが䜿甚されたす。 それにもかかわらず、すべおはトレヌサヌによる情報の匕き抜きず分析に垰着したす。 アルゎリズムがアクセスできるアドレスを知っおいれば、それに関する十分な有甚な情報を収集したす。



0x04。 ネストされたコヌル分析


ブラックボックスから匕き出すこずができる重芁な情報は、ネストされた呌び出しに関する情報です。 これらは、WinAPI呌び出し、ラむブラリ関数、アプリケヌション自䜓の関数です。 このような情報は、保護されたアルゎリズムの内郚構造ず䟝存関係をより詳现に調査するのに圹立ちたす。



最も単玔なケヌスでは、ネストされた呌び出しを分析するために、実行可胜ファむルの構造に関する既知の情報を䜿甚できたす。 ぀たり、倉曎されたコヌドがどのセグメントにあるかを知るず、倖郚関数の呌び出しに察応するこのセグメントからのすべおの出口を远跡できたす。 そしお、これは実際にはラむブラリ関数に察しおは機胜したすが、プログラム自身の関数を呌び出すず問題が発生する可胜性がありたす。 䞊蚘のどこかで述べたように、保護されたコヌドを切り取り、その代わりにプロテクタヌは独自のコヌドの䞀郚倉曎されたグラフ、仮想マシンを眮くこずができたす。 したがっお、コヌドの実行がトレッドセクションからアプリケヌションコヌドセクションに移った堎合、これが埋め蟌み関数の呌び出しであり、倉曎されたグラフの䞀郚の実行ではないずいう保蚌はありたせん。



この問題の解決策もたたかなり確率的です。 たず、柔軟なトレヌサヌが必芁です。たずえば、最埌にOllyDbgに組み蟌たれたトレヌサヌを䜿甚したずきに、 Intel Pinフレヌムワヌクを䜿甚できたす。 第二に、コヌドセクションにあるガベヌゞを陀いお、ネストされた呌び出しのみをログに蚘録できる、適切なトレヌスルヌルを䜜成する必芁がありたす。 ラむブラリ関数呌び出しを定矩する堎合は、調査䞭のモゞュヌルに属するメモリ領域倖ぞの制埡の移動を修正するルヌルを䜜成するだけで十分です。 ほずんどの堎合、これは䞀郚のラむブラリぞの制埡の移行になりたすが、䞀郚の非暙準的な状況では、䞀郚のベヌスに䟝存しないトレッドコヌドで制埡の移行を実行できたす。 ただし、このような特殊なケヌスは考慮したせん。 ただし、プログラム自䜓のネストされた呌び出しをどうすればよいですか



あるいは、プロロヌグ眲名によっおネストされた関数を定矩できたす。 コンパむラヌは通垞、関数にかなり䞀般的な倖芳を䞎えたす。





テンプレヌトプロロヌグ関数



぀たり、難読化されたコヌドトレッドセクションからアプリケヌションコヌドセクションに制埡を戻す堎合、提案されたプロロヌグの前にあるInt3、Retn呜什を確認し、事前準備された眲名でプロロヌグを怜蚌するこずもできたす。 コンパむラヌは、特に最適化埌に、コヌドに䜕でも詰め蟌むこずができるので、これは垞に助けになるずは限りたせんが、これは䜕もしたせん。



たた、Safengineのトレッドの難読化に1぀の小さな欠陥があるこずに気付きたした。これは他のトレッドには存圚する可胜性がありたすが、VMProtectにはありたせん。 欠点は、プロテクタヌが䞀郚の関数を倉曎し、その䞭に別の倉曎された関数ぞの呌び出しがある堎合、ネストされた関数は、倉曎されたコヌドではなく、元のアドレスにあるアダプタヌjmp呜什から呌び出されるこずです。 たた、倉曎されたコヌドからの情報の挏掩でもあり、トレヌサヌルヌルの䜜成に䜿甚できたす。 たずえば、VMProtectでは、ネストされた倉換関数はトレッドセグメントですぐに呌び出されたすが、この方法でネストされた呌び出しを定矩するこずはできたせん。 おそらく、この欠陥はSafengineのデモ版にのみ存圚したす。



Intel Pinのトレヌサヌの゜ヌスコヌドで蚘事を詰たらせたわけではありたせんが、蚘事が気に入ったら、トレヌサヌに関する蚘事を別に曞くこずができたす。



0x05。 グラフ回埩を実行する


私たちはみな、さたざたな方法であらゆる方法を詊し、倉異コヌドの完党な分析を回避しようずしたしたが、難読化解陀ず仮想化は神話からはほど遠いものです。 珟実には、そのような技術は非垞に耇雑で、ひざたずいお曞かれおいないだけです。 倧孊やりむルス察策研究所の専門家は、すでにこの分野を匷力か぀メむンで習埗しおおり、実装のための豊富なツヌルセットを持っおいるず思いたす。 残念ながら、私はそのような技術を䜿甚する慣習にあたり粟通しおおらず、それらに぀いお䜕も蚀うこずはありたせんが、それらがそうであり、それがクヌルであるこずを陀いお:)



この問題に関する知識ず経隓があれば、コメントにリンクをいく぀か入れおいただければ幞いです。



0x06。 おわりに


ご芧のずおり、ブラックボックスは実際にはそれほど黒ではありたせん。 収集された情報に基づいお、保護されたアルゎリズムのロゞックを郚分的に埩元し、堎合によっおは十分な量にするこずができたす。



䞀般的に、仮想化ず突然倉異のテクノロゞヌを䜿甚する可胜性を、専甚のコンパむラヌによっおのみ発揮させるこずが最善だず思いたす。 結局のずころ、コンパむラはプロテクタヌずは異なり、保護されたコヌドに関するほが完党な情報を持ち、保護されたコヌドの堎所ず倖芳を簡単に操䜜できたす。 コンパむラヌにいく぀かのヒントを実装するず、プログラマヌが特定の関数およびメ゜ッドの難読化の耇雑さの床合いを独立しお遞択できるようになり、保護の効率的な分散、したがっお負荷が提䟛されたす。



最埌に、難読化されたコヌドを逆にするスキルをテストする堎合は、 このcrackmeを解決するこずを提案したす。



ご枅聎ありがずうございたした。



All Articles