文件无壳 拖入ida 进入主函数 F5查看伪c代码
继续跟进vm_operad
-
Case 1: 将
v4
的值存储在Str
数组的特定偏移量(v6 + 100
)处,并更新索引。 -
Case 2: 执行加法操作,将
a1[v9 + 1]
(下一个数组元素,作为操作数)与Str[v8]
相加,结果存储在v4
中,并跳过下一个数组元素。 -
Case 3: 执行减法操作,从
Str[v8]
中减去a1[v9 + 1]
的低字节,结果存储在v4
中,并跳过下一个数组元素。 -
Case 4: 执行异或操作,将
Str[v8]
与a1[v9 + 1]
进行异或,结果存储在v4
中,并跳过下一个数组元素。 -
Case 5: 执行乘法操作,将
Str[v8]
与a1[v9 + 1]
相乘,结果存储在v4
中,并跳过下一个数组元素。 -
Case 6: 跳过当前指令(即不执行任何操作,只增加索引)。
-
Case 7: 执行条件检查,如果
Str[v7 + 100]
不等于a1[v9 + 1]
,则打印错误消息并退出程序。 -
Case 8: 将
v4
的值存储在Str
数组的v5
索引处,并更新索引。 -
Case 10: 调用
read
函数(这里可能是个错误,因为read
通常用于文件或套接字,而不是直接用于字符串。这可能是个占位符或特定于环境的函数)。 -
Case 11 和 Case 12: 分别对
Str[v8]
执行减一和加一操作,并更新索引。
int __cdecl vm_operad(int *a1, int a2)
{
int result; // eax
char Str[200]; // [esp+13h] [ebp-E5h] BYREF
char v4; // [esp+DBh] [ebp-1Dh]
int v5; // [esp+DCh] [ebp-1Ch]
int v6; // [esp+E0h] [ebp-18h]
int v7; // [esp+E4h] [ebp-14h]
int v8; // [esp+E8h] [ebp-10h]
int v9; // [esp+ECh] [ebp-Ch]
v9 = 0;
v8 = 0;
v7 = 0;
v6 = 0;
v5 = 0;
while ( 1 )
{
result = v9;
if ( v9 >= a2 )
return result;
switch ( a1[v9] )
{
case 1:
Str[v6 + 100] = v4;
++v9;
++v6;
++v8;
break;
case 2:
v4 = a1[v9 + 1] + Str[v8];
v9 += 2;
break;
case 3:
v4 = Str[v8] - LOBYTE(a1[v9 + 1]);
v9 += 2;
break;
case 4:
v4 = a1[v9 + 1] ^ Str[v8];
v9 += 2;
break;
case 5:
v4 = a1[v9 + 1] * Str[v8];
v9 += 2;
break;
case 6:
++v9;
break;
case 7:
if ( Str[v7 + 100] != a1[v9 + 1] )
{
printf("what a shame...");
exit(0);
}
++v7;
v9 += 2;
break;
case 8:
Str[v5] = v4;
++v9;
++v5;
break;
case 10:
read(Str);
++v9;
break;
case 11:
v4 = Str[v8] - 1;
++v9;
break;
case 12:
v4 = Str[v8] + 1;
++v9;
break;
default:
continue;
}
}
}
find地址:
借鉴师傅的代码
import angr
p = angr.Project(r'D:\HuaweiMoveData\Users\86135\Desktop\signal.exe')
state = p.factory.entry_state()
simgr = p.factory.simgr(state)
simgr.explore(find=0x004017A5 ,avoid=0x004016E6)
flag = simgr.found[0].posix.dumps(0)[:15]
print(flag)
得到flag
flag{757515121f3d478}