BUUCTF reverse wp 71 - 75

[NPUCTF2020]你好sao啊

在这里插入图片描述

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  __int64 v4; // rdx
  __int64 v5; // rax
  size_t v6; // rax
  __int64 v7; // rax
  __int64 v8; // rdx
  __int64 v9; // rax
  __int64 v11; // rdx
  __int64 v12; // rax
  char *s1; // [rsp+8h] [rbp-68h]
  char s2[8]; // [rsp+10h] [rbp-60h] BYREF
  __int64 v15; // [rsp+18h] [rbp-58h]
  __int64 v16; // [rsp+20h] [rbp-50h]
  __int64 v17; // [rsp+28h] [rbp-48h]
  char v18; // [rsp+30h] [rbp-40h]
  char s[40]; // [rsp+40h] [rbp-30h] BYREF
  unsigned __int64 v20; // [rsp+68h] [rbp-8h]

  v20 = __readfsqword(0x28u);
  v3 = std::operator<<<std::char_traits<char>>(&std::cout, "Welcome To Reverier-Encode Program!", envp);
  std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
  v5 = std::operator<<<std::char_traits<char>>(&std::cout, "Input Your flag:", v4);
  std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>);
  *(_QWORD *)s2 = 0xFD370FEB59C9B9ELL;
  v15 = 0xDEAB7F029C4FD1B2LL;
  v16 = 0xFACD9D40E7636559LL;
  v17 = 4LL;
  v18 = 0;
  __isoc99_scanf("%33s", s);
  s1 = (char *)RxEncode(s, 33);
  if ( strlen(s) == 32 )
  {
    if ( !strcmp(s1, s2) )
      v12 = std::operator<<<std::char_traits<char>>(&std::cout, "Congratulations!", v11);
    else
      v12 = std::operator<<<std::char_traits<char>>(&std::cout, "Wrong!", v11);
    std::ostream::operator<<(v12, &std::endl<char,std::char_traits<char>>);
    return 0;
  }
  else
  {
    v6 = strlen(s);
    v7 = std::ostream::operator<<(&std::cout, v6);
    std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>);
    v9 = std::operator<<<std::char_traits<char>>(&std::cout, "Wrong!", v8);
    std::ostream::operator<<(v9, &std::endl<char,std::char_traits<char>>);
    return 0;
  }
}

在这里插入图片描述

估计是base64, 但是仔细读一下RxEncode函数, 发现是b64解码函数, 拿工具编码一下

void *__fastcall RxEncode(const char *a1, int a2)
{
  int v3; // [rsp+18h] [rbp-38h]
  int v4; // [rsp+1Ch] [rbp-34h]
  int v5; // [rsp+20h] [rbp-30h]
  int v6; // [rsp+24h] [rbp-2Ch]
  int v7; // [rsp+28h] [rbp-28h]
  int v8; // [rsp+28h] [rbp-28h]
  int i; // [rsp+2Ch] [rbp-24h]
  _BYTE *v10; // [rsp+30h] [rbp-20h]
  void *s; // [rsp+38h] [rbp-18h]

  v3 = 3 * (a2 / 4);
  v4 = 0;
  v5 = 0;
  if ( a1[a2 - 1] == 61 )
    v4 = 1;
  if ( a1[a2 - 2] == 61 )
    ++v4;
  if ( a1[a2 - 3] == 61 )
    ++v4;
  if ( v4 == 3 )
  {
    v3 += 2;
  }
  else if ( v4 <= 3 )
  {
    if ( v4 == 2 )
    {
      v3 += 3;
    }
    else if ( v4 )
    {
      if ( v4 == 1 )
        v3 += 4;
    }
    else
    {
      v3 += 4;
    }
  }
  s = malloc(v3);
  if ( s )
  {
    memset(s, 0, v3);
    v10 = s;
    while ( v5 < a2 - v4 )
    {
      v6 = 0;
      v7 = 0;
      while ( v6 <= 3 && v5 < a2 - v4 )
      {
        v7 = (v7 << 6) | (char)find_pos(a1[v5]);
        ++v6;
        ++v5;
      }
      v8 = v7 << (6 * (4 - v6));
      for ( i = 0; i <= 2 && i != v6; ++i )
        *v10++ = v8 >> (8 * (2 - i));
    }
    *v10 = 0;
    return s;
  }
  else
  {
    puts("No enough memory.");
    return 0LL;
  }
}

