[buuctf.reverse] 082_[FlareOn2]very_success

一打开只有3个函数还以为是有壳,一查没有,确实是3个

第1个是start,给401000传个a1作为将来输入flag加密后的对比值:密文。这里c代码没有对a1的说明,32位系统中第1参数就是ebp的值,这里就是4010E4开始的37字节。

.text:004010DF                               public start
.text:004010DF                               start proc near
.text:004010DF E8 1C FF FF FF                call    sub_401000
.text:004010DF
.text:004010DF                               start endp
.text:004010DF
.text:004010DF                               ; ---------------------------------------------------------------------------
.text:004010E4 AF                            db 0AFh
.text:004010E5 AA                            db 0AAh
.text:004010E6 AD                            db 0ADh

第2函数只是传递下参数和主程序,加密在后边

// positive sp value has been detected, the output may be wrong!
BOOL __usercall sub_401000@<eax>(int a1@<ebp>)
{
  int v1; // eax
  int v3; // [esp-14h] [ebp-14h]
  HANDLE StdHandle; // [esp-10h] [ebp-10h]
  HANDLE v5; // [esp-Ch] [ebp-Ch]
  int v6; // [esp-8h] [ebp-8h] BYREF
  int v7; // [esp-4h] [ebp-4h]

  v1 = v7;
  v7 = a1;
  v3 = v1;
  StdHandle = GetStdHandle(0xFFFFFFF6);
  v5 = GetStdHandle(0xFFFFFFF5);
  WriteFile(v5, aYouCrushedThat, 0x43u, (LPDWORD)&v6, 0);
  ReadFile(StdHandle, byte_402159, 0x32u, (LPDWORD)&v6, 0);
  if ( sub_401084((int)&v6, v3, byte_402159, v6) )
    return WriteFile(v5, aYouAreSuccess, 0x11u, (LPDWORD)&v6, 0);
  else
    return WriteFile(v5, aYouAreFailure, 0x11u, (LPDWORD)&v6, 0);
}

第3个是加密过程

int __usercall sub_401084@<eax>(int result@<eax>, int a2, char *input, int a4)
{
  __int16 v4; // bx
  int v5; // ecx
  _BYTE *v7; // edi
  char v8; // al
  unsigned int v9; // kr00_4
  char v10; // al
  char v11; // cf
  __int16 v12; // ax
  bool v13; // zf
  _BYTE *v14; // edi
  int v15; // [esp+0h] [ebp-Ch]

  v4 = 0;
  v5 = 37;
  if ( a4 >= 37 )
  {
    v7 = (_BYTE *)(a2 + 36);
    while ( 1 )
    {
      LOWORD(result) = 455;
      v15 = result;
      v8 = *input++;
      v9 = __readeflags();
      v10 = v15 ^ v8;                           // 输入值与result异或再加1248 与a3反向比较
      __writeeflags(v9);
      v12 = (unsigned __int8)(__ROL1__(1, v4 & 3) + v11 + v10);// v11 //cf位:运算是否产生进位 ROL左转后CF等于结果的最低bit,就是2341H的1。CF通常是进位标志,但根据具体指令有不同的意义,像ROL中不存在进位,就用作指示其他的情况。
      v4 += v12;
      v13 = *v7 == (unsigned __int8)v12;
      v14 = v7 + 1;
      if ( !v13 )
        LOWORD(v5) = 0;
      result = v15;
      if ( !v5 )
        break;
      v7 = v14 - 2;                             // 取前一字节
      if ( !--v5 )
        return result;
    }
  }
  return 0;
}

这里除了v11以外都好理解,将输入值与455异或后加上1左移0-3位再加上v11就得到密文(反向)

这里v11是cf位,这个是进位标记,在rol时表示右位,所以这里__rol1__(1,n)是1。

解密就简单了

cipher = bytes.fromhex('AFAAADEBAEAAECA4BAAFAEAA8AC0A7B0BC9ABAA5A5BAAFB89DB8F9AE9DABB4BCB6B3909AA8')[::-1]

flag = [0]*37
v4 = 0
for i in range(37):
    flag[i] = ((cipher[i] - (1<<(v4&3)) - 1)^455)&0xff 
    v4 +=cipher[i]

print(bytes(flag))
#a_Little_b1t_harder_plez@flare-on.com
#flag{a_Little_b1t_harder_plez@flare-on.com}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值