この記事は、リバースエンジニアリングに興味があり、CPU、アセンブリ言語の動作を基本的に理解している初心者を対象としています。 このクラックメは比較的古く単純ですが、それを解決するとき、基本的にはより複雑なものを解決するときと同じ方法が使用されます。 Webで、彼の分析を含む
この記事のようないくつかの記事を見つけることができます。
また 、
ここでも言及してい
ます (歴史のあるクラック)。しかし、それらの決定はこれほど詳細ではありません。 かつては、このような行ごとの解析が本当に不足していたので、混乱したり、コードのこの部分が何をするのか理解できなかったときに調べることができました。 この投稿が少なくとも1人に役立つと判明した場合、私が試したのは無駄ではありませんでした。 すべてのスクリーンショット(最初のスクリーンショットを除く)はクリック可能です。 読書をお楽しみください。
したがって、単純なクラックメットになる前に、それを実行して、それがどのように機能するかを確認してください。
ええ、それはかなり簡単です。正しいシリアルを入力する必要があります。 次に、逆アセンブラでプログラムを開きます。 原則として、逆アセンブルされたリストは、比較的単純なプログラムでさえ、非常に膨大です。 シリアルの入力をチェックするコードの部分を決定するために、「Fail、Serial is invalid !!!」というエラーメッセージのある行がプログラムメモリのどこに格納されているか、どのコードがこの行を参照しているかを見つけます。
データセクションに目的の行が表示され、その下に逆アセンブラーがその行を参照するコードセクションへのリンクを形成し、リンクをクリックします。
Loc_140001191はトランジションのラベルです。下に「
call cs:MessageBoxA 」という行があります。 これが、「Fail、Serial is invalid !!!」というテキストを含むウィンドウを描画する関数の呼び出し方法であるとします。 間違ったシリアルを入力すると、ラベル
Loc_140001191によって制御が正確に転送されることが
わかります。 さて、掘り続けて、同じラベルにまだアクセスできる場所を見つけましょう。そのラベルの右のリンクをたどります。逆アセンブラーはそこに注意深く配置しました。
これは非常に重要なコードです。詳しく見てください。
GetDlgItemTextA関数の呼び出しがあります。名前には
getと
textという単語
が含まれており、明らかにこの関数は入力されたシリアルを読み取ります。 関数が機能した後、コマンド「
lea rcx、[rsp + 78h + String] 」がスタックから何か
のアドレスを
rcxレジスタにロードします。 次に、
eaxから
edxに値を書き込み、
sub_140001000関数を呼び出します。 呼び出し前のレジスタの操作はランダムではないため、関数に引数を渡します。関数が完了した後、コマンド「
test eax、eax 」は
eaxの内容をチェックし、
0でない場合、すべてを報告する行のアドレスが読み込まれます約 その後、ウィンドウは対応する通知で描画を開始します。
eaxの操作
sub_140001000が
0の場合、制御は以前に考慮されたラベルに転送され、エラーメッセージが表示されます。 結論:
sub_140001000は
eaxレジスタの値を返します。 これで、このcrackmeのロジックを復元できます
。GetDlgItemTextA関数が
呼び出されます。おそらく、シリアルを読み取り、その後、
sub_140001000関数が
呼び出されます
。sub_140001000関数が
呼び出されます。 「ゼロ」の場合、正しいシリアル番号が入力され、「ゼロ」の場合は正しくありません。 入力
を確認するのが
sub_140001000であると仮定し、
便利でわかりやすいようにリストのラベルと機能の名前を変更します。 これで、リストは次のようになります。
これでフロアが完成しました。
check_func関数が引数として
受け取るものを把握しましょう。これを行うには、関数を呼び出す前にデバッガーでプログラムを実行し、
rcxと
edxに格納されているものを確認します。
12345と入力しました。 チェック機能の呼び出しで実行が停止しました。 レジスタを調べます
。rcxには
12F660という数字があります。このアドレスを知っているので、下のウィンドウでメモリダンプを調べます。そうです、入力があります
。edx(rdxの若い部分)に
5があり、これがシリアル番号。 そこで、どの引数と検証関数が返すかを見つけました。今では、そのプロトタイプが
int check_func(* char、int)のように見えると仮定できます。 それを勉強する時間です。 逆アセンブラでチェック機能を開きます。 非常に大きいので、部分的に分析します。
ここではすべてが比較的簡単です。
edxレジスタは入力されたシリアル番号のサイズを保存し、そのアドレスをメモリに
rcxします。 まず、
check_func関数が入力された数値の長さをチェックしていることが
わかります。 それは
19 (16進法では
13 )である必要があり、そうであれば、検証は続行(
good_sizeラベルに切り替え)、そうでなければ制御は
bad_serialラベルに渡されます。終了機能。 結論:
19文字の有効なシリアル番号と、それがさらに理解されます。 入力された番号のアドレスは、すぐにレジスタ
R8に配置されることに注意してください。
検証メカニズムの調査を続けています。
R8はシリアルの最初の要素を指していることを覚えています。つまり、5番目の要素のアドレスは
R8 + 4に格納され、
RAXに記録されます。 さらに、非常に奇妙な一連のコマンドがあり、それらは2回以上会います。
xchg ax, ax db 66h, 66h xchg ax, ax
より詳細に:
「
Xchg ax、ax」は、
x86プラットフォームの「
nop 」コマンドに相当します。
次の行はいわゆるプレフィックスであり、次の命令の長さを示すために使用されます。 このコードは無視できます。 これらの指示の後、次の種類のチェックが行われます
。RAXアドレス(およびシリアルの
5番目の要素のアドレス)にあるものは、2D(16進法で)の数と等しくなければなりません。 2DはASCIIコード記号「-」です。
1.入力を読み取る関数は、数値ではなく文字列を読み取ります。
2.シリアルには、ハイフンで区切られた4つの数字のグループがいくつかあります。
5番目の文字が「-」ではない場合、シリアル番号が正しくなく、bad_serialラベルは0の値で終了しますが、ハイフンで5番目の位置にある場合、
RAXは10を指すときに5増加しますこの文字はこの位置にある要素がチェックされます。 合計で、このようなチェックは3回実行され、シリアルの各5番目の文字は「-」であり、19文字しかありません。つまり、XXXX-XXXX-XXXX-XXXXという形式になります。 入力形式が適切な場合、検証は続行されます。
関数の次のセクションは、特に関心を引くものではありません。
どうぞ
次のことに注意してください:
R9は常にブロックの最初の要素を示し、
RCXはブロック内にオフセットを保存します。したがって、チェック後、
R9は次のブロックに到達するために5増加し、ブロックをチェックした後
RCXはゼロになります
。RDXにはゼロがあることに注意してください。したがって、
zero_to_rcxへのゼロ化が発生します。 「
add eax、0FFFFFFD0h 」という行は
、見た目ほど単純ではありません。 実際、これは加算ではなく減算です。 はい、あなたの目を信じないでください、コンピューターの0FFFFFFD0hは-30hの数字です。明らかに、コマンド「
add eax、0FFFFFFD0h 」は、コンパイラーの観点から「
sub eax、30h 」よりも最適です。 エレメントのASCIIコードは
eaxに格納され、30hから減算され、9と比較されます。意味は次のとおりです。0〜9の数字のASCIIコードはそれぞれ30h〜39hです。したがって、数字コードから30hを減算しても、結果が9を超えても9を超えることはありません、したがって、eaxではコードは数字ではなく、他の記号であり、それから
wrong_serialラベルを
調べます。 シリアルは数字とハイフンで構成する必要があります。 次に、ブロックの4つの要素すべてのコードが要約され、4番目の要素のコードが3回加算され、150hが減算されます。 結果はスタックにプッシュされ、R10で合計したすべてのブロックの合計が4で除算されます。
これで、4つのブロックすべての金額がチェックされます。 各ブロックの値は、合計を4で割った値に等しくなければなりません。つまり、最初の文字のASCIIコードと2番目、3番目のコード、4番目のコードの3倍、マイナス150hの合計は、すべてのブロックで同じである必要があります。
検証の最終段階は残ります。
ここではすべてが明確であり、シリアルは同じブロックを持つべきではありません。
R8は入力のアドレスを格納し、
RAXはブロック内の文字を選択するために使用され、
R8はシリアル番号内のブロックを選択するために
使用されることを忘れないでください。
これで検証の実行方法がわかり、keygenを作成できます。 ソリューションをできるだけ詳細に説明しようとしましたが、コメントで質問することができます。読んでくれてありがとう。