File Monitor - Sysinternals: www.sysinternals.com
Registry Monitor - Sysinternals: www.sysinternals.com
csrss.exe
services.exe
cmd.exe
explorer.exe
windbg.exe
w32dsm89.exe
importrec.exe
lordpe.exe
softice.exe
peid.exe
检测了一堆进程,以这个作为已知条件,很容易找到代码(起始直接看winmain就好)
int __stdcall sub_434EF0(HWND hDlg, int a2, int a3, int a4)
{
size_t v4; // ST0C_4
CHAR *v5; // esi
size_t v6; // eax
int v8; // [esp+Ch] [ebp-1A40h]
int i; // [esp+1C4h] [ebp-1888h]
char v10[1032]; // [esp+1D0h] [ebp-187Ch]
unsigned __int8 v11[40]; // [esp+5D8h] [ebp-1474h]
size_t v12; // [esp+600h] [ebp-144Ch]
_BYTE v13[1032]; // [esp+60Ch] [ebp-1440h]
char v14; // [esp+A14h] [ebp-1038h]
char v15; // [esp+A15h] [ebp-1037h]
char v16; // [esp+E1Ch] [ebp-C30h]
char v17; // [esp+E1Dh] [ebp-C2Fh]
CHAR String; // [esp+1224h] [ebp-828h]
char v19; // [esp+1225h] [ebp-827h]
UINT v20; // [esp+162Ch] [ebp-420h]
char v21; // [esp+1638h] [ebp-414h]
char v22; // [esp+1639h] [ebp-413h]
int v23; // [esp+1A40h] [ebp-Ch]
v23 = 0;
v21 = 0;
j__memset(&v22, 0, 0x3FFu);
v8 = a2;
if ( a2 == 16 )
ExitProcess(0);
if ( v8 == WM_INITDIALOG )
{
v23 = sub_42D4F1();
if ( v23 == 1 )
ExitProcess(0);
v23 = 0;
v23 = sub_42E428();
if ( v23 == 1 )
ExitProcess(0);
v23 = 0;
v23 = sub_42D825();
if ( v23 == 1 )
ExitProcess(0);
sub_42D14F(hDlg, 1);
return 0;
}
if ( v8 != WM_COMMAND )
return 0;
v8 = (unsigned __int16)a3;
if ( (unsigned __int16)a3 == 1002 )
{
String = 0;
j__memset(&v19, 0, 0x3FFu);
v16 = 0;
j__memset(&v17, 0, 0x3FFu);
v20 = GetDlgItemTextA(hDlg, 1001, &String, 1025);
v14 = 0;
j__memset(&v15, 0, 0x3FFu);
base64_decode_42D267((int)&String, 1024, (int)&v16);
v13[0] = 0;
j__memset(&v13[1], 0, 0x3FFu);
base64_decode_42D267((int)&v16, 1024, (int)&v14);
trans_42D96A(&v14, (int)v13, 1024);
v12 = 3;
sm3_42DA78(&v14, 3u, (int)v11);
for ( i = 0; i < 32; ++i )
j__sprintf(&v10[2 * i], "%02x", v11[i]);
v4 = j__strlen(v10);
v5 = &String + j__strlen(&String);
v6 = j__strlen(v10);
// 输入的base64串的后64位与 原始字符串的sm3值相等
if ( !j__memcmp(v10, &v5[-v6], v4) )
{
sub_42D0B4();
if ( sub_42D9AB((int)byte_49B000, (int)v13) == 1 )
MessageBoxA(0, "ok", "CrackMe", 0);
}
}
return 1;
}
对话框的窗口回调函数。IDA7.0 还是比较给力,memset这些都失败出来了,6.8的就不行。
//这个流程也不复杂
假设输入的字符串为 string_base64_encode
经过两次解码 string=base64_decode(base64_decode(string_base64_encode))
然后在
trans_42D96A(&v14, (int)v13, 1024);
中做类似摩斯电码解码的操作
int __cdecl sub_435DE0(char *a1, int a2, int a3)
{
int result; // eax
char v4; // [esp+D3h] [ebp-4Dh]
int v5; // [esp+DCh] [ebp-44h]
int v6; // [esp+E8h] [ebp-38h]
int v7; // [esp+F4h] [ebp-2Ch]
int v8_i; // [esp+100h] [ebp-20h]
void *v9_buf_9; // [esp+10Ch] [ebp-14h]
int v10; // [esp+118h] [ebp-8h]
v10 = 0;
v9_buf_9 = sub_42DE38();
v8_i = 0;
v7 = 0;
v6 = 0;
v4 = 42;
j__memset(v9_buf_9, '*', 8u);
v5 = j__strlen(a1);
while ( 1 )
{
result = v8_i;
if ( v8_i >= v5 )
break;
if ( v6 > a3 )
return j__printf("the string buffer is too little\n");
v10 = 0; // 一堆反调试
// // 一堆反调试
v10 = sub_42D23F();
if ( v10 == 1 )
sub_42E086();
v10 = sub_42D334();
if ( v10 == 1 )
sub_42E086();
v10 = 0;
v10 = sub_42DD66();
if ( v10 == 1 )
sub_42E086();
v10 = 0;
v10 = sub_42D92E();
if ( v10 == 1 )
sub_42E086();
v10 = 0;
v10 = sub_42DF7D();
if ( v10 == 1 )
sub_42E086();
v10 = 0;
v10 = sub_42E31F();
if ( v10 == 1 )
sub_42E086();
if ( a1[v8_i] == ' ' || a1[v8_i] == '/' )
{
if ( a1[v8_i] != ' ' || a1[v8_i - 1] == '/' )
{
if ( a1[v8_i] == '/' )
*(_BYTE *)(v6++ + a2) = ' ';
}
else
{
if ( j_trans_char_435D00((int)v9_buf_9, (int)&v4) != 1 || v7 >= 5 )
{
if ( j_trans_num_435AA0((int)v9_buf_9, (int)&v4) == 1 )
{
*(_BYTE *)(v6++ + a2) = v4;
}
else if ( sub_42E414((int)v9_buf_9, (int)&v4) == 1 )// 转换特殊符号
{
*(_BYTE *)(v6++ + a2) = v4;
}
else
{
j__printf("error !\n");
}
}
else
{
*(_BYTE *)(v6++ + a2) = v4;
}
v7 = 0;
j__memset(v9_buf_9, 42, 8u);
}
}
else
{
*((_BYTE *)v9_buf_9 + v7++) = a1[v8_i];
}
++v8_i;
}
return result;
}
三个函数分别转换数字 字母 特殊符号 两个 电码之间以 空格字符或者/分割。
sm3_42DA78(&v14, 3u, (int)v11);
这个函数根据下边函数里的初始值很容易搜到是国密算法sm3
int __cdecl sub_436700(_DWORD *a1)
{
int result; // eax
*a1 = 0;
a1[1] = 0;
a1[2] = 0x7380166F;
a1[3] = 0x4914B2B9;
a1[4] = 0x172442D7;
a1[5] = 0xDA8A0600;
a1[6] = 0xA96F30BC;
a1[7] = 0x163138AA;
a1[8] = 0xE38DEE4D;
a1[9] = 0xB0FB0E4E;
if ( sub_42DA7D() == 1 )
sub_42E086();
sub_42D389();
if ( sub_42D807() == 1 )
sub_42E086();
result = sub_42D39D();
if ( result == 1 )
sub_42E086();
return result;
}
主要是计算解码后的字符串的sm3 值。
string_sm3 =sm3(string);
for ( i = 0; i < 32; ++i )
j__sprintf(&v10[2 * i], "%02x", v11[i]);
v4 = j__strlen(v10);
v5 = &String + j__strlen(&String);
v6 = j__strlen(v10);
// 输入的base64串的后64位与 原始字符串的sm3值相等
if ( !j__memcmp(v10, &v5[-v6], v4) )
接着是比较string_sm3 是否等于输入的
string_base64_encode的后64位时候相等。