abex"cracme分析#1


その名の通り、crackmeはひび割れの練習のために作成され公開されたプログラムである.

📌 abex' crackme #1



デバッガが起動する前にファイルを実行すると、「Makeme think your HDはCD-ROMです」というメッセージボックスが表示されます.
CD-ROMという言葉からハードディスクはハードディスクを意味すると推測できる.

[OK]をクリックしてエラーメッセージボックスを終了します.コードを分割する方法はまだ理解できません.そのため、コードを表示し、理解する必要があります.

🔹 Start debugging


OLLDbgを使用してファイルを開きます.

以前のHelloWorldファイルとは異なり、abex「crapme」ファイルはコンポーネント言語で作成された実行可能ファイルであるため、EPコードが非常に短いことがわかります.
他の開発ツールを使用すると、コンパイラは他のソースコードを追加するため、dissアセンブリを行う際に複雑になります.
しかし,コンポーネント言語を用いて記述すると,コンポーネントコードはすぐにdisコンポーネントコードとなるため,EPにmain関数を直接表示する直感的なコードがコンポーネント言語で開発されていることが証明される.

🔹 コード解析


主にWin 32 API関数呼び出しについて説明します.

MessageBox("Make me think your HD is a CD-Rom.")
GetDriveType("C:\")
...
MessageBox("Nah... This is not a CD-Rom Drive!")
MessageBox("OK, I really think that your HD is a CD-Rom! :p")
ExitProcess()
Windowsでプログラミングを行ったことがある場合は、これらの関数の意味を理解しているかもしれません.
GetDriveType()APIを使用してCドライブのタイプ(ほとんどのハードディスクタイプはエコー)を取得し、操作によりCD-ROMタイプと認識させ、「OK、I really though you HDはCD-ROM!:p」メッセージボックスを出力します.
明細別詳細分析; MessageBoxA() 호출 ; 함수 내부에서 ESI = FFFFFFFF로 세팅됩니다. ; GetDriveTypeA() 호출 ; 리턴 값(EAX)은 3(DRIVE_FIXED) 입니다.
40101D ; ESI = 040101E ; EAX = 240101F ; 의미 없는 JMP 명령(garbage code)401021 ; ESI = 1401022 ; ESI = 2401023 ; EAX = 1 ; 조건 분기(401028 또는 40103D)
401024 ; EAX(1)과 ESI(2) 비교401026 ; JE(Jump if Equal) 조건 분기 명령, 두 값이 같으면 40103D로 점프하고, 다르면 밑(401028)으로 진행. 40103D 주소는 제작자가 원하는 메시지 박스 출력 코드 ; 실패 MessageBoxA() 호출 ; 성공 MessageBoxA() 호출 ; 프로세스 종료

🔹 上のコードで使用するコンポーネントコマンドの説明


命令の説明
PUSHスタックに値を入力
CALL指定アドレスの関数を呼び出す
INC値を1増加
DEC値減少1
JMP指定アドレスへジャンプ
CMPで与えられた2つのオペランドの比較
*SUBコマンドと同じですが、オペランド値は変更されず、EmFLAGSレジスタのみ変更されます
(両方のオペランドの値が同じ場合、SUB結果は0、ZF=1に設定)
JE条件分岐(Jump if Equal)
*ZF=1はジャンプ

📌 ひび割れ


プログラムをクラッシュさせるためにコードをパッチします.
リダイレクトでは、既存のコード(またはデータ)を意図的に他のコードで上書きする動作を「パッチ」と呼ぶ.
簡単なパッチを使用する場合は、[Assemble]機能[Space]を使用して、401026アドレスコマンド(JE SHOUT 0040103 D)をJP 0040103 Dコマンドに変更します.

「条件分岐」(JE)コマンドを「ジャンプ」(JMP)コマンドに変換します.△CMPコマンドの結果にかかわらず、無条件にジャンプします.

📌 スタックにパラメータを渡す方法


上記のコードでは、関数を呼び出すときにパラメータをスタックに渡す方法に注意してください.
401000-40100 Eアドレス間のコマンドでは、MessageBoxA()関数を呼び出す前に、4つのPUSHコマンドを使用して必要なパラメータを逆順に入力します.

上記のコンポーネントコードをC言語に翻訳すると、
MessageBox(NULL, "Make me think your HD is a CD-Rom.", "abex' 1st crackme", MB_OK|MB_APPLMODAL);
パラメータを実際のC言語ソースコードから関数に渡す順序は、コンポーネント言語から역순に移行する.
スタックは「最初の入力」(FILO)構造であるため、逆順序で入力される.
FILO構造であるため、パラメータを逆順に配置すると、受信者(MessageBox関数)から正しい順序で取り出すことができます.

デバッガを使用してEIP=00400100 Eポイントに進み、スタックを表示すると、x 86環境ではスタックが下に広がり(アドレスが小さくなる方向に進む-スタックに値を入力するとESP値が小さくなる)、MessageBoxA()関数の最初のパラメータがスタックの上部に表示され、最後のパラメータがスタックの下部にスタックされます.
したがって、MessageBoxA()関数では、スタックのFILO構造に応じて、パラメータがスタックから1つずつ取り出される.(C言語のソースコードに作成された順序で)
パラメータを抽出するために使用されるMessageBoxA()関数は、スタックにパラメータの順序でパラメータを配置することに相当します.
Garbage Codeは、デバッグを妨げ、リサイクルプログラムを混乱させるために故意に追加されています.ⓒ 리버싱 핵심 원리