• BUUCTF reverse wp 91 - 95


    [SCTF2019]Who is he

    IKUN题
    在这里插入图片描述
    Unity逆向, dnSpy反编译Assembly-CSharp.dll, 搜索字符串定位到关键代码

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Security.Cryptography;
    using System.Text;
    using UnityEngine;
    using UnityEngine.UI;
    
    // Token: 0x02000005 RID: 5
    public class TestClick : MonoBehaviour
    {
    	// Token: 0x0600000A RID: 10 RVA: 0x000020C4 File Offset: 0x000002C4
    	private string Encrypt(string str)
    	{
    		string result;
    		try
    		{
    			byte[] bytes = Encoding.Unicode.GetBytes(TestClick.encryptKey);
    			byte[] bytes2 = Encoding.Unicode.GetBytes(str);
    			DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider();
    			MemoryStream memoryStream = new MemoryStream();
    			CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateEncryptor(bytes, bytes), CryptoStreamMode.Write);
    			cryptoStream.Write(bytes2, 0, bytes2.Length);
    			cryptoStream.FlushFinalBlock();
    			byte[] inArray = memoryStream.ToArray();
    			cryptoStream.Close();
    			memoryStream.Close();
    			result = Convert.ToBase64String(inArray);
    		}
    		catch
    		{
    			result = str;
    		}
    		return result;
    	}
    
    	// Token: 0x0600000B RID: 11 RVA: 0x0000215C File Offset: 0x0000035C
    	private string Decrypt(string str)
    	{
    		string result;
    		try
    		{
    			byte[] bytes = Encoding.Unicode.GetBytes(TestClick.encryptKey);
    			byte[] array = Convert.FromBase64String(str);
    			DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider();
    			MemoryStream memoryStream = new MemoryStream();
    			CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateDecryptor(bytes, bytes), CryptoStreamMode.Write);
    			cryptoStream.Write(array, 0, array.Length);
    			cryptoStream.FlushFinalBlock();
    			byte[] bytes2 = memoryStream.ToArray();
    			cryptoStream.Close();
    			memoryStream.Close();
    			result = Encoding.Unicode.GetString(bytes2);
    		}
    		catch
    		{
    			result = str;
    		}
    		return result;
    	}
    
    	// Token: 0x0600000C RID: 12 RVA: 0x000020C1 File Offset: 0x000002C1
    	private void Start()
    	{
    	}
    
    	// Token: 0x0600000D RID: 13 RVA: 0x000021F4 File Offset: 0x000003F4
    	public void OnClick()
    	{
    		Debug.Log("Button Clicked. TestClick.");
    		Debug.Log(this.Name.text);
    		bool flag = this.Name.text.Equals(this.Decrypt(this.EncryptData));
    		if (flag)
    		{
    			Debug.Log("Right");
    			TestClick.Messagebox.MessageBox(IntPtr.Zero, "Haha, same as you!", "Info:", 0);
    		}
    		else
    		{
    			Debug.Log("Wrong");
    			TestClick.Messagebox.MessageBox(IntPtr.Zero, "Emmmmm,I don't think so.", "Info:", 0);
    		}
    	}
    
    	// Token: 0x04000003 RID: 3
    	private static string encryptKey = "1234";
    
    	// Token: 0x04000004 RID: 4
    	private string EncryptData = "1Tsy0ZGotyMinSpxqYzVBWnfMdUcqCMLu0MA+22Jnp+MNwLHvYuFToxRQr0c+ONZc6Q7L0EAmzbycqobZHh4H23U4WDTNmmXwusW4E+SZjygsntGkO2sGA==";
    
    	// Token: 0x04000005 RID: 5
    	public Text Name;
    
    	// Token: 0x02000006 RID: 6
    	public class Messagebox
    	{
    		// Token: 0x06000010 RID: 16
    		[DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    		public static extern int MessageBox(IntPtr handle, string message, string title, int type);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101

    验证的密文b64解码后des解密然后和输入的串check, 但是这里的1Tsy0ZGotyMinSpxqYzVBWnfMdUcqCMLu0MA+22Jnp+MNwLHvYuFToxRQr0c+ONZc6Q7L0EAmzbycqobZHh4H23U4WDTNmmXwusW4E+SZjygsntGkO2sGA==是假的, 用CE动态搜

    在这里插入图片描述

    ctrl+B浏览相关内存区域
    在这里插入图片描述

    在这里插入图片描述

    第一个还是假的, 第二个解出来是flag (注意, 在C#中,字符串默认是Unicode字符串,所以转成字节数组,在每个字符字节后都要加一个"\x00"

    from pyDes import des,PAD_PKCS5,CBC
    import base64
    
    s2 = base64.b64decode('xZWDZaKEhWNMCbiGYPBIlY3+arozO9zonwrYLiVL4njSez2RYM2WwsGnsnjCDnHs7N43aFvNE54noSadP9F8eEpvTs5QPG+KL0TDE/40nbU=')
    key2 = ''.join(['t','\x00','e','\x00','s','\x00','t','\x00'])
    des_obj = des(key2,CBC,key2,padmode=PAD_PKCS5)
    m = des_obj.decrypt(s2)
    print(m.decode('UTF-16'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    [MRCTF2020]EasyCpp

    在这里插入图片描述

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      __int64 v3; // rax
      __int64 v4; // rbx
      __int64 v5; // rax
      int v6; // ebx
      __int64 v7; // rax
      __int64 v8; // rax
      __int64 v9; // rax
      __int64 v10; // rax
      __int64 v11; // rax
      __int64 v12; // rax
      char v14[40]; // [rsp+0h] [rbp-140h] BYREF
      __int64 v15; // [rsp+28h] [rbp-118h] BYREF
      __int64 v16; // [rsp+30h] [rbp-110h] BYREF
      int v17; // [rsp+3Ch] [rbp-104h] BYREF
      char v18[32]; // [rsp+40h] [rbp-100h] BYREF
      char v19[48]; // [rsp+60h] [rbp-E0h] BYREF
      char v20[31]; // [rsp+90h] [rbp-B0h] BYREF
      char v21; // [rsp+AFh] [rbp-91h] BYREF
      char v22[47]; // [rsp+B0h] [rbp-90h] BYREF
      char v23; // [rsp+DFh] [rbp-61h] BYREF
      char v24[36]; // [rsp+E0h] [rbp-60h] BYREF
      unsigned int v25; // [rsp+104h] [rbp-3Ch]
      char *v26; // [rsp+108h] [rbp-38h]
      int *v27; // [rsp+110h] [rbp-30h]
      _DWORD *v28; // [rsp+118h] [rbp-28h]
      int *v29; // [rsp+120h] [rbp-20h]
      int i; // [rsp+128h] [rbp-18h]
      unsigned int v31; // [rsp+12Ch] [rbp-14h]
    
      v31 = 0;
      std::vector<int>::vector(v20, argv, envp);
      std::vector<bool>::vector(v19);
      std::allocator<char>::allocator(&v21);
      std::string::basic_string(v18, &unk_500E, &v21);
      std::allocator<char>::~allocator(&v21);
      v3 = std::operator<<<std::char_traits<char>>(&std::cout, "give me your key!");
      std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
      for ( i = 0; i <= 8; ++i )
      {
        std::istream::operator>>(&std::cin, &keys[i]);
        std::to_string((std::__cxx11 *)v22, keys[i]);
        std::string::operator+=(v18, v22);
        std::string::~string(v22);
      }
      v28 = keys;
      v29 = keys;
      v27 = (int *)&unk_83E4;
      while ( v29 != v27 )
      {
        v17 = *v29;
        std::vector<int>::push_back(v20, &v17);
        ++v29;
      }
      v4 = std::vector<int>::end(v20);
      v5 = std::vector<int>::begin(v20);
      std::for_each<__gnu_cxx::__normal_iterator<int *,std::vector<int>>,main::{lambda(int &)#1}>(v5, v4);
      v26 = v20;
      v16 = std::vector<int>::begin(v20);
      v15 = std::vector<int>::end(v26);
      while ( (unsigned __int8)__gnu_cxx::operator!=<int *,std::vector<int>>(&v16, &v15) )
      {
        v25 = *(_DWORD *)__gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator*(&v16);
        std::allocator<char>::allocator(&v23);
        std::string::basic_string(v14, &unk_500E, &v23);
        std::allocator<char>::~allocator(&v23);
        depart(v25, v14);
        {lambda(std::string &)#1}::operator()(&func, v14);
        std::string::basic_string(v24, v14);
        v6 = {lambda(std::string,int)#2}::operator()(&check, v24, v31) ^ 1;
        std::string::~string(v24);
        if ( (_BYTE)v6 )
        {
          v7 = std::operator<<<std::char_traits<char>>(&std::cout, "Wrong password!");
          std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>);
          system("pause");
          exit(0);
        }
        ++v31;
        std::string::~string(v14);
        __gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator++(&v16);
      }
      v8 = std::operator<<<std::char_traits<char>>(&std::cout, "right!");
      std::ostream::operator<<(v8, &std::endl<char,std::char_traits<char>>);
      v9 = std::operator<<<std::char_traits<char>>(&std::cout, "flag:MRCTF{md5(");
      v10 = std::operator<<<char>(v9, v18);
      v11 = std::operator<<<std::char_traits<char>>(v10, ")}");
      std::ostream::operator<<(v11, &std::endl<char,std::char_traits<char>>);
      v12 = std::operator<<<std::char_traits<char>>(
              &std::cout,
              "md5()->{32/upper case/put the string into the function and transform into md5 hash}");
      std::ostream::operator<<(v12, &std::endl<char,std::char_traits<char>>);
      system("pause");
      std::string::~string(v18);
      std::vector<bool>::~vector(v19);
      std::vector<int>::~vector(v20);
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99

    depart函数, 把一个数分解成素因子的乘积

    __int64 __fastcall depart(int a1, __int64 a2)
    {
      char v3[32]; // [rsp+20h] [rbp-60h] BYREF
      char v4[40]; // [rsp+40h] [rbp-40h] BYREF
      int i; // [rsp+68h] [rbp-18h]
      int v6; // [rsp+6Ch] [rbp-14h]
    
      v6 = a1;
      for ( i = 2; std::sqrt<int>((unsigned int)a1) >= (double)i; ++i )
      {
        if ( !(a1 % i) )
        {
          v6 = i;
          depart((unsigned int)(a1 / i), a2);
          break;
        }
      }
      std::to_string((std::__cxx11 *)v4, v6);
      std::operator+<char>(v3, &unk_500C, v4);
      std::string::operator+=(a2, v3);
      std::string::~string(v3);
      return std::string::~string(v4);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    第一个lambda函数, 对每一项进行与1异或的操作

    __int64 __fastcall std::for_each<__gnu_cxx::__normal_iterator<int *,std::vector<int>>,main::{lambda(int &)#1}>(
            __int64 a1,
            __int64 a2)
    {
      unsigned int v2; // ebx
      __int64 v3; // rax
      char v5; // [rsp+Fh] [rbp-21h] BYREF
      __int64 v6; // [rsp+10h] [rbp-20h] BYREF
      __int64 v7[3]; // [rsp+18h] [rbp-18h] BYREF
    
      v7[0] = a1;
      v6 = a2;
      while ( (unsigned __int8)__gnu_cxx::operator!=<int *,std::vector<int>>(v7, &v6) )
      {
        v3 = __gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator*(v7);
        main::{lambda(int &)#1}::operator()(&v5, v3);
        __gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator++(v7);
      }
      return v2;
    }
    
    _DWORD *__fastcall main::{lambda(int &)#1}::operator()(__int64 a1, _DWORD *a2)
    {
      _DWORD *result; // rax
    
      result = a2;
      *a2 ^= 1u;
      return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    第二个lambda函数, 替换操作

    __int64 __fastcall {lambda(std::string &)#1}::operator()(__int64 a1, __int64 a2)
    {
      __int64 v2; // rbx
      __int64 v3; // rax
      __int64 v4; // rbx
      __int64 v5; // rax
      __int64 v6; // rbx
      __int64 v7; // rax
      __int64 v8; // rbx
      __int64 v9; // rax
      __int64 v10; // rbx
      __int64 v11; // rax
      __int64 v12; // rbx
      __int64 v13; // rax
      __int64 v14; // rbx
      __int64 v15; // rax
      __int64 v16; // rbx
      __int64 v17; // rax
      __int64 v18; // rbx
      __int64 v19; // rax
      __int64 v20; // rbx
      __int64 v21; // rax
      __int64 v22; // rbx
      __int64 v23; // rax
      char v25; // [rsp+1Ah] [rbp-26h] BYREF
      char v26; // [rsp+1Bh] [rbp-25h] BYREF
      char v27; // [rsp+1Ch] [rbp-24h] BYREF
      char v28; // [rsp+1Dh] [rbp-23h] BYREF
      char v29; // [rsp+1Eh] [rbp-22h] BYREF
      char v30; // [rsp+1Fh] [rbp-21h] BYREF
      char v31; // [rsp+20h] [rbp-20h] BYREF
      char v32; // [rsp+21h] [rbp-1Fh] BYREF
      char v33; // [rsp+22h] [rbp-1Eh] BYREF
      char v34; // [rsp+23h] [rbp-1Dh] BYREF
      char v35; // [rsp+24h] [rbp-1Ch] BYREF
      char v36; // [rsp+25h] [rbp-1Bh] BYREF
      char v37; // [rsp+26h] [rbp-1Ah] BYREF
      char v38; // [rsp+27h] [rbp-19h] BYREF
      char v39; // [rsp+28h] [rbp-18h] BYREF
      char v40; // [rsp+29h] [rbp-17h] BYREF
      char v41; // [rsp+2Ah] [rbp-16h] BYREF
      char v42; // [rsp+2Bh] [rbp-15h] BYREF
      char v43; // [rsp+2Ch] [rbp-14h] BYREF
      char v44; // [rsp+2Dh] [rbp-13h] BYREF
      char v45; // [rsp+2Eh] [rbp-12h] BYREF
      char v46[17]; // [rsp+2Fh] [rbp-11h] BYREF
    
      v25 = 79;
      v26 = 48;
      v2 = std::string::end(a2);
      v3 = std::string::begin(a2);
      std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v3, v2, &v26, &v25);
      v27 = 108;
      v28 = 49;
      v4 = std::string::end(a2);
      v5 = std::string::begin(a2);
      std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v5, v4, &v28, &v27);
      v29 = 122;
      v30 = 50;
      v6 = std::string::end(a2);
      v7 = std::string::begin(a2);
      std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v7, v6, &v30, &v29);
      v31 = 69;
      v32 = 51;
      v8 = std::string::end(a2);
      v9 = std::string::begin(a2);
      std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v9, v8, &v32, &v31);
      v33 = 65;
      v34 = 52;
      v10 = std::string::end(a2);
      v11 = std::string::begin(a2);
      std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v11, v10, &v34, &v33);
      v35 = 115;
      v36 = 53;
      v12 = std::string::end(a2);
      v13 = std::string::begin(a2);
      std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v13, v12, &v36, &v35);
      v37 = 71;
      v38 = 54;
      v14 = std::string::end(a2);
      v15 = std::string::begin(a2);
      std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v15, v14, &v38, &v37);
      v39 = 84;
      v40 = 55;
      v16 = std::string::end(a2);
      v17 = std::string::begin(a2);
      std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v17, v16, &v40, &v39);
      v41 = 66;
      v42 = 56;
      v18 = std::string::end(a2);
      v19 = std::string::begin(a2);
      std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v19, v18, &v42, &v41);
      v43 = 113;
      v44 = 57;
      v20 = std::string::end(a2);
      v21 = std::string::begin(a2);
      std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v21, v20, &v44, &v43);
      v45 = 61;
      v46[0] = 32;
      v22 = std::string::end(a2);
      v23 = std::string::begin(a2);
      return std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v23, v22, v46, &v45);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103

    第三个lambda函数, 加密后的字符串与一个已知字符串ans[abi:cxx11]做对比

    _BOOL8 __fastcall {lambda(std::string,int)#2}::operator()(__int64 a1, __int64 a2, int a3)
    {
      const char *v3; // rbx
      const char *v4; // rax
    
      v3 = (const char *)std::string::c_str((char *)&ans[abi:cxx11] + 32 * a3);
      v4 = (const char *)std::string::c_str(a2);
      return strcmp(v4, v3) == 0;
    }
    
    int __fastcall __static_initialization_and_destruction_0(int a1, int a2)
    {
      int result; // eax
      char v3; // [rsp+17h] [rbp-29h] BYREF
      char v4; // [rsp+18h] [rbp-28h] BYREF
      char v5; // [rsp+19h] [rbp-27h] BYREF
      char v6; // [rsp+1Ah] [rbp-26h] BYREF
      char v7; // [rsp+1Bh] [rbp-25h] BYREF
      char v8; // [rsp+1Ch] [rbp-24h] BYREF
      char v9; // [rsp+1Dh] [rbp-23h] BYREF
      char v10; // [rsp+1Eh] [rbp-22h] BYREF
      char v11[33]; // [rsp+1Fh] [rbp-21h] BYREF
    
      if ( a1 == 1 && a2 == 0xFFFF )
      {
        std::ios_base::Init::Init((std::ios_base::Init *)&std::__ioinit);
        __cxa_atexit((void (__fastcall *)(void *))&std::ios_base::Init::~Init, &std::__ioinit, &_dso_handle);
        std::allocator<char>::allocator(&v3);
        std::string::basic_string(&ans[abi:cxx11], "=zqE=z=z=z", &v3);
        std::allocator<char>::~allocator(&v3);
        std::allocator<char>::allocator(&v4);
        std::string::basic_string((char *)&ans[abi:cxx11] + 32, "=lzzE", &v4);
        std::allocator<char>::~allocator(&v4);
        std::allocator<char>::allocator(&v5);
        std::string::basic_string((char *)&ans[abi:cxx11] + 64, "=ll=T=s=s=E", &v5);
        std::allocator<char>::~allocator(&v5);
        std::allocator<char>::allocator(&v6);
        std::string::basic_string((char *)&ans[abi:cxx11] + 96, "=zATT", &v6);
        std::allocator<char>::~allocator(&v6);
        std::allocator<char>::allocator(&v7);
        std::string::basic_string((char *)&ans[abi:cxx11] + 128, "=s=s=s=E=E=E", &v7);
        std::allocator<char>::~allocator(&v7);
        std::allocator<char>::allocator(&v8);
        std::string::basic_string((char *)&ans[abi:cxx11] + 160, "=EOll=E", &v8);
        std::allocator<char>::~allocator(&v8);
        std::allocator<char>::allocator(&v9);
        std::string::basic_string((char *)&ans[abi:cxx11] + 192, "=lE=T=E=E=E", &v9);
        std::allocator<char>::~allocator(&v9);
        std::allocator<char>::allocator(&v10);
        std::string::basic_string((char *)&ans[abi:cxx11] + 224, "=EsE=s=z", &v10);
        std::allocator<char>::~allocator(&v10);
        std::allocator<char>::allocator(v11);
        std::string::basic_string((char *)&ans[abi:cxx11] + 256, "=AT=lE=ll", v11);
        std::allocator<char>::~allocator(v11);
        return __cxa_atexit(_tcf_0, 0LL, &_dso_handle);
      }
      return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    整体逻辑:

    • 输入9个数字, 与1异或
    • depart处理成素因数的字符串, 空格隔开
    • 替换
    • check

    import hashlib
    
    checklist = [
        "=zqE=z=z=z",
        "=lzzE",
        "=ll=T=s=s=E",
        "=zATT",
        "=s=s=s=E=E=E",
        "=EOll=E",
        "=lE=T=E=E=E",
        "=EsE=s=z",
        "=AT=lE=ll"
    ]
    
    def replace_func(string):
        string = string.replace("O","0")
        string = string.replace("l","1")
        string = string.replace("z","2")
        string = string.replace("E","3")
        string = string.replace("A","4")
        string = string.replace("s","5")
        string = string.replace("G","6")
        string = string.replace("T","7")
        string = string.replace("B","8")
        string = string.replace("q","9")
        string = string.replace("="," ")
        return string
    
    for i in range(len(checklist)):
        checklist[i] = replace_func(checklist[i])
    
    print(checklist)
    numbers = []
    for eachstr in checklist:
        tmp = eachstr.split(' ')[1:]
        num = 1
        for n in tmp:
            tmpn = int(n)
            num *= tmpn
        numbers.append(num)
    
    print(numbers)
    flag = ''
    for i in range(len(numbers)):
        flag += str(numbers[i] ^ 1)
    
    md5obj = hashlib.md5()
    md5obj.update(flag.encode('utf-8'))
    
    print('flag{{{}}}'.format(md5obj.hexdigest()))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    [NPUCTF2020]Baby Obfuscation

    在这里插入图片描述

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      int v3; // eax
      int v4; // ebx
      int v5; // esi
      int v6; // ebx
      int v7; // ebx
      int v8; // esi
      int v9; // ebx
      int v10; // ebx
      int v11; // ebx
      int v12; // esi
      int v13; // eax
      int v14; // ebx
      int v15; // esi
      int v16; // ebx
      int v17; // eax
      bool v18; // bl
      int v19; // eax
      int v20; // esi
      int v21; // ebx
      int v22; // ebx
      int v23; // eax
      int v24; // eax
      int v25; // eax
      int v26; // ebx
      int A0X3[65]; // [rsp+20h] [rbp-60h] BYREF
      char A0X2[1001]; // [rsp+130h] [rbp+B0h] BYREF
      int A0X1[1001]; // [rsp+520h] [rbp+4A0h] BYREF
      int A0X5[4]; // [rsp+14D0h] [rbp+1450h]
      int A0X4[4]; // [rsp+14E0h] [rbp+1460h]
      int length; // [rsp+14F0h] [rbp+1470h]
      int i_1; // [rsp+14F4h] [rbp+1474h]
      int i_0; // [rsp+14F8h] [rbp+1478h]
      int i; // [rsp+14FCh] [rbp+147Ch]
    
      _main();
      memset(A0X1, 0, sizeof(A0X1));
      memset(A0X3, 0, sizeof(A0X3));
      for ( i = 0; i <= 64; ++i )
        A0X3[i] = i + 1;
      A0X4[0] = 2;
      A0X4[1] = 3;
      A0X4[2] = 4;
      A0X4[3] = 5;
      A0X5[0] = 2;
      A0X5[1] = 3;
      A0X5[2] = 4;
      A0X5[3] = 5;
      puts("WHERE IS MY KEY!?");
      scanf("%32s", A0X2);
      length = strlen(A0X2);
      v3 = F0X1(A0X3[i_0], A0X3[i_0]);
      for ( i_0 = v3 / A0X3[i_0]; i_0 <= length; ++i_0 )
      {
        v4 = (A0X3[i_0] + A0X3[i_0 + 1]) * (A0X3[i_0] + A0X3[i_0 + 1]);
        if ( v4 >= F0X5(2, 2) * A0X3[i_0] * A0X3[i_0 + 1] )
        {
          v5 = ~A0X2[F0X4(i_0, 1)];
          v6 = F0X4(i_0, 1);
          A0X1[i_0] = ~(v5 + A0X4[v6 % F0X5(2, 2)]);
        }
        v7 = F0X1(A0X3[i_0], A0X3[i_0 + 1]);
        if ( v7 > F0X1(A0X3[i_0 + 1], ~(~A0X3[i_0 + 1] + A0X3[i_0])) )
        {
          v8 = A0X1[i_0];
          v9 = F0X4(i_0, 1);
          A0X1[i_0] = ~(~v8 + A0X3[v9 % F0X5(2, 2)]) * v8;
        }
        v10 = A0X3[i_0 + 1];
        v11 = F0X5(2, 1) * v10;
        v12 = A0X3[i_0];
        v13 = F0X5(2, 1);
        v14 = F0X1(v12 * v13, v11);
        v15 = F0X5(2, 1);
        if ( v14 == v15 * F0X1(A0X3[i_0], A0X3[i_0 + 1]) )
        {
          v16 = F0X4(i_0, 1);
          A0X1[i_0] ^= A0X4[v16 % F0X5(2, 2)];
        }
        v17 = F0X5(V0X3, A0X3[i_0]);
        v18 = v17 < A0X3[i_0] + 1;
        v19 = F0X5(2, 4);
        if ( F0X3(v19 >= i_0, v18) )
        {
          v20 = ~A0X2[F0X4(i_0, 1)];
          v21 = F0X4(i_0, 1);
          A0X1[i_0] ^= ~(v20 + A0X4[v21 % F0X5(2, 2)]);
        }
        v22 = F0X5(2, 3);
        v23 = F0X1(A0X3[i_0], A0X3[i_0]);
        A0X1[i_0] *= v22 + F0X5(2, v23 / A0X3[i_0]);
      }
      v24 = F0X5(2, 4);
      if ( F0X4(v24, 1) != length )
        goto LABEL_23;
      v25 = F0X1(A0X3[i_1], A0X3[i_1]);
      for ( i_1 = v25 / A0X3[i_1]; i_1 <= length; ++i_1 )
      {
        v26 = A0X1[i_1];
        if ( v26 == F0X4(A0X6[i_1], 1) / 10 )
          ++V0X2;
      }
      if ( V0X2 == length )
        puts("\nPASS");
      else
    LABEL_23:
        puts("\nDENIED");
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110

    看起来基本是函数名, 变量名的混淆, 逻辑不复杂, 从后往前分析

    在这里插入图片描述

    在这里插入图片描述
    抛去恒为假的分支, 保留关键处理逻辑, 可以直接逆回去

    arr1 = [2, 3, 4, 5]
    
    checklist = [
        0, 7801, 7801, 8501, 5901, 8001, 6401, 11501,
        4601, 9801, 9601, 11701, 5301, 9701, 10801, 12501
    ]
    
    inputs = [0] * 16
    
    for i in range(1, 16):
        checklist[i] = (checklist[i] - 1) // 10 // 10
        checklist[i] ^= arr1[(i - 1) % 4]
        inputs[i - 1] = (~(((~checklist[i]) & 0xFF) - arr1[(i - 1) % 4]) % 0xFF) + 1
    
    print(inputs)
    
    flag = ''
    for i in range(len(inputs)):
        flag += chr(inputs[i])
    
    print(flag)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    [NPUCTF2020]BasicASM

    给了汇编文件的一部分, 和对应的结果

    00007FF7A8AC5A50  push        rbp  
    00007FF7A8AC5A52  push        rdi  
    00007FF7A8AC5A53  sub         rsp,238h  
    00007FF7A8AC5A5A  lea         rbp,[rsp+20h]  
    00007FF7A8AC5A5F  mov         rdi,rsp  
    00007FF7A8AC5A62  mov         ecx,8Eh  
    00007FF7A8AC5A67  mov         eax,0CCCCCCCCh  
    00007FF7A8AC5A6C  rep stos    dword ptr [rdi]  
    00007FF7A8AC5A6E  mov         rax,qword ptr [__security_cookie (07FF7A8AD3018h)]  
    00007FF7A8AC5A75  xor         rax,rbp  
    00007FF7A8AC5A78  mov         qword ptr [rbp+208h],rax  
    00007FF7A8AC5A7F  lea         rcx,[__06A15900_ConsoleApplication@cpp (07FF7A8AD902Ah)]  
    00007FF7A8AC5A86  call        __CheckForDebuggerJustMyCode (07FF7A8AC1122h)  
    00007FF7A8AC5A8B  lea         rdx,[string "flag{this_is_a_fake_flag}" (07FF7A8ACF450h)]  
    00007FF7A8AC5A92  lea         rcx,[flag]  
    00007FF7A8AC5A96  call        std::basic_string,std::allocator >::basic_string,std::allocator > (07FF7A8AC15E1h)  
    00007FF7A8AC5A9B  nop  
    00007FF7A8AC5A9C  mov         dword ptr [p],0  
    00007FF7A8AC5AA3  mov         dword ptr [rbp+64h],0  
    00007FF7A8AC5AAA  jmp         main+64h (07FF7A8AC5AB4h)  
    00007FF7A8AC5AAC  mov         eax,dword ptr [rbp+64h]  
    00007FF7A8AC5AAF  inc         eax  
    00007FF7A8AC5AB1  mov         dword ptr [rbp+64h],eax  
    00007FF7A8AC5AB4  movsxd      rax,dword ptr [rbp+64h]  
    00007FF7A8AC5AB8  mov         qword ptr [rbp+1F8h],rax  
    00007FF7A8AC5ABF  lea         rcx,[flag]  
    00007FF7A8AC5AC3  call        std::basic_string,std::allocator >::length (07FF7A8AC122Bh)  
    00007FF7A8AC5AC8  mov         rcx,qword ptr [rbp+1F8h]  
    00007FF7A8AC5ACF  cmp         rcx,rax  
    00007FF7A8AC5AD2  jae         main+1B2h (07FF7A8AC5C02h)  
    00007FF7A8AC5AD8  mov         eax,dword ptr [rbp+64h]  
    00007FF7A8AC5ADB  and         eax,1  
    00007FF7A8AC5ADE  cmp         eax,1  
    00007FF7A8AC5AE1  jne         main+126h (07FF7A8AC5B76h)  
    00007FF7A8AC5AE7  movsxd      rax,dword ptr [rbp+64h]  
    00007FF7A8AC5AEB  mov         rdx,rax  
    00007FF7A8AC5AEE  lea         rcx,[flag]  
    00007FF7A8AC5AF2  call        std::basic_string,std::allocator >::operator[] (07FF7A8AC1442h)  
    00007FF7A8AC5AF7  movsx       eax,byte ptr [rax]  
    00007FF7A8AC5AFA  xor         eax,42h  
    00007FF7A8AC5AFD  mov         dword ptr [p],eax  
    00007FF7A8AC5B00  mov         dl,30h  
    00007FF7A8AC5B02  lea         rcx,[rbp+144h]  
    00007FF7A8AC5B09  call        std::setfill (07FF7A8AC1046h)  
    00007FF7A8AC5B0E  mov         qword ptr [rbp+1F8h],rax  
    00007FF7A8AC5B15  mov         edx,2  
    00007FF7A8AC5B1A  lea         rcx,[rbp+168h]  
    00007FF7A8AC5B21  call        std::setw (07FF7A8AC10D2h)  
    00007FF7A8AC5B26  mov         qword ptr [rbp+200h],rax  
    00007FF7A8AC5B2D  lea         rdx,[std::hex (07FF7A8AC1488h)]  
    00007FF7A8AC5B34  mov         rcx,qword ptr [__imp_std::cout (07FF7A8AD71C0h)]  
    00007FF7A8AC5B3B  call        qword ptr [__imp_std::basic_ostream >::operator<< (07FF7A8AD7160h)]  
    00007FF7A8AC5B41  mov         rcx,qword ptr [rbp+200h]  
    00007FF7A8AC5B48  mov         rdx,rcx  
    00007FF7A8AC5B4B  mov         rcx,rax  
    00007FF7A8AC5B4E  call        std::operator<<,__int64> (07FF7A8AC12F8h)  
    00007FF7A8AC5B53  mov         rcx,qword ptr [rbp+1F8h]  
    00007FF7A8AC5B5A  mov         rdx,rcx  
    00007FF7A8AC5B5D  mov         rcx,rax  
    00007FF7A8AC5B60  call        std::operator<<,char> (07FF7A8AC11A4h)  
    00007FF7A8AC5B65  mov         edx,dword ptr [p]  
    00007FF7A8AC5B68  mov         rcx,rax  
    00007FF7A8AC5B6B  call        qword ptr [__imp_std::basic_ostream >::operator<< (07FF7A8AD7158h)]  
    00007FF7A8AC5B71  jmp         main+1ADh (07FF7A8AC5BFDh)  
    00007FF7A8AC5B76  movsxd      rax,dword ptr [rbp+64h]  
    00007FF7A8AC5B7A  mov         rdx,rax  
    00007FF7A8AC5B7D  lea         rcx,[flag]  
    00007FF7A8AC5B81  call        std::basic_string,std::allocator >::operator[] (07FF7A8AC1442h)  
    00007FF7A8AC5B86  movsx       eax,byte ptr [rax]  
    00007FF7A8AC5B89  mov         dword ptr [p],eax  
    00007FF7A8AC5B8C  mov         dl,30h  
    00007FF7A8AC5B8E  lea         rcx,[rbp+194h]  
    00007FF7A8AC5B95  call        std::setfill (07FF7A8AC1046h)  
    00007FF7A8AC5B9A  mov         qword ptr [rbp+1F8h],rax  
    00007FF7A8AC5BA1  mov         edx,2  
    00007FF7A8AC5BA6  lea         rcx,[rbp+1B8h]  
    00007FF7A8AC5BAD  call        std::setw (07FF7A8AC10D2h)  
    00007FF7A8AC5BB2  mov         qword ptr [rbp+200h],rax  
    00007FF7A8AC5BB9  lea         rdx,[std::hex (07FF7A8AC1488h)]  
    00007FF7A8AC5BC0  mov         rcx,qword ptr [__imp_std::cout (07FF7A8AD71C0h)]  
    00007FF7A8AC5BC7  call        qword ptr [__imp_std::basic_ostream >::operator<< (07FF7A8AD7160h)]  
    00007FF7A8AC5BCD  mov         rcx,qword ptr [rbp+200h]  
    00007FF7A8AC5BD4  mov         rdx,rcx  
    00007FF7A8AC5BD7  mov         rcx,rax  
    00007FF7A8AC5BDA  call        std::operator<<,__int64> (07FF7A8AC12F8h)  
    00007FF7A8AC5BDF  mov         rcx,qword ptr [rbp+1F8h]  
    00007FF7A8AC5BE6  mov         rdx,rcx  
    00007FF7A8AC5BE9  mov         rcx,rax  
    00007FF7A8AC5BEC  call        std::operator<<,char> (07FF7A8AC11A4h)  
    00007FF7A8AC5BF1  mov         edx,dword ptr [p]  
    00007FF7A8AC5BF4  mov         rcx,rax  
    00007FF7A8AC5BF7  call        qword ptr [__imp_std::basic_ostream >::operator<< (07FF7A8AD7158h)]  
    00007FF7A8AC5BFD  jmp         main+5Ch (07FF7A8AC5AACh)  
    00007FF7A8AC5C02  mov         dword ptr [rbp+1E4h],0  
    00007FF7A8AC5C0C  lea         rcx,[flag]  
    00007FF7A8AC5C10  call        std::basic_string,std::allocator >::~basic_string,std::allocator > (07FF7A8AC1302h)  
    00007FF7A8AC5C15  mov         eax,dword ptr [rbp+1E4h]  
    00007FF7A8AC5C1B  mov         edi,eax  
    00007FF7A8AC5C1D  lea         rcx,[rbp-20h]  
    00007FF7A8AC5C21  lea         rdx,[__xt_z+540h (07FF7A8ACEFE0h)]  
    00007FF7A8AC5C28  call        _RTC_CheckStackVars (07FF7A8AC1596h)  
    00007FF7A8AC5C2D  mov         eax,edi  
    00007FF7A8AC5C2F  mov         rcx,qword ptr [rbp+208h]  
    00007FF7A8AC5C36  xor         rcx,rbp  
    00007FF7A8AC5C39  call        __security_check_cookie (07FF7A8AC1190h)  
    00007FF7A8AC5C3E  lea         rsp,[rbp+218h]  
    00007FF7A8AC5C45  pop         rdi  
    00007FF7A8AC5C46  pop         rbp  
    00007FF7A8AC5C47  ret  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109

    100来行, 直接读汇编就行
    call std::basic_string < char,std::char_traits,std::allocator >::length (07FF7A8AC122Bh) 计算flag的长度
    call std::basic_string < char,std::char_traits,std::allocator >::operator[] (07FF7A8AC1442h) 构建一个数组
    这里是下标为奇数时^0x42

    在这里插入图片描述
    逻辑不复杂, 只有xor操作, 逆回去

    s = '662e61257b26301d7972751d6b2c6f355f3a38742d74341d61776d7d7d'
    
    flag = ''
    odd = 0
    for i in range(0, len(s), 2):
        intval = int(s[i:i + 2], 16)
        if odd % 2 == 1:
            intval ^= 0x42
        odd += 1
        flag += chr(intval)
    
    print(flag)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    [ACTF新生赛2020]Splendid_MineCraft

    在这里插入图片描述

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      char *v3; // eax
      char *v4; // eax
      char v6; // [esp+0h] [ebp-68h]
      int i; // [esp+14h] [ebp-54h]
      char *v8; // [esp+18h] [ebp-50h]
      char v9; // [esp+20h] [ebp-48h]
      char Str1; // [esp+24h] [ebp-44h] BYREF
      _BYTE v11[3]; // [esp+25h] [ebp-43h] BYREF
      char v12; // [esp+3Dh] [ebp-2Bh]
      int v13; // [esp+44h] [ebp-24h]
      __int16 v14; // [esp+48h] [ebp-20h]
      char v15[4]; // [esp+4Ch] [ebp-1Ch]
      __int16 v16; // [esp+50h] [ebp-18h]
      int v17; // [esp+54h] [ebp-14h] BYREF
      __int16 v18; // [esp+58h] [ebp-10h]
      int v19; // [esp+5Ch] [ebp-Ch]
      __int16 v20; // [esp+60h] [ebp-8h]
    
      sub_401020("%s\n", (char)aWelcomeToActfS);
      sub_401050("%s", (char)&Str1);
      if ( &v11[strlen(&Str1)] - v11 == 26 && !strncmp(&Str1, "ACTF{", 5u) && v12 == 125 )
      {
        v12 = 0;
        v3 = strtok(&Str1, "_");
        v17 = *(_DWORD *)(v3 + 5);
        v18 = *(_WORD *)(v3 + 9);
        v19 = *(_DWORD *)(v3 + 5);
        v20 = *(_WORD *)(v3 + 9);
        v4 = strtok(0, "_");
        v13 = *(_DWORD *)v4;
        v14 = *((_WORD *)v4 + 2);
        v8 = strtok(0, "_");
        *(_DWORD *)v15 = *(_DWORD *)v8;
        v16 = *((_WORD *)v8 + 2);
        dword_403354 = (int)&unk_4051D8;
        if ( ((int (__cdecl *)(int *))unk_4051D8)(&v17) )
        {
          v9 = BYTE2(v19) ^ HIBYTE(v20) ^ v19 ^ HIBYTE(v19) ^ BYTE1(v19) ^ v20;
          for ( i = 256; i < 496; ++i )
            byte_405018[i] ^= v9;
          __asm { jmp     eax }
        }
      }
      sub_401020("Wrong\n", v6);
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    char *strtok(char *s, char *delim): 对字符串s进行操作, 以delim中的字符为分界符, 将s切分成一个个子串; 如果s为NULL, 则函数保存的指针SAVE_PTR在下一次调用中将作为起始位置.

    这里有个SMC
    在这里插入图片描述

    这题基本就是动调, 一阶段是第一个SMC, 检测flag前5个字符"ACTF{", 二阶段是自修改出来的代码进行flag中第一部分字符的check和第二个SMC, 这里可以逐位cmp出来flag的第一部分yOu0y*
    在这里插入图片描述

    跟第二个SMC可以得到, flag的第二部分的处理代码和第三个SMC
    在这里插入图片描述

    三阶段继续跟SMC, 指令自修改后就是直接和5位字符比较, 得到第三部分flag为5mcsM<
    二阶段的check代码是经过检索表处理, 动调拿到加密后的数据, 逆回去

    table = [
    	0xF6, 0xA3, 0x5B, 0x9D, 0xE0, 0x95, 0x98, 0x68, 0x8C, 0x65,
        0xBB, 0x76, 0x89, 0xD4, 0x09, 0xFD, 0xF3, 0x5C, 0x3C, 0x4C,
        0x36, 0x8E, 0x4D, 0xC4, 0x80, 0x44, 0xD6, 0xA9, 0x01, 0x32,
        0x77, 0x29, 0x90, 0xBC, 0xC0, 0xA8, 0xD8, 0xF9, 0xE1, 0x1D,
        0xE4, 0x67, 0x7D, 0x2A, 0x2C, 0x59, 0x9E, 0x3D, 0x7A, 0x34,
        0x11, 0x43, 0x74, 0xD1, 0x62, 0x60, 0x02, 0x4B, 0xAE, 0x99,
        0x57, 0xC6, 0x73, 0xB0, 0x33, 0x18, 0x2B, 0xFE, 0xB9, 0x85,
        0xB6, 0xD9, 0xDE, 0x7B, 0xCF, 0x4F, 0xB3, 0xD5, 0x08, 0x7C,
        0x0A, 0x71, 0x12, 0x06, 0x37, 0xFF, 0x7F, 0xB7, 0x46, 0x42,
        0x25, 0xC9, 0xD0, 0x50, 0x52, 0xCE, 0xBD, 0x6C, 0xE5, 0x6F,
        0xA5, 0x15, 0xED, 0x64, 0xF0, 0x23, 0x35, 0xE7, 0x0C, 0x61,
        0xA4, 0xD7, 0x51, 0x75, 0x9A, 0xF2, 0x1E, 0xEB, 0x58, 0xF1,
        0x94, 0xC3, 0x2F, 0x56, 0xF7, 0xE6, 0x86, 0x47, 0xFB, 0x83,
        0x5E, 0xCC, 0x21, 0x4A, 0x24, 0x07, 0x1C, 0x8A, 0x5A, 0x17,
        0x1B, 0xDA, 0xEC, 0x38, 0x0E, 0x7E, 0xB4, 0x48, 0x88, 0xF4,
        0xB8, 0x27, 0x91, 0x00, 0x13, 0x97, 0xBE, 0x53, 0xC2, 0xE8,
        0xEA, 0x1A, 0xE9, 0x2D, 0x14, 0x0B, 0xBF, 0xB5, 0x40, 0x79,
        0xD2, 0x3E, 0x19, 0x5D, 0xF8, 0x69, 0x39, 0x5F, 0xDB, 0xFA,
        0xB2, 0x8B, 0x6E, 0xA2, 0xDF, 0x16, 0xE2, 0x63, 0xB1, 0x20,
        0xCB, 0xBA, 0xEE, 0x8D, 0xAA, 0xC8, 0xC7, 0xC5, 0x05, 0x66,
        0x6D, 0x3A, 0x45, 0x72, 0x0D, 0xCA, 0x84, 0x4E, 0xF5, 0x31,
        0x6B, 0x92, 0xDC, 0xDD, 0x9C, 0x3F, 0x55, 0x96, 0xA1, 0x9F,
        0xCD, 0x9B, 0xE3, 0xA0, 0xA7, 0xFC, 0xC1, 0x78, 0x10, 0x2E,
        0x82, 0x8F, 0x30, 0x54, 0x04, 0xAC, 0x41, 0x93, 0xD3, 0x3B,
        0xEF, 0x03, 0x81, 0x70, 0xA6, 0x1F, 0x22, 0x26, 0x28, 0x6A,
        0xAB, 0x87, 0xAD, 0x49, 0x0F, 0xAF
    ]
    
    m = [0x30,0x4,0x4,0x3,0x30,0x63]
    
    flag = ''
    for i in range(len(m)):
    	flag+=chr(table.index(m[i])^(i+0x83))
    
    print('flag{'+'yOu0y*_'+flag+'_5mcsM<}')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    ** 这个题出得挺好的, SMC嵌套, 可以锻炼动调能力

  • 相关阅读:
    【深入浅出 Yarn 架构与实现】5-1 Yarn 资源调度器基本框架
    四氧化三铁Fe3O4/二氧化硅SiO2/二氧化钛TIO2/氧化锌ZNO/二氧化锰MnO2/二硫化钨MoS2/二硒化钨WSe2/碲化钨WTe2纳米粒包载顺铂
    MyBatis: 向oracle表中插入null字段的处理
    Spring Cloud Gateway 实现原理
    English语法_介词 - 表时间
    技术应用:使用Spring Boot、MyBatis Plus和Dynamic DataSource实现多数据源
    基于ARM架构openEuler系统通过qemu模拟器自动安装启动ARM架构的openEuler虚拟机
    计算机网络(HTTP上)
    JAVA Web应用常见漏洞与修复建议
    中国大陆IP段(含港澳)【2024-04-25】APNIC lasted 2024-04-25
  • 原文地址:https://blog.csdn.net/qq_33976344/article/details/133418725