文章目录
[NPUCTF2020]Baby Obfuscation
把五个Fox分析一下
F0X1(int a, int b):
int __cdecl F0X1(int a, int b)
{
int result; // eax
if ( b )
result = F0X1(b, a % b);
else
result = a;
return result;
}
运用辗转相除法求得最大公因数(学到一个词汇:最大公约数GCD,最小公倍数LCM)
F0X2(bool a, bool b):
bool __cdecl F0X2(bool a, bool b)
{
return a == b && !a;
}
仅有一种情况返回真:a==b==0
F0X3(bool a, bool b):
bool __cdecl F0X3(bool a, bool b)
{
bool v2; // bl
bool v3; // al
v2 = F0X2(b, b);
v3 = F0X2(a, a);
return F0X2(v3, v2);
}
仅有一种情况返回真:a==b==1
F0X4(int a, int b):
int __cdecl F0X4(int a, int b)
{
return ~(~a + b);
}
解析
00000100 4
00000010 2
01111011 未知
00000010 2
01111101
00000010 2
00000111 7
00000010 2
01111000
00000010
01111010
00000101 5
00001000 8
00000111 7
01110111
00000111
01111110
00000001
01111101
00000111
10000100
11111011 -5
返回值是a-b
F0X5(int a, int b):
int __cdecl F0X5(int a, int b)
{
int ans; // [rsp+Ch] [rbp-4h]
ans = 1;
while ( b )
{
if ( (b & 1) != 0 )
ans *= a;
a *= a;
b >>= 1;
}
return ans;
}
总结后如下:
a b ans
2 2 1
4 1 4
16 0 4
11
a b ans
2 3 2
4 1 8
16 0 8
a b ans
3 4 1
9 2 1
81 1 81
81*81 0 81
返回值是ab
整体分析
_main();
memset(A0X1, 0, 0xFA0ui64);
A0X1[1000] = 0;
memset(A0X3, 0, 0x100ui64);
A0X3[64] = 0;
for ( i = 0; i <= 64; ++i )
A0X3[i] = i + 1;
A0X4[0] = 2;
A0X4[1] = 3;
A0X4[2] = 4;
A0X4[3] = 5;
A0X5[0] = 2;
A0X5[1] = 3;
A0X5[2] = 4;
A0X5[3] = 5;
puts("WHERE IS MY KEY!?");
scanf("%32s", A0X2);
V0X1 = strlen(A0X2);
v3 = F0X1(A0X3[i_0], A0X3[i_0]);
for ( i_0 = v3 / A0X3[i_0]; i_0 <= V0X1; ++i_0 )// i_0这个变量从1开始
{
v4 = (A0X3[i_0] + A0X3[i_0 + 1]) * (A0X3[i_0] + A0X3[i_0 + 1]);// (a+b)的平方
if ( v4 >= F0X5(2, 2) * A0X3[i_0] * A0X3[i_0 + 1] )// 4*a*b if中恒为真
{
v5 = ~A0X2[F0X4(i_0, 1)];
v6 = F0X4(i_0, 1);
A0X1[i_0] = ~(v5 + A0X4[v6 % F0X5(2, 2)]);
}
v7 = F0X1(A0X3[i_0], A0X3[i_0 + 1]); // 恒为1
if ( v7 > F0X1(A0X3[i_0 + 1], ~(~A0X3[i_0 + 1] + A0X3[i_0])) )// 恒为1 if中恒为假
{
v8 = A0X1[i_0];
v9 = F0X4(i_0, 1);
A0X1[i_0] = ~(~v8 + A0X3[v9 % F0X5(2, 2)]) * v8;
}
v10 = A0X3[i_0 + 1];
v11 = F0X5(2, 1) * v10; // v11=2v10
v12 = A0X3[i_0];
v13 = F0X5(2, 1);
v14 = F0X1(v12 * v13, v11); // v14=fox1(2*AOX[i_0],2*AOX[i_0+1])
v15 = F0X5(2, 1);
if ( v14 == v15 * F0X1(A0X3[i_0], A0X3[i_0 + 1]) )// 2*FOX1(AOX[i_0],AOX[i_0+1])恒为真
{
v16 = F0X4(i_0, 1);
A0X1[i_0] ^= A0X4[v16 % F0X5(2, 2)];
}
v17 = F0X5(V0X3, A0X3[i_0]);
v18 = v17 < A0X3[i_0] + 1; // 恒为0
v19 = F0X5(2, 4); // 16
if ( F0X3(v19 >= i_0, v18) ) // 恒为假
{
v20 = ~A0X2[F0X4(i_0, 1)];
v21 = F0X4(i_0, 1);
A0X1[i_0] ^= ~(v20 + A0X4[v21 % F0X5(2, 2)]);
}
v22 = F0X5(2, 3);
v23 = F0X1(A0X3[i_0], A0X3[i_0]);
A0X1[i_0] *= v22 + F0X5(2, v23 / A0X3[i_0]);
}
v24 = F0X5(2, 4);
if ( F0X4(v24, 1) != V0X1 )
goto LABEL_23;
v25 = F0X1(A0X3[i_1], A0X3[i_1]);
for ( i_1 = v25 / A0X3[i_1]; i_1 <= V0X1; ++i_1 )
{
v26 = A0X1[i_1]; // 取值
if ( v26 == F0X4(A0X6[i_1], 1) / 10 ) // 比较
++V0X2;
}
if ( V0X2 == V0X1 )
puts("\nPASS");
else
LABEL_23:
puts("\nDENIED");
return 0;
}
关键代码:
v5 = ~A0X2[F0X4(i_0, 1)];
v6 = F0X4(i_0, 1);
A0X1[i_0] = ~(v5 + A0X4[v6 % F0X5(2, 2)]);
v16 = F0X4(i_0, 1);
A0X1[i_0] ^= A0X4[v16 % F0X5(2, 2)];
v22 = F0X5(2, 3);
v23 = F0X1(A0X3[i_0], A0X3[i_0]);
A0X1[i_0] *= v22 + F0X5(2, v23 / A0X3[i_0]);
v26 == F0X4(A0X6[i_1], 1) / 10
脚本
" // " 表示整数除法,返回整数 比如 7/3 结果为2
“ / ” 表示浮点数除法,返回浮点数 (即小数) 比如 8/2 结果为4.0
AOX4=[2,3,4,5]
AOX6=[0,7801,7801,8501,5901,8001,6401,11501,4601,9801,9601,11701,5301,9701,10801,12501]
inputs=[None]*16
for i in range(1,len(AOX6)):
inputs[i]=(AOX6[i]-1)//10//10
inputs[i]=inputs[i]^AOX4[(i-1)%4]
inputs[i]=inputs[i]+AOX4[(i-1)%4]
print(inputs)
AOX4=[2,3,4,5]
AOX6=[0,7801,7801,8501,5901,8001,6401,11501,4601,9801,9601,11701,5301,9701,10801,12501]
for i in range(1,len(AOX6)):
AOX6[i]=(AOX6[i]-1)//10//10
AOX6[i]=AOX6[i]^AOX4[(i-1)%4]
AOX6[i]=AOX6[i]+AOX4[(i-1)%4]
print(AOX6)
flag=[78,80,85,67,84,70,123,48,98,102,117,53,101,114,125]
lists=""
for i in range(len(flag)):
lists+=chr(flag[i])
print(lists)
NPUCTF{0bfu5er}
[HDCTF2019]MFC
查看程序
然后利用xspy查看相应的窗口
发现了一个没有系统库名的OnMsg,也就是没有VM_……
这串,接下来用SendMessage发送一个0x0464
消息试试
发消息
#include <iostream>
#include<Windows.h>
int main()
{
HWND handle = FindWindow(NULL, "Flag就在控件里");
if (handle == NULL) {
printf("没抓到");
}
else {
SendMessage(handle, 0x0464, NULL, NULL);
}
}
接下来程序变成这样,找到一个DES key
解密
{I am a Des key}
而DES
密文在这:
944c8d100f82f0c18b682f63e4dbaa207a2f1e72581c2f1b
thIs_Is_real_kEy_hahaaa