在这里插入图片描述

[安洵杯 2019]crackMe

在这里插入图片描述

int __cdecl __noreturn main_0(int argc, const char **argv, const char **envp)
{
  int (__cdecl *v3)(int); // [esp-4h] [ebp-D0h]

  printf("please Input the flag:\n");
  scanf_s("%s", &input);
  MessageBoxW(0, L"Exception", L"Warning", 0);
  v3 = sub_41100F;
  MEMORY[0] = 1;
  sub_411136(HIWORD(v3));
}

void __noreturn sub_4132E0()
{
  if ( !j_strcmp(Str1, Str2) )
    printf("right\n");
  else
    printf("wrong\n");
  system("pause");
  exit(0);
}

静态代码的逻辑找不到线索, 动调一下, 进入下面这个函数, 大小写互换
在这里插入图片描述

输入flag之后, 会进入exception处理, 这里会被AddVectoredExceptionHandlerhook, 然后调用handler执行, 点进去

int __stdcall Handler_0(_DWORD **a1)
{
  char v2[20]; // [esp+D0h] [ebp-18h] BYREF

  if ( **a1 == -1073741819 )
  {
    qmemcpy(v2, "where_are_u_now?", 16);
    sub_951172(&unk_95A218, v2);
    SetUnhandledExceptionFilter(TopLevelExceptionFilter);
  }
  return 0;
}

int __cdecl sub_951F50(int a1, unsigned int *a2)
{
  int result; // eax
  unsigned int v3; // [esp+D0h] [ebp-B8h]
  unsigned int v4; // [esp+DCh] [ebp-ACh]
  unsigned int v5; // [esp+E0h] [ebp-A8h]
  unsigned int v6; // [esp+E4h] [ebp-A4h]
  int v7[35]; // [esp+E8h] [ebp-A0h]
  unsigned int v8; // [esp+174h] [ebp-14h]
  unsigned int v9; // [esp+178h] [ebp-10h]
  unsigned int v10; // [esp+17Ch] [ebp-Ch]
  unsigned int v11; // [esp+180h] [ebp-8h]

  v3 = 0;
  v8 = _byteswap_ulong(*a2);
  v9 = _byteswap_ulong(a2[1]);
  v10 = _byteswap_ulong(a2[2]);
  v11 = _byteswap_ulong(a2[3]);
  v4 = v8 ^ 0xA3B1BAC6;
  v5 = dword_957A68[1] ^ v9;
  v6 = dword_957A68[2] ^ v10;
  result = 12;
  v7[0] = dword_957A68[3] ^ v11;
  while ( v3 < 0x20 )
  {
    v7[v3 + 1] = *(&v4 + v3) ^ sub_9514E0(dword_957A78[v3] ^ v7[v3] ^ v7[v3 - 1] ^ *(&v5 + v3));
    *(_DWORD *)(a1 + 4 * v3) = v7[v3 + 1];
    result = ++v3;
  }
  return result;
}

跟进去发现逻辑看不懂, 试用findcrypt找下一下是否有密码函数
在这里插入图片描述

发现SM4的特征值, 猜测sub_951F50是SM4加密, 密钥是where_are_u_now?, 继续跟TopLevelExceptionFilter

int __cdecl sub_952C30(_DWORD *a1)
{
  int result; // eax
  char v2; // [esp+D3h] [ebp-11h]
  size_t i; // [esp+DCh] [ebp-8h]

  result = (int)a1;
  if ( *(_DWORD *)*a1 == 0xC0000005 )
  {
    for ( i = 0; i < j_strlen(Str2); i += 2 )   // process str2
    {
      v2 = Str2[i];
      Str2[i] = Str2[i + 1];
      Str2[i + 1] = v2;
    }
    Str1 = (char *)sub_95126C(byte_95A180);     // process str1 
    *(_DWORD *)(a1[1] + 176) = *(_DWORD *)(*a1 + 20);
    *(_DWORD *)(a1[1] + 164) = *(_DWORD *)(*a1 + 24);
    *(_DWORD *)(a1[1] + 172) = *(_DWORD *)(*a1 + 28);
    *(_DWORD *)(a1[1] + 168) = *(_DWORD *)(*a1 + 32);
    *(_DWORD *)(a1[1] + 156) = *(_DWORD *)(*a1 + 36);
    *(_DWORD *)(a1[1] + 160) = *(_DWORD *)(*a1 + 40);
    *(_DWORD *)(a1[1] + 184) = checkfunc;
    return -1;
  }
  return result;
}

