一、z3.exe运行效果
二、使用exeinfope查壳工具看是否加壳:
结果显示为无壳,那就简单了。既然是64位,那就用IDA64位进行查看,找到主函数F5反汇编得到:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rdx@1
__int64 v4; // rdx@1
__int64 v5; // rdx@3
int v7; // [sp+20h] [bp-60h]@1
int v8; // [sp+24h] [bp-5Ch]@1
int v9; // [sp+28h] [bp-58h]@1
int v10; // [sp+2Ch] [bp-54h]@1
int v11; // [sp+30h] [bp-50h]@1
int v12; // [sp+34h] [bp-4Ch]@1
int v13; // [sp+38h] [bp-48h]@1
int v14; // [sp+3Ch] [bp-44h]@1
int v15; // [sp+40h] [bp-40h]@1
int v16; // [sp+44h] [bp-3Ch]@1
int v17; // [sp+48h] [bp-38h]@1
int v18; // [sp+4Ch] [bp-34h]@1
int v19; // [sp+50h] [bp-30h]@1
int v20; // [sp+54h] [bp-2Ch]@1
int v21; // [sp+58h] [bp-28h]@1
int v22; // [sp+5Ch] [bp-24h]@1
int v23; // [sp+60h] [bp-20h]@1
int v24; // [sp+64h] [bp-1Ch]@1
int v25; // [sp+68h] [bp-18h]@1
int v26; // [sp+6Ch] [bp-14h]@1
int v27; // [sp+70h] [bp-10h]@1
int v28; // [sp+74h] [bp-Ch]@1
int v29; // [sp+78h] [bp-8h]@1
int v30; // [sp+7Ch] [bp-4h]@1
int v31; // [sp+80h] [bp+0h]@1
int v32; // [sp+84h] [bp+4h]@1
int v33; // [sp+88h] [bp+8h]@1
int v34; // [sp+8Ch] [bp+Ch]@1
int v35; // [sp+90h] [bp+10h]@1
int v36; // [sp+94h] [bp+14h]@1
int v37; // [sp+98h] [bp+18h]@1
int v38; // [sp+9Ch] [bp+1Ch]@1
int v39; // [sp+A0h] [bp+20h]@1
int v40; // [sp+A4h] [bp+24h]@1
int v41; // [sp+A8h] [bp+28h]@1
int v42; // [sp+ACh] [bp+2Ch]@1
int v43; // [sp+B0h] [bp+30h]@1
int v44; // [sp+B4h] [bp+34h]@1
int v45; // [sp+B8h] [bp+38h]@1
int v46; // [sp+BCh] [bp+3Ch]@1
int v47; // [sp+C0h] [bp+40h]@1
int v48; // [sp+C4h] [bp+44h]@1
unsigned __int8 v49; // [sp+D0h] [bp+50h]@1
unsigned __int8 v50; // [sp+D1h] [bp+51h]@1
unsigned __int8 v51; // [sp+D2h] [bp+52h]@1
unsigned __int8 v52; // [sp+D3h] [bp+53h]@1
unsigned __int8 v53; // [sp+D4h] [bp+54h]@1
unsigned __int8 v54; // [sp+D5h] [bp+55h]@1
unsigned __int8 v55; // [sp+D6h] [bp+56h]@1
unsigned __int8 v56; // [sp+D7h] [bp+57h]@1
unsigned __int8 v57; // [sp+D8h] [bp+58h]@1
unsigned __int8 v58; // [sp+D9h] [bp+59h]@1
unsigned __int8 v59; // [sp+DAh] [bp+5Ah]@1
unsigned __int8 v60; // [sp+DBh] [bp+5Bh]@1
unsigned __int8 v61; // [sp+DCh] [bp+5Ch]@1
unsigned __int8 v62; // [sp+DDh] [bp+5Dh]@1
unsigned __int8 v63; // [sp+DEh] [bp+5Eh]@1
unsigned __int8 v64; // [sp+DFh] [bp+5Fh]@1
unsigned __int8 v65; // [sp+E0h] [bp+60h]@1
unsigned __int8 v66; // [sp+E1h] [bp+61h]@1
unsigned __int8 v67; // [sp+E2h] [bp+62h]@1
unsigned __int8 v68; // [sp+E3h] [bp+63h]@1
unsigned __int8 v69; // [sp+E4h] [bp+64h]@1
unsigned __int8 v70; // [sp+E5h] [bp+65h]@1
unsigned __int8 v71; // [sp+E6h] [bp+66h]@1
unsigned __int8 v72; // [sp+E7h] [bp+67h]@1
unsigned __int8 v73; // [sp+E8h] [bp+68h]@1
unsigned __int8 v74; // [sp+E9h] [bp+69h]@1
unsigned __int8 v75; // [sp+EAh] [bp+6Ah]@1
unsigned __int8 v76; // [sp+EBh] [bp+6Bh]@1
unsigned __int8 v77; // [sp+ECh] [bp+6Ch]@1
unsigned __int8 v78; // [sp+EDh] [bp+6Dh]@1
unsigned __int8 v79; // [sp+EEh] [bp+6Eh]@1
unsigned __int8 v80; // [sp+EFh] [bp+6Fh]@1
unsigned __int8 v81; // [sp+F0h] [bp+70h]@1
unsigned __int8 v82; // [sp+F1h] [bp+71h]@1
unsigned __int8 v83; // [sp+F2h] [bp+72h]@1
unsigned __int8 v84; // [sp+F3h] [bp+73h]@1
unsigned __int8 v85; // [sp+F4h] [bp+74h]@1
unsigned __int8 v86; // [sp+F5h] [bp+75h]@1
unsigned __int8 v87; // [sp+F6h] [bp+76h]@1
unsigned __int8 v88; // [sp+F7h] [bp+77h]@1
unsigned __int8 v89; // [sp+F8h] [bp+78h]@1
unsigned __int8 v90; // [sp+F9h] [bp+79h]@1
int v91[43]; // [sp+110h] [bp+90h]@1
int i; // [sp+1BCh] [bp+13Ch]@1
_main(*(_QWORD *)&argc, argv, envp);
memcpy(*(_QWORD *)&argc, argv, &unk_404020, v91, 168LL);
printf(*(_QWORD *)&argc, argv, v3, "plz input your flag:");
scanf(*(_QWORD *)&argc, argv, &v49, "%42s");
v7 = 34 * v52 + 12 * v49 + 53 * v50 + 6 * v51 + 58 * v53 + 36 * v54 + v55;
v8 = 27 * v53 + 73 * v52 + 12 * v51 + 83 * v49 + 85 * v50 + 96 * v54 + 52 * v55;
v9 = 24 * v51 + 78 * v49 + 53 * v50 + 36 * v52 + 86 * v53 + 25 * v54 + 46 * v55;
v10 = 78 * v50 + 39 * v49 + 52 * v51 + 9 * v52 + 62 * v53 + 37 * v54 + 84 * v55;
v11 = 48 * v53 + 14 * v51 + 23 * v49 + 6 * v50 + 74 * v52 + 12 * v54 + 83 * v55;
v12 = 15 * v54 + 48 * v53 + 92 * v51 + 85 * v50 + 27 * v49 + 42 * v52 + 72 * v55;
v13 = 26 * v54 + 67 * v52 + 6 * v50 + 4 * v49 + 3 * v51 + 68 * v55;
v14 = 34 * v59 + 12 * v56 + 53 * v57 + 6 * v58 + 58 * v60 + 36 * v61 + v62;
v15 = 27 * v60 + 73 * v59 + 12 * v58 + 83 * v56 + 85 * v57 + 96 * v61 + 52 * v62;
v16 = 24 * v58 + 78 * v56 + 53 * v57 + 36 * v59 + 86 * v60 + 25 * v61 + 46 * v62;
v17 = 78 * v57 + 39 * v56 + 52 * v58 + 9 * v59 + 62 * v60 + 37 * v61 + 84 * v62;
v18 = 48 * v60 + 14 * v58 + 23 * v56 + 6 * v57 + 74 * v59 + 12 * v61 + 83 * v62;
v19 = 15 * v61 + 48 * v60 + 92 * v58 + 85 * v57 + 27 * v56 + 42 * v59 + 72 * v62;
v20 = 26 * v61 + 67 * v59 + 6 * v57 + 4 * v56 + 3 * v58 + 68 * v62;
v21 = 34 * v66 + 12 * v63 + 53 * v64 + 6 * v65 + 58 * v67 + 36 * v68 + v69;
v22 = 27 * v67 + 73 * v66 + 12 * v65 + 83 * v63 + 85 * v64 + 96 * v68 + 52 * v69;
v23 = 24 * v65 + 78 * v63 + 53 * v64 + 36 * v66 + 86 * v67 + 25 * v68 + 46 * v69;
v24 = 78 * v64 + 39 * v63 + 52 * v65 + 9 * v66 + 62 * v67 + 37 * v68 + 84 * v69;
v25 = 48 * v67 + 14 * v65 + 23 * v63 + 6 * v64 + 74 * v66 + 12 * v68 + 83 * v69;
v26 = 15 * v68 + 48 * v67 + 92 * v65 + 85 * v64 + 27 * v63 + 42 * v66 + 72 * v69;
v27 = 26 * v68 + 67 * v66 + 6 * v64 + 4 * v63 + 3 * v65 + 68 * v69;
v28 = 34 * v73 + 12 * v70 + 53 * v71 + 6 * v72 + 58 * v74 + 36 * v75 + v76;
v29 = 27 * v74 + 73 * v73 + 12 * v72 + 83 * v70 + 85 * v71 + 96 * v75 + 52 * v76;
v30 = 24 * v72 + 78 * v70 + 53 * v71 + 36 * v73 + 86 * v74 + 25 * v75 + 46 * v76;
v31 = 78 * v71 + 39 * v70 + 52 * v72 + 9 * v73 + 62 * v74 + 37 * v75 + 84 * v76;
v32 = 48 * v74 + 14 * v72 + 23 * v70 + 6 * v71 + 74 * v73 + 12 * v75 + 83 * v76;
v33 = 15 * v75 + 48 * v74 + 92 * v72 + 85 * v71 + 27 * v70 + 42 * v73 + 72 * v76;
v34 = 26 * v75 + 67 * v73 + 6 * v71 + 4 * v70 + 3 * v72 + 68 * v76;
v35 = 34 * v80 + 12 * v77 + 53 * v78 + 6 * v79 + 58 * v81 + 36 * v82 + v83;
v36 = 27 * v81 + 73 * v80 + 12 * v79 + 83 * v77 + 85 * v78 + 96 * v82 + 52 * v83;
v37 = 24 * v79 + 78 * v77 + 53 * v78 + 36 * v80 + 86 * v81 + 25 * v82 + 46 * v83;
v38 = 78 * v78 + 39 * v77 + 52 * v79 + 9 * v80 + 62 * v81 + 37 * v82 + 84 * v83;
v39 = 48 * v81 + 14 * v79 + 23 * v77 + 6 * v78 + 74 * v80 + 12 * v82 + 83 * v83;
v40 = 15 * v82 + 48 * v81 + 92 * v79 + 85 * v78 + 27 * v77 + 42 * v80 + 72 * v83;
v41 = 26 * v82 + 67 * v80 + 6 * v78 + 4 * v77 + 3 * v79 + 68 * v83;
v42 = 34 * v87 + 12 * v84 + 53 * v85 + 6 * v86 + 58 * v88 + 36 * v89 + v90;
v43 = 27 * v88 + 73 * v87 + 12 * v86 + 83 * v84 + 85 * v85 + 96 * v89 + 52 * v90;
v44 = 24 * v86 + 78 * v84 + 53 * v85 + 36 * v87 + 86 * v88 + 25 * v89 + 46 * v90;
v45 = 78 * v85 + 39 * v84 + 52 * v86 + 9 * v87 + 62 * v88 + 37 * v89 + 84 * v90;
v46 = 48 * v88 + 14 * v86 + 23 * v84 + 6 * v85 + 74 * v87 + 12 * v89 + 83 * v90;
v47 = 15 * v89 + 48 * v88 + 92 * v86 + 85 * v85 + 27 * v84 + 42 * v87 + 72 * v90;
v4 = 26 * v89 + 67 * v87 + 6 * v85 + 4 * v84 + 3 * (unsigned int)v86;
v48 = v4 + 68 * v90;
for ( i = 0; i <= 41; ++i )
{
v4 = (unsigned int)*(&v7 + i);
if ( (_DWORD)v4 != v91[i] )
{
printf(*(_QWORD *)&argc, argv, v4, "error");
exit(*(_QWORD *)&argc, argv, v5, 0LL);
}
}
printf(*(_QWORD *)&argc, argv, v4, "win");
return 0;
}
这么一段代码,看着是不是很眼熟,没错很明显使用z3约束求解器。当然也可以使用angr(这个特别方便)。上面这一段大致意思就是说解出上述方程组的答案来与v91进行对比,相等就行了。那么v91是什么呢?大家看这里:
看到这个memcpy函数了吗?memcpy函数的原型是 :void *memcpy(void *str1, const void *str2, size_t n)
将str1指向的数据复制大小为n个字节到目标数组str2中。在上述代码中跟进&unk_404020,可以发现对应的v91中的值是:
没错,就是这些字符,这样看不舒服,我们换种方式:
这样就舒服多了,由于是64bit的可以明显看出来,可以分为0x4F17、0x9CF6、.....、0x3A1D这些数。接下来就简单了,上脚本代码:
from z3 import *
s = Solver()
v49, v50, v51, v52, v53, v54, v55 = Ints("v49 v50 v51 v52 v53 v54 v55")
v56, v57, v58, v59, v60, v61, v62 = Ints("v56 v57 v58 v59 v60 v61 v62")
v63, v64, v65, v66, v67, v68, v69 = Ints("v63 v64 v65 v66 v67 v68 v69")
v70, v71, v72, v73, v74, v75, v76 = Ints("v70 v71 v72 v73 v74 v75 v76")
v77, v78, v79, v80, v81, v82, v83 = Ints("v77 v78 v79 v80 v81 v82 v83")
v84, v85, v86, v87, v88, v89, v90 = Ints("v84 v85 v86 v87 v88 v89 v90")
s.add(0x4F17 == 34 * v52 + 12 * v49 + 53 * v50 + 6 * v51 + 58 * v53 + 36 * v54 + v55)
s.add(0x9CF6 == 27 * v53 + 73 * v52 + 12 * v51 + 83 * v49 + 85 * v50 + 96 * v54 + 52 * v55)
s.add(0x8DDB == 24 * v51 + 78 * v49 + 53 * v50 + 36 * v52 + 86 * v53 + 25 * v54 + 46 * v55)
s.add(0x8EA6 == 78 * v50 + 39 * v49 + 52 * v51 + 9 * v52 + 62 * v53 + 37 * v54 + 84 * v55)
s.add(0x6929 == 48 * v53 + 14 * v51 + 23 * v49 + 6 * v50 + 74 * v52 + 12 * v54 + 83 * v55)
s.add(0x9911 == 15 * v54 + 48 * v53 + 92 * v51 + 85 * v50 + 27 * v49 + 42 * v52 + 72 * v55)
s.add(0x40A2 == 26 * v54 + 67 * v52 + 6 * v50 + 4 * v49 + 3 * v51 + 68 * v55)
s.add(0x2F3E == 34 * v59 + 12 * v56 + 53 * v57 + 6 * v58 + 58 * v60 + 36 * v61 + v62)
s.add(0x62B6 == 27 * v60 + 73 * v59 + 12 * v58 + 83 * v56 + 85 * v57 + 96 * v61 + 52 * v62)
s.add(0x4B82 == 24 * v58 + 78 * v56 + 53 * v57 + 36 * v59 + 86 * v60 + 25 * v61 + 46 * v62)
s.add(0x486C == 78 * v57 + 39 * v56 + 52 * v58 + 9 * v59 + 62 * v60 + 37 * v61 + 84 * v62)
s.add(0x4002 == 48 * v60 + 14 * v58 + 23 * v56 + 6 * v57 + 74 * v59 + 12 * v61 + 83 * v62)
s.add(0x52D7 == 15 * v61 + 48 * v60 + 92 * v58 + 85 * v57 + 27 * v56 + 42 * v59 + 72 * v62)
s.add(0x2DEF == 26 * v61 + 67 * v59 + 6 * v57 + 4 * v56 + 3 * v58 + 68 * v62)
s.add(0x28DC == 34 * v66 + 12 * v63 + 53 * v64 + 6 * v65 + 58 * v67 + 36 * v68 + v69)
s.add(0x640D == 27 * v67 + 73 * v66 + 12 * v65 + 83 * v63 + 85 * v64 + 96 * v68 + 52 * v69)
s.add(0x528F == 24 * v65 + 78 * v63 + 53 * v64 + 36 * v66 + 86 * v67 + 25 * v68 + 46 * v69)
s.add(0x613B == 78 * v64 + 39 * v63 + 52 * v65 + 9 * v66 + 62 * v67 + 37 * v68 + 84 * v69)
s.add(0x4781 == 48 * v67 + 14 * v65 + 23 * v63 + 6 * v64 + 74 * v66 + 12 * v68 + 83 * v69)
s.add(0x6B17 == 15 * v68 + 48 * v67 + 92 * v65 + 85 * v64 + 27 * v63 + 42 * v66 + 72 * v69)
s.add(0x3237 == 26 * v68 + 67 * v66 + 6 * v64 + 4 * v63 + 3 * v65 + 68 * v69)
s.add(0x2A93 == 34 * v73 + 12 * v70 + 53 * v71 + 6 * v72 + 58 * v74 + 36 * v75 + v76)
s.add(0x615F == 27 * v74 + 73 * v73 + 12 * v72 + 83 * v70 + 85 * v71 + 96 * v75 + 52 * v76)
s.add(0x50BE == 24 * v72 + 78 * v70 + 53 * v71 + 36 * v73 + 86 * v74 + 25 * v75 + 46 * v76)
s.add(0x598E == 78 * v71 + 39 * v70 + 52 * v72 + 9 * v73 + 62 * v74 + 37 * v75 + 84 * v76)
s.add(0x4656 == 48 * v74 + 14 * v72 + 23 * v70 + 6 * v71 + 74 * v73 + 12 * v75 + 83 * v76)
s.add(0x5B31 == 15 * v75 + 48 * v74 + 92 * v72 + 85 * v71 + 27 * v70 + 42 * v73 + 72 * v76)
s.add(0x313A == 26 * v75 + 67 * v73 + 6 * v71 + 4 * v70 + 3 * v72 + 68 * v76)
s.add(0x3010 == 34 * v80 + 12 * v77 + 53 * v78 + 6 * v79 + 58 * v81 + 36 * v82 + v83)
s.add(0x67FE == 27 * v81 + 73 * v80 + 12 * v79 + 83 * v77 + 85 * v78 + 96 * v82 + 52 * v83)
s.add(0x4D5F == 24 * v79 + 78 * v77 + 53 * v78 + 36 * v80 + 86 * v81 + 25 * v82 + 46 * v83)
s.add(0x58DB == 78 * v78 + 39 * v77 + 52 * v79 + 9 * v80 + 62 * v81 + 37 * v82 + 84 * v83)
s.add(0x3799 == 48 * v81 + 14 * v79 + 23 * v77 + 6 * v78 + 74 * v80 + 12 * v82 + 83 * v83)
s.add(0x60A0 == 15 * v82 + 48 * v81 + 92 * v79 + 85 * v78 + 27 * v77 + 42 * v80 + 72 * v83)
s.add(0x2750 == 26 * v82 + 67 * v80 + 6 * v78 + 4 * v77 + 3 * v79 + 68 * v83)
s.add(0x3759 == 34 * v87 + 12 * v84 + 53 * v85 + 6 * v86 + 58 * v88 + 36 * v89 + v90)
s.add(0x8953 == 27 * v88 + 73 * v87 + 12 * v86 + 83 * v84 + 85 * v85 + 96 * v89 + 52 * v90)
s.add(0x7122 == 24 * v86 + 78 * v84 + 53 * v85 + 36 * v87 + 86 * v88 + 25 * v89 + 46 * v90)
s.add(0x81F9 == 78 * v85 + 39 * v84 + 52 * v86 + 9 * v87 + 62 * v88 + 37 * v89 + 84 * v90)
s.add(0x5524 == 48 * v88 + 14 * v86 + 23 * v84 + 6 * v85 + 74 * v87 + 12 * v89 + 83 * v90)
s.add(0x8971 == 15 * v89 + 48 * v88 + 92 * v86 + 85 * v85 + 27 * v84 + 42 * v87 + 72 * v90)
s.add(0x3A1D == 26 * v89 + 67 * v87 + 6 * v85 + 4 * v84 + 3 * v86 + 68 * v90)
flag = []
if s.check() == sat:
ans = s.model()
flag.append(ans[v49])
flag.append(ans[v50])
flag.append(ans[v51])
flag.append(ans[v52])
flag.append(ans[v53])
flag.append(ans[v54])
flag.append(ans[v55])
flag.append(ans[v56])
flag.append(ans[v57])
flag.append(ans[v58])
flag.append(ans[v59])
flag.append(ans[v60])
flag.append(ans[v61])
flag.append(ans[v62])
flag.append(ans[v63])
flag.append(ans[v64])
flag.append(ans[v65])
flag.append(ans[v66])
flag.append(ans[v67])
flag.append(ans[v68])
flag.append(ans[v69])
flag.append(ans[v70])
flag.append(ans[v71])
flag.append(ans[v72])
flag.append(ans[v73])
flag.append(ans[v74])
flag.append(ans[v75])
flag.append(ans[v76])
flag.append(ans[v77])
flag.append(ans[v78])
flag.append(ans[v79])
flag.append(ans[v80])
flag.append(ans[v81])
flag.append(ans[v82])
flag.append(ans[v83])
flag.append(ans[v84])
flag.append(ans[v85])
flag.append(ans[v86])
flag.append(ans[v87])
flag.append(ans[v88])
flag.append(ans[v89])
flag.append(ans[v90])
for x in flag:
print(x, end=",")
哇!!!!看到起都脑壳大。但是不要慌,解出来的还不是最终答案,它是对应的ascii码:
看不清楚是什么?没关系还有手动的:
102,108,97,103,123,55,101,49,55,49,100,52,51,45,54,51,98,57,45,52,101,49,56,45,57,57,48,101,45,54,101,49,52,99,50,97,102,101,54,52,56,125,
哟西!最紧张的时候到了,解ascii码,代码奉上:
s = [102, 108, 97, 103, 123, 55, 101, 49, 55, 49, 100, 52, 51, 45, 54, 51, 98, 57, 45, 52, 101,
49, 56, 45, 57, 57, 48, 101, 45, 54, 101, 49, 52, 99, 50, 97, 102, 101, 54, 52, 56, 125]
for x in s:
print(chr(x), end="")
多得也不说了flag也整上:
flag{7e171d43-63b9-4e18-990e-6e14c2afe648}
好了!好了!OVER!!!其实还是挺简单的哈。。。。。