另外那个签到就不说了

easystd

img

这里可以看到用的是so层的函数

img

分析加密

核心加密逻辑:

img

每4字节字节加密,通过前4个取得下一个

每轮的伪代码类似于:

1
2
3
key = input[i+1]^input[i+2]^input[i+3]^Abox[i]
mid = xxxx(key)
output = mid^input[i]

ARM汇编看不了一点,所以只能全靠猜,最后还是在za师傅的协助下完成了,好耶!

取得最后的输出然后写脚本逆向即可:

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include<iostream>
#include<Windows.h>
#include<cstdlib>
UINT8 change_box[] = { 0xD1, 0x97, 0xEE, 0xF9, 0xCB, 0xE6, 0x3A, 0xB0, 0x11, 0xB1, 0x13, 0xC5, 0x2F, 0xFC, 0x2B, 0x02, 0x2C, 0x60, 0x9D, 0x71, 0x2D, 0xB9, 0x03, 0xC4, 0xAD, 0x43, 0x14, 0x21, 0x4E, 0x81, 0x01, 0x9E, 0x9B, 0x45, 0x57, 0xF3, 0x96, 0xE8, 0x9F, 0x7D, 0x34, 0x53, 0x0C, 0x44, 0xEA, 0xC8, 0xAB, 0x65, 0xE3, 0xB4, 0x1B, 0xAE, 0xCE, 0x0F, 0xEF, 0x92, 0x87, 0xD8, 0x93, 0xFD, 0x72, 0x88, 0x38, 0xA1, 0x40, 0x00, 0xA0, 0xFB, 0xF4, 0x74, 0x10, 0xBD, 0x84, 0x5E, 0x3B, 0x1E, 0xE1, 0x82, 0x48, 0xAF, 0x6F, 0x6C, 0x86, 0xB5, 0x76, 0x63, 0xDD, 0x8C, 0xFF, 0xEC, 0x08, 0x4C, 0x77, 0x51, 0x9A, 0x32, 0x19, 0x23, 0x09, 0x59, 0x64, 0x5F, 0xD6, 0xA5, 0x22, 0x25, 0x7B, 0x3C, 0x06, 0x26, 0x7F, 0x80, 0xD3, 0x07, 0x41, 0x50, 0x98, 0xD4, 0x20, 0x55, 0x4B, 0x31, 0x05, 0xE0, 0xA7, 0xC3, 0xCF, 0x99, 0xED, 0xB8, 0x8D, 0xD5, 0x47, 0xC0, 0x3F, 0xB2, 0xA4, 0xF0, 0xF5, 0xC9, 0xFE, 0x66, 0x12, 0xA6, 0xE7, 0xA9, 0x5A, 0xA3, 0x9C, 0x33, 0x1D, 0x52, 0xAA, 0x94, 0x35, 0x37, 0xF2, 0x8B, 0xB6, 0xE4, 0x1A, 0xF1, 0xE5, 0x29, 0x85, 0x61, 0xCD, 0x67, 0xC7, 0x2E, 0x24, 0xAC, 0x0A, 0x54, 0x49, 0x68, 0xD2, 0xDC, 0x30, 0x42, 0xD9, 0xFA, 0x89, 0x28, 0x04, 0xF8, 0x6D, 0x75, 0x6A, 0x6B, 0x5C, 0x56, 0x8A, 0x1C, 0xA8, 0x95, 0xBC, 0xDA, 0xBB, 0x78, 0x16, 0xDE, 0x5B, 0x46, 0x18, 0x17, 0x5D, 0xDF, 0x0D, 0xC6, 0x36, 0x8F, 0xA2, 0xCA, 0x7C, 0xBA, 0x2A, 0x73, 0xD7, 0x15, 0xBF, 0xE2, 0xB3, 0xB7, 0x8E, 0x6E, 0x90, 0x4D, 0x0B, 0x91, 0x70, 0x79, 0x62, 0xBE, 0xF6, 0x0E, 0xC2, 0x69, 0xC1, 0x83, 0x1F, 0xF7, 0x7A, 0xEB, 0x3D, 0xDB, 0x4A, 0x27, 0x7E, 0xE9, 0x58, 0x39, 0xD0, 0xCC, 0x3E, 0x4F };
UINT32 xor_box[] = { 0x80A3B97F, 0xB9D4ECD6, 0x7425ECAA, 0x339BD365, 0xA5D18B13, 0x56A7A4DE, 0xE907C73E, 0xD0AA04A9, 0x6C827F28, 0xE997196A, 0x0C2F2AD8, 0xFD9D6DA5, 0x164DDA6D, 0x5FDCC2A4, 0x489987B7, 0xFDEF5978, 0x96C21ACA, 0x7FF46259, 0xB9ADC94E, 0x47FB566D, 0x8CCFC943, 0x8DA5E336, 0x1B49D41B, 0x6647A175, 0xC3DE9068, 0xF6708794, 0xE94AB191, 0x540B89A4, 0xB6ABA320, 0x2A7764D0, 0xEDC490A7, 0xC1F6DA35 };
unsigned int last[12] = {
0x2DF2B839, 0x4CA553D7, 0x72FC8455, 0xBFEC6CFF, 0x597F4EE6, 0x9EC140C6, 0xB1E70DEA, 0xBFDC0DAB,
0xD05154AF, 0x25A2F8C6, 0x36A4EE33, 0xD116C3F1
};