_BYTE *__cdecl sub_953090(char *Str)
{
  int k; // [esp+E4h] [ebp-5Ch]
  int v3; // [esp+F0h] [ebp-50h]
  int j; // [esp+FCh] [ebp-44h]
  int v5; // [esp+108h] [ebp-38h]
  signed int i; // [esp+114h] [ebp-2Ch]
  _BYTE *v7; // [esp+120h] [ebp-20h]
  signed int v8; // [esp+12Ch] [ebp-14h]
  int v9; // [esp+138h] [ebp-8h]

  v5 = 0;
  v8 = j_strlen(Str);
  if ( v8 % 3 )
    v9 = 4 * (v8 / 3) + 4;
  else
    v9 = 4 * (v8 / 3);
  v7 = malloc(__CFADD__(v9, 1) ? -1 : v9 + 1);
  v7[v9] = 0;
  for ( i = 0; i < v8; i += 3 )
  {
    v3 = 0;
    for ( j = 0; j < 3; ++j )
      v3 |= (unsigned __int8)Str[j + i] << (8 * (2 - j));
    for ( k = 0; k < 4; ++k )
    {
      if ( k >= 4 - (i + 3 - v8) && i + 3 > v8 )
        v7[v5] = 33;
      else
        v7[v5] = BASE64_table_95A080[sub_9510FF((v3 >> (6 * (3 - k))) & 0x3F)];
      ++v5;
    }
  }
  return v7;
}

int __cdecl sub_952760(int a1)
{
  return (a1 + 24) % 64;
}

Str2经过奇偶位交换后得到, Str1是经过类似base64编码处理, 跟进去发现sub_952760会进行变表, 猜测是变表base64
最后Str1和Str2进行比较, 逆向思路: Str2处理后, 经过变表base64解码, 然后SM4解密

import base64
from pysm4 import decrypt


def b64_change_decode(encodestr):
    changebase64 = "yzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/abcdefghijklmnopqrstuvwx"
    originbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

    trans_encodestr = encodestr.translate(str.maketrans(changebase64,originbase64))
    res = base64.b64decode(trans_encodestr)
    return res


Str2 = [
    0x31, 0x55, 0x54, 0x41, 0x4F, 0x49, 0x6B, 0x70, 0x79, 0x4F, 
    0x53, 0x57, 0x47, 0x76, 0x2F, 0x6D, 0x4F, 0x59, 0x46, 0x59, 
    0x34, 0x52, 0x21, 0x21
]

Str2_exc = [0 for _ in range(len(Str2))]

for i in range(0, len(Str2), 2):
    Str2_exc[i] = chr(Str2[i + 1]) 
    Str2_exc[i + 1] = chr(Str2[i])
    
Str2 = ''.join(Str2_exc)
print(Str2)

tmp_flag = b64_change_decode(Str2[:len(Str2) - 2] + '==')
mid_flag = int.from_bytes(tmp_flag, byteorder='big')
print(tmp_flag, hex(mid_flag))

key = 'where_are_u_now?'
key_tmp = key.encode('utf-8')
key_int = int.from_bytes(key_tmp, byteorder='big')
print(hex(key_int))

decrypt_flag = decrypt(mid_flag, key_int)
flag = bytes.fromhex(hex(decrypt_flag)[2:]).decode()
# {{ stands for /, }} stands for /
print('flag{{{}}}'.format(flag))

[WUSTCTF2020]funnyre

在这里插入图片描述

无法反编译, 直接读汇编, 这里需要从命令行输入参数
在这里插入图片描述

接下来是头尾的单字节比较, 要求前5个字符是flag{,第38个字符是}, 中间32位字节分别 xor 和 add N个硬编码数据, 如下面的操作, 即对32个字节进行xor操作之后, 再add操作
在这里插入图片描述
在这里插入图片描述

最后和验证数组进行比较
在这里插入图片描述

这些操作可以叠加起来看作是只有一次xor和add, 所以有checklist可以直接爆破

checklist = [
    217,  44,  39, 214, 216,  42, 218,  45, 215,  44, 
    220, 225, 219,  44, 217, 221,  39,  45,  42, 220, 
    219,  44, 225,  41, 218, 218,  44, 218,  42, 217, 
    41,  42
]

