IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> [buuctf.reverse] 33到50题 -> 正文阅读

[C++知识库][buuctf.reverse] 33到50题

目录

033_[MRCTF2020]Xor

034_[GWCTF 2019]xxor

035_[MRCTF2020]hello_world_go

036_[WUSTCTF2020]level3

037_[FlareOn4]IgniteMe

038_[WUSTCTF2020]Cr0ssfun

039_[FlareOn6]Overlong

040_[FlareOn3]Challenge1

041_[BJDCTF2020]BJD hamburger competition

042_[UTCTF2020]basic-re

043_[ACTF新生赛2020]Oruga

044_[Zer0pts2020]easy strcmp

045_[ACTF新生赛2020]Universe_final_answer

046_特殊的 BASE64

047_[WUSTCTF2020]level4

048_crackMe

049_[网鼎杯 2020 青龙组]singal

050_[GUET-CTF2019]number_game


033_[MRCTF2020]Xor

名字叫xor,但进去后没法F5

.text:00401090                 push    offset aGiveMeYourFlag ; "Give Me Your Flag String:\n"
.text:00401095                 call    sub_401020
.text:0040109A                 push    64h ; 'd'
.text:0040109C                 push    offset byte_4212C0
.text:004010A1                 push    offset aS       ; "%s"
.text:004010A6                 call    sub_401050
.text:004010AB                 mov     edx, offset byte_4212C0
.text:004010B0                 add     esp, 10h
.text:004010B3                 lea     ecx, [edx+1]
.text:004010B6
.text:004010B6 loc_4010B6:                             ; CODE XREF: _main+2B↓j
.text:004010B6                 mov     al, [edx]
.text:004010B8                 inc     edx
.text:004010B9                 test    al, al
.text:004010BB                 jnz     short loc_4010B6
.text:004010BD                 sub     edx, ecx
.text:004010BF                 cmp     edx, 1Bh
.text:004010C2                 jnz     short loc_4010FF
.text:004010C4                 xor     eax, eax
.text:004010C6                 db      66h, 66h
.text:004010C6                 nop     word ptr [eax+eax+00000000h]
.text:004010D0
.text:004010D0 loc_4010D0:                             ; CODE XREF: _main+53↓j
.text:004010D0                 mov     cl, byte_4212C0[eax]
.text:004010D6                 xor     cl, al
.text:004010D8                 cmp     cl, ds:byte_41EA08[eax]
.text:004010DE                 jnz     short loc_4010FF
.text:004010E0                 inc     eax
.text:004010E1                 cmp     eax, edx
.text:004010E3                 jb      short loc_4010D0
.text:004010E5                 push    offset aRight   ; "Right!\n"
.text:004010EA                 call    sub_401020
.text:004010EF                 push    offset aPause   ; "pause"
.text:004010F4                 call    sub_404B7E

从4010C6这块就不清楚了,于是把这些不理它直接跳过,从汇编上看前边是scanf读入,后边就是个xor然后for结束就出right了。

在4010D0 读入一字节到cl,然后和al异或,al存的是位置偏移——序号,就是跟序号异或。

a = b'MSAWB~FXZ:J:`tQJ"N@ bpdd}8g'
print(bytes([i^v for i,v in enumerate(a)]))
#MRCTF{@_R3@1ly_E2_R3verse!}
#flag{@_R3@1ly_E2_R3verse!}

034_[GWCTF 2019]xxor

又一个xor但这个能F5,可以看到它每两上字节作个加密。这个似曾相识,叫RC4吧。就是前一半和后一半用对方加密,这样从后向前进行N轮就能解密

