本帖最后由 solly 于 2023-6-10 23:25 编辑
整理了一下代码,IDA中F5如下:
[C] 纯文本查看 复制代码 int sub_401057()
{
SIZE_T v0; // ecx
int *virtual_machine_buffer_v1; // eax
int v2; // eax
int v3; // eax
int v4; // eax
int v5; // eax
void *v6; // eax
unsigned int v8; // [esp-8h] [ebp-5Ch]
char *virtual_machine_buffer_v9; // [esp-4h] [ebp-58h]
char v10; // [esp+1Ch] [ebp-38h]
char *v11; // [esp+20h] [ebp-34h]
int v12; // [esp+20h] [ebp-34h]
int v13; // [esp+20h] [ebp-34h]
int v14; // [esp+20h] [ebp-34h]
int v15; // [esp+24h] [ebp-30h]
int code_index_sub_40187F; // [esp+28h] [ebp-2Ch]
int index_sub_40187F; // [esp+28h] [ebp-2Ch]
int index_sub_40187Fa; // [esp+28h] [ebp-2Ch]
int ValueByAddress_sub_40187F; // [esp+38h] [ebp-1Ch]
int result_v20; // [esp+3Ch] [ebp-18h]
void *inputString_v21; // [esp+40h] [ebp-14h]
int next_ip_v22; // [esp+44h] [ebp-10h]
int current_ip_v23; // [esp+48h] [ebp-Ch]
char *data_base_v24; // [esp+4Ch] [ebp-8h]
_DWORD *lpa; // [esp+50h] [ebp-4h]
char *lpBuffer; // [esp+50h] [ebp-4h]
// 初始化
lpa = (_DWORD *)alloc_sub_402588(8u);
*lpa = dword_405530[0];
lpa[1] = dword_405530[1];
next_ip_v22 = 0;
inputString_v21 = 0;
get_length_sub_401010(&src_dword_405200); // get size
virtual_machine_buffer_v1 = (int *)alloc_sub_402588(v0);// v0 = size
qmemcpy(virtual_machine_buffer_v1, &src_dword_405200, v8);// 将虚拟机数据和代码拷贝到缓冲区
virtual_machine_buffer_v9 = (char *)virtual_machine_buffer_v1;
free_sub_402576(lpa);
lpBuffer = virtual_machine_buffer_v9;
data_base_v24 = virtual_machine_buffer_v9 + 8;
current_ip_v23 = (int)(virtual_machine_buffer_v9 + 96);
//执行虚拟机
while ( 1 )
{
code_index_sub_40187F = getValueByAddress_sub_40187F(current_ip_v23 + 4);
if ( getValueByAddress_sub_40187F((int)&data_base_v24[code_index_sub_40187F]) == 0x114514 )// 输出信息
{
ValueByAddress_sub_40187F = getValueByAddress_sub_40187F(current_ip_v23);
v10 = int2pointer_sub_4019A3((int)&data_base_v24[ValueByAddress_sub_40187F]);// v10 = (char *)data_base_v24[v19]
//显示字符串
WriteConsole_sub_402950(2u, 0, 0, 0, v10);// 第1次显示 'WELCOME TO THIS CRACKME',第2次显示 'you xim.'
WriteConsole_sub_402950(2u, 0, 0, 0, (char)CrLf_asc_4054E9);
////
if ( getValueByAddress_sub_40187F(current_ip_v23 + 8) )// // code = 0-jmp, other-next_code
current_ip_v23 = (int)&data_base_v24[getValueByAddress_sub_40187F(current_ip_v23 + 8)];
else
current_ip_v23 += 12;
//
next_ip_v22 = current_ip_v23 + 8;
}
index_sub_40187F = getValueByAddress_sub_40187F(current_ip_v23 + 4);
if ( getValueByAddress_sub_40187F((int)&data_base_v24[index_sub_40187F]) == 0x1919810 ) // 输入数据
{
inputString_v21 = (void *)getch_sub_402A40(1, 0, 0, 0);// 输入字符串
if ( (int)strlen_sub_402B20(1, inputString_v21) < 16 )// 检查输入的长度
{
break; // 长度不够,退出程序
}
WriteConsole_sub_402950(2u, 0, 0, 0, (char)CrLf_asc_4054E9);
// 将输入的pwd拷贝到虚拟机数据空间,每次4字节,拷贝4次,共16字节
v11 = &data_base_v24[getValueByAddress_sub_40187F(current_ip_v23)];// copy pwd[0]
v2 = getValueByAddress_sub_40187F((int)inputString_v21);
Save_Integer_sub_401A1A(v11, v2);
v12 = (int)&data_base_v24[getValueByAddress_sub_40187F(current_ip_v23) + 4];// copy pwd[1]
v3 = getValueByAddress_sub_40187F((int)inputString_v21 + 4);
Save_Integer_sub_401A1A(v12, v3);
v13 = (int)&data_base_v24[getValueByAddress_sub_40187F(current_ip_v23) + 8];// copy pwd[2]
v4 = getValueByAddress_sub_40187F((int)inputString_v21 + 8);
Save_Integer_sub_401A1A(v13, v4);
v14 = (int)&data_base_v24[getValueByAddress_sub_40187F(current_ip_v23) + 12];// copy pwd[3]
v5 = getValueByAddress_sub_40187F((int)inputString_v21 + 12);
Save_Integer_sub_401A1A(v14, v5);
////
current_ip_v23 = (int)(data_base_v24 + 160);
next_ip_v22 = (int)(data_base_v24 + 168);
}
index_sub_40187Fa = getValueByAddress_sub_40187F(current_ip_v23 + 4);
v15 = getValueByAddress_sub_40187F(current_ip_v23);
//执行减法
result_v20 = subtract_processor_sub_401A2D(index_sub_40187Fa, v15, data_base_v24);// 执行减法指令
//设置两个常量
Set_Constant_sub_4024DB((_DWORD *)data_base_v24 + 20, 0);
Set_Constant_sub_4024DB((_DWORD *)data_base_v24 + 21, 1);
if ( result_v20 > 0 ) // 减法结果检查,0-jxx_check, other-next_code
{
current_ip_v23 += 12;
next_ip_v22 = current_ip_v23 + 8;
}
else
{
if ( getValueByAddress_sub_40187F(next_ip_v22) == -1 )// 是否退出
goto exit_label; //// 指令为-1则退出程序
if ( getValueByAddress_sub_40187F(next_ip_v22) )// code = 0-next_code, other-jmp
current_ip_v23 = (int)&data_base_v24[getValueByAddress_sub_40187F(next_ip_v22)];
else
current_ip_v23 += 12;
////
next_ip_v22 = current_ip_v23 + 8;
}
}
WriteConsole_sub_402950(2u, 0, 0, 0, (char)length_shorter_asc_405504);// 显示长度不够
//退出程序
exit_label:
WriteConsole_sub_402950(2u, 0, 0, 0, (char)aPressEnterToEx);// press enter to exit
v6 = (void *)getch_sub_402A40(1, 0, 0, 0); // pause
if ( v6 )
free_sub_402576(v6);
free_sub_402576(lpBuffer);
if ( inputString_v21 )
free_sub_402576(inputString_v21);
return 0;
}
每条指令为12个字节,由3个 dword 组成,第1,2个是操作数索引,第3个是操作码(0:执行下一条指令;-1:exit;大于0则是jmp,并且其值为目标索引),所有索引都是基于 data_base 的字节偏移量。 |