强网杯 复盘 baby_apk 混淆
apk逆向,混淆+rot13+tea
一、混淆
首先就是rot13实现的位置
该函数的第一个参数为:
(inputtt_7 + v97) | 0xFFFFFFF2)- (*(_BYTE )(inputtt_7 + v97) & 0xF2)+ 2 * ((unsigned __int8 *)(inputtt_7 + v97) | 0xD) + 1
其实就是在做rot13加密了,可以用python跑一下试试
一个迷惑人的代码语句:
*a3 = (*a3 ^ (a1 >> 31)) - (a1 >> 0x1F);
这个代码实现的功能就是 *a3 = *a3 ,没错,一动不动
加法的混淆
(2 * (summ | v154) - (summ ^ v154))
等价于 sum + v154
++的混淆
v97 = (v97 | 0xFFFFFFFE) - (v97 & 0xFFFFFFFE) + 2 * (v97 | 1) + 1;
混淆。。。实际上就是从一到32
生成固定值的代码
虽然前面取了时间值,但这行代码运行到最后其实是固定值...
固定为0x35970c13
还有不少混淆,没再仔细看了,已经可以了
下面给出解密脚本
二、exp
#include <stdio.h> #include <stdint.h> //加密函数 void encrypt (uint32_t* v, uint32_t* k) { uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */ uint32_t delta=0x9e3779b9; /* a key schedule constant */ uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */ for (i=0; i < 32; i++) { /* basic cycle start */ sum += delta; v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1); v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3); } /* end cycle */ v[0]=v0; v[1]=v1; } //解密函数 void decrypt (uint32_t* v, uint32_t* k) { uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */ uint32_t delta=0x9e3779b9; /* a key schedule constant */ uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */ for (i=0; i<32; i++) { /* basic cycle start */ v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3); v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1); sum -= delta; } /* end cycle */ v[0]=v0; v[1]=v1; } void conver_to_bytes(uint32_t* v){ uint32_t v0=v[0], v1=v[1]; printf("%c",v[0] & 0x000000ff); printf("%c",(v[0] & 0x0000ff00) >> 8); printf("%c",(v[0] & 0x00ff0000) >> 16); printf("%c",(v[0] & 0xff000000) >> 24); printf("%c",v[1] & 0x000000ff); printf("%c",(v[1] & 0x0000ff00) >> 8); printf("%c",(v[1] & 0x00ff0000) >> 16); printf("%c",(v[1] & 0xff000000) >> 24); } void Tea() { uint32_t v[]={0x5d94aa84,0x14fa24a0,0x2b560210,0xb69bdd49,0xaaefead4,0x4b8cf4c6,0x097fb8c9,0xb5ec51d2}; uint32_t k[4]={0x33323130,0x37363534,0x62613938,0x66656463}; for(int i = 0;i<=3;i++){ decrypt(&v[i*2], k); //printf("'%x' ,'%x' ,",v[i*2],v[i*2+1]); conver_to_bytes(&v[i*2]); } } int main() { Tea(); //xTea(); //xxTea(); return 0; } # synt{Vg_Vf_A0g_guNg_zHpu_unEqre} # rot13 后.flag为: flag{it_is_n0t_that_much_harder}
三、使用D-810插件去混淆
看了Arr3stY0u战队的wp,发现了一个去除混淆的插件D810
去混淆后,代码比较清楚