unsigned int lastb[12] = { 0x39B8F22D,0xD753A54C,0x5584FC72,0xFF6CECBF,0xE64E7F59,0xC640C19E,0xEA0DE7B1,0xAB0DDCBF,0xAF5451D0,0xC6F8A225,0x33EEA436,0xF1C316D1 };

#define PAIR64(high, low) (((uint64_t)(high) << 32) | (uint32_t)(low))
UINT64 get(int index) {
return change_box[index & 0xff] ^ 7;
}

void enc(UINT32* input) {
UINT32 changer, p2, p4, p3, p1;


for (int i = 0; i < 32; i++)
{
p1 = input[i];
p2 = input[i + 1];
p3 = input[i + 2];
p4 = input[i + 3];
UINT32 m = p2 ^ p3 ^ p4 ^ xor_box[i];
UINT32* pm = &m;
UINT8* p = (UINT8*)pm;
UINT32 need1 = get(p[3]);
UINT32 need2 = (need1 << 24) | (get(p[2]) << 16);
UINT32 cul_num1 = (get(p[3]) << 24) | (get(p[2]) << 16) | (get(p[1]) << 8) | get(p[0]);
UINT64 cul_num2 = ((get(p[0]) << 24) | (get(p[3]) << 16) | (get(p[2]) << 8) | get(p[1])) << 8;
UINT32 final_enc = cul_num1 ^ (cul_num2 >> 8) ^ p1 ^ ((need1 >> 6) | cul_num1 << 2) ^ (PAIR64(cul_num1, need2) >> 22) ^ (PAIR64(cul_num1, cul_num2) >> 14);

//std::cout << "0x" << std::hex << final_enc << " ,";
input[i + 4] = final_enc;
}
std::cout << std::endl;

}

void dec(UINT* input) {
UINT32 changer, p2, p4, p3, p1;
UINT32 out[5] = {};
for (int i = 35; i > 3; i--) {
p1 = input[i - 3];
p2 = input[i - 2];
p3 = input[i - 1];
p4 = input[i];

UINT32 m = p1 ^ p2 ^ p3 ^ xor_box[i - 4];
UINT32* pm = &m;
UINT8* p = (UINT8*)pm;
UINT32 need1 = get(p[3]);
UINT32 need2 = (need1 << 24) | (get(p[2]) << 16);
UINT32 cul_num1 = (get(p[3]) << 24) | (get(p[2]) << 16) | (get(p[1]) << 8) | get(p[0]);
UINT64 cul_num2 = ((get(p[0]) << 24) | (get(p[3]) << 16) | (get(p[2]) << 8) | get(p[1])) << 8;
UINT32 final_dec = cul_num1 ^ (cul_num2 >> 8) ^ p4 ^ ((need1 >> 6) | cul_num1 << 2) ^ (PAIR64(cul_num1, need2) >> 22) ^ (PAIR64(cul_num1, cul_num2) >> 14);

if (i < 8) {
out[i - 4] = final_dec;
input[i - 4] = final_dec;
}
else
{
input[i - 4] = final_dec;
}
//std::cout << "0x" << std::hex << final_dec << " ";
}

//std::cout << std::endl;
//std::cout << "0x" << std::hex << out[0] << "0x" << std::hex << out[1] << "0x" << std::hex << out[2] << "0x" << std::hex << out[3];
std::cout << (char*)out << std::endl;
}

int main(void) {
//UINT32 input_num[36] = { 0x31323334, 0x31323334, 0x35363738, 0x35363738 };
//UINT32 encn[36] = {};
//for (int i = 0; i < 4; i++)
//{
// encn[i] = input_num[i];
//}
//enc(encn);
//UINT32 lll[32] = { 0xee53ae6d ,0xad8d58d3 ,0xe904c44a ,0xffa30914 ,0xa34d50fe ,0x6d0b76d8 ,0x93d7b44c ,0x9f34dba ,0x43f64ea2 ,0xd2961d0a ,0xabc12a71 ,0x5506c498 ,0xe60804c1 ,0x6fab9817 ,0xa680fb2e ,0xc903775d ,0xacae3b34 ,0x564cb9a3 ,0x93db754a ,0x66321125 ,0xbc6fcb43 ,0x5a069224 ,0x3661a351 ,0xa06815fb ,0xa7096626 ,0xc78b501 ,0xf9d14107 ,0x1ecbf7c7 ,0xd23229c8 ,0xf04e9414 ,0x4eee3557 ,0xd01d30b3 };
//for (int i = 0; i < 32; i++)
//{
// encn[i] = 0;
//}
//dec(encn);
for (int i = 0; i < 12; i += 4)
{
UINT32 tround[36] = {};
tround[32] = lastb[i + 3];
tround[33] = lastb[i + 2];
tround[34] = lastb[i + 1];
tround[35] = lastb[i];
dec(tround);
}

}

注意最后输出顺序是倒序输出,当时被这个坑了


最后看完其它人的wp发现这个就是个SM4,我白学了QAQ