TEA,XTEA,XXTEA,c语言代码,汇编代码区别
-
前言:本文只对这三个加密进行表层的了解,不进行原理上的剖析
-
TEA
1 2 3 4 5 6 7 8 9 10 11void tea_encrypt(uint32_t v[2], uint32_t k[4]) { uint32_t v0 = v[0], v1 = v[1], sum = 0; uint32_t delta = 0x9e3779b9; for (int i = 0; i < 32; i++) { sum += delta; v0 += ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]); v1 += ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]); } v[0] = v0; v[1] = v1; } -
XTEA
1 2 3 4 5 6 7 8 9 10 11void xtea_encrypt(uint32_t v[2], uint32_t k[4]) { uint32_t v0 = v[0], v1 = v[1], sum = 0; uint32_t delta = 0x9e3779b9; for (int i = 0; i < 32; i++) { v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); sum += delta; v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]); } v[0] = v0; v[1] = v1; } -
XXTEA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20#define MX ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (k[(p & 3) ^ e] ^ z)) void xxtea_encrypt(uint32_t *v, int n, uint32_t k[4]) { uint32_t y, z, sum = 0; uint32_t delta = 0x9e3779b9; int p, rounds = 6 + 52 / n; z = v[n - 1]; do { sum += delta; uint32_t e = (sum >> 2) & 3; for (p = 0; p < n - 1; p++) { y = v[p + 1]; z = v[p] += MX; } y = v[0]; z = v[n - 1] += MX; } while (--rounds); } -
TEA的x86-64汇编实现
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138; TEA加密函数 - x86-64汇编 ; 参数: RDI=v[2], RSI=k[4] tea_encrypt: push rbx push r12 push r13 push r14 ; 加载数据 mov eax, [rdi] ; v0 mov ebx, [rdi+4] ; v1 mov r12d, [rsi] ; k[0] mov r13d, [rsi+4] ; k[1] mov r14d, [rsi+8] ; k[2] mov r15d, [rsi+12] ; k[3] xor ecx, ecx ; sum = 0 mov edx, 0x9e3779b9 ; delta mov r8d, 32 ; 循环计数器 .tea_loop: ; sum += delta add ecx, edx ; v0 += ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]) mov r9d, ebx ; v1 shl r9d, 4 add r9d, r12d ; (v1 << 4) + k[0] mov r10d, ebx ; v1 add r10d, ecx ; v1 + sum mov r11d, ebx ; v1 shr r11d, 5 add r11d, r13d ; (v1 >> 5) + k[1] xor r9d, r10d xor r9d, r11d add eax, r9d ; 更新v0 ; v1 += ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]) mov r9d, eax ; v0 shl r9d, 4 add r9d, r14d ; (v0 << 4) + k[2] mov r10d, eax ; v0 add r10d, ecx ; v0 + sum mov r11d, eax ; v0 shr r11d, 5 add r11d, r15d ; (v0 >> 5) + k[3] xor r9d, r10d xor r9d, r11d add ebx, r9d ; 更新v1 dec r8d jnz .tea_loop ; 存储结果 mov [rdi], eax mov [rdi+4], ebx pop r14 pop r13 pop r12 pop rbx ret ; TEA解密函数 tea_decrypt: push rbx push r12 push r13 push r14 ; 加载数据 mov eax, [rdi] ; v0 mov ebx, [rdi+4] ; v1 mov r12d, [rsi] ; k[0] mov r13d, [rsi+4] ; k[1] mov r14d, [rsi+8] ; k[2] mov r15d, [rsi+12] ; k[3] mov ecx, 0xC6EF3720 ; sum = delta * 32 mov edx, 0x9e3779b9 ; delta mov r8d, 32 ; 循环计数器 .tea_decrypt_loop: ; v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]) mov r9d, eax ; v0 shl r9d, 4 add r9d, r14d ; (v0 << 4) + k[2] mov r10d, eax ; v0 add r10d, ecx ; v0 + sum mov r11d, eax ; v0 shr r11d, 5 add r11d, r15d ; (v0 >> 5) + k[3] xor r9d, r10d xor r9d, r11d sub ebx, r9d ; 更新v1 ; sum -= delta sub ecx, edx ; v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]) mov r9d, ebx ; v1 shl r9d, 4 add r9d, r12d ; (v1 << 4) + k[0] mov r10d, ebx ; v1 add r10d, ecx ; v1 + sum mov r11d, ebx ; v1 shr r11d, 5 add r11d, r13d ; (v1 >> 5) + k[1] xor r9d, r10d xor r9d, r11d sub eax, r9d ; 更新v0 dec r8d jnz .tea_decrypt_loop ; 存储结果 mov [rdi], eax mov [rdi+4], ebx pop r14 pop r13 pop r12 pop rbx ret -
XTEA的x86-64汇编实现
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; XTEA加密函数 - x86-64汇编 ; 参数: RDI=v[2], RSI=k[4] xtea_encrypt: push rbx push r12 push r13 ; 加载数据 mov eax, [rdi] ; v0 mov ebx, [rdi+4] ; v1 mov r12, rsi ; k指针 xor ecx, ecx ; sum = 0 mov edx, 0x9e3779b9 ; delta mov r8d, 32 ; 循环计数器 .xtea_loop: ; v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]) mov r9d, ebx ; v1 mov r10d, ebx shl r9d, 4 shr r10d, 5 xor r9d, r10d add r9d, ebx ; ((v1 << 4) ^ (v1 >> 5)) + v1 ; 计算 sum + k[sum & 3] mov r10d, ecx ; sum and r10d, 3 ; sum & 3 mov r11d, [r12 + r10*4] ; k[sum & 3] add r11d, ecx ; sum + k[sum & 3] xor r9d, r11d add eax, r9d ; 更新v0 ; sum += delta add ecx, edx ; v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]) mov r9d, eax ; v0 mov r10d, eax shl r9d, 4 shr r10d, 5 xor r9d, r10d add r9d, eax ; ((v0 << 4) ^ (v0 >> 5)) + v0 ; 计算 sum + k[(sum >> 11) & 3] mov r10d, ecx ; sum shr r10d, 11 and r10d, 3 ; (sum >> 11) & 3 mov r11d, [r12 + r10*4] ; k[(sum >> 11) & 3] add r11d, ecx ; sum + k[(sum >> 11) & 3] xor r9d, r11d add ebx, r9d ; 更新v1 dec r8d jnz .xtea_loop ; 存储结果 mov [rdi], eax mov [rdi+4], ebx pop r13 pop r12 pop rbx ret -
XXXTEA的x86-64汇编实现
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 103 104 105 106 107 108 109; XXTEA加密函数 - x86-64汇编 ; 参数: RDI=v[], ESI=n, RDX=k[4] xxtea_encrypt: push rbx push r12 push r13 push r14 push r15 push rbp mov rbp, rsp ; 保存参数 mov r12, rdi ; v[] mov r13d, esi ; n mov r14, rdx ; k[4] ; 计算轮数: rounds = 6 + 52/n mov eax, 52 cdq idiv r13d add eax, 6 mov r15d, eax ; rounds ; 加载z = v[n-1] mov ecx, r13d dec ecx mov eax, [r12 + rcx*4] ; z = v[n-1] mov [rbp-8], eax ; 保存z在栈上 mov edx, 0x9e3779b9 ; delta xor ebx, ebx ; sum = 0 .round_loop: add ebx, edx ; sum += delta mov eax, ebx shr eax, 2 and eax, 3 ; e = (sum >> 2) & 3 xor ecx, ecx ; p = 0 .block_loop: ; 计算y = v[p+1] mov edi, ecx inc edi cmp edi, r13d jl .not_wrap xor edi, edi ; 如果p+1 == n,则y = v[0] .not_wrap: mov edi, [r12 + rdi*4] ; y = v[p+1] ; 计算MX ; MX = ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (k[(p & 3) ^ e] ^ z)) ; 第一部分: (z >> 5 ^ y << 2) mov esi, [rbp-8] ; z mov r8d, esi shr r8d, 5 ; z >> 5 mov r9d, edi ; y shl r9d, 2 ; y << 2 xor r8d, r9d ; z >> 5 ^ y << 2 ; 第二部分: (y >> 3 ^ z << 4) mov r9d, edi ; y shr r9d, 3 ; y >> 3 mov r10d, esi ; z shl r10d, 4 ; z << 4 xor r9d, r10d ; y >> 3 ^ z << 4 ; 第三部分: 相加 add r8d, r9d ; (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ; 第四部分: (sum ^ y) mov r9d, ebx ; sum xor r9d, edi ; sum ^ y ; 第五部分: k[(p & 3) ^ e] ^ z mov r10d, ecx ; p and r10d, 3 ; p & 3 xor r10d, eax ; (p & 3) ^ e mov r11d, [r14 + r10*4] ; k[(p & 3) ^ e] xor r11d, esi ; k[(p & 3) ^ e] ^ z ; 第六部分: 相加 add r9d, r11d ; (sum ^ y) + (k[(p & 3) ^ e] ^ z) ; 第七部分: 最终异或 xor r8d, r9d ; MX结果 ; 更新v[p]和z add [r12 + rcx*4], r8d ; v[p] += MX mov eax, [r12 + rcx*4] ; z = v[p] mov [rbp-8], eax ; 循环控制 inc ecx cmp ecx, r13d jl .block_loop ; 外层循环控制 dec r15d jnz .round_loop pop rbp pop r15 pop r14 pop r13 pop r12 pop rbx ret
观察差异
- tea特征,较多左移,右移,异或操作,32/64这种轮数,key一般比较整128bit,有魔数delta,一般为0x9E3779B9
- tea和xtea,xxtea这俩的一大明显差别是后二者多了&操作,也就使得汇编多了
and指令 - xtea和xxtea的差别是xxtea调用的寄存器比较多,操作复杂
例题
极客大挑战2025week2,reReverse
这题主要难点在于汇编中那一段爆红的汇编代码。
出题人:利用信号机制倒置了执行流,可以使用gdb的忽略信号机制调试。(这玩意挺有意思的,先鸽着有时间写个文章学一学)
所以这题要不就像无机盐大手子一样直接看汇编盯帧,要不然就用idapython,讲执行流倒置回来。
由于本人脚本编写能力有限,所以先使用盯帧法。于是就有了上面的关于tea,xtea,xxtea加密的识别
|
|
这里有魔数0x9E3779B9h,基本确定是tea加密家族,顺带把key得了
|
|
这里出现很多寄存器
|
|
这里出现了很多and
基本确定xxtea加密,密文是硬编码的也可以直接得到,但是这个密文顺序是不确定的需要暴力枚举
exp如下
|
|
结果如下

或者也可以观察出密文块的顺序
|
|
这里可以看出密文是存到寄存器里面的
现在只要知道寄存器在栈里的顺序就可以知道真正的密文顺序了
|
|
可知
|
|
根据这个就可以直接获得密文,无需遍历
SYC{sakurakouji_runasama_wa_seikai_ichi}