考点一览
tea加密
//加密函数(了解就行)
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;
}
//解密函数
//long long a2[4]={1,3,1,4}; /*可换*/
__int64 __fastcall sub_1400010B4(unsigned int *a1, long long *a2)
{
int v2; // ebx
long long v3; // r11d
int v4; // edi
int v5; // esi
int v6; // ebp
unsigned int v7; // r9d
__int64 v8; // rdx
unsigned int v9; // r10d
__int64 result; // rax
v2 = *a2;
v3 = 0;
v4 = a2[1];
v5 = a2[2];
v6 = a2[3];
v7 = *a1;
v8 = 32;
v9 = a1[1];
for(int i = 0 ; i < 32 ; i ++ )
{
v3-=0x61C98747; /*可换*/
}
do
{
result = v3 + v7;
v9 -= result ^ (v5 + 16 * v7) ^ (v6 + (v7 >> 5));
v7 -= (v3 + v9) ^ (v2 + 16 * v9) ^ (v4 + (v9 >> 5));
v3 += 0x61C98747; /*可换*/
--v8;
}
while ( v8 );
*a1 = v7;
a1[1] = v9;
return result;
}
认真解题
查壳,反编译之后,将十进制数转化为十六进制,我们可以看到本题的主函数部分使用了小端序的排列方式。再看到下面这个赋值语句:
进入之后看到一串十六进制数‘45678901345678902345678912345678h’,我们再看到后面的调用函数:
调用了四次该函数。
(char※)Buf1+8==(int※)Buf1+2:两个字符放在一个字节,往后移8个字节的字符都放入第二个函数,再从首地址后移八个字节,将其后面的字符放入第二个函数==第一个函数放两个元素的数,再从首地址后移两个地址,将后面的元素放入第二个函数。
上段中我并没有说,后面的字符/元素是多少个,因为我们现在还不能确定,并且后面的v10的作用仍然不清楚。且输入函数‘sub_140001064(“%50s”);’也没有告诉我们输入的字符存到哪里。为此,我们可以动态调试来看看输入的字符去了哪里。
我们在此处下断点,进行输入字符,这里可以尽可能多输入一点。
我先输入了‘123456789012345678901234567890’,再点开此处的v10,它前面有16个数字,也就是说我们输入的数字一半进入了Buf1数组,一半进入了v10数组。
综上,也就是说两个Buf2元素一组是由Buf1数组,v10数组分别两次,共四次调用sub_1400010B4这个加密函数,得来的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tTRSB71T-1673956186008)(null)]
点开sub_1400010B4加密函数,我们知道这是一个Tea加密,并且通过定义变量,我们知道a2是一个包含四个元素的数组。因此联系到‘si128.m128i_i32’是一个包含四个元素的数组。由前面那一长串赋值字符串可以知道,si128.m128i_i32[4]= {0x12345678,0x23456789,0x34567890,0x45678901}。
现在我们已知加密后的结果,再将加密函数逆向得到解密函数即可,脚本如下:
__int64 __fastcall sub_1400010B4(unsigned int *a1, long long *a2)
{
int v2; // ebx
long long v3; // r11d
int v4; // edi
int v5; // esi
int v6; // ebp
unsigned int v7; // r9d
__int64 v8; // rdx
unsigned int v9; // r10d
__int64 result; // rax
v2 = *a2;
v3 = 0;
v4 = a2[1];
v5 = a2[2];
v6 = a2[3];
v7 = *a1;
v8 = 32;
v9 = a1[1];
for(int i = 0 ; i < 32 ; i ++ )
{
v3-=0x543210DD;
}
do
{
result = v3 + v7;
v9 -= result ^ (v5 + 16 * v7) ^ (v6 + (v7 >> 5));
v7 -= (v3 + v9) ^ (v2 + 16 * v9) ^ (v4 + (v9 >> 5));
v3 += 1412567261;
--v8;
}
while ( v8 );
*a1 = v7;
a1[1] = v9;
return result;
}
int main ()
{
long long a2[4]={0x12345678,0x23456789,0x34567890,0x45678901};
unsigned int Buf2[8]={0};
Buf2[0] = 0x2E63829D;
Buf2[1] = 0xC14E400F;
Buf2[2] = 0x9B39BFB9;
Buf2[3] = 0x5A1F8B14;
Buf2[4] = 0x61886DDE;
Buf2[5] = 0x6565C6CF;
Buf2[6] = 0x9F064F64;
Buf2[7] = 0x236A43F6;
for(int i = 0 ; i < 8 ; i+=2 )
{
sub_1400010B4(Buf2+i,a2);
}
for(int i = 0 ; i < 8 ; i++ )
{
unsigned int tmp = Buf2[i];
for(int j = 0 ; j< 4 ; j++ )
{
printf("%c",tmp%0x100);
tmp/=0x100;
}
}
printf("k}");
}
hgame{Tea_15_4_v3ry_h3a1thy_drlnk}