En primer lugar, escupemos el campo de entrenamiento de invitados rojos. No hay un pwn para la pregunta. Solo puedo probar Reverse.
CrackMe
- Inspección de rutina, sin shell, programa de 32 bits
- Ejecute el programa para ver la situación general.
- Abra el ida de 32 bits, quiero recuperar la cadena FALSE y encontrar la función clave, pero parece que no puedo encontrarla en la ventana de la cadena. Vaya a la sección rdata (sección de datos de recursos, todos los datos de recursos utilizados por el programa está aquí) y la sección de datos (esta sección Almacene los datos globales del programa, las constantes globales, etc.) Búsquelo y finalmente déjeme encontrar 'FALSE' en la sección rdata
ctrl + x para encontrar la función que hace referencia a él
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);
}
Probablemente inicializamos un dato para nosotros al principio, calculamos i & 1 y descubrimos que está desalineado para realizar operaciones XOR con v13 y v12, por lo que la lógica principal de esta pregunta es realizar operaciones XOR en la desalineación de nuestros datos de entrada con v13 y v12, y finalmente obtenga la matriz inicializada. Siempre que la matriz inicializada tenga XORed con v13 y v12, los valores de entrada correctos
v13 y v12 se pueden obtener desde aquí
v3 = GetModuleHandleW(0);
v4 = *((unsigned __int8 *)v3 + 1);
v12 = *(_BYTE *)v3;
v13 = v4;
La explicación de Baidu Encyclopedia de la función GetModuleHandleW (0) no es muy clara a partir del significado literal. Estaba atrapado aquí en ese momento. Después de depurar con od durante mucho tiempo, no encontré el valor de v13 y v12.
Después del juego , Depuro con ida. De acuerdo con la longitud de la matriz de inicialización Es 8, por lo que la longitud de los datos que ingresamos también es 8. Al cambiar, simplemente ingrese una cadena de longitud 8 para
encontrar su valor. La declaración de asignación se encuentra principalmente aquí . Encontré v12 y v13 en la ventana de locales y
obtuve v12. Y el valor de v13, puede escribir un script para calcular el código de registro correcto
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)
Debería ser porque no estoy familiarizado con el ensamblaje, por lo que lo uso más fácilmente que od, ida.
Antidebug
- Inspección de rutina, programa de 32 bits, sin shell
- Ejecute el programa para ver la situación general.
- Debido a que es la entrada del cuadro de diálogo, primero use Resource Hacker para encontrar la posición del cuadro de entrada y vea que el ID de control de la clave es 1000
en ida alt + i, abra el cuadro de búsqueda inmediata, busque 1000 y haga doble clic para
encontrar el lugar de llamada
En la función clave, se encuentra que jz y jnz saltan a la misma posición. Inicialmente se sospecha que hay una instrucción de flor que afecta el funcionamiento normal de ida. Nop (ruta clave - > Complete range, pathc is nop) elimina
el local_401524 al que saltan, preste atención 00401524 es una instrucción de varios bytes, primero use la tecla de método abreviado d para convertirla en datos, luego apáguela y luego convierta la tecla de método abreviado c en el código.
Después de la modificación,
puede encontrar la posición de inicio de la función push ebp, haga clic con el botón derecho en la función de crear, luego puede ver que la
lógica del pseudocódigo f5 es simple, cuando el valor es igual a la entrada de 2,882,395,322 cuando se le solicite corregir
este problema es investigar una instrucción para gastar