単純なクラックメの研究

こんにちは、Habralyudi。 このトピックでは、単純なクラックミーをどのように探ったかを説明します。 このkryakmisは、まず、逆転を練習したい初心者向けです。 このテーマに関する一連の記事を、単純なものから複雑なものへと徐々に進めていきます。



開始する



それでは始めましょう。

必要なツール:



開始するには、クラックを実行します。 名前と登録コードを入力するための2つのフィールドがある単純なフォームが表示されます。 偽のデータを入力すると、シリアルが間違っているという不正なメッセージが表示されます。

MessageBoxA関数によって呼び出されたメッセージが表示され、フィールドのテキストがGetDlgItemTextA関数によってバッファに入力されると、状況はより明確になります。



アクションプラン



したがって、アクションのさらなるアルゴリズム:

1.クラックをデバッガーにロードします。

2. MessageBoxAおよびGetDlgItemTextA関数のすべての呼び出しにブレークを設定します(Ollyでは、Alt + F1キーの組み合わせを押して、表示されるフォームにbpx%function_name%コマンドを入力します)。

3.ブレークポイントまでプログラムを実行し、以下を実行します。a)虐待メッセージでブランチへの遷移の場所を探し、条件付き遷移を変更して、「正しい」メッセージでブランチに移動します。

b)シリアルの名前を変更する場所を探し、暗号化アルゴリズムを見つけて、keygenを記述します。

私の主な目標は調査することなので、計画bに従います。



デバッグ防止コード



ブレークを配置してプログラムを実行すると、MessageBoxAのブレークが機能したことがわかります。 しかし、デバッガなしで初めてプログラムを実行した後、メッセージが表示されなかった他のMessagBoxは何ですか? プログラムを一歩進めて(OlliでF8キーを押す)、次のように表示されます。

画像

私たちのクラックには、デバッグ防止コードがあります。 それを回避する必要があります。 コードを少し上にスクロールし、「デバッグ対策メッセージボックス」へのジャンプ元を見つけます。 この場所からのコードは次のとおりです。



004027DA . 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]

004027E0 . 8B40 30 MOV EAX,DWORD PTR DS:[EAX+30]

004027E3 . 8B40 18 MOV EAX,DWORD PTR DS:[EAX+18]

004027E6 . 8378 10 00 CMP DWORD PTR DS:[EAX+10],0

004027EA 75 01 JNZ SHORT crackme_.004027ED //








パッチを適用する必要があります。 JNZコマンド(opcode 75)をJE(opcode 74)に変更します。 パッチを適用し、デバッガーでプログラムを再起動しますが、不正なメッセージボックスは表示されません。



アルゴリズム



フィールドに偽のデータを入力し(someuser:somepasswordと入力)、[確認]をクリックします。 そして、GetDlgItemTextA関数の呼び出しでブレークダウンがトリガーされます。 このコードは次のとおりです。



00401D3E . E8 CD0D0000 CALL <JMP.&user32.GetDlgItemTextA> // GetDlgItemTextA

00401D43 . BE 64404000 MOV ESI,crackme_.00404064 // ESI

00401D48 > 8006 01 ADD BYTE PTR DS:[ESI],1 // 1 ESI

00401D4B . 83C6 02 ADD ESI,2 // ESI 2, ESI ,

00401D4E . 803E 00 CMP BYTE PTR DS:[ESI],0 // ESI

00401D51 .^75 F5 JNZ SHORT crackme_.00401D48 // "" 00401D48

00401D53 . E9 BB010000 JMP crackme_.00401F13 // "" 00401F13






したがって、ユーザー名暗号化アルゴリズムが表示されます。

さらにトレースすると、次のセクションに進みます。



00401F1D . 81F9 00500000 CMP ECX,5000

00401F23 -7F FE JG SHORT crackme_.00401F23








私の意見では、これはもう1つのデバッグ対策手法であるため、JGをJEに置き換え、静かにトレースします。 また、GetDlgItemTextA関数の内訳に出会います。 今回、彼女はregを読みます。 コード:



00401FE6 > E8 250B0000 CALL <JMP.&user32.GetDlgItemTextA> // GetDlgItemTextA

00401FEB . BE 64404000 MOV ESI,crackme_.00404064 // ESI ( . )

00401FF0 . BF 64484000 MOV EDI,crackme_.00404864 // EDI . ,

00401FF5 . 8B07 MOV EAX,DWORD PTR DS:[EDI] // EAX . ,

00401FF7 . 8B1E MOV EBX,DWORD PTR DS:[ESI] // EBX .

00401FF9 . 3BC3 CMP EAX,EBX //

00401FFB 0F85 C4020000 JNZ crackme_.004022C5 // , 004022C5

00402001 . 83C6 04 ADD ESI,4

00402004 . 83C7 04 ADD EDI,4

00402007 . 8B1E MOV EBX,DWORD PTR DS:[ESI] // EBX .

00402009 . 8B07 MOV EAX,DWORD PTR DS:[EDI] // EAX . ,

0040200B . 3BC3 CMP EAX,EBX //

0040200D 0F85 B2020000 JNZ crackme_.004022C5 // 004022C5

00402013 . E9 5C000000 JMP crackme_.00402074 // ""








おわりに


したがって、暗号化アルゴリズム全体は、名前の2文字ごとの文字をASCIIテーブル内の後続の文字に置き換えたものであることがわかります。

さらに、プログラムはシリアルの最初の8文字のみをチェックするため、欠点です。



Keygen



そして、keygenは次のとおりです。

var

s:string;

i:integer;

c:char;

begin

readln(s);

while i<= length(s) do begin

Inc(s[i]);

i:=i+2;

end;

writeln(s);

end.






ご清聴ありがとうございました。

PSパスカル、すみません、別のコンパイラが見つかりませんでした。

PPSそして、シンプルで申し訳ありません。



All Articles