TEA加密逆向

发布于:2024-11-27 ⋅ 阅读:(122) ⋅ 点赞:(0)

IDA伪代码

 do
    {
      if ( v15 )
        v17 = v38;                              // x12=0x0->0x79168ba790, 输入字符串经过check1处理后字符串
      else
        v17 = v40;
      v18 = (unsigned int *)&v17[v16];          // 0x78cbbd47fc    add     x12, x12, x8    ; x12=0x79168ba790->0x79168ba798,每次取8个字符
      v20 = *v18;                               // 0x78cbbd4800    ldp     w16, w14, [x12] ; x14=0x79168ba790->0x78777675, x16=0x78cbbf9eb8->0x74737271,8个字符分别给到v20 和 v19
      v19 = v18[1];
      v21 = 32;
      v22 = 0x9E3779B9;                         // TEA加密算法的常数DELTA值
      do
      {
        v20 += (DWORD1(k) + (v19 >> 5)) ^ (k + 16 * v19) ^ (v19 + v22);// k 的值是 0x42, 0x37, 0x2C,  0x21 , 是在JNI_OnLoad 赋值
        --v21;
        v19 += (DWORD2(k) + 16 * v20) ^ (v22 + v20) ^ (HIDWORD(k) + (v20 >> 5));
        v22 -= 0x61C88647;                      
      }
      while ( v21 );                            // 循环加密32轮
      *v18 = v20;                               // 加密后的数据再给到v18 ,就是加密后字符串再写回内存
      v18[1] = v19;
      v16 += 8LL;                               // 取下一个 8个字符
      if ( (v37 & 1) != 0 )
        v23 = v39;                              // v23 = 0x20
      else
        v23 = (unsigned __int64)v37 >> 1;
      v15 = (v37 & 1) == 0;                     // v15 = 0
    }
    while ( v23 > v16 );                        // 循环条件是 v16 < 32 , 32就是待加密的字符串长度,v16是递增8,就是每次取待加密的字符串8位

核心代码标识

1、TEA加密算法的常数DELTA值 0x9E3779B9 和 0x61C88647
2、4个key值
3、左移4位、右移5位、2个异或

v22 = 0x9E3779B9;                         // TEA加密算法的常数DELTA值
      do
      {
        v20 += (DWORD1(k) + (v19 >> 5)) ^ (k + 16 * v19) ^ (v19 + v22);// k 的值是 0x42, 0x37, 0x2C,  0x21 , 是在JNI_OnLoad 赋值
        --v21;
        v19 += (DWORD2(k) + 16 * v20) ^ (v22 + v20) ^ (HIDWORD(k) + (v20 >> 5));
        v22 -= 0x61C88647; 
      }

arm指令
在这里插入图片描述

加解密代码

    private static final int DELTA = 0x9E3779B9;
    private  static int sum = 0xC6EF3720;

    public static void encrypt(int[] v, int[] key) {
        int v0 = v[0], v1 = v[1];
        int sum = 0;
        for (int i = 0; i < 32; i++) {
            v0 += ((v1 << 4) + key[0]) ^ (v1 + sum) ^ ((v1 >>> 5) + key[1]);
            v1 += ((v0 << 4) + key[2]) ^ (v0 + sum) ^ ((v0 >>> 5) + key[3]);
            sum += DELTA;
        }
        v[0] = v0;
        v[1] = v1;
    }

    public static void decrypt(int[] v, int[] key) {
        int v0 = v[0], v1 = v[1];
        for (int i = 0; i < 32; i++) {
            v1 -= ((v0 << 4) + key[2]) ^ (v0 + sum) ^ ((v0 >>> 5) + key[3]);
            v0 -= ((v1 << 4) + key[0]) ^ (v1 + sum) ^ ((v1 >>> 5) + key[1]);
            sum -= DELTA;
        }
        v[0] = v0;
        v[1] = v1;
    }
    public static void main(String[] args) {
        int[] key = {0x42, 0x37, 0x2c, 0x21}; // 128-bit key
        int[] plaintext = new int[2]; // 64-bit plaintext

        plaintext[0] = 0x10e14834;
        plaintext[1] = 0x3d635efc;

        // Decrypt
        decrypt(plaintext, key);
        System.out.printf("Decrypted: %08X %08X%n", plaintext[0], plaintext[1]);
    }

网站公告

今日签到

点亮在社区的每一天
去签到