(54)[GDOUCTF 2023]Tea

GDOUCTF 2023 Tea题解题分析
部署运行你感兴趣的模型镜像

(54)[GDOUCTF 2023]Tea

nss:3688

关于这个题,看题目我们就知道很什么有关系。

那我们拖进IDA观察一下

image-20250308085918352

我们发现这个题里面有好多函数,说明这个题没有我们想的那么简单,不仅仅是一个加密哦。

我们一步步来看吧(我把函数名字重新赋一个名字,便于打字)

image-20250308090153158

我们先进入step1看看这个函数

__int64 __fastcall sub_1400117D0(_DWORD *a1, __int64 a2, __int64 a3)
{
  char *v3; // rdi
  __int64 i; // rcx
  __int64 result; // rax
  char v6; // [rsp+20h] [rbp+0h] BYREF
  int v7; // [rsp+2Ch] [rbp+Ch]
  int v8; // [rsp+30h] [rbp+10h]
  unsigned int v9; // [rsp+34h] [rbp+14h]
​
  v3 = &v6;
  for ( i = 14i64; i; --i )
  {
    *(_DWORD *)v3 = -858993460;
    v3 += 4;
  }
  j___CheckForDebuggerJustMyCode((__int64)&unk_140023009, a2, a3);
  v7 = 4455;
  v8 = 6677;
  v9 = 8899;
  *a1 = 2233;
  a1[1] = v7;
  a1[2] = v8;
  result = v9;
  a1[3] = v9;
  return result;
}

它传入v9然后将v9的值给变更。

所以v9经过改变后的值变成了

unsinged int v9[4]={2233,4455,6677,8899};

我们接着往后看step2,我们发现后面就没有用到v11,并且我们进入函数,这个函数也是一个没起到作用的函数。

image-20250308090419651

然后我们进入step3,它传入的v9和flag

image-20250308090447768

这个有点类似于tea了对不对,但跟我们标准的tea加密还不一样,但是解密我们仿照它写就对了。

通过观察,我们发现deault是v7

key是v9

我们就把这个代码逆过来就是以下代码:

#include <stdio.h>
#include <stdint.h>
​
​
int main() {
​
    uint32_t key[4] = { 2233, 4455, 6677, 8899 };
    uint32_t enc[10] = { 444599258, 4154859931, 1226314200, 4060164904, 359413339, 1013885656,
                         2228535080, 4045045479, 856928850, 3718242937
                       };
​
    for (int i = 8; i >= 0; i--) {
        unsigned int v6 = 33;
        unsigned int v7 = 256256256 * (i + v6);
​
        do {
​
            v7 -= 256256256 ;
            enc[i + 1] -= (v7 + key[(v7 >> 11) & 3]) ^ (enc[i] + ((enc[i] >> 5) ^ (16 * enc[i])));
            enc[i] -= v7 ^ (enc[i + 1] + ((enc[i + 1] >> 5) ^ (16 * enc[i + 1]))) ^ (v7 + key[v7 & 3]);
​
            --v6;
​
​
        } while (v6 > 0);
​
​
​
    }
    for (int i = 0; i < 10; i++) {
        printf("%x", enc[i]);
    }
    printf("\n");
​
    //下面是将小端序搞出来
​
​
    for (int i = 0; i < 10; i++) {
        uint32_t val = enc[i];
        putchar((val >> 24) & 0xFF);
        putchar((val >> 16) & 0xFF);
        putchar((val >> 8)  & 0xFF);
        putchar(val & 0xFF);
    }
​
​
//  for (int i = 0; i < 40; i++) {
//      printf("%c", *(((char *)enc) + i));
//  }
}
​
​
​

485a4354467b687a4374665f39345f726536363666696e676372793536343171717d0 HZCTF{hzCtf_94_re666fingcry5641qq}

image-20250308092509496

最后讲一下这里,关于大小端序的问题。

我们知道我们电脑基本都是小端序,当我用我注释的这几行错误代码,我们将enc转化为一个char*类型,原本是4字节,char之后是一字节,便于我们去转换字符。然后我这里错在这里。

当我们强制转换类型之后,enc是小端存储,他原本的首地址,存储的

所以我们如果按我这个写的就不对了

我们可以这样改一下哦

//  for (int i = 0; i < 40; i++) {
//      // 计算当前字节所在的大端序位置
//      int block = i / 4;          // 当前是第几个 4 字节块
//      int offset = i % 4;         // 当前块内的偏移
//      int adjusted_i = block * 4 + (3 - offset); // 大端序调整后的偏移
//      printf("%c", *(((char *)enc) + adjusted_i));
//  }

然后我们运行之后,就是正确答案了

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值