原理
离散余弦变换(DCT for Discrete Cosine Transform)是与傅里叶变换相关的一种变换,它类似于离散傅里叶变换,但是只使用实数。离散余弦变换相当于一个长度大概是它两倍的离散傅里叶变换,这个离散傅里叶变换是对一个实偶函数进行的(因为一个实偶函数的傅里叶变换仍然是一个实偶函数),在有些变形里面需要将输入或者输出的位置移动半个单位(DCT有8种标准类型,其中4种是常见的)。
dct
dct的公式为
其中X是输入,
N为输入的长度,
αk则是归一化系数,用来调整第k个量的权重.
当k=0时,α为根号下的1/N,
当k!=0时,α为根号下的2/N.
idct
idct的公式为
其中X是输入,
N为输入的长度,
αk仍是归一化系数,取值和dct相同.
当k=0时,α为根号下的1/N,
当k!=0时,α为根号下的2/N.
代码实现
python中scipy库就提供了dct及其逆过程idct,dct函数一共有8种模式,一般使用norm='ortho'模式
import numpy as np
from scipy.fftpack import dct, idct
x = np.array([0x68, 0x65, 0x6c, 0x6c, 0x6f])
print("明文: ", x)
y = dct(x, norm='ortho')
print("加密: ", y)
z = idct(y, norm='ortho')
print("解密: ", np.round(z))
根据公式,自己实现的dct和idct
import numpy as np
import math
def dct(x):
result=[]
size = len(x)
for i in range(size):
sum = 0
for j in range(size):
v1 = math.cos((j+0.5)*math.pi*i/size)
v2 = x[j]*v1
sum += v2
if i:
v3 = math.sqrt(2/size)
else:
v3 = math.sqrt(1/size)
result.append(v3*sum)
return result
def idct(x):
result = []
size = len(x)
for i in range(size):
sum = 0
for j in range(size):
v1 = math.cos((i + 0.5) * math.pi * j / size)
if j == 0:
v2 = math.sqrt(1 / size)
else:
v2 = math.sqrt(2 / size)
v3 = x[j]*v2
sum += v3 * v1
result.append(sum)
return result
x = np.array([0x68, 0x65, 0x6c, 0x6c, 0x6f])
print("明文: ", x)
y = dct(x)
print("加密: ", y)
z = idct(y)
print("解密: ", np.round(z))
2024羊城杯 你这主函数保真么
题目分析
先丢到die里查壳
无壳,32位程序
进去是假的主函数
找到初始化的位置
要求输入33位的flag
接着是对输入进行rot13加密
void __cdecl rot13_encrypt(char *input)
{
char v1; // al
while ( *input )
{
if ( *input > 64 && *input <= 90 || *input > 96 && *input <= 122 )
{
if ( *input <= 64 || *input > 90 )
v1 = 97;
else
v1 = 65;
*input = (*input - v1 + 13) % 26 + v1;
}
++input;
}
}
接着就是dct算法加密了
void __cdecl Test2::~Test2(Test2 *const this)
{
std::vector<int> *v1; // eax
char v2; // bl
int v3; // eax
std::allocator<int> *v4; // [esp+0h] [ebp-68h]
std::allocator<int> *const v5; // [esp+0h] [ebp-68h]
std::vector<double> *const v6; // [esp+0h] [ebp-68h]
std::vector<double> *const v7; // [esp+0h] [ebp-68h]
std::vector<double> *const v8; // [esp+0h] [ebp-68h]
__gnu_cxx::__normal_iterator<double*,std::vector<double> > *v9; // [esp+0h] [ebp-68h]
__gnu_cxx::__normal_iterator<double*,std::vector<double> > *const v10; // [esp+0h] [ebp-68h]
std::vector<int>::size_type v11; // [esp+4h] [ebp-64h]
std::vector<double> *v12; // [esp+4h] [ebp-64h]
const std::vector<int>::allocator_type *v13; // [esp+8h] [ebp-60h]
std::vector<double>::iterator __for_end; // [esp+24h] [ebp-44h] BYREF
std::vector<double>::iterator __for_begin; // [esp+28h] [ebp-40h] BYREF
std::vector<int> input; // [esp+2Ch] [ebp-3Ch] BYREF
std::vector<int>::size_type __n[3]; // [esp+3Bh] [ebp-2Dh] BYREF
double val; // [esp+48h] [ebp-20h]
std::vector<double> *__for_range; // [esp+54h] [ebp-14h]
int i; // [esp+58h] [ebp-10h]
int cd; // [esp+5Ch] [ebp-Ch]
std::allocator<int>::allocator(v4);
v1 = (std::vector<int> *)strlen(flag);
std::vector<int>::vector(v1, (std::vector<int>::size_type)__n, v13);
std::allocator<int>::~allocator(v5);
for ( i = 0; strlen(flag) > i; ++i )
{
v2 = flag[i];
*std::vector<int>::operator[]((std::vector<int> *const)i, v11) = v2;
}
encrypt((std::vector<double> *)((char *)__n + 1), &input);
std::vector<double>::operator=((std::vector<double> *const)((char *)__n + 1), v12);
std::vector<double>::~vector(v6);
cd = 0;
__for_range = &encrypted;
LODWORD(__for_begin._M_current) = (std::vector<double>::iterator)std::vector<double>::begin(v7)._M_current;
LODWORD(__for_end._M_current) = (std::vector<double>::iterator)std::vector<double>::end(v8)._M_current;
while ( __gnu_cxx::operator!=<double *,std::vector<double>>(&__for_begin, &__for_end) )
{
val = *__gnu_cxx::__normal_iterator<double *,std::vector<double>>::operator*(v9);
v3 = cd++;
in[v3] = val;
__gnu_cxx::__normal_iterator<double *,std::vector<double>>::operator++(v10);
}
std::vector<int>::~vector((std::vector<int> *const)v9);
}
最后则是在这里进行比较,绝对值之差小于0.0001
exp
在之前已经对dct算法进行了分析,这里就可以直接提取出数据进行解密
# import numpy as np
# from scipy.fftpack import dct, idct
# x = 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])
# flag = idct(x, norm='ortho')
# print(np.round(flag))
import numpy as np
import math
def idct(x):
result = []
size = len(x)
for i in range(size):
sum = 0
for j in range(size):
v1 = math.cos((i + 0.5) * math.pi * j / size)
if j == 0:
v2 = math.sqrt(1 / size)
else:
v2 = math.sqrt(2 / size)
v3 = x[j]*v2
sum += v3 * v1
result.append(sum)
return result
x = 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])
print(np.round(idct(x)))
将得到的数组[81, 78, 70, 80, 71, 83, 123, 74, 117, 48, 95, 49, 102, 95,
90, 110, 49, 97, 95, 64, 97, 113, 95, 83, 104, 97, 97, 76,
95, 81, 112, 103, 125]转为字符:QNFPGS{Ju0_1fZn1a@aq_ShaaL_Qpg}
再经过一次rot13就得到flag
buildctf ez_asm
给的是一个txt文件,是从ida上直接复制来的,使用arm指令集
首先找到main函数,要求输入33位flag,然后对其进行encrypt,最后把加密结果和密文全部乘以10再比较应该是精度问题.
.text:0000000000000CC4 ; int __fastcall main(int argc, const char **argv, const char **envp)
.text:0000000000000CC4 EXPORT main
.text:0000000000000CC4 main ; DATA XREF: .got:main_ptr↓o
.text:0000000000000CC4
.text:0000000000000CC4 var_1A0 = -0x1A0
.text:0000000000000CC4 var_198 = -0x198
.text:0000000000000CC4 var_190 = -0x190
.text:0000000000000CC4 dest = -0x180
.text:0000000000000CC4 s = -0x78
.text:0000000000000CC4 ptr = -0x10
.text:0000000000000CC4 var_8 = -8
.text:0000000000000CC4 var_4 = -4
.text:0000000000000CC4
.text:0000000000000CC4 ; __unwind {
.text:0000000000000CC4 STP X29, X30, [SP,#var_1A0]!
.text:0000000000000CC8 MOV X29, SP
.text:0000000000000CCC STR D8, [SP,#0x1A0+var_190]
.text:0000000000000CD0 ADRL X0, aPlzInputFlag ; "plz input flag:"
.text:0000000000000CD8 BL .printf
.text:0000000000000CDC ADD X0, SP, #0x1A0+s
.text:0000000000000CE0 MOV X1, X0
.text:0000000000000CE4 ADRL X0, aS ; "%s"
.text:0000000000000CEC BL .scanf
.text:0000000000000CF0 ADD X0, SP, #0x1A0+s ; s
.text:0000000000000CF4 BL .strlen
.text:0000000000000CF8 STR W0, [SP,#0x1A0+var_8]
.text:0000000000000CFC LDR W0, [SP,#0x1A0+var_8]
.text:0000000000000D00 CMP W0, #0x20 ; ' '
.text:0000000000000D04 B.GT loc_D14
.text:0000000000000D08 ADRL X0, aLenthError ; "lenth error"
.text:0000000000000D10 BL .printf
.text:0000000000000D14
.text:0000000000000D14 loc_D14 ; CODE XREF: main+40↑j
.text:0000000000000D14 LDRSW X0, [SP,#0x1A0+var_8]
.text:0000000000000D18 LSL X0, X0, #3 ; size
.text:0000000000000D1C BL .malloc
.text:0000000000000D20 STR X0, [SP,#0x1A0+ptr]
.text:0000000000000D24 ADRP X0, #unk_E48@PAGE
.text:0000000000000D28 ADD X1, X0, #unk_E48@PAGEOFF
.text:0000000000000D2C ADD X0, SP, #0x1A0+dest ; dest
.text:0000000000000D30 MOV X3, X1
.text:0000000000000D34 MOV X1, #0x108
.text:0000000000000D38 MOV X2, X1 ; n
.text:0000000000000D3C MOV X1, X3 ; src
.text:0000000000000D40 BL .memcpy
.text:0000000000000D44 ADD X0, SP, #0x1A0+s ; char *
.text:0000000000000D48 LDR W2, [SP,#0x1A0+var_8] ; int
.text:0000000000000D4C LDR X1, [SP,#0x1A0+ptr] ; double *
.text:0000000000000D50 BL _Z7encryptPKcPdi ; encrypt(char const*,double *,int)
.text:0000000000000D54 STR WZR, [SP,#0x1A0+var_4]
.text:0000000000000D58
.text:0000000000000D58 loc_D58 ; CODE XREF: main+124↓j
.text:0000000000000D58 LDR W1, [SP,#0x1A0+var_4]
.text:0000000000000D5C LDR W0, [SP,#0x1A0+var_8]
.text:0000000000000D60 CMP W1, W0
.text:0000000000000D64 B.GE loc_DEC
.text:0000000000000D68 LDRSW X0, [SP,#0x1A0+var_4]
.text:0000000000000D6C LSL X0, X0, #3
.text:0000000000000D70 LDR X1, [SP,#0x1A0+ptr]
.text:0000000000000D74 ADD X0, X1, X0
.text:0000000000000D78 LDR D0, [X0]
.text:0000000000000D7C MOV X0, #0x412E848000000000
.text:0000000000000D84 FMOV D1, X0
.text:0000000000000D88 FMUL D0, D0, D1 ; x
.text:0000000000000D8C BL .round
.text:0000000000000D90 FMOV D8, D0
.text:0000000000000D94 LDRSW X0, [SP,#0x1A0+var_4]
.text:0000000000000D98 LSL X0, X0, #3
.text:0000000000000D9C ADD X1, SP, #0x1A0+dest
.text:0000000000000DA0 LDR D0, [X1,X0]
.text:0000000000000DA4 MOV X0, #0x412E848000000000
.text:0000000000000DAC FMOV D1, X0
.text:0000000000000DB0 FMUL D0, D0, D1 ; x
.text:0000000000000DB4 BL .round
.text:0000000000000DB8 FCMP D8, D0
.text:0000000000000DBC B.EQ loc_DD8
.text:0000000000000DC0 LDR W1, [SP,#0x1A0+var_4]
.text:0000000000000DC4 ADRL X0, aError ; "error\n"
.text:0000000000000DCC BL .printf
.text:0000000000000DD0 MOV W0, #0
.text:0000000000000DD4 B loc_E04
.text:0000000000000DD8 ; ---------------------------------------------------------------------------
.text:0000000000000DD8
.text:0000000000000DD8 loc_DD8 ; CODE XREF: main+F8↑j
.text:0000000000000DD8 NOP
.text:0000000000000DDC LDR W0, [SP,#0x1A0+var_4]
.text:0000000000000DE0 ADD W0, W0, #1
.text:0000000000000DE4 STR W0, [SP,#0x1A0+var_4]
.text:0000000000000DE8 B loc_D58
.text:0000000000000DEC ; ---------------------------------------------------------------------------
.text:0000000000000DEC
.text:0000000000000DEC loc_DEC ; CODE XREF: main+A0↑j
.text:0000000000000DEC ADRL X0, aRight ; "right!"
.text:0000000000000DF4 BL .puts
.text:0000000000000DF8 LDR X0, [SP,#0x1A0+ptr] ; ptr
.text:0000000000000DFC BL .free
.text:0000000000000E00 MOV W0, #0
.text:0000000000000E04
.text:0000000000000E04 loc_E04 ; CODE XREF: main+110↑j
.text:0000000000000E04 LDR D8, [SP,#0x1A0+var_190]
.text:0000000000000E08 LDP X29, X30, [SP+0x1A0+var_1A0],#0x1A0
.text:0000000000000E0C RET
.text:0000000000000E0C ; } // starts at CC4
.text:0000000000000E0C ; End of function main
.text:0000000000000E0C
.text:0000000000000E0C ; .text ends
接下来找到encrypt函数,其实就只是调用dct函数对输入进行加密
.text:0000000000000B84 ; __int64 __fastcall encrypt(const char *, double *, int)
.text:0000000000000B84 EXPORT _Z7encryptPKcPdi
.text:0000000000000B84 _Z7encryptPKcPdi ; CODE XREF: main+8C↓p
.text:0000000000000B84
.text:0000000000000B84 var_40 = -0x40
.text:0000000000000B84 var_38 = -0x38
.text:0000000000000B84 var_24 = -0x24
.text:0000000000000B84 var_20 = -0x20
.text:0000000000000B84 var_18 = -0x18
.text:0000000000000B84 ptr = -0x10
.text:0000000000000B84 var_4 = -4
.text:0000000000000B84
.text:0000000000000B84 ; __unwind {
.text:0000000000000B84 STP X29, X30, [SP,#var_40]!
.text:0000000000000B88 MOV X29, SP
.text:0000000000000B8C STR X0, [SP,#0x40+var_18]
.text:0000000000000B90 STR X1, [SP,#0x40+var_20]
.text:0000000000000B94 STR W2, [SP,#0x40+var_24]
.text:0000000000000B98 LDRSW X0, [SP,#0x40+var_24]
.text:0000000000000B9C LSL X0, X0, #3 ; size
.text:0000000000000BA0 BL .malloc
.text:0000000000000BA4 STR X0, [SP,#0x40+ptr]
.text:0000000000000BA8 STR WZR, [SP,#0x40+var_4]
.text:0000000000000BAC
.text:0000000000000BAC loc_BAC ; CODE XREF: encrypt(char const*,double *,int)+6C↓j
.text:0000000000000BAC LDR W1, [SP,#0x40+var_4]
.text:0000000000000BB0 LDR W0, [SP,#0x40+var_24]
.text:0000000000000BB4 CMP W1, W0
.text:0000000000000BB8 B.GE loc_BF4
.text:0000000000000BBC LDRSW X0, [SP,#0x40+var_4]
.text:0000000000000BC0 LDR X1, [SP,#0x40+var_18]
.text:0000000000000BC4 ADD X0, X1, X0
.text:0000000000000BC8 LDRB W1, [X0]
.text:0000000000000BCC LDRSW X0, [SP,#0x40+var_4]
.text:0000000000000BD0 LSL X0, X0, #3
.text:0000000000000BD4 LDR X2, [SP,#0x40+ptr]
.text:0000000000000BD8 ADD X0, X2, X0
.text:0000000000000BDC UCVTF D0, W1
.text:0000000000000BE0 STR D0, [X0]
.text:0000000000000BE4 LDR W0, [SP,#0x40+var_4]
.text:0000000000000BE8 ADD W0, W0, #1
.text:0000000000000BEC STR W0, [SP,#0x40+var_4]
.text:0000000000000BF0 B loc_BAC
.text:0000000000000BF4 ; ---------------------------------------------------------------------------
.text:0000000000000BF4
.text:0000000000000BF4 loc_BF4 ; CODE XREF: encrypt(char const*,double *,int)+34↑j
.text:0000000000000BF4 LDR W2, [SP,#0x40+var_24] ; int
.text:0000000000000BF8 LDR X1, [SP,#0x40+var_20] ; double *
.text:0000000000000BFC LDR X0, [SP,#0x40+ptr] ; double *
.text:0000000000000C00 BL _Z3dctPdS_i ; dct(double *,double *,int)
.text:0000000000000C04 LDR X0, [SP,#0x40+ptr] ; ptr
.text:0000000000000C08 BL .free
.text:0000000000000C0C NOP
.text:0000000000000C10 LDP X29, X30, [SP+0x40+var_40],#0x40
.text:0000000000000C14 RET
.text:0000000000000C14 ; } // starts at B84
.text:0000000000000C14 ; End of function encrypt(char const*,double *,int)
至于dct,经过大致阅读后发现和我们所写的加密算法是一致的,那么就可以直接利用idct来解密
.text:00000000000008D8 ; __int64 __fastcall dct(double *, double *, int)
.text:00000000000008D8 EXPORT _Z3dctPdS_i
.text:00000000000008D8 _Z3dctPdS_i ; CODE XREF: encrypt(char const*,double *,int)+7C↓p
.text:00000000000008D8
.text:00000000000008D8 var_60 = -0x60
.text:00000000000008D8 var_58 = -0x58
.text:00000000000008D8 var_50 = -0x50
.text:00000000000008D8 var_34 = -0x34
.text:00000000000008D8 var_30 = -0x30
.text:00000000000008D8 var_28 = -0x28
.text:00000000000008D8 var_18 = -0x18
.text:00000000000008D8 var_10 = -0x10
.text:00000000000008D8 var_8 = -8
.text:00000000000008D8 var_4 = -4
.text:00000000000008D8
.text:00000000000008D8 ; __unwind {
.text:00000000000008D8 STP X29, X30, [SP,#var_60]!
.text:00000000000008DC MOV X29, SP
.text:00000000000008E0 STR D8, [SP,#0x60+var_50]
.text:00000000000008E4 STR X0, [SP,#0x60+var_28]
.text:00000000000008E8 STR X1, [SP,#0x60+var_30]
.text:00000000000008EC STR W2, [SP,#0x60+var_34]
.text:00000000000008F0 LDR W0, [SP,#0x60+var_34]
.text:00000000000008F4 SCVTF D0, W0
.text:00000000000008F8 FMOV D1, #2.0
.text:00000000000008FC FDIV D0, D1, D0 ; x
.text:0000000000000900 BL .sqrt
.text:0000000000000904 STR D0, [SP,#0x60+var_18]
.text:0000000000000908 STR WZR, [SP,#0x60+var_4]
.text:000000000000090C
.text:000000000000090C loc_90C ; CODE XREF: dct(double *,double *,int)+138↓j
.text:000000000000090C LDR W1, [SP,#0x60+var_4]
.text:0000000000000910 LDR W0, [SP,#0x60+var_34]
.text:0000000000000914 CMP W1, W0
.text:0000000000000918 B.GE loc_A14
.text:000000000000091C STR XZR, [SP,#0x60+var_10]
.text:0000000000000920 STR WZR, [SP,#0x60+var_8]
.text:0000000000000924
.text:0000000000000924 loc_924 ; CODE XREF: dct(double *,double *,int)+C4↓j
.text:0000000000000924 LDR W1, [SP,#0x60+var_8]
.text:0000000000000928 LDR W0, [SP,#0x60+var_34]
.text:000000000000092C CMP W1, W0
.text:0000000000000930 B.GE loc_9A0
.text:0000000000000934 LDRSW X0, [SP,#0x60+var_8]
.text:0000000000000938 LSL X0, X0, #3
.text:000000000000093C LDR X1, [SP,#0x60+var_28]
.text:0000000000000940 ADD X0, X1, X0
.text:0000000000000944 LDR D8, [X0]
.text:0000000000000948 LDR W0, [SP,#0x60+var_8]
.text:000000000000094C SCVTF D1, W0
.text:0000000000000950 FMOV D0, #0.5
.text:0000000000000954 FADD D0, D1, D0
.text:0000000000000958 ADRP X0, #qword_F50@PAGE
.text:000000000000095C LDR D1, [X0,#qword_F50@PAGEOFF]
.text:0000000000000960 FMUL D1, D0, D1
.text:0000000000000964 LDR W0, [SP,#0x60+var_4]
.text:0000000000000968 SCVTF D0, W0
.text:000000000000096C FMUL D1, D1, D0
.text:0000000000000970 LDR W0, [SP,#0x60+var_34]
.text:0000000000000974 SCVTF D0, W0
.text:0000000000000978 FDIV D0, D1, D0 ; x
.text:000000000000097C BL .cos
.text:0000000000000980 FMUL D0, D8, D0
.text:0000000000000984 LDR D1, [SP,#0x60+var_10]
.text:0000000000000988 FADD D0, D1, D0
.text:000000000000098C STR D0, [SP,#0x60+var_10]
.text:0000000000000990 LDR W0, [SP,#0x60+var_8]
.text:0000000000000994 ADD W0, W0, #1
.text:0000000000000998 STR W0, [SP,#0x60+var_8]
.text:000000000000099C B loc_924
.text:00000000000009A0 ; ---------------------------------------------------------------------------
.text:00000000000009A0
.text:00000000000009A0 loc_9A0 ; CODE XREF: dct(double *,double *,int)+58↑j
.text:00000000000009A0 LDR W0, [SP,#0x60+var_4]
.text:00000000000009A4 CMP W0, #0
.text:00000000000009A8 B.NE loc_9E4
.text:00000000000009AC LDR W0, [SP,#0x60+var_34]
.text:00000000000009B0 SCVTF D0, W0
.text:00000000000009B4 FMOV D1, #1.0
.text:00000000000009B8 FDIV D0, D1, D0 ; x
.text:00000000000009BC BL .sqrt
.text:00000000000009C0 FMOV D1, D0
.text:00000000000009C4 LDRSW X0, [SP,#0x60+var_4]
.text:00000000000009C8 LSL X0, X0, #3
.text:00000000000009CC LDR X1, [SP,#0x60+var_30]
.text:00000000000009D0 ADD X0, X1, X0
.text:00000000000009D4 LDR D0, [SP,#0x60+var_10]
.text:00000000000009D8 FMUL D0, D1, D0
.text:00000000000009DC STR D0, [X0]
.text:00000000000009E0 B loc_A04
.text:00000000000009E4 ; ---------------------------------------------------------------------------
.text:00000000000009E4
.text:00000000000009E4 loc_9E4 ; CODE XREF: dct(double *,double *,int)+D0↑j
.text:00000000000009E4 LDRSW X0, [SP,#0x60+var_4]
.text:00000000000009E8 LSL X0, X0, #3
.text:00000000000009EC LDR X1, [SP,#0x60+var_30]
.text:00000000000009F0 ADD X0, X1, X0
.text:00000000000009F4 LDR D1, [SP,#0x60+var_10]
.text:00000000000009F8 LDR D0, [SP,#0x60+var_18]
.text:00000000000009FC FMUL D0, D1, D0
.text:0000000000000A00 STR D0, [X0]
.text:0000000000000A04
.text:0000000000000A04 loc_A04 ; CODE XREF: dct(double *,double *,int)+108↑j
.text:0000000000000A04 LDR W0, [SP,#0x60+var_4]
.text:0000000000000A08 ADD W0, W0, #1
.text:0000000000000A0C STR W0, [SP,#0x60+var_4]
.text:0000000000000A10 B loc_90C
.text:0000000000000A14 ; ---------------------------------------------------------------------------
.text:0000000000000A14
.text:0000000000000A14 loc_A14 ; CODE XREF: dct(double *,double *,int)+40↑j
.text:0000000000000A14 NOP
.text:0000000000000A18 LDR D8, [SP,#0x60+var_50]
.text:0000000000000A1C LDP X29, X30, [SP+0x60+var_60],#0x60
.text:0000000000000A20 RET
.text:0000000000000A20 ; } // starts at 8D8
.text:0000000000000A20 ; End of function dct(double *,double *,int)
exp
把数据提取出来再8字节一组转为浮点数
import struct
import numpy as np
import math
enc = [0x4E ,0x7B ,0x4A ,0xCE ,0x89 ,0x69 ,0x80 ,0x40 ,0xB5 ,0xDF ,0xDA ,0x89 ,0x92 , 8 ,0x2E ,0x40 ,0x3D ,0xEF ,0xC6 ,0x82 ,0xC2 ,0xD0 ,0x3E ,0xC0 ,0x43 ,0x3B ,0xA7 ,0x59 ,0xA0 ,0xBD ,0x3A ,0x40 ,0xA7 ,0x5B ,0x76 ,0x88 ,0x7F ,0xD8 ,0x2E ,0x40 ,0xE4 ,0x12 ,0x47 ,0x1E ,0x88 ,0x5C ,0x1F ,0xC0 ,0x3D ,0x82 ,0x1B ,0x29 ,0x5B ,0x28 ,0x40 ,0x40 ,0x65 ,0x8C , 0xF ,0xB3 ,0x97 ,0xC3 ,0x43 ,0xC0 ,0xA0 ,0x17 ,0xEE ,0x5C ,0x18 ,0x29 ,0x29 ,0x40 ,0xEC ,0x13 ,0x40 ,0x31 ,0xB2 ,0xC6 ,0x47 ,0xC0 ,0x16 ,0xDB ,0xA4 ,0xA2 ,0xB1 ,0x8E ,0x38 ,0x40 ,0xB6 ,0xA2 ,0xCD ,0x71 ,0x6E ,0xB3 ,0x1E ,0xC0 ,0xD2 ,0xC5 ,0xA6 ,0x95 ,0x42 ,0x4E ,0x46 ,0xC0 ,0x8F ,0x37 ,0xF9 ,0x2D ,0x3A ,0xB1 ,0x39 ,0xC0 ,0xD7 ,0x16 ,0x9E ,0x97 ,0x8A ,0x79 ,0x37 ,0xC0 ,0x22 ,0x89 ,0x5E ,0x46 ,0xB1 ,0xE0 ,0x34 ,0x40 ,0xAE , 0xF ,0xEB ,0x8D ,0x5A ,0x8D ,0x31 ,0x40 ,0xFD ,0xF8 ,0x4B ,0x8B ,0xFA ,0x24 ,0x1A ,0xC0 , 4 ,0x75 ,0xCA ,0xA3 ,0x1B ,0xA1 ,0x1E ,0x40 ,0x93 , 1 ,0xA0 ,0x8A ,0x1B , 9 ,0x48 ,0xC0 ,0x33 ,0xDF ,0xC1 ,0x4F ,0x1C ,0x28 ,0x21 ,0x40 ,0x2A ,0xE5 ,0xB5 ,0x12 ,0xBA ,0xDF ,0x41 ,0xC0 ,0x16 ,0x32 ,0x57 , 6 ,0xD5 ,0x86 ,0x1E ,0x40 ,0x7C ,0x65 ,0xDE ,0xAA ,0xEB ,0xDC ,0x39 ,0x40 , 5 ,0xA3 ,0x92 ,0x3A , 1 ,0x4D ,0x16 ,0x40 ,0xE4 ,0x4A ,0x3D , 0xB ,0x42 ,0xF9 ,0x46 ,0xC0 ,0xA4 ,0x50 ,0x16 ,0xBE ,0xBE ,0x66 ,0x40 ,0xC0 ,0xD5 ,0x42 ,0xC9 ,0xE4 ,0xD4 ,0xDE ,0x12 ,0xC0 ,0xEB ,0x6F , 9 ,0xC0 ,0x3F ,0x45 ,0x30 ,0x40 ,0x1C ,0x95 ,0x9B ,0xA8 ,0xA5 ,0x69 ,0x1F ,0xC0 ,0x3F ,0x39 , 0xA ,0x10 , 5 ,0xF3 ,0xF3 ,0x3F ,0x11 ,0xA6 ,0x28 ,0x97 ,0xC6 , 0xF , 0xB ,0x40 , 0xA ,0x66 ,0x4C ,0xC1 ,0x1A ,0x67 ,0x3E ,0x40]
def hex_to_float(enc):
floats = []
for i in range(0, len(enc), 8):
byte_chunk = enc[i:i+8]
packed = bytes(byte_chunk)
float_value = struct.unpack('d', packed)[0]
floats.append(float_value)
return floats
def idct(x):
result = []
size = len(x)
for i in range(size):
sum = 0
for j in range(size):
v1 = math.cos((i + 0.5) * math.pi * j / size)
if j == 0:
v2 = math.sqrt(1 / size)
else:
v2 = math.sqrt(2 / size)
v3 = x[j]*v2
sum += v3 * v1
result.append(sum)
return result
float_values = hex_to_float(enc)
x = np.array(float_values)
print(np.round(idct(x)))
解密得到数组[ 66, 117, 105, 108, 100, 67, 84, 70, 123, 72, 48, 118, 118, 95,
119, 48, 110, 100, 101, 118, 102, 85, 108, 95, 97, 114, 109, 38,
38, 68, 84, 67, 125],转为字符串得到flag: BuildCTF{H0vv_w0ndevfUl_arm&&DTC}