[羊城杯 2021]BabySmc-复现

43 篇文章 1 订阅
10 篇文章 0 订阅

SMC:自解函数

BOOL sub_7FF7E2A01E30()
{
  _BYTE *v0; // r9
  __int64 v1; // rdx
  DWORD flOldProtect; // [rsp+20h] [rbp-8h] BYREF

  VirtualProtect(lpAddress, qword_7FF7E2A2AD88 - (_QWORD)lpAddress, 0x40u, &flOldProtect);
  v0 = lpAddress;
  v1 = qword_7FF7E2A2AD88;
  if ( (unsigned __int64)lpAddress < qword_7FF7E2A2AD88 )
  {
    do
    {
      *v0 = __ROR1__(*v0, 3) ^ 0x5A;
      ++v0;
      v1 = qword_7FF7E2A2AD88;
    }
    while ( (unsigned __int64)v0 < qword_7FF7E2A2AD88 );
    v0 = lpAddress;
  }
  return VirtualProtect(v0, v1 - (_QWORD)v0, flOldProtect, &flOldProtect);
}

选一个地方下断点,得到自解后的Main函数

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rbx
  __int64 v4; // r12
  __int64 v5; // r13
  unsigned __int64 v6; // rax
  char v7; // sp
  char v8; // cl
  __int64 v9; // rcx
  __int64 v11; // rax
  __int64 v12; // rcx
  unsigned __int128 v13; // rax
  char v14; // r9
  char v15; // r10
  char v16; // r8
  const char *v17; // rsi
  char *v18; // rdi
  bool v19; // cf
  unsigned __int8 v20; // dl
  int v21; // eax
  const char *v22; // rcx
  __int64 v23; // rcx
  unsigned __int64 v24; // rcx
  __int128 v26[2]; // [rsp+0h] [rbp-1C8h] BYREF
  _QWORD v27[2]; // [rsp+20h] [rbp-1A8h]
  __int128 v28; // [rsp+30h] [rbp-198h]
  char v29; // [rsp+40h] [rbp-188h] BYREF
  char v30; // [rsp+41h] [rbp-187h]
  char v31[254]; // [rsp+42h] [rbp-186h] BYREF
  __int128 v32[4]; // [rsp+140h] [rbp-88h]
  __m128i v33; // [rsp+180h] [rbp-48h] BYREF
  __int128 v34; // [rsp+190h] [rbp-38h]
  __int128 v35; // [rsp+1A0h] [rbp-28h]
  __int64 v36; // [rsp+1B0h] [rbp-18h]

  sub_7FF7E2A01EB0(0i64, 0i64, envp);
  v33 = 0i64;
  v34 = 0i64;
  v35 = 0i64;
  sub_7FF7E2A01D40((int)"Input Your Flag : ");
  sub_7FF7E2A01DC0("%46s", v33.m128i_i8);
  lpAddress = &loc_7FF7E2A01085;
  qword_7FF7E2A2AD88 = (__int64)&loc_7FF7E2A01D00;
  sub_7FF7E2A01E30();
  v6 = 256i64;
  do
  {
    *(__int128 *)((char *)&v28 + v6) = 0i64;
    *(_OWORD *)&v27[v6 / 8] = 0i64;
    v26[v6 / 0x10 + 1] = 0i64;
    v26[v6 / 0x10] = 0i64;
    v6 -= 64i64;
  }
  while ( v6 );
  v32[0] = *(_OWORD *)&byte_7FF7E2A1E340;
  v32[1] = *(_OWORD *)&byte_7FF7E2A1E350;
  v32[2] = *(_OWORD *)&byte_7FF7E2A1E360;
  v32[3] = *(_OWORD *)&byte_7FF7E2A1E370;
  v8 = v7 + 0x80;
  v9 = v8 & 0xF;
  if ( !_BitScanForward((unsigned int *)&v11, (unsigned int)_mm_movemask_epi8(_mm_cmpeq_epi8((__m128i)0i64, v33)) >> v9) )
    v11 = sub_7FF7E2A02340(v9, &v33.m128i_i8[v9]);
  v12 = v11;
  v13 = 0xAAAAAAAAAAAAAAABui64 * (unsigned __int128)(unsigned __int64)v11;
  if ( *((_QWORD *)&v13 + 1) >> 1 )
  {
    if ( *((_QWORD *)&v13 + 1) >> 5 )
    {
      *(_QWORD *)&v28 = v3;
      v27[1] = v4;
      v27[0] = v5;
      v29 = *((_BYTE *)v32 + (v33.m128i_i8[0] >> 2)) ^ 0xA6;
      v30 = *((_BYTE *)v32 + ((v33.m128i_i8[1] >> 4) | (16 * (v33.m128i_i8[0] & 3)))) ^ 0xA3;
      v31[0] = *((_BYTE *)v32 + ((v33.m128i_i8[2] >> 6) | (4 * (v33.m128i_i8[1] & 0xF)))) ^ 0xA9;
      v31[1] = *((_BYTE *)v32 + (v33.m128i_i8[2] & 0x3F)) ^ 0xAC;
      v31[2] = *((_BYTE *)v32 + (v33.m128i_i8[3] >> 2)) ^ 0xA6;
      v31[3] = *((_BYTE *)v32 + ((v33.m128i_i8[4] >> 4) | (16 * (v33.m128i_i8[3] & 3)))) ^ 0xA3;
      v31[4] = *((_BYTE *)v32 + ((v33.m128i_i8[5] >> 6) | (4 * (v33.m128i_i8[4] & 0xF)))) ^ 0xA9;
      v31[5] = *((_BYTE *)v32 + (v33.m128i_i8[5] & 0x3F)) ^ 0xAC;
      v31[6] = *((_BYTE *)v32 + (v33.m128i_i8[6] >> 2)) ^ 0xA6;
      v31[7] = *((_BYTE *)v32 + ((v33.m128i_i8[7] >> 4) | (16 * (v33.m128i_i8[6] & 3)))) ^ 0xA3;
      v31[8] = *((_BYTE *)v32 + ((v33.m128i_i8[8] >> 6) | (4 * (v33.m128i_i8[7] & 0xF)))) ^ 0xA9;
      v31[9] = *((_BYTE *)v32 + (v33.m128i_i8[8] & 0x3F)) ^ 0xAC;
      v31[10] = *((_BYTE *)v32 + (v33.m128i_i8[9] >> 2)) ^ 0xA6;
      v31[11] = *((_BYTE *)v32 + ((v33.m128i_i8[10] >> 4) | (16 * (v33.m128i_i8[9] & 3)))) ^ 0xA3;
      v31[12] = *((_BYTE *)v32 + ((v33.m128i_i8[11] >> 6) | (4 * (v33.m128i_i8[10] & 0xF)))) ^ 0xA9;
      v31[13] = *((_BYTE *)v32 + (v33.m128i_i8[11] & 0x3F)) ^ 0xAC;
      v31[14] = *((_BYTE *)v32 + (v33.m128i_i8[12] >> 2)) ^ 0xA6;
      v31[15] = *((_BYTE *)v32 + ((v33.m128i_i8[13] >> 4) | (16 * (v33.m128i_i8[12] & 3)))) ^ 0xA3;
      JUMPOUT(0x7FF7E2A0143Di64);
    }
    JUMPOUT(0x7FF7E2A01B22i64);
  }
  if ( v12 == 1 )
  {
    strcpy(v31, "14");
    v14 = *((_BYTE *)v32 + (unsigned __int8)(16 * (v33.m128i_i8[0] & 3))) ^ 0xA3;
    v29 = *((_BYTE *)v32 + (v33.m128i_i8[0] >> 2)) ^ 0xA6;
    v30 = v14;
  }
  else if ( v12 == 2 )
  {
    v15 = *((_BYTE *)v32 + 4 * (v33.m128i_i8[1] & 0xFu)) ^ 0xA9;
    v16 = *((_BYTE *)v32 + ((v33.m128i_i8[1] >> 4) | (16 * (v33.m128i_i8[0] & 3)))) ^ 0xA3;
    v29 = *((_BYTE *)v32 + (v33.m128i_i8[0] >> 2)) ^ 0xA6;
    v30 = v16;
    v31[0] = v15;
    strcpy(&v31[1], "4");
  }
  else
  {
    v29 = 0;
  }
  v17 = "H>oQn6aqLr{DH6odhdm0dMe`MBo?lRglHtGPOdobDlknejmGI|ghDb<4";
  v18 = &v29;
  while ( 1 )
  {
    v19 = (unsigned __int8)*v18 < (unsigned int)*v17;
    if ( *v18 != *v17 )
      break;
    if ( !*v18 )
      goto LABEL_20;
    v20 = v18[1];
    v19 = v20 < (unsigned int)v17[1];
    if ( v20 != v17[1] )
      break;
    v18 += 2;
    v17 += 2;
    if ( !v20 )
    {
LABEL_20:
      v21 = 0;
      goto LABEL_22;
    }
  }
  v21 = v19 ? -1 : 1;
