vm逆向与符号执行angr

经典无壳,IDAF5直接逆向,改几个名字

int __cdecl vm_operad(int *a1yizhi, int a2)
{
int result; // eax
char inputs[200]; // [esp+13h] [ebp-E5h] BYREF
char v4; // [esp+DBh] [ebp-1Dh]
int v5; // [esp+DCh] [ebp-1Ch]
int z; // [esp+E0h] [ebp-18h]
int v7; // [esp+E4h] [ebp-14h]
int x; // [esp+E8h] [ebp-10h]
int i; // [esp+ECh] [ebp-Ch]

i = 0;
x = 0;
v7 = 0;
z = 0;
v5 = 0;
while ( 1 )
{
result = i;
if ( i >= a2 )
return result;
switch ( a1yizhi[i] )
{
case 1:
inputs[z + 100] = v4;
++i;
++z;
++x;
break;
case 2:
v4 = a1yizhi[i + 1] + inputs[x];
i += 2;
break;
case 3:
v4 = inputs[x] - LOBYTE(a1yizhi[i + 1]);
i += 2;
break;
case 4:
v4 = a1yizhi[i + 1] ^ inputs[x];
i += 2;
break;
case 5:
v4 = a1yizhi[i + 1] * inputs[x];
i += 2;
break;
case 6:
++i;
break;
case 7:
if ( inputs[v7 + 100] != a1yizhi[i + 1] )
{
printf("what a shame...");
exit(0);
}
++v7;
i += 2;
break;
case 8:
inputs[v5] = v4;
++i;
++v5;
break;
case 10:
read(inputs);
++i;
break;
case 11:
v4 = inputs[x] - 1;
++i;
break;
case 12:
v4 = inputs[x] + 1;
++i;
break;
default:
continue;
}
}
}

看上去好复杂,慢慢分析吧

a1yizhi数组是已知的

// aiyizhi[]
0x0A,0x04,0x10,0x08,0x03,0x05,0x01,
0x04,0x20,0x08,0x05,0x03,0x01,
0x03,0x02,0x08,0x0B,0x01,
0x0C,0x08,0x04,0x04,0x01,
0x23,0x05,0x03,0x08,0x03,0x21,0x01,
0x0B,0x08,0x0B,0x32,0x01,
0x04,0x09,0x08,0x03,0x20,0x01,
0x02,0x51,0x08,0x04,0x24,0x01,
0x0C,0x08,0x0B,0x48,0x01,
0x05,0x02,0x08,0x02,0x25,0x01,
0x02,0x36,0x08,0x04,0x41,0x01,
0x02,0x20,0x08,0x05,0x01,0x01,
0x05,0x03,0x08,0x02,0x25,0x01,
0x04,0x09,0x08,0x03,0x20,0x01,
0x02,0x41,0x08,0x0C,0x01,

0x07,0x22,0x07,0x3F,0x07,0x34,0x07,0x32,0x07,0x72,0x07,0x33,
0x07,0x18,0x07,0xA7,0xFF,0xFF,0xFF,0x07,0x31,0x07,0xF1,0xFF,0xFF,0xFF,0x07,0x28,
0x07,0x84,0xFF,0xFF,0xFF,0x07,0xC1,0xFF,0xFF,0xFF,0x07,0x1E,0x07,0x7A

可以看出case7是在检测flag输入的真假

0x22,0x3F,0x34,0x32,0x72,0x33,0x18,0xA7,0xFF,0xFF,0xFF,0x31,0xF1,0xFF,0xFF,0xFF,0x28,0x84,0xFF,0xFF,0xFF,0xC1,0xFF,0xFF,0xFF,0x1E,0x7A

input[0]^0x10-0x05=0x22 ‘7’

input[1]^0x20*0x03=0x3f ‘5’

input[2]-0x02-0x01=0x34 ‘7’

input[3]+1^0x04=0x32 ‘5’

input[4]*3-0x21=0x72 ‘1’

input[5]-2=0x33 ‘5’

input[6]^0x09-0x20=0x18 ‘1’

input[7]+0x51^0x24=0xA7 ‘2’

input[8]=0x31 ‘1’

input[9]*2+0x25=0xf1 ‘f’

input[10]+0x36^0x41=0x28 ‘3’

input[11]+0x20=0x84 ‘d’

input[12]*3+0x25=0xC1 ‘4’

input[13]^0x09-0x20=0x1E ‘7’

input[14]+0x42=0x7A ‘8’

flag{757515121f3d478}

这是手动试出来的,写代码挺麻烦的就算了

Ponce插件符号获取flag

不知道怎么装,

https://github.com/illera88/Ponce

使用python angr符号执行解决

代码

import angr
p = angr.Project('signal.exe')
st = p.factory.entry_state()
sm = p.factory.simulation_manager(st)
sm.explore(find=0x40175E, avoid=0x4016E6)
print(sm.found[0].posix.dumps(0))