まず、赤いゲストトレーニングキャンプを吐き出しましょう。質問のpwnはありません。私はReverseしか試すことができません。
CrackMe
- 定期検査、シェルなし、32ビットプログラム
- プログラムを実行して、一般的な状況を確認します
- 32ビットidaを開き、文字列FALSEを取得してキー関数を見つけたいのですが、文字列ウィンドウで見つからないようです。rdataセクション(リソースデータセクション、によって使用されるすべてのリソースデータ)に移動します。プログラムはここにあります)およびデータセクション(このセクションはプログラムのグローバルデータ、グローバル定数などを格納します)それを探し、最後にrdataセクション
ctrl + xで「FALSE」を見つけて、それを参照する関数を見つけます
int __thiscall sub_401730(CWnd *this)
{
int v2; // edi
HMODULE v3; // eax
int v4; // edx
struct CWnd *v5; // eax
int v6; // esi
int i; // eax
int v8; // eax
CWnd *v9; // eax
char v11[4]; // [esp+10h] [ebp-1D0h] BYREF
int v12; // [esp+14h] [ebp-1CCh]
int v13; // [esp+18h] [ebp-1C8h]
int v14; // [esp+1Ch] [ebp-1C4h] BYREF
int v15; // [esp+20h] [ebp-1C0h]
char v16[396]; // [esp+24h] [ebp-1BCh] BYREF
int v17[8]; // [esp+1B0h] [ebp-30h]
int v18; // [esp+1DCh] [ebp-4h]
v17[0] = 0xE; #初始化的数据
v17[1] = 0x28;
v17[2] = 0xC;
v17[3] = 0x39;
v17[4] = 6;
v17[5] = 5;
v17[6] = 0x20;
v17[7] = 0x1F;
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v14);
v2 = 0;
v18 = 0;
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(v11);
LOBYTE(v18) = 1;
v3 = GetModuleHandleW(0);
v4 = *((unsigned __int8 *)v3 + 1);
v12 = *(_BYTE *)v3;
v13 = v4;
CWnd::UpdateData(this, 1);
v5 = CWnd::GetDlgItem(this, 1000);
CWnd::GetWindowTextW(v5);
v6 = *(_DWORD *)(v14 - 12);
v15 = 0;
memset(v16, 0, sizeof(v16));
if ( v6 > 0 )
{
do
{
*(&v15 + v2) = (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v14, v2);
++v2;
}
while ( v2 < v6 );
}
for ( i = 0; i < v6; ++i )
{
if ( (i & 1) != 0 )
*(&v15 + i) ^= v13;
else
*(&v15 + i) ^= v12;
}
v8 = 0;
if ( v6 <= 0 )
goto LABEL_14;
do
{
if ( *(&v15 + v8) != v17[v8] )
break;
++v8;
}
while ( v8 < v6 );
if ( v8 == 8 && v6 == 8 )
{
MessageBoxW(0, L"TRUE", &Caption, 0);
}
else
{
LABEL_14:
MessageBoxW(0, L"FALSE", &word_4037A8, 0);
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::operator=(&v14, &unk_4037C0);
v9 = CWnd::GetDlgItem(this, 1000);
CWnd::SetWindowTextW(v9);
}
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(v11);
return ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v14);
}
おそらく、最初にデータの一部を初期化し、i&1を計算し、v13およびv12でXOR演算を実行するのがずれていることがわかったため、この質問の主なロジックは、入力データのずれに対してXOR演算を実行することですv13とv12を使用して、最後に初期化された配列を取得します。初期化された配列がv13およびv12とXORされている限り、正しい入力値
v13およびv12はここから取得できます。
v3 = GetModuleHandleW(0);
v4 = *((unsigned __int8 *)v3 + 1);
v12 = *(_BYTE *)v3;
v13 = v4;
Baidu百科事典によるGetModuleHandleW(0)関数の説明は、文字通りの意味からはあまり明確ではありません。そのときはここで立ち往生していました。odで長時間デバッグした
後、v13とv12の値が見つかりませんでした。ゲーム後、idaでデバッグします。初期化配列の長さによると8なので、入力したデータの長さも8です。変更するときは、長さ8の文字列を入力するだけで
、値を見つけることができます。割り当てステートメントは主にここにあります。 。ローカルウィンドウでv12とv13を見つけ、v12を
取得しました。v13の値を指定すると、正しい登録コードを計算するスクリプトを記述できます。
a=[0x0e,0x28,0x0c,0x39,6,5,0x20,0x1f]
v12=0x4d
v13=0x5a
string=""
for i in range(8):
if (i&1)!=0:
string+=chr(a[i]^v13)
else:
string+=chr(a[i]^v12)
print(string)
組み立てに慣れていないので、od、idaよりも使いやすいからです。
アンチデバッグ
- 定期検査、32ビットプログラム、シェルなし
- プログラムを実行して、一般的な状況を確認します
- これはダイアログボックスの入力であるため、最初にResource Hackerを使用して入力ボックスの位置を見つけ、キーのコントロールIDが
ida alt + iで1000であることを確認し、検索即時ボックスを表示して、1000を検索します。そして、するためにダブルクリックして
呼び出し場所を見つける
。キー機能で、同じ位置にJZとJNZジャンプは最初のIDAの正常な動作に影響を与える花の指示があることが疑われていることが判明したNOP(キーパス。 - >範囲を埋める、pathcはnop)
ジャンプ先のlocal_401524をドロップし、注意を払う00401524はマルチバイト命令です。最初にショートカットキーdを使用してデータに変換し、次にオフにしてから、ショートカットキーcをに変換します。コード
変更後
、関数の開始位置push ebpを見つけ、関数の作成を右クリックすると、f5疑似コード
ロジックが単純であることがわかります。
この問題を修正するように求められたときに値が2,882,395,322入力に等しい場合、調査する必要があります使うための指示