def add(xx, kk):
    return [(x+kk) & 0xFF for x in xx]


def xor(xx, kk):
    return [x ^ kk for x in xx]


def check(xx):
    for x in xx:
        if x < ord('0') or (x > ord('9') and x < ord('a')) or x > ord('f'):
            return False
    return True


if __name__ == '__main__':
    for k1 in range(0x100):
        tmp_add = add(checklist, k1)
        for k2 in range(0x100):
            tmp_xor = xor(tmp_add, k2)
            if check(tmp_xor):
                print(bytes(tmp_xor))
                print(k1, k2)

'''
b'1dc20f6e3d497d15cef47d9a66d6f1af'
42 50
b'1dc20f6e3d497d15cef47d9a66d6f1af'
74 18
b'1dc20f6e3d497d15cef47d9a66d6f1af'
170 178
b'1dc20f6e3d497d15cef47d9a66d6f1af'
'''

[WMCTF2020]easy_re

在这里插入图片描述

直接逆找不到线索, 搜索一下 perlapp 逆向找到一个帖子

在这里插入图片描述

perl打包的exe需要找到解压函数, 动态调试, 断点到这个函数之后可以定位到关键代码, 这个解压函数会带有特征字符串script

在这里插入图片描述

rax就是解压函数的返回值, 点进去就发现解压出来的flag

在这里插入图片描述

[GUET-CTF2019]encrypt

在这里插入图片描述

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  unsigned int v3; // eax
  unsigned int length; // eax
  char v6[4]; // [rsp+4h] [rbp-93Ch] BYREF
  int i; // [rsp+8h] [rbp-938h]
  int v8; // [rsp+Ch] [rbp-934h]
  char v9[1040]; // [rsp+10h] [rbp-930h] BYREF
  char v10[16]; // [rsp+420h] [rbp-520h] BYREF
  char input[256]; // [rsp+430h] [rbp-510h] BYREF
  char encrypt[1032]; // [rsp+530h] [rbp-410h] BYREF
  unsigned __int64 v13; // [rsp+938h] [rbp-8h]

  v13 = __readfsqword(0x28u);
  v10[0] = 16;
  v10[1] = 32;
  v10[2] = 48;
  v10[3] = 48;
  v10[4] = 32;
  v10[5] = 32;
  v10[6] = 16;
  v10[7] = 64;
  memset(input, 0, sizeof(input));
  v8 = strlen(input);
  memset(encrypt, 0, 0x400uLL);
  printf("please input your flag:");
  scanf("%s", input);
  memset(v9, 0, 0x408uLL);
  func1(v9, v10, 8LL);
  v3 = strlen(input);
  func2(v9, input, v3);
  length = strlen(input);
  func3(input, length, encrypt, v6);
  for ( i = 0; i <= 50; ++i )
  {
    if ( encrypt[i] != checklist[i] )
    {
      puts("Wrong");
      return 0LL;
    }
  }
  puts("Good");
  return 0LL;
}

bool __fastcall sub_4006B6(_DWORD *a1, __int64 a2, int a3)
{
  bool result; // al
  int i; // [rsp+1Ch] [rbp-18h]
  int j; // [rsp+1Ch] [rbp-18h]
  int v6; // [rsp+20h] [rbp-14h]
  int v7; // [rsp+24h] [rbp-10h]
  int v8; // [rsp+28h] [rbp-Ch]
  _DWORD *v9; // [rsp+2Ch] [rbp-8h]

  *a1 = 0;
  a1[1] = 0;
  v9 = a1 + 2;
  for ( i = 0; i <= 255; ++i )
    v9[i] = i;
  v7 = 0;
  result = 0;
  LOBYTE(v6) = 0;
  for ( j = 0; j <= 255; ++j )
  {
    v8 = v9[j];
    v6 = (unsigned __int8)(v6 + v8 + *(_BYTE *)(v7 + a2));
    v9[j] = v9[v6];
    v9[v6] = v8;
    result = ++v7 >= a3;
    if ( v7 >= a3 )
      v7 = 0;
  }
  return result;
}