......
  for ( j = 0; j <= 2; ++j )
  {
    dword_601078 = v6[j];
    dword_60107C = HIDWORD(v6[j]);
    a2 = (char **)dword_601060;
    sub_400686((unsigned int *)&dword_601078, dword_601060);// RC4加密
    LODWORD(v7[j]) = dword_601078;
    HIDWORD(v7[j]) = dword_60107C;
  }
}
//加密
__int64 __fastcall sub_400686(unsigned int *a1, _DWORD *a2)
{
  __int64 result; // rax
  unsigned int v3; // [rsp+1Ch] [rbp-24h]
  unsigned int v4; // [rsp+20h] [rbp-20h]
  int v5; // [rsp+24h] [rbp-1Ch]
  unsigned int i; // [rsp+28h] [rbp-18h]

  v3 = *a1;
  v4 = a1[1];
  v5 = 0;
  for ( i = 0; i <= 0x3F; ++i )
  {
    v5 += 0x458BCD42;
    v3 += (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
    v4 += (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
  }
  *a1 = v3;
  result = v4;
  a1[1] = v4;
  return result;
}
//结果,加密后对比
__int64 __fastcall sub_400770(_DWORD *a1)
{
  __int64 result; // rax

  if ( a1[2] - a1[3] == 0x84A236FFLL
    && a1[3] + a1[4] == 0xFA6CB703LL
    && a1[2] - a1[4] == 0x42D731A8LL
    && *a1 == 0xDF48EF7E
    && a1[5] == 0x84F30420
    && a1[1] == 0x20CAACF4 )
  {
    puts("good!");
    result = 1LL;
  }
  else
  {
    puts("Wrong!");
    result = 0LL;
  }
  return result;
}

解密

v7 = [0xDF48EF7E, 0x20CAACF4, 0,0,0,0]
v7[2] = ((0x84A236FF+0x42D731A8+0xFA6CB703)//2)& 0xffffffff
v7[3] = (v7[2] - 0x84A236FF) & 0xffffffff
v7[4] = (v7[2] - 0x42D731A8) & 0xffffffff
v7[5] = 0x84F30420

a2 = [2,2,3,4]
tab = [0]*0x40 
v5 = 0
for i in range(0x40):
    v5 += 0x458BCD42
    v5 = v5 & 0xffffffff
    tab[i] = v5 

#[print(hex(i)) for i in tab]
    

from libnum import n2s
#    v3 += (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
#    v4 += (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
def rc4(v3,v4):
    global flag
    for i in range(0x3f,-1,-1):
        v4 -= (v3 + tab[i] + 20)^((v3 << 6)+ a2[2]) ^ ((v3>>9) + a2[3]) ^ 0x10 
        v4 = v4 & 0xffffffff
        v3 -= (v4 + tab[i] + 11)^((v4 << 6)+ a2[0]) ^ ((v4>>9) + a2[1]) ^ 0x20 
        v3 = v3 & 0xffffffff
    #print(n2s(v3), n2s(v4), hex(v3), hex(v4))
    flag +=n2s(v3) + n2s(v4)

flag = b''
for i in range(0,6,2):
    rc4(v7[i], v7[i+1])

print(flag)
#flag{re_is_great!}

035_[MRCTF2020]hello_world_go

这个啥也不用

.rodata:00000000004D3C58 aFlagHelloWorld db 'flag{hello_world_gogogo}function not implementedgcDrainN phase in'

036_[WUSTCTF2020]level3

一个变表的base64

__int64 O_OLookAtYou()
{
  __int64 result; // rax
  char v1; // [rsp+1h] [rbp-5h]
  int i; // [rsp+2h] [rbp-4h]

  for ( i = 0; i <= 9; ++i )
  {
    v1 = base64_table[i];
    base64_table[i] = base64_table[19 - i];
    result = 19 - i;
    base64_table[result] = v1;
  }
  return result;
}

直接转加再base64

code = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
ncode = list(code)
for i in range(10):
    ncode[i],ncode[19-i] = ncode[19-i],ncode[i]

ncode = bytes(ncode)
print(ncode)
c = b"d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD=="
c = bytes([code[ncode.index(i)] for i in c])
print(c)
from base64 import b64decode 
print(b64decode(c))
#wctf2020{Base64_is_the_start_of_reverse}
#flag{Base64_is_the_start_of_reverse}

037_[FlareOn4]IgniteMe

程序很短,有点像AES,先用初始值异或,然后存回,再用加密后的值异或下一个

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

  v1 = strlen((int)byte_403078);
  v4 = ret_4();                                 // 4
  for ( i = v1 - 1; i >= 0; --i )
  {
    byte_403180[i] = v4 ^ byte_403078[i];
    v4 = byte_403078[i];
  }
  for ( j = 0; j < 0x27; ++j )
  {
    if ( byte_403180[j] != (unsigned __int8)byte_403000[j] )
      return 0;
  }
  return 1;
}

从前向后再来一遍

a = [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]
v4 = 4
b = [0]*0x27
for i in range(0x26,-1,-1):
    a[i] = v4^a[i]
    v4 = a[i]

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

038_[WUSTCTF2020]Cr0ssfun

这个有很多下边这样的函数,每个对比3字节

_BOOL8 __fastcall finally_fun(_BYTE *a1)
{
  return a1[1] == 99 && a1[25] == 64 && a1[27] == 101;
}

都写一起就是

a = [0]*33
a[10]=112
a[13]=64
......
a[27]=101
print(bytes(a))
#wctf2020{cpp_@nd_r3verse_@re_fun}
#flag{cpp_@nd_r3verse_@re_fun}

039_[FlareOn6]Overlong

除了不运行都有了

int __cdecl sub_401000(_BYTE *a1, char *a2)
{
  int v3; // [esp+0h] [ebp-8h]
  char v4; // [esp+4h] [ebp-4h]

  if ( (int)(unsigned __int8)*a2 >> 3 == 30 )
  {
    v4 = a2[3] & 0x3F | ((a2[2] & 0x3F) << 6);
    v3 = 4;
  }
  else if ( (int)(unsigned __int8)*a2 >> 4 == 14 )
  {
    v4 = a2[2] & 0x3F | ((a2[1] & 0x3F) << 6);
    v3 = 3;
  }
  else if ( (int)(unsigned __int8)*a2 >> 5 == 6 )
  {
    v4 = a2[1] & 0x3F | ((*a2 & 0x1F) << 6);
    v3 = 2;
  }
  else
  {
    v4 = *a2;
    v3 = 1;
  }
  *a1 = v4;
  return v3;
}

照这个写一下再运行

a = [0xE0,0x81,0x89,0xC0,0xA0,0xC1,0xAE,0xE0,0x81,0xA5,0xC1,0xB6,0xF0,0x80,0x81,0xA5,0xE0,0x81,0xB2,0xF0,0x80,0x80,0xA0,0xE0,0x81,0xA2,0x72,0x6F,0xC1,0xAB,0x65,0xE0,0x80,0xA0,0xE0,0x81,0xB4,0xE0,0x81,0xA8,0xC1,0xA5,0x20,0xC1,0xA5,0xE0,0x81,0xAE,0x63,0xC1,0xAF,0xE0,0x81,0xA4,0xF0,0x80,0x81,0xA9,0x6E,0xC1,0xA7,0xC0,0xBA,0x20,0x49,0xF0,0x80,0x81,0x9F,0xC1,0xA1,0xC1,0x9F,0xC1,0x8D,0xE0,0x81,0x9F,0xC1,0xB4,0xF0,0x80,0x81,0x9F,0xF0,0x80,0x81,0xA8,0xC1,0x9F,0xF0,0x80,0x81,0xA5,0xE0,0x81,0x9F,0xC1,0xA5,0xE0,0x81,0x9F,0xF0,0x80,0x81,0xAE,0xC1,0x9F,0xF0,0x80,0x81,0x83,0xC1,0x9F,0xE0,0x81,0xAF,0xE0,0x81,0x9F,0xC1,0x84,0x5F,0xE0,0x81,0xA9,0xF0,0x80,0x81,0x9F,0x6E,0xE0,0x81,0x9F,0xE0,0x81,0xA7,0xE0,0x81,0x80,0xF0,0x80,0x81,0xA6,0xF0,0x80,0x81,0xAC,0xE0,0x81,0xA1,0xC1,0xB2,0xC1,0xA5,0xF0,0x80,0x80,0xAD,0xF0,0x80,0x81,0xAF,0x6E,0xC0,0xAE,0xF0,0x80,0x81,0xA3,0x6F,0xF0,0x80,0x81,0xAD,0]

def sub_401000(p):
    global b
    
    if a[p]>>3 == 30: #f0
        v4 = ((a[p+3]&0x3f) | ((a[p+2]&0x3f)<<6)) &0xff 
        v3 = 4 
    elif a[p]>>4 == 14: #e0
        v4 = ((a[p+2]&0x3f)|((a[p+1]&0x3f)<<6))&0xff
        v3 = 3
    elif a[p]>>5 == 6: #c0
        v4 = ((a[p+1]&0x3f)|((a[p]&0x1f)<<6))& 0xff
        v3 = 2
    else:
        v4 = a[p]
        v3 = 1 
    b.append(v4)
    return v3 

p = 0
b = []
while True:
    p += sub_401000(p)
    if b[-1]==0:
        print(bytes(b))
        break
#b'I never broke the encoding: I_a_M_t_h_e_e_n_C_o_D_i_n_g@flare-on.com\x00'
#flag{I_a_M_t_h_e_e_n_C_o_D_i_n_g@flare-on.com}

040_[FlareOn3]Challenge1

变表的base64

    v7 = v3 + (v5 << 16) + (v4 << 8);
    v8[v9] = aZyxabcdefghijk[(v7 >> 18) & 0x3F];// 前6位
    v10 = v9 + 1;
    v8[v10] = aZyxabcdefghijk[(v7 >> 12) & 0x3F];
    v8[++v10] = aZyxabcdefghijk[(v7 >> 6) & 0x3F];
    v8[++v10] = aZyxabcdefghijk[v3 & 0x3F];
    v9 = v10 + 1;
code = 'ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/='
ncode= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
c = "x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q"
m = ''.join([ncode[code.index(i)] for i in c])
from base64 import *
print(b64decode(m))
#sh00ting_phish_in_a_barrel@flare-on.com
#flag{sh00ting_phish_in_a_barrel@flare-on.com}

041_[BJDCTF2020]BJD hamburger competition

这题做过了,Unity的游戏找Assembly-CSharp.dll文件用dnSpy打开,给sha1求md5转大写前20位,由于输入是数字而且不大,直接爆破

from hashlib import *

s_sha1 = 'DD01903921EA24941C26A48F2CEC24E0BB0E8CC7'.lower()
for i in range(999999):
    if sha1(str(i).encode()).hexdigest() == s_sha1:
        print('flag{'+md5(str(i).encode()).hexdigest().upper()[:20]+'}')
        break
#flag{B8C37E33DEFDE51CF91E}

042_[UTCTF2020]basic-re

打开以后汇编里有flag

.text:00000000000012FA                 lea     rax, aUtflagStr1ngs1 ; "utflag{str1ngs_1s_y0ur_fr13nd}"

043_[ACTF新生赛2020]Oruga

ida打开发现主要逻辑是4个字母应该分别表示的是上下左右,应该是迷宫,找到迷宫串

  while ( byte_201020[v2] != 33 )
  {
    v2 -= v4;
    if ( *(_BYTE *)(v3 + a1) != 87 || v4 == -16 )// W
    {
      if ( *(_BYTE *)(v3 + a1) != 69 || v4 == 1 )// E
      {
        if ( *(_BYTE *)(v3 + a1) != 77 || v4 == 16 )// M
        {
          if ( *(_BYTE *)(v3 + a1) != 74 || v4 == -1 )// J
            return 0LL;
          v4 = -1;
        }
        else
        {
          v4 = 16;
        }
      }
      else
      {
        v4 = 1;
      }
    }
    else
    {
      v4 = -16;
    }
    ++v3;
    while ( !byte_201020[v2] )
    {
      if ( v4 == -1 && (v2 & 0xF) == 0 )        // 边界 滑行不能出边界
        return 0LL;
      if ( v4 == 1 && v2 % 16 == 15 )
        return 0LL;
      if ( v4 == 16 && (unsigned int)(v2 - 240) <= 0xF )
        return 0LL;
      if ( v4 == -16 && (unsigned int)(v2 + 15) <= 0x1E )
        return 0LL;
      v2 += v4;
    }
  
.data:0000000000201020 byte_201020     db 4 dup(0), 23h, 7 dup(0), 4 dup(23h), 3 dup(0), 2 dup(23h)
.data:0000000000201020                                         ; DATA XREF: sub_78A+23↑o
.data:0000000000201020                                         ; sub_78A+DC↑o
.data:0000000000201020                 db 3 dup(0), 2 dup(4Fh), 0Eh dup(0), 2 dup(4Fh), 0, 2 dup(50h)
.data:0000000000201020                 db 6 dup(0), 4Ch, 0, 2 dup(4Fh), 0, 2 dup(4Fh), 0, 2 dup(50h)
.data:0000000000201020                 db 6 dup(0), 4Ch, 0, 2 dup(4Fh), 0, 2 dup(4Fh), 0, 50h
.data:0000000000201020                 db 6 dup(0), 2 dup(4Ch), 0, 2 dup(4Fh), 4 dup(0), 50h
.data:0000000000201020                 db 9 dup(0), 2 dup(4Fh), 4 dup(0), 50h, 4 dup(0), 23h
.data:0000000000201020                 db 1Bh dup(0), 23h, 9 dup(0), 3 dup(4Dh), 3 dup(0), 23h
.data:0000000000201020                 db 0Ah dup(0), 3 dup(4Dh), 4 dup(0), 2 dup(45h), 3 dup(0)
.data:0000000000201020                 db 30h, 0, 4Dh, 0, 4Dh, 0, 4Dh, 4 dup(0), 45h, 0Fh dup(0)
.data:0000000000201020                 db 2 dup(45h), 3 dup(54h), 49h, 0, 4Dh, 0, 4Dh, 0, 4Dh
.data:0000000000201020                 db 4 dup(0), 45h, 2 dup(0), 54h, 0, 49h, 0, 4Dh, 0, 4Dh
.data:0000000000201020                 db 0, 4Dh, 4 dup(0), 45h, 2 dup(0), 54h, 0, 49h, 0, 4Dh
.data:0000000000201020                 db 0, 4Dh, 0, 4Dh, 21h, 3 dup(0), 2 dup(45h)
.data:0000000000201020 _data           ends

只处理0和非0要结束

data = open('oruga', 'rb').read()[0x1020: 0x1020+0x100]
print('*'*16)	
for i in range(16):
    for j in range(16):
        if data[i*16+j] == 0:
            print(' ', end='')
        elif data[i*16+j] == 33:
            print('O', end='')
        else:
            print('#', end='')
            
    print('*')
print('*'*16)	
'''
****************
    #       ####*
   ##   ##      *
        ## ##   *
   # ## ## ##   *
   # ## ## #    *
  ## ##    #    *
     ##    #    *
#               *
            #   *
      ###   #   *
       ###    ##*
   # # # #    # *
              ##*
#### # # #    # *
 # # # # #    # *
 # # # # #O   ##*
****************
'''

用手走出迷宫

#MEWEMEWJMEWJM
#flag{MEWEMEWJMEWJM}

044_[Zer0pts2020]easy strcmp

这是个加法操作,这个少见

__int64 __fastcall sub_6EA(__int64 a1, __int64 a2)
{
  int i; // [rsp+18h] [rbp-8h]
  int v4; // [rsp+18h] [rbp-8h]
  int j; // [rsp+1Ch] [rbp-4h]

  for ( i = 0; *(_BYTE *)(i + a1); ++i )
    ;
  v4 = (i >> 3) + 1;
  for ( j = 0; j < v4; ++j )
    *(_QWORD *)(8 * j + a1) -= qword_201060[j];
  return qword_201090(a1, a2);
}

还有一个特殊的串

.rodata:00000000000008C8 ; const char format[]
.rodata:00000000000008C8 format          db 'Usage: %s <FLAG>',0Ah,0
.rodata:00000000000008C8                                         ; DATA XREF: main+1F↑o
.rodata:00000000000008DA                 align 20h
.rodata:00000000000008E0 ; const char s2[]
.rodata:00000000000008E0 s2              db 'zer0pts{********CENSORED********}',0
.rodata:00000000000008E0                                         ; DATA XREF: main+3D↑o
.rodata:0000000000000902 ; const char s[]
.rodata:0000000000000902 s               db 'Correct!',0         ; DATA XREF: main+50↑o
.rodata:000000000000090B ; const char aWrong[]
.rodata:000000000000090B aWrong          db 'Wrong!',0           ; DATA XREF: main:loc_825↑o
.rodata:000000000000090B _rodata         ends

加法操作的第1个数是0,就是没处理,所以头是原头,这个串就是

key = [0,0x410A4335494A0942, 0x0B0EF2F50BE619F0, 0x4F0A3A064A35282B]
a = b'zer0pts{********CENSORED********'

from libnum import s2n,n2s 
flag = b''
for i in range(4):
    j = s2n(a[i*8: i*8+8][::-1]) + key[i]  #大端存储
    flag += n2s(j)[::-1]

print(flag)  
#b'zer0pts{l3ts_m4k3_4_DETOUR_t0d4y'
#flag{l3ts_m4k3_4_DETOUR_t0d4y}  

045_[ACTF新生赛2020]Universe_final_answer

看上去是个很复杂的操作

bool __fastcall sub_860(char *a1)
{
  int v2; // ecx
  int v1; // esi
  int v3; // edx
  int v4; // er9
  int v5; // er11
  int v7; // ebp
  int v6; // ebx
  int v8; // er8
  int v9; // er10
  bool result; // al
  int v11; // [rsp+0h] [rbp-38h]

  v2 = a1[1];
  v1 = *a1;
  v3 = a1[2];
  v4 = a1[3];
  v5 = a1[4];
  v7 = a1[6];
  v6 = a1[5];
  v8 = a1[7];
  v9 = a1[8];
  result = 0;
  if ( -85 * v9 + 58 * v8 + 97 * v7 + v6 + -45 * v5 + 84 * v4 + 95 * v1 - 20 * v2 + 12 * v3 == 12613 )
  {
    v11 = a1[9];
    if ( 30 * v11 + -70 * v9 + -122 * v7 + -81 * v6 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v2 - 15 * v1 - 30 * v8 == -54400
      && -103 * v11 + 120 * v8 + 108 * v6 + 48 * v4 + -89 * v3 + 78 * v2 - 41 * v1 + 31 * v5 - (v7 << 6) - 120 * v9 == -10283
      && 71 * v7 + (v6 << 7) + 99 * v5 + -111 * v3 + 85 * v2 + 79 * v1 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855
      && 5 * v11 + 23 * v9 + 122 * v8 + -19 * v7 + 99 * v6 + -117 * v5 + -69 * v3 + 22 * v2 - 98 * v1 + 10 * v4 == -2944
      && -54 * v11 + -23 * v8 + -82 * v3 + -85 * v1 + 124 * v2 - 11 * v4 - 8 * v5 - 60 * v6 + 95 * v7 + 100 * v9 == -2222
      && -83 * v11 + -111 * v6 + -57 * v1 + 41 * v2 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v7 + 77 * v8 - 63 * v9 == -13258
      && 81 * v11 + -48 * v9 + 66 * v8 + -104 * v7 + -121 * v6 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v1 + 80 * v2 == -1559
      && 101 * v11 + -85 * v9 + 7 * v7 + 117 * v6 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v2 + 18 * v1 - v8 == 6308 )
    {
      result = 99 * v11 + -28 * v9 + 5 * v8 + 93 * v7 + -18 * v6 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v2 + 58 * v1 == -1697;
    }
  }
  return result;
}

其实就是个行列比,直接用numpy.linalg求解

'''
 if ( -85 * v9 + 58 * v8 + 97 * v7 + v6 + -45 * v5 + 84 * v4 + 95 * v1 - 20 * v2 + 12 * v3 == 12613 )
  {
    v11 = a1[9];
    if ( 30 * v11 + -70 * v9 + -122 * v7 + -81 * v6 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v2 - 15 * v1 - 30 * v8 == -54400
      && -103 * v11 + 120 * v8 + 108 * v6 + 48 * v4 + -89 * v3 + 78 * v2 - 41 * v1 + 31 * v5 - (v7 << 6) - 120 * v9 == -10283
      && 71 * v7 + (v6 << 7) + 99 * v5 + -111 * v3 + 85 * v2 + 79 * v1 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855
      && 5 * v11 + 23 * v9 + 122 * v8 + -19 * v7 + 99 * v6 + -117 * v5 + -69 * v3 + 22 * v2 - 98 * v1 + 10 * v4 == -2944
      && -54 * v11 + -23 * v8 + -82 * v3 + -85 * v1 + 124 * v2 - 11 * v4 - 8 * v5 - 60 * v6 + 95 * v7 + 100 * v9 == -2222
      && -83 * v11 + -111 * v6 + -57 * v1 + 41 * v2 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v7 + 77 * v8 - 63 * v9 == -13258
      && 81 * v11 + -48 * v9 + 66 * v8 + -104 * v7 + -121 * v6 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v1 + 80 * v2 == -1559
      && 101 * v11 + -85 * v9 + 7 * v7 + 117 * v6 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v2 + 18 * v1 - v8 == 6308 )
    {
      result = 99 * v11 + -28 * v9 + 5 * v8 + 93 * v7 + -18 * v6 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v2 + 58 * v1 == -1697;
    }
'''
tab_a = [
[95,-20,12,84,-45,1,97,58,-85,0],
[-15,-86,-41,-115,-66,-81,-122,-30,-70,30],
[-41,78,-89,48,31,108,-64,120,-120,-103],
[79,85,-111,-30,99,128,71,-119,48,-16],
[-98,22,-69,10,-117,99,-19,122,23,5],
[-85,124,-82,-11,-8,-60,95,-23,100,-54],
[-57,41,73,-18,26,-111,16,77,-63,-83],
[-85,80,60,85,95,-121,-104,66,-48,81],
[18,-28,90,-101,-83,117,7,-1,-85,101],
[58,-93,-9,6,-127,-18,93,5,-28,99]
]
tab_b = [12613,-54400,-10283,22855,-2944,-2222,-13258,-1559,6308,-1697]

import numpy as np
an = np.array(tab_a)
bn = np.array(tab_b)

x = np.linalg.solve(an,bn)
print(x)
print(bytes([round(i) for i in x]))
#F0uRTy_7w@
#actf{F0uRTy_7w@_42}
#flag{F0uRTy_7w@_42}

046_特殊的 BASE64

同上,一个变列的base64

code ="AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0987654321/+="
ncode = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
c = "mTyqm7wjODkrNLcWl0eqO8K8gc1BPk1GNLgUpI=="
m = ''.join([ncode[code.index(i)] for i in c])
from base64 import *
print(b64decode(m))
#flag{Special_Base64_By_Lich}

047_[WUSTCTF2020]level4

给了二叉树的中序和后序遍历,求先序,手工处理了

v2 = "I{_}Af2700ih_secTS2Et_wr"
#Traversal type 1:2f0t02T{hcsiI_SwA__r7Ee}   中序
#Traversal type 2:20f0Th{2tsIS_icArE}e7__w   后序
#先序
#wctf2020{This_IS_A_7reE}
#flag{This_IS_A_7reE}

048_crackMe

加了一堆反调试语句,大至就是与user,pass异或

  }                                             // 16进制转数字
  while ( v6 < 8 )
  {
    v11 += byte_416050[++v12];
    v13 = byte_416050[v12];
    v8 = byte_416050[v11];
    byte_416050[v11] = v13;
    byte_416050[v12] = v8;
    if ( ((int)NtCurrentPeb()->UnicodeCaseTableData & 0x70) != 0 )
      v13 = v11 + v12;
    *(&v17 + v6) = byte_416050[(unsigned __int8)(v8 + v13)] ^ *(&v15 + v5);// ^pass
    if ( (unsigned __int8)*(_DWORD *)&NtCurrentPeb()->BeingDebugged )
    {
      v11 = -83;
      v12 = 43;
    }
    sub_401710((int)&v17, (const char *)user, v6++);// ^user
    v5 = v6;
    if ( v6 >= (unsigned int)(&v15 + strlen(&v15) + 1 - v16) )
      v5 = 0;
  }
  v14 = 0;
  sub_401470(a1, &v17, &v14);
  return v14 == 0xAB94;

然后再异或回来

user = (b"welcomebeijing"*20)[:256]

byte_416050 = [i for i in range(256)]
v9 = 0
for i in range(256):
    v9 += byte_416050[i] + user[i]
    v9 = v9 & 0xff
    byte_416050[i],byte_416050[v9] = byte_416050[v9],byte_416050[i]

v10 = 0
v5  = 0
v11 = 0
out = [0x64,0x62,0x61,0x70,0x70,0x73,0x65,0x63] #结果 = byte_416050 ^ user ^ pass 
v16 = [0]*8
for  v5 in range(8):
    v11 +=1
    v11  = v11 & 0xff 
    v10 += byte_416050[v11]
    v10  = v10&0xff
    v12  = byte_416050[v11]
    v7   = byte_416050[v10]
    byte_416050[v10] = v12 
    byte_416050[v11] = v7 
    v16[v5] = byte_416050[(v7 + v12)&0xff] ^ user[v5] ^ out[v5] #sub_401710 #^ pass[v5]

print(v16)
password = ''
for i in v16:
    password +=hex(i)[2:]
print(password)
from hashlib import md5
print('flag{'+ md5(password.encode()).hexdigest()+'}')
#39d09ffa4cfcc4cc

结果不对,网上说是(没有异或user)

#4eb5f3992391a1ae
print('flag{'+ md5(b'4eb5f3992391a1ae').hexdigest()+'}')
#flag{d2be2981b84f2a905669995873d6a36c}

049_[网鼎杯 2020 青龙组]singal

像VM的题,不过数据都给出来了,只是按样子写个东西运行就行

data = open('signal.exe', 'rb').read()[0x1e40:0x1e40+114*4]
from pwn import u32
data = [ u32(data[i*4: i*4+4]) for i in range(114) ][1:]
print(data)

idx = 0
v5,v6,v7,v8,v9 = 0,0,0,0,0
s = [f"str[{i}]" for i in range(15)]
t,v = [],[]
while v9< len(data):
    if data[v9] == 2:
        v4 = f"({s[v8]}) + {data[v9+1]} "
        v9+=2
    elif data[v9] == 3:
        v4 = f"({s[v8]}) - {data[v9+1]}"
        v9+=2
    elif data[v9] == 4:
        v4 = f"({s[v8]}) ^ {data[v9+1]}"
        v9+=2
    elif data[v9] == 5:
        v4 = f"({s[v8]}) * {data[v9+1]}"
        v9+=2
    elif data[v9] == 11:
        v4 = f"({s[v8]}) -1 "
        v9+=1
    elif data[v9] == 12:
        v4 = f"({s[v8]}) +1"
        v9+=1
    elif data[v9] == 6:
        v9+=1

    elif data[v9] == 1:
        v.append(v4)
        v9+=1
        v6+=1
        v8+=1
    elif data[v9] == 8:
        #s.append(f"str[{v5}] = "+ v4)
        s[v5] = v4
        v9+=1
        v5+=1
    elif data[v9] == 7:
        if data[v9+1] > 0x80000000:
            data[v9+1] = data[v9+1] - 0x100000000
        t.append(f' == {data[v9+1]}')
        v9+=2
        v7+=1
        
print(s)
print(v)
print(t) 
for i in range(15): 
    print(v[i] + t[i])

str = [0]*15
for i in range(15):
    for j in range(0x20,0x7f):
        str[i] = j 
        if eval(v[i] + t[i]+ "&0xff"):
            print(chr(j), end='')
            break 

#757515121f3d478
#flag{757515121f3d478}

050_[GUET-CTF2019]number_game

二叉树遍历,再查重(5*5行列不重复,类似数独,但相当简单)这块手工算,再二叉权遍历手工算

  if ( (unsigned int)sub_4006D6((const char *)&v5) )// 01234组成的10位串
  {
    v4 = sub_400758(&v5, 0LL, 10LL);            // 按层二叉树填充
    sub_400807(v4, &v7);                        // 中序遍历取回 7381940526
    v9 = 0;
    sub_400881(&v7);
    if ( (unsigned int)sub_400917() )
    {
      puts("TQL!");
      printf("flag{");
      printf("%s", (const char *)&v5);
      puts("}");
    }
    else
    {
      puts("your are cxk!!");
    }
  }

__int64 __fastcall sub_400807(__int64 a1, __int64 a2)
{
  __int64 result; // rax

  result = a1;
  if ( a1 )
  {
    sub_400807(*(_QWORD *)(a1 + 8), a2);   //中序遍历
    *(_BYTE *)(a2 + dword_601080++) = *(_BYTE *)a1;
    result = sub_400807(*(_QWORD *)(a1 + 16), a2);
  }
  return result;
}
__int64 sub_400917()
{
  unsigned int v1; // [rsp+0h] [rbp-10h]
  int i; // [rsp+4h] [rbp-Ch]
  int j; // [rsp+8h] [rbp-8h]
  int k; // [rsp+Ch] [rbp-4h]

  v1 = 1;
  for ( i = 0; i <= 4; ++i )
  {
    for ( j = 0; j <= 4; ++j )
    {
      for ( k = j + 1; k <= 4; ++k )
      {
        if ( *((_BYTE *)&unk_601060 + 5 * i + j) == *((_BYTE *)&unk_601060 + 5 * i + k) )
          v1 = 0;
        if ( *((_BYTE *)&unk_601060 + 5 * j + i) == *((_BYTE *)&unk_601060 + 5 * k + i) )
          v1 = 0;
      }
    }
  }
  return v1;
}

手工

#0421421430  中序排列后的结果,中序的顺序7381940526
#1134240024  按中中序顺序取回
#flag{1134240024}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-11 16:14:51  更:2022-05-11 16:15:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 0:55:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码