[HZNUCTF 2023 final]虽然他送了我玫瑰花

先用die查了一下,32位无壳
直接打开ida
发现F5反编译不了了
代码也没有爆红
只能硬着头皮看了
发现了这段代码
在这里插入图片描述中间的代码就是花指令,没什么意义,纯纯不给我F5的
全nop掉
在main函数按p重新生成函数
然后就能F5了
main函数代码如下

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int i; // esi
  int v4; // eax
  char v6; // [esp+0h] [ebp-F8h]
  char v7; // [esp+0h] [ebp-F8h]
  char v8[100]; // [esp+Ch] [ebp-ECh]
  __int128 v9; // [esp+70h] [ebp-88h]
  int v10; // [esp+80h] [ebp-78h]
  int v11; // [esp+84h] [ebp-74h]
  int v12; // [esp+88h] [ebp-70h]
  char v13; // [esp+8Ch] [ebp-6Ch]
  char flag[100]; // [esp+90h] [ebp-68h] BYREF

  print((char *)&Format, v6);
  sub_401050("%s", (char)flag);
  v10 = -171171450;  		//F5CC 2186
  v11 = -669748952;			//D814 7128
  v12 = 1651994351;			//6277 6EEF
  v13 = -6;					//FFFF FFFA
  v9 = xmmword_402170;
  if ( strlen(flag) == 29 )
  {
    for ( i = 0; i < 29; ++i )
      v8[i] = funcs_40117E[i % 5u](flag[i]);/推测是函数指针,数组
    v4 = 0;
    while ( v8[v4] == *((_BYTE *)&v9 + v4) )
    {
      if ( ++v4 >= 29 )
      {
        print("Congratulations!!\n", v7);
        return 0;
      }
    }
    print("try again\n", v7);
  }
  else
  {
    print("wwwhhhaaattt???\n", v7);
  }
  return 0;
}

开始看代码,输入一个字符串,应该就是flag,改个名
v9直接双击xmmword_402170
shift+e提取数据
这才16字节,代码中用到了28字节
发现v9,v10,v11,v12,v13的地址其实是连着的
所以要使用到,v10,v11,v12,v13的部分(int 4字节)
还得是小端序
在这里插入图片描述
继续双击进入funcs_40117E
发现五个函数地址
在这里插入图片描述
双击第一个,sub_401080
在这里插入图片描述
F5一下
在这里插入图片描述
后面四个相同方法
然后得到五个函数

int __cdecl sub_401080(int a1)
{
    return a1 ^ 0x19;
}
int __cdecl sub_401090(int a1)
{
    return a1 + 18;
}
int __cdecl sub_4010A0(int a1)
{
    return a1 - 16;
}
int __cdecl sub_4010B0(int a1)
{
    return 2 * (a1 & 0x7F);
}
int __cdecl sub_4010C0(int a1)
{
    return a1 ^ ((unsigned __int8)a1 ^ (unsigned __int8)~(_BYTE)a1) & 0x80;
  /*化简一下  =>    a1 ^ (a1 ^ (~a1)) & 0x80;
             =>    a1 ^ 0xFF         & 0x80
             =>    a1 ^ 0x80              */
}

先& 后^ 可以试验下,发现化简正确

最后完整解题脚本

#include<stdio.h>
#include<Windows.h>
char v8[] =
{
    0x7F, 0x7E, 0x51, 0xCE, 0xFB, 0x4E, 0x7A, 0x24, 0xE8, 0xDF,
    0x59, 0x71, 0x26, 0xCA, 0xE1, 0x6C, 0x86, 0x21, 0xCC, 0xF5,
    0x28, 0x71, 0x14, 0xD8, 0xEF, 0x6E, 0x77, 0x62, 0xFA,
};
int __cdecl sub_401080(int a1)
{
    return a1 ^ 0x19;
}
int __cdecl sub_401090(int a1)
{
    return a1 - 18;
}
int __cdecl sub_4010A0(int a1)
{
    return a1 + 16;
}
int __cdecl sub_4010B0(int a1)
{
    return (a1 >>1)&0x7f;
}
int __cdecl sub_4010C0(int a1)
{
    //return a1 ^ ((unsigned __int8)a1 ^ (unsigned __int8)~(BYTE)a1) & 0x80;
    return a1 ^ 0x80;
}
int main()
{
    char flag[30];
    int (_cdecl*fun[5])(int)= {sub_401080,sub_401090 ,sub_4010A0 ,sub_4010B0 ,sub_4010C0 };
    for (int i = 0; i < 29; i++) {
        flag[i] = fun[i % 5](v8[i]);
    }
    printf("%s", flag);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值