_DWORD *__fastcall func2(_DWORD *a1, __int64 input, int a3)
{
  _DWORD *result; // rax
  int i; // [rsp+18h] [rbp-1Ch]
  int v5; // [rsp+1Ch] [rbp-18h]
  int v6; // [rsp+20h] [rbp-14h]
  int v7; // [rsp+24h] [rbp-10h]
  int v8; // [rsp+28h] [rbp-Ch]
  _DWORD *v9; // [rsp+2Ch] [rbp-8h]

  v5 = *a1;
  v6 = a1[1];
  v9 = a1 + 2;
  for ( i = 0; i < a3; ++i )
  {
    v5 = (unsigned __int8)(v5 + 1);
    v7 = v9[v5];
    v6 = (unsigned __int8)(v6 + v7);
    v8 = v9[v6];
    v9[v5] = v8;
    v9[v6] = v7;
    *(_BYTE *)(i + input) ^= LOBYTE(v9[(unsigned __int8)(v7 + v8)]);
  }
  *a1 = v5;
  result = a1;
  a1[1] = v6;
  return result;
}

_DWORD *__fastcall func3(__int64 input, int length, const char *encrypt, _DWORD *a4)
{
  int v4; // eax
  int v5; // eax
  unsigned __int8 v6; // al
  int v7; // eax
  unsigned __int8 v8; // al
  int v9; // eax
  int v10; // edx
  _DWORD *result; // rax
  char v13; // [rsp+2Dh] [rbp-13h]
  unsigned __int8 v14; // [rsp+2Eh] [rbp-12h]
  unsigned __int8 v15; // [rsp+2Fh] [rbp-11h]
  int v16; // [rsp+30h] [rbp-10h]
  int i; // [rsp+34h] [rbp-Ch]

  v16 = 0;
  i = 0;
  while ( i < length )
  {
    v4 = i++;
    v13 = *(_BYTE *)(v4 + input);
    if ( i >= length )
    {
      v6 = 0;
    }
    else
    {
      v5 = i++;
      v6 = *(_BYTE *)(v5 + input);
    }
    v14 = v6;
    if ( i >= length )
    {
      v8 = 0;
    }
    else
    {
      v7 = i++;
      v8 = *(_BYTE *)(v7 + input);
    }
    v15 = v8;
    encrypt[v16] = ((v13 >> 2) & 0x3F) + '=';
    encrypt[v16 + 1] = ((((int)v14 >> 4) | (16 * v13)) & 0x3F) + '=';
    encrypt[v16 + 2] = ((((int)v8 >> 6) | (4 * v14)) & 0x3F) + '=';
    v9 = v16 + 3;
    v16 += 4;
    encrypt[v9] = (v15 & 0x3F) + '=';
  }
  if ( length % 3 == 1 )
  {
    encrypt[--v16] = '=';
  }
  else if ( length % 3 != 2 )
  {
    goto LABEL_15;
  }
  encrypt[v16 - 1] = 61;
LABEL_15:
  v10 = strlen(encrypt);
  result = a4;
  *a4 = v10;
  return result;
}

RC4加密, 动调拿xor数组, 写逆

#include <stdio.h>


