[MTCTF 2021]wow
这题隐藏着一个heaven's gate考点 做了西湖2023再来看就清晰多了
CSDN那篇完全没讲怎么得到key/enc这些的...
如果不dump出来分析而是在原基础上patch很难搞
所以写一篇记录一下
把retf后的lazydump后用ida64看
void __fastcall sub_5(unsigned int *a1)
{
unsigned int v1; // r9d
int v2; // ebp
unsigned int v3; // esi
unsigned int *v4; // rdi
unsigned int *v5; // r10
unsigned int v6; // ebx
unsigned int i; // r11d
unsigned int v8; // r8d
int v9; // edx
unsigned int v10; // eax
unsigned int v11; // r9d
unsigned int v12; // r8d
int v13; // ebx
int v14; // ebx
int v15; // ebx
int v16; // edx
unsigned int v17; // eax
unsigned int v18; // r9d
v1 = a1[8];
v2 = 12;
v3 = 0;
while ( 1 ) // xxtea
{
v3 += 0x67452301;
v4 = a1 + 1;
v5 = a1;
v6 = v3 >> 2;
for ( i = 0; i < 8; ++i )
{
v8 = *v4;
if ( (((unsigned __int8)i ^ (unsigned __int8)v6) & 3) != 0 )
{
switch ( ((unsigned __int8)i ^ (unsigned __int8)v6) & 3 )
{
case 1:
v9 = (v1 >> 5) ^ (4 * v8);
v10 = v1;
v11 = v1 ^ 0x10325476;
break;
case 2:
v9 = (v1 >> 5) ^ (4 * v8);
v10 = v1;
v11 = v1 ^ 0x98BADCFE;
break;
case 3:
v9 = (v1 >> 5) ^ (4 * v8);
v10 = v1;
v11 = v1 ^ 0xC3D2E1F0;
break;
default:
goto LABEL_12;
}
}
else
{
v9 = (v1 >> 5) ^ (4 * v8);
v10 = v1;
v11 = v1 ^ 0xEFCDAB89;
}
*v5 += (v11 + (v3 ^ v8)) ^ (((16 * v10) ^ (v8 >> 3)) + v9);
v1 = *v5;
LABEL_12:
++v4;
++v5;
}
v12 = *a1;
v13 = ((unsigned __int8)i ^ (unsigned __int8)v6) & 3;
if ( !v13 )
{
v16 = (v1 >> 5) ^ (4 * v12);
v17 = v1;
v18 = v1 ^ 0xEFCDAB89;
goto LABEL_21;
}
v14 = v13 - 1;
if ( !v14 )
{
v16 = (v1 >> 5) ^ (4 * v12);
v17 = v1;
v18 = v1 ^ 0x10325476;
goto LABEL_21;
}
v15 = v14 - 1;
if ( !v15 )
{
v16 = (v1 >> 5) ^ (4 * v12);
v17 = v1;
v18 = v1 ^ 0x98BADCFE;
LABEL_21:
a1[8] += (v18 + (v3 ^ v12)) ^ (((16 * v17) ^ (v12 >> 3)) + v16);
v1 = a1[8];
goto LABEL_22;
}
if ( v15 == 1 )
{
v16 = (v1 >> 5) ^ (4 * v12);
v17 = v1;
v18 = v1 ^ 0xC3D2E1F0;
goto LABEL_21;
}
LABEL_22:
if ( !--v2 )
__asm { retfq }
}
}
这里魔改了一些点(不容易看出来》。。)
重点是这个rounds是12 ...
然后key值根据switch找就行了
最后check点没找着 但是看原程序可以知道
这个unk就是enc值
转一下刚好9个DWORD
exp:
#include <stdio.h>
#include <stdint.h>
#define DELTA 0x67452301
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p^e)&3] ^ z)))
void btea(uint32_t *v, int n, uint32_t const key[4])
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 6 + 52/n;
sum = 0;
z = v[n-1];
do
{
sum += DELTA;
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);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 12;
sum = rounds*DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--)
{
z = v[p-1];
y = v[p] -= MX;
}
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
}
while (--rounds);
}
}
int main()
{
uint32_t v[]= {0xD8F758F5, 0x526849DB, 0xE2D72563, 0x485EEFAC, 0x608F4BC6, 0x5859F76A, 0xB03565A3, 0x3E4091C1,
0xD3DB5B9A, 0x00000000};
uint32_t const k[4]= {0xEFCDAB89,0x10325476,0x98BADCFE,0xC3D2E1F0};
int n= -9;
btea(v, n, k);
for(int i=0;i<(-n);i++){
for(int j=0;j<4;j++){
printf("%c",(v[i]>>(8*j))&0xff);
}
}
return 0;
}
flag{529e3d91db48e084f76fca97b94499}