0x00 前言

学习大佬WP后的自己复现

首先解释一下IDA的两个功能

C指令

把当前的数据按照代码(code)的形式来显示

D指令

把当前的数据用数据(data)的形式来显示

0x01 small

拿到附件Die查个壳 64位无壳ELF二进制文件

xpvpXn.png

丢IDA

xpvCmq.png

在IDA View界面地址处按C转换汇编代码

xpvS6s.png

xpjzlj.png

分析一下汇编代码

关键 add , mov , xor

可以看到一开始 add 了一个 67452301h

下面又 add 了四个较小的数

猜测可能是TEA加密的delta和4个key

然后在IDA view界面按D 找到密文 (暂时没想通为什么秘文是good后面的字符)

x9p5L9.png

然后进行TEA解密

大佬脚本如下

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
#include <stdio.h>
#include <stdint.h>//加密函数
void encrypt(unsigned int num_rounds, uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0, i;
uint32_t delta = 0x67452301;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i < num_rounds; i++) {
sum += delta;
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
}
v[0] = v0; v[1] = v1;
}
//解密函数
void decrypt(unsigned int num_rounds, uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], i;
uint32_t delta = 0x67452301,sum = delta*num_rounds;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i<num_rounds; i++) {
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
}
v[0] = v0; v[1] = v1;
}
//打印数据 hex_or_chr: 1-hex 0-chr
void dump_data(uint32_t * v,int n,bool hex_or_chr)
{
if(hex_or_chr)
{
for(int i=0;i<n;i++)
{
printf("0x%x,",v[i]);
}
}
else
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < sizeof(uint32_t)/sizeof(uint8_t); j++)
{
printf("%c", (v[i] >> (j * 8)) & 0xFF);
}
}
}
printf("\n");
return;
}
int main()
{
// v 为要加解密的数据
uint32_t v[] =
{ 0xde087143,0xc4f91bd2,0xdaf6dadc,0x6d9ed54c,0x75eb4ee7,0x5d1ddc04,0x511b0fd9,0x51dc88fb };
// k 为加解密密钥, 4 个 32 位无符号整数,密钥长度为 128 位
uint32_t k[4] = { 0x01,0x23,0x45,0x67 };
// num_rounds,建议取值为 32
unsigned int r = 35;
int n = sizeof(v) / sizeof(uint32_t);
/*
printf("加密前明文数据: ");
dump_data(v,n,1);
for(int i=0;i<n/2;i++)
{
encrypt(r,&v[i*2], k);
}
printf("加密后密文数据: ");
dump_data(v,n,1);
*/
for(int i=0;i<n/2;i++)
{
decrypt(r,&v[i*2], k);
}
printf("解密后明文数据: ");
dump_data(v,n,1);
printf("解密后明文字符: ");
dump_data(v,n,0);
return 0;
}