Buuctf reverse [FlareOn4]IgniteMe 题解

一. 查壳
无壳32位程序请添加图片描述
二. ida打开

请添加图片描述

  1. GetStdHandle函数根据微软官方文档可以得知是获取标准输入/输出/错误的句柄
    参数里的 0xFFFFFFF6转换一下是4294967286, 对应(DWORD) -10
    所以这里的WriteFile函数实际上是实现了printf的功能

请添加图片描述

  1. sub_4010F0()函数
    其功能是通过ReadFile函数读取输入的字符串并保存到地址为403078的内存处
int sub_4010F0()
{
  unsigned int v0; // eax
  char Buffer[260]; // [esp+0h] [ebp-110h] BYREF
  DWORD NumberOfBytesRead; // [esp+104h] [ebp-Ch] BYREF
  unsigned int i; // [esp+108h] [ebp-8h]
  char v5; // [esp+10Fh] [ebp-1h]

  v5 = 0;
  for ( i = 0; i < 260; ++i )
    Buffer[i] = 0;                              // 清空buffer数组
  ReadFile(hFile, Buffer, 260u, &NumberOfBytesRead, 0);// 读取数据到buffer中
  for ( i = 0; ; ++i )
  {
    v0 = strlen_401020(Buffer);                 // int类型修改为char*,获取字符串长度
    if ( i >= v0 )
      break;
    v5 = Buffer[i];
    if ( v5 != '\n' && v5 != '\r' )
    {
      if ( v5 )
        input_403078[i] = v5;                   // 将Buffer串保存到403078中
    }
  }
  return 1;
}

其中的401020()函数的功能不难发现是返回字符串长度,这里用strlen命名便于理解
另外ida可能会把函数参数认为是int类型(由于32位指针占4字节),可以右键使用set call type将int改为char*

在这里插入图片描述

  1. sub_401050函数
    这个函数的功能是:
    对输入字符串进行加密,加密操作是从flag的末尾到flag的开头进行一个异或操作
    将加密后的字符串和程序保存的加密串进行比较,所以加密串是已知的

v4的初始值由sub_401000()函数赋值,401000中仅有一个rol4函数
_ROL4_函数的功能是循环左移,位移时最高位不舍弃,将最高位挪回最低位
比如二进制数据 10000,循环左移2位后得到00010
这里循环左移四位后再右移一位,最终返回值是0x380004,也就是v4初值

在这里插入图片描述

int sub_401050()
{
  int len; // [esp+0h] [ebp-Ch]
  int i; // [esp+4h] [ebp-8h]
  unsigned int j; // [esp+4h] [ebp-8h]
  char v4; // [esp+Bh] [ebp-1h]

  len = strlen_401020(input_403078);
  v4 = sub_401000();                            // 返回的是0x380004
  for ( i = len - 1; i >= 0; --i )
  {
    encode_flag[i] = v4 ^ input_403078[i];      // 异或操作
    v4 = input_403078[i];
  }
  for ( j = 0; j < 39; ++j )
  {
    if ( encode_flag[j] != (unsigned __int8)encode_flag000[j] )
      return 0;
  }
  return 1;
}
  1. 解题脚本
#include <stdio.h>

int main() {
	unsigned char encode_flag000[] =
	{
	  0x0D, 0x26, 0x49, 0x45, 0x2A, 0x17, 0x78, 0x44, 0x2B, 0x6C,
	  0x5D, 0x5E, 0x45, 0x12, 0x2F, 0x17, 0x2B, 0x44, 0x6F, 0x6E,
	  0x56, 0x09, 0x5F, 0x45, 0x47, 0x73, 0x26, 0x0A, 0x0D, 0x13,
	  0x17, 0x48, 0x42, 0x01, 0x40, 0x4D, 0x0C, 0x02, 0x69, 0x00
	};

	char tmp = 0x380004;
	unsigned char flag[40] = { 0 };
	for (int i = 38; i >=0; i--)
	{
		flag[i] = encode_flag000[i] ^ tmp;
		tmp = flag[i];
	}
	puts(flag);
	return 0;
}

得到flag{R_y0u_H0t_3n0ugH_t0_1gn1t3@flare-on.com}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OrientalGlass

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值