int data0[258] = {
    0x00, 0x00, 0xB0, 0x31, 0x75, 0x70, 0xF8, 0xDF,
    0x07, 0x3C, 0x78, 0x71, 0x50, 0x29, 0x2C, 0x16,
    0x69, 0x12, 0xC8, 0x2B, 0x3B, 0x7F, 0xB2, 0xE7,
    0x4B, 0x68, 0x8C, 0xC5, 0xA6, 0x15, 0x03, 0x58,
    0x47, 0x04, 0x13, 0x8D, 0x87, 0x26, 0x09, 0xED,
    0x17, 0x8A, 0xC2, 0xF2, 0x43, 0xC0, 0xAC, 0x59,
    0x97, 0xF5, 0x3F, 0x67, 0x5E, 0x39, 0x86, 0xD5,
    0x72, 0x61, 0xDA, 0xF7, 0x01, 0x05, 0x8B, 0xC3,
    0xB1, 0x77, 0xAF, 0x1D, 0x30, 0xC6, 0x45, 0x0E,
    0x5F, 0xEE, 0xAE, 0xF0, 0x28, 0xCE, 0xCD, 0xA7,
    0x9B, 0x2A, 0x19, 0x48, 0x08, 0x44, 0x20, 0xFE,
    0x6D, 0xB5, 0x2E, 0x6A, 0xF1, 0x34, 0xBC, 0x1E,
    0x3E, 0xCC, 0x41, 0x92, 0xD8, 0xBD, 0xA5, 0xE8,
    0x4D, 0x0A, 0x49, 0x0D, 0xA2, 0xFA, 0x62, 0x74,
    0xD4, 0x83, 0x96, 0x94, 0x3D, 0xCB, 0x18, 0x63,
    0x99, 0x46, 0xCA, 0xB7, 0x8E, 0xCF, 0xFB, 0xA3,
    0x6C, 0x7E, 0x51, 0x27, 0x60, 0x9A, 0x11, 0xF3,
    0x5C, 0x6E, 0xBA, 0x42, 0x76, 0x2F, 0xEF, 0xBF,
    0x21, 0xAA, 0xE4, 0xD6, 0x1B, 0x55, 0x7D, 0xBE,
    0xEA, 0xD3, 0x10, 0xF4, 0xC7, 0x4A, 0x23, 0x79,
    0x84, 0xA4, 0x1C, 0xAB, 0x14, 0xDB, 0x4C, 0x3A,
    0xB8, 0x52, 0xEC, 0x37, 0x38, 0xB6, 0xD2, 0xA0,
    0x5A, 0x5B, 0x98, 0x66, 0x54, 0x9E, 0x4E, 0x4F,
    0xB4, 0xC4, 0xC9, 0xD0, 0x25, 0x9C, 0x80, 0xDE,
    0x2D, 0x06, 0x22, 0x0B, 0x91, 0x6B, 0x9F, 0xF6,
    0xE6, 0xE2, 0xC1, 0x0F, 0x93, 0x90, 0x7B, 0x9D,
    0x8F, 0xDD, 0xE5, 0x65, 0x35, 0xAD, 0xA9, 0xDC,
    0x82, 0xBB, 0x00, 0x53, 0xD1, 0xA8, 0x33, 0xE9,
    0x40, 0x1A, 0xFF, 0xA1, 0x95, 0x36, 0xD9, 0xEB,
    0x89, 0xE3, 0x7C, 0x73, 0x85, 0x88, 0x7A, 0xE0,
    0xFD, 0x64, 0x0C, 0x57, 0x32, 0xB3, 0xB9, 0x1F,
    0xD7, 0xFC, 0x81, 0xE1, 0x02, 0xF9, 0x5D, 0x56,
    0x6F, 0x24 
};
    
unsigned char checklist[52] = {
	0x5a, 0x60, 0x54, 0x7A, 0x7A, 0x54, 0x72, 0x44, 0x7C, 0x66, 0x51, 0x50, 0x5B, 0x5F, 0x56, 0x56, 
	0x4C, 0x7C, 0x79, 0x6E, 0x65, 0x55, 0x52, 0x79, 0x55, 0x6D, 0x46, 0x6B, 0x6C, 0x56, 0x4A, 0x67, 
	0x4C, 0x61, 0x73, 0x4A, 0x72, 0x6F, 0x5A, 0x70, 0x48, 0x52, 0x78, 0x49, 0x55, 0x6C, 0x48, 0x5C, 
	0x76, 0x5A, 0x45, 0x3D
};

void exchange(unsigned char*flag, int len) {
    int v7, v8,i,v3,v4;
    v7 = data0[0];
    v8 = data0[1];
    int* v9 = data0 + 2;
    for (i = 0; i < len; ++i) {
        v7 = (unsigned char)(v7 + 1);
        v3 = v9[v7];
        v8 = (unsigned char)(v8 + v3);
        v4 = v9[v8];
        v9[v7] = v4;
        v9[v8] = v3;
        flag[i] ^= v9[(unsigned char)(v3 + v4)];
    }
}

int main() {
    unsigned char flag[40] = { 0 };
    int i = 0,j = 0;
    for (i = 0; i < 52; i++)
        checklist[i] -= 61;
        
    for (i = 0, j = 0; i < 52; i += 4, j += 3) {
        flag[j] = checklist[i] << 2 | checklist[i + 1] >> 4;
        flag[j + 1] = (checklist[i + 1] & 0xF) << 4 | checklist[i + 2] >> 2;
        flag[j + 2] = (checklist[i + 2] & 0xF) << 6 | checklist[i + 3];
    }
    
    exchange(flag, 39);
    flag[38] = 0;
    printf("%s\n", (char*)flag);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值