Check_Your_Luck
下载文件是cpp
是个解方程的题,用python的z3
from z3 import *
v,w,x,y,z=BitVecs('v w x y z',16)
l=Solver()
l.add(v * 23 + w * -32 + x * 98 + y * 55 + z * 90 == 333322)
l.add(v * 123 + w * -322 + x * 68 + y * 67 + z * 32 == 707724)
l.add(v * 266 + w * -34 + x * 43 + y * 8 + z * 32 == 1272529)
l.add(v * 343 + w * -352 + x * 58 + y * 65 + z * 5 == 1672457)
l.add(v * 231 + w * -321 + x * 938 + y * 555 + z * 970 == 3372367)
if l.check() == sat:
print(l.model())
else:
print ('Error')
#[y = 1754, z = 777, x = 677, w = 123, v = 4544]
Tea
打开可执行文件有输出,直接打开ida
shift+F12点进去
他提示你,这是假的flag,看看哪个函数引用了它,往上追,就来到了关键的地方
__int64 sub_140016230()
{
char *v0; // rdi
__int64 i; // rcx
char v3[32]; // [rsp+0h] [rbp-20h] BYREF
char v4; // [rsp+20h] [rbp+0h] BYREF
int v5; // [rsp+24h] [rbp+4h]
int v6; // [rsp+44h] [rbp+24h]
int v7[12]; // [rsp+68h] [rbp+48h] BYREF
_DWORD v8[16]; // [rsp+98h] [rbp+78h] BYREF
int v9[31]; // [rsp+D8h] [rbp+B8h] BYREF
int j; // [rsp+154h] [rbp+134h]
int k; // [rsp+174h] [rbp+154h]
int m; // [rsp+194h] [rbp+174h]
v0 = &v4;
for ( i = 102i64; i; --i )
{
*(_DWORD *)v0 = -858993460;
v0 += 4;
}
sub_14001137F(&unk_140023009);
v5 = 32;
v6 = 0;
v7[0] = 1234;
v7[1] = 5678;
v7[2] = 9012;
v7[3] = 3456;
memset(v8, 0, 0x28ui64);
v9[15] = 0;
v9[23] = 0;
sub_1400113E8();
for ( j = 0; j < 10; ++j )
sub_1400111FE("%x", &v8[j]);
sub_140011339(v7);
sub_140011145(v8, v9);
sub_1400112B7(v8, v7);
v6 = sub_140011352(v8);
if ( v6 )
{
printf("you are right\n");
for ( k = 0; k < 10; ++k )
{
for ( m = 3; m >= 0; --m )
printf("%c", (unsigned __int8)((unsigned int)v9[k] >> (8 * m)));
}
}
else
{
printf("fault!\nYou can go online and learn the tea algorithm!");
}
sub_140011311(v3, &unk_14001AE90);
return 0i64;
}
最后一句话提醒了我们这是tea加密
最后v9输出flag。
v6 = sub_140011352(v8);
进去发现是一个返回值为bool类型的函数
说明了形参a1等于v8
由此我们知道了tea加密后的v8的值
sub_1400112B7(v8, v7);
进入这个函数,就是魔改版的茶加密,在解密前,我们还要知道v7
的值。
sub_140011339(v7);
进入这个函数,直接对v7进行赋值。
然后我们再解密,我们首先把加密改成c语言形式
for (int i = 0; i <= 8; ++i )
{
v5 = 0;
v6 = 256256256 * i;
v3 = i + 1;
do
{
++v5;
v8[i] += v6 ^ (v8[v3]+ ((v8[v3] >> 5) ^ (16 * v8[v3]))) ^ (v6 + v7[v6&3]);
v8[v3] += (v6 + v7[(v6>>11)&3]) ^ (v8[i]+ ((v8[i] >> 5) ^ (16 * v8[i])));
v6 += 256256256;
}
while ( v5 <= 0x20 );
}
之后再逆向写,为了检验正确性,自己可以赋值一组数,然后互相解密,看看结果对不对
#include <bits/stdc++.h>
using namespace std;
int sub_140011339(int *a1)
{
int v6;
int v7;
int v8;
int v9;
v6 = 2233;
v7 = 4455;
v8 = 6677;
v9 = 8899;
*a1 = 2233;
*(a1+1) = v7;
*(a1+2) = v8;
*(a1+3) = v9;
return 0;
}
int main()
{
int v7[12];
unsigned int v8[15];
int v5,v6,v3;
v7[0] = 1234;
v7[1] = 5678;
v7[2] = 9012;
v7[3] = 3456;
sub_140011339(v7);
//cout<<v7[3]<<endl;
v8[0] = 444599258;
v8[1] = 4154859931;
v8[2] = 1226314200;
v8[3] = 4060164904;
v8[4] = 359413339;
v8[5] = 1013885656;
v8[6] = -2066432216;
v8[7] = -249921817;
v8[8] = 856928850;
v8[9] = 3718242937;
for (int i = 8; i >= 0; --i )
{
v5 = 0;
v6 = 0xF462900 * i;
v3 = i + 1;
v6=v6+(33*0xF462900);
do
{
v6-=0xF462900;
v8[v3]-=(v6+v7[(v6>>11)&3])^(v8[i]+((v8[i]>>5)^(16 * v8[i])));
v8[i]-=v6^(v8[v3]+((v8[v3]>>5)^(16*v8[v3])))^(v6+v7[v6&3]);
++v5;
}
while ( v5 <= 0x20 );
}
/*for(int j=0;j<10;j++)
cout<<v8[j]<<endl;*/
for (int k = 0; k < 10; ++k )
{
for (int m = 3; m >= 0; --m )
printf("%c",(v8[k] >> (8 * m)));
}
return 0;
}
要注意不能把v8定义成int
类型,要定义成unsigned int
类型