0x00 前言

构造函数当主逻辑,第一次见

0x01 解

无壳,直接拖IDA

搜main可以发现有两个main,一个是_main还有一个是___main

查引用发现___main_main之前调用

两个函数都没什么东西

_main

___main

不过发现___main有一个跳转,进去之后可以看到有个函数指针

动调发现这个是从下往上调用的

调试,直到有flag字样的函数出现,步入,发现调用了读起来像是构造和析构函数的东西,

继续跟进,发现两个test对象

一个个看,test是主逻辑,读字符串并进行长度判断,由此可知flag长度为0x21

再看test2,发现是个ROT13,应该直接调的库,没有魔改

之后继续跟进,发现在___tcf3内还有东西

这里面是Test2类的析构函数,而析构函数里面调用了输入在ROT13操作后的结果

之后可以看到一个encrypt函数

进去发现又是一段加密,用到了一些三角函数,经查询这是DCT变换

之后发现加密的结果丢到了这个变量_encrypted里面

既然Test2类的析构函数有搞事情,那么Test估计也有

这边F5一下可以看到清晰的逻辑

通过查看发现这个in数组就是上面的_encrypted里的东西,由此可以知道上面的三角函数应该是加密的最后一步了

这边比较有意思的是check的结果都是dq(double或quadro word,不过都要解析成双精度浮点数)

最后上脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import numpy as np
import cv2

# DCT
enc = [513.355, -37.7986, 8.7316, -10.7832, -1.3097, -20.5779,6.98641, -29.2989, 15.9422, 21.4138, 29.4754, -2.77161,-6.58794, -4.22332, -7.20771, 8.83506, -4.38138, -19.3898,18.3453, 6.88259, -14.7652, 14.6102, 24.7414, -11.6222,-9.754759999999999, 12.2424, 13.4343, -34.9307, -35.735,-20.0848, 39.689, 21.879, 26.8296]
# https://blog.csdn.net/Icathia7/article/details/132687445
# 密文=明文·c(u)·A
A = np.array([[np.cos((j + 0.5) * i * np.pi / 33) for j in range(33)] for i in range(33)])
# 明文·A=密文/c(u)
b = np.array([enc[i] / np.sqrt(1.0 / 33) if i == 0 else enc[i] / np.sqrt(2.0 / 33) for i in range(33)])

# https://blog.csdn.net/weixin_45870904/article/details/111397520
solution, residuals, rank, s = np.linalg.lstsq(A, b, rcond=None)
print("a values:")
print(solution)
# np.round对数组保留指定位小数(四舍五入,默认为0位)
s = np.round(solution).astype(int)
print("Rounded a values:")
print(''.join([chr(x) for x in s]))

# 当然也可以用cv2库
enc = np.array([513.355, -37.7986, 8.7316, -10.7832, -1.3097, -20.5779,6.98641, -29.2989, 15.9422, 21.4138, 29.4754, -2.77161,-6.58794, -4.22332, -7.20771, 8.83506, -4.38138, -19.3898,18.3453, 6.88259, -14.7652, 14.6102, 24.7414, -11.6222,-9.754759999999999, 12.2424, 13.4343, -34.9307, -35.735,-20.0848, 39.689, 21.879, 26.8296],dtype=np.float32)
s=cv2.idct(enc).round().astype(int).flatten().tolist()
print(s)

# ROT13
flag = ''
for x in s:
if chr(x).isalpha():
if chr(x).isupper():
new_ascii = (x - 65 - 13) % 26 + 65
else:
new_ascii = (x - 97 - 13) % 26 + 97
flag+=chr(new_ascii)
else:
flag+=chr(x)

print(flag)
# DASCTF{Wh0_1s_Ma1n_@nd_FunnY_Dct}