LABEL_22:
  v22 = "No.\r\n";
  if ( !v21 )
    v22 = "Yes.\r\n";
  sub_7FF7E2A01D40((int)v22);
  sub_7FF7E2A06B38("pause");
  v23 = v36;
  v36 = 0i64;
  v24 = (unsigned __int64)v26 ^ v23;
  if ( v24 == _security_cookie )
    return 0;
  else
    return sub_7FF7E2A01D40(v24);
}

通过观察,显然为一个base64变异加密,即异或

找到表:

 

table = [0xE4, 0xC4, 0xE7, 0xC7, 0xE6, 0xC6, 0xE1, 0xC1, 0xE0, 0xC0,
         0xE3, 0xC3, 0xE2, 0xC2, 0xED, 0xCD, 0xEC, 0xCC, 0xEF, 0xCF,
         0xEE, 0xCE, 0xE9, 0xC9, 0xE8, 0xC8, 0xEB, 0xCB, 0xEA, 0xCA,
         0xF5, 0xD5, 0xF4, 0xD4, 0xF7, 0xD7, 0xF6, 0xD6, 0xF1, 0xD1,
         0xF0, 0xD0, 0xF3, 0xD3, 0xF2, 0xD2, 0xFD, 0xDD, 0xFC, 0xDC,
         0xFF, 0xDF, 0x95, 0x9C, 0x9D, 0x92, 0x93, 0x90, 0x91, 0x96,
         0x97, 0x94, 0x8A, 0x8E]

 找到加密后的结果:

res = 'H>oQn6aqLr{DH6odhdm0dMe`MBo?lRglHtGPOdobDlknejmGI|ghDb<4'

 找到异或的值:

temp = [0xA6, 0xA3, 0xA9, 0xAC]

 在网上找到python写的base64解密脚本,进行改写

# base_table
table = [0xE4, 0xC4, 0xE7, 0xC7, 0xE6, 0xC6, 0xE1, 0xC1, 0xE0, 0xC0,
         0xE3, 0xC3, 0xE2, 0xC2, 0xED, 0xCD, 0xEC, 0xCC, 0xEF, 0xCF,
         0xEE, 0xCE, 0xE9, 0xC9, 0xE8, 0xC8, 0xEB, 0xCB, 0xEA, 0xCA,
         0xF5, 0xD5, 0xF4, 0xD4, 0xF7, 0xD7, 0xF6, 0xD6, 0xF1, 0xD1,
         0xF0, 0xD0, 0xF3, 0xD3, 0xF2, 0xD2, 0xFD, 0xDD, 0xFC, 0xDC,
         0xFF, 0xDF, 0x95, 0x9C, 0x9D, 0x92, 0x93, 0x90, 0x91, 0x96,
         0x97, 0x94, 0x8A, 0x8E]
table = ''.join(chr(i) for i in table)
print(table)
res = 'H>oQn6aqLr{DH6odhdm0dMe`MBo?lRglHtGPOdobDlknejmGI|ghDb<4'  # 结果
temp = [0xA6, 0xA3, 0xA9, 0xAC]  # 异或的key
res_temp = ''.join(chr(ord(res[i]) ^ temp[i % 4]) for i in range(len(res) - 1))  # 异或回去
print(res_temp)
table_temp = []
for i in range(len(res_temp)):
    table_temp.append(table.index(res_temp[i]))  # 索引
flag = ""
for i in range(0, 52, 4):  # 解密
    f1 = (table_temp[i] << 2) | (table_temp[i + 1] >> 4) & 0xff
    f2 = ((table_temp[i + 1] << 4) | (table_temp[i + 2] >> 2)) & 0xff
    f3 = ((table_temp[i + 2] << 6) | (table_temp[i + 3])) & 0xff
    flag += chr(f1) + chr(f2) + chr(f3)
f1 = (table_temp[52] << 2) | (table_temp[53] >> 4) & 0xff
f2 = ((table_temp[53] << 4) | (table_temp[54] >> 2)) & 0xff
flag += chr(f1) + chr(f2)
print(flag)
# SangFor{XSAYT0u5DQhaxveIR50X1U13M-pZK5A0}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值