# DreamHack's Rev_basic (0-9)
Rev-basic 0
---
Đề bài cho chúng ta một file thực thi `(.exe)`, tìm và debug binary trong hàm `main()` để dịch ngược ra flag
- Hàm main
```c=
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[256]; // [rsp+20h] [rbp-118h] BYREF
memset(buf, 0, sizeof(buf));
sub_140001190("Input : ", argv, envp);
sub_1400011F0("%256s", buf);
if ( (unsigned int)sub_140001000(buf) )
puts("Correct");
else
puts("Wrong");
return 0;
}
```
- Chúng ta thấy rằng chương trình bắt nhập một chuỗi string sau đó trả về "Correct" nếu hàm `sub_14001000` đúng và "Wrong" nếu hàm sai
- Hàm `sub_14001000`
```c
_BOOL8 __fastcall sub_140001000(const char *Str1)
{
return strcmp(Str1, "Compar3_the_str1ng") == 0;
}
```
--> `strcmp` so sánh 2 chuỗi `Str1` và `"Compar3_the_str1ng"` nếu giống thì trả về 0
Flag: DH{Compar3_the_str1ng}
---
Rev-basic 1
---
Đề bài cho chúng ta một file thực thi `(.exe)`, tìm và debug binary trong hàm `main()` để dịch ngược ra flag
- Hàm main
```c=
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[256]; // [rsp+20h] [rbp-118h] BYREF
memset(buf, 0, sizeof(buf));
sub_1400013E0("Input : ", argv, envp);
sub_140001440("%256s", buf);
if ( (unsigned int)sub_140001000(buf) )
puts("Correct");
else
puts("Wrong");
return 0;
}
```
- Chúng ta thấy rằng chương trình bắt nhập một chuỗi string sau đó trả về "Correct" nếu hàm `sub_14001000` đúng và "Wrong" nếu hàm sai
- Hàm `sub_14001000`
```c=
like_BOOL8 __fastcall sub_140001000(_BYTE *a1)
{
if ( *a1 != 67 ) //C
return 0LL;
if ( a1[1] != 111 ) //o
return 0LL;
if ( a1[2] != 109 ) //m
return 0LL;
if ( a1[3] != 112 ) //p
return 0LL;
if ( a1[4] != 97 ) //a
return 0LL;
if ( a1[5] != 114 ) //r
return 0LL;
if ( a1[6] != 51 ) //3
return 0LL;
if ( a1[7] != 95 ) //_
return 0LL;
if ( a1[8] != 116 ) //t
return 0LL;
if ( a1[9] != 104 ) //h
return 0LL;
if ( a1[10] != 101 ) //e
return 0LL;
if ( a1[11] != 95 ) //_
return 0LL;
if ( a1[12] != 99 ) //c
return 0LL;
if ( a1[13] != 104 ) //h
return 0LL;
if ( a1[14] != 52 ) //4
return 0LL;
if ( a1[15] != 114 ) //r
return 0LL;
if ( a1[16] != 97 ) //a
return 0LL;
if ( a1[17] != 99 ) //c
return 0LL;
if ( a1[18] != 116 ) //t
return 0LL;
if ( a1[19] != 51 ) //3
return 0LL;
if ( a1[20] == 114 ) //r
return a1[21] == 0;
return 0LL;
}
```
--> Hàm kiểm tra lần lượt vị trí của chuỗi `a1` theo kí tự ASCII để trả về "Correct"
Flag: DH{Compar3_the_ch4ract3r}
---
Rev-basic 2
---
Đề bài cho chúng ta một file thực thi `(.exe)`, tìm và debug binary trong hàm `main()` để dịch ngược ra flag
- Hàm main
```c=
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[256]; // [rsp+20h] [rbp-118h] BYREF
memset(buf, 0, sizeof(buf));
sub_1400011B0((__int64)"Input : ", argv, envp);
sub_140001210("%256s", buf);
if ( (unsigned int)sub_140001000((__int64)buf) )
puts("Correct");
else
puts("Wrong");
return 0;
}
```
- Chúng ta thấy rằng chương trình bắt nhập một chuỗi string sau đó trả về "Correct" nếu hàm `sub_14001000` đúng và "Wrong" nếu hàm sai
- Hàm `sub_14001000`
```c=
__int64 __fastcall sub_140001000(__int64 buf)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x12; ++i )
{
if ( *(_DWORD *)&aC[4 * i] != *(unsigned __int8 *)(buf + i) )// "C"
return 0LL;
}
return 1LL;
}
```
--> Hàm `sub_140001000` so sánh 18 byte đầu của input với mảng hằng `aC`. Mỗi byte input được so sánh trực tiếp với một giá trị cố định. Do đó chỉ cần dump `aC` là có thể khôi phục input hợp lệ.
--> Ta nhìn qua assembly code

- Kiểm tra thanh stack chứa địa chỉ aC và thấy được flag

Flag: DH{Comp4re_the_arr4y}
---
Rev-basic 3
---
Đề bài cho chúng ta một file thực thi `(.exe)`, tìm và debug binary trong hàm `main()` để dịch ngược ra flag
- Hàm main
```cpp=
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[256]; // [rsp+20h] [rbp-118h] BYREF
memset(buf, 0, sizeof(buf));
sub_1400011B0("Input : ", argv, envp);
sub_140001210("%256s", buf);
if ( (unsigned int)sub_140001000(buf) )
puts("Correct");
else
puts("Wrong");
return 0;
```
- Chúng ta thấy rằng chương trình bắt nhập một chuỗi string sau đó trả về "Correct" nếu hàm `sub_14001000` đúng và "Wrong" nếu hàm sai
- Hàm `sub_14001000`
```cpp=
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x18; ++i )
{
if ( byte_140003000[i] != (i ^ *(unsigned __int8 *)(a1 + i)) + 2 * i )
return 0LL;
}
return 1LL;
}
```
Ta hiểu hàm trên muốn làm như sau:
`byte_1400300[i]= i ^ s[i] + 2 * index
--> s[i] = (byte_1400300 - 2 * index) ^ index`
- `byte_1400300[i]`

`
--> Tiến hành dịch ngược để lấy flag:
```cpp=
#include <bits/stdc++.h>
#define ll long long
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
const ll Nmax=1e6+5;
int main()
{
fastio;
int byte_1400300[] = {
0x49, 0x60, 0x67, 0x74, 0x63, 0x67, 0x42, 0x66,
0x80, 0x78, 0x69, 0x69, 0x7B, 0x99, 0x6D, 0x88,
0x68, 0x94, 0x9F, 0x8D, 0x4D, 0xA5, 0x9D, 0x45
};
string s;
for(ll i=0; i<0x18; i++){
s+= ( byte_1400300[i] -2*i ) ^ i;
}
cout<<s; //I_am_X0_xo_Xor_eXcit1ng
}
```
Flag: DH{I_am_X0_xo_Xor_eXcit1ng}
---
Rev-basic 4
---
Đề bài cho chúng ta một file thực thi `(.exe)`, tìm và debug binary trong hàm `main()` để dịch ngược ra flag
- Hàm main
```cpp=
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[256]; // [rsp+20h] [rbp-118h] BYREF
memset(buf, 0, sizeof(buf));
sub_1400011C0("Input : ", argv, envp);
sub_140001220("%256s", buf);
if ( (unsigned int)sub_140001000(buf) )
puts("Correct");
else
puts("Wrong");
return 0;
}
```
- Chúng ta thấy rằng chương trình bắt nhập một chuỗi string sau đó trả về "Correct" nếu hàm `sub_14001000` đúng và "Wrong" nếu hàm sai
- Hàm `sub_140001000`
```cpp=
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x1C; ++i )
{
if ( ((unsigned __int8)(16 * *(_BYTE *)(a1 + i)) | ((int)*(unsigned __int8 *)(a1 + i) >> 4)) != byte_140003000[i] )
return 0LL;
}
return 1LL;
}
```
- Ta hiểu hàm trên muốn làm như sau:
byte140003000[i] = s[i] << 4 | s[i] >>4
- Nhận thấy đây là kĩ thuật ``[swap 2 nibbles in a byte]`` nên mình sẽ tiến hành swap lại thêm một lần nữa
-- Ví dụ ta có : AB(plaintext) -> BA(encrypted text) -> AB
- Decrypted Code:
```c=
#include <bits/stdc++.h>
#define ll long long
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
const ll Nmax=1e6+5;
int main()
{
fastio;
int byte_1400300[] = {
0x24, 0x27, 0x13, 0xC6, 0xC6, 0x13, 0x16, 0xE6,
0x47, 0xF5, 0x26, 0x96, 0x47, 0xF5, 0x46, 0x27,
0x13, 0x26, 0x26, 0xC6, 0x56, 0xF5, 0xC3, 0xC3,
0xF5, 0xE3, 0xE3
};
string s;
for(ll i=0; i<0x1C; i++){
s+= (byte_1400300[i] << 4 | byte_1400300[i] >> 4 ) & 0xFF;
}
cout<<s;
}
```
Flag: DH{Br1ll1ant_bit_dr1bble_<<_>>}
---
Rev-basic 5
---
Đề bài cho chúng ta một file thực thi `(.exe)`, tìm và debug binary trong hàm `main()` để dịch ngược ra flag
- Hàm main
```c=
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[256]; // [rsp+20h] [rbp-118h] BYREF
memset(buf, 0, sizeof(buf));
sub_1400011C0("Input : ", argv, envp);
sub_140001220("%256s", buf);
if ( (unsigned int)sub_140001000(buf) )
puts("Correct");
else
puts("Wrong");
return 0;
}
```
- Chúng ta thấy rằng chương trình bắt nhập một chuỗi string sau đó trả về "Correct" nếu hàm `sub_14001000` đúng và "Wrong" nếu hàm sai
- Hàm `sub_14001000`
```c=
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x18; ++i )
{
if ( *(unsigned __int8 *)(a1 + i + 1) + *(unsigned __int8 *)(a1 + i) != byte_140003000[i] )
return 0LL;
}
return 1LL;
}
```
- Hàm trên tiến hành như sau:
-- `byte_140003000[i] = s[i] + s[i+1] --> s[i]= byte_140003000[i] - s[i+1]`
Nhưng vì byte_140003000[i] - s[i+1] là không logic vì chưa biết được kí tự s[i+1] nên không suy ra được s[i]
Ví dụ:
```c=
byte[0] = s[0] + s[1]
byte[1] = s[1] + s[2]
byte[2] = s[2] + s[3]
s[0]=byte[0]-s[1]
s[1]=byte[1]-s[2]
s[2]=byte[2]-s[3]
```
-->Không biết `s[3]` thì không thể dịch ngược về được
Nên mình có hướng giải quyết như sau:
```c=
#include <bits/stdc++.h>
#define ll long long
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
const ll Nmax=1e6+5;
int main()
{
fastio;
int byte_1400300[] = {
0xAD, 0xD8, 0xCB, 0xCB, 0x9D, 0x97, 0xCB, 0xC4,
0x92, 0xA1, 0xD2, 0xD7, 0xD2, 0xD6, 0xA8, 0xA5,
0xDC, 0xC7, 0xAD, 0xA3, 0xA1, 0x98, 0x4C
};
char s[25];
s[24]='}'; //DH{...}
for(ll i=0x18; i>=0; i--){
s[i]=char(byte_1400300[i]-s[i+1]);
}
cout<<s;
}
```
Flag: DH{All_l1fe_3nds_w1th_NULL}
---
Rev-basic 6
---
Đề bài cho chúng ta một file thực thi `(.exe)`, tìm và debug binary trong hàm `main()` để dịch ngược ra flag
- Hàm main
```c=
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[256]; // [rsp+20h] [rbp-118h] BYREF
memset(buf, 0, sizeof(buf));
sub_1400011B0("Input : ", argv, envp);
sub_140001210("%256s", buf);
if ( (unsigned int)sub_140001000(buf) )
puts("Correct");
else
puts("Wrong");
return 0;
}
```
- Chúng ta thấy rằng chương trình bắt nhập một chuỗi string sau đó trả về "Correct" nếu hàm `sub_14001000` đúng và "Wrong" nếu hàm sai
- Hàm `sub_140001000`
```c=
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x12; ++i )
{
if ( byte_140003020[*(unsigned __int8 *)(a1 + i)] != byte_140003000[i] )
return 0LL;
}
return 1LL;
}
```
- Hàm trên tiến hành như sau:
`byte_140003000[i] = byte_140003020[s[i]] --> s[i] = inv_byte_140003020[byte_140003000[i]]`
- Nhận xét: hàm trên sử dụng kĩ thuật `AES Inverse S-box` nên mình có decrypted code như sau:
```c=
#include <bits/stdc++.h>
#define ll long long
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
const ll Nmax=1e6+5;
int main()
{
string s;
int inv_byte14003020[256];
fastio;
int byte_14003020[] = {
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};
int byte_14003000[] = {
0x0,0x4D, 0x51, 0x50, 0xEF, 0xFB, 0xC3, 0xCF,
0x92, 0x45, 0x4D, 0xCF, 0xF5, 0x04, 0x40,
0x50, 0x43, 0x63
};
for (int i = 0; i < 256; i++)
inv_byte14003020[byte_14003020[i]] = i;
for(ll i=0;i<0x12; i++){
s+=char(inv_byte14003020[byte_14003000[i]]);
}
cout<<s;
}
```
Flag: DH{Replac3_the_w0rld}
---
Rev-basic 7
---
Đề bài cho chúng ta một file thực thi `(.exe)`, tìm và debug binary trong hàm `main()` để dịch ngược ra flag
- Hàm main
```c=
-int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[256]; // [rsp+20h] [rbp-118h] BYREF
memset(buf, 0, sizeof(buf));
sub_140001120("Input : ", argv, envp);
sub_1400011B0("%256s", buf);
if ( (unsigned int)sub_140001000(buf) )
puts("Correct");
else
puts("Wrong");
return 0;
}
```
- Chúng ta thấy rằng chương trình bắt nhập một chuỗi string sau đó trả về "Correct" nếu hàm `sub_14001000` đúng và "Wrong" nếu hàm sai
- Hàm `sub_140001000`
```c=
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x1F; ++i )
{
if ( (i ^ (unsigned __int8)__ROL1__(*(_BYTE *)(a1 + i), i & 7)) != byte_140003000[i] )
return 0LL;
}
return 1LL;
}
```
- Hàm trên tiến hành như sau:
`byte_140003000[i]= i ^ ROL1(s[i], i & 7 ) --> s[i]= ROR1(byte_140003000[i] ^ i, i & 7 )`
- byte_140003000[i]

-- Đến đây mình chỉ cần dịch ngược lại thôi:
```c=
#include <bits/stdc++.h>
#define ll long long
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
const ll Nmax=1e6+5;
ll ROR(int x, int y){
return ( x >> y | x << (8- y));
}
int main()
{
string s;
fastio;
int byte_14003000[] = {
0x52,0xDF,0xB3,0x60,0xF1,0x8B,0x1C,0xB5,
0x57,0xD1,0x9F,0x38,0x4B,0x29,0xD9,0x26,
0x7F,0xC9,0xA3,0xE9,0x53,0x18,0x4F,0xB8,
0x6A,0xCB,0x87,0x58,0x5B,0x39,0x1E
};
for(ll i=0 ;i<0x1F;i++){
s+= (ROR(byte_14003000[i]^ i ,i&7));
}
cout<<s;
}
```
Flag: DH{Roll_the_left!_Roll_the_right!}
---
Rev-basic 8
----
Đề bài cho chúng ta một file thực thi `(.exe)`, tìm và debug binary trong hàm `main()` để dịch ngược ra flag
- Hàm main
```c=
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[256]; // [rsp+20h] [rbp-118h] BYREF
memset(buf, 0, sizeof(buf));
sub_1400011B0("Input : ", argv, envp);
sub_140001210("%256s", buf);
if ( (unsigned int)sub_140001000(buf) )
puts("Correct");
else
puts("Wrong");
return 0;
}
```
- Chúng ta thấy rằng chương trình bắt nhập một chuỗi string sau đó trả về "Correct" nếu hàm `sub_14001000` đúng và "Wrong" nếu hàm sai
- Hàm sub_14001000
```c=
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x15; ++i )
{
if ( (unsigned __int8)(-5 * *(_BYTE *)(a1 + i)) != byte_140003000[i] )
return 0LL;
}
return 1LL;
}
```
- Hàm trên thực hiện cụ thể như sau:
`byte_140003000[i]= s[i]* (unsigned_int8)-5`
- Do kết quả của phép nhân được ép kiểu về unsigned_int8, nên mọi phép toán đều được thực hiện trong modulo 256. Khi đó, biểu thức trên tương đương với: `byte_140003000[i] ≡ -5 × s[i] (mod 256)`
- Để khôi phục lại giá trị s[i], mình cần đảo ngược phép nhân trên trong modulo 256. Tuy nhiên, không thể sử dụng phép chia thông thường, mà phải dùng nghịch đảo modulo
-Reversed code:
```c=
#include <bits/stdc++.h>
#define ll long long
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
const ll Nmax=1e6+5;
int main()
{
// freopen("liq.inp","r",stdin);
// freopen("liq.out","w",stdout);
fastio;
int byte_14001000[] = {
0xAC, 0xF3, 0x0C, 0x25, 0xA3,
0x10, 0xB7, 0x25, 0x16, 0xC6,
0xB7, 0xBC, 0x07, 0x25, 0x02,
0xD5, 0xC6, 0x11, 0x07, 0xC5,
};
string s;
for(ll i=0;i<0x15;i++){
s+= (byte_14001000[i]*51) & 0xFF;
}
cout<<s;
}
```
Flag: DH{Did_y0u_brute_force?}
---
Rev-basic 9
---
Đây là bài cuối cùng trong chuỗi bài Rev-basic của mình rồi, cảm ơn các bạn vì đã đọc đến tận đây!!
Đề bài cho chúng ta một file thực thi `(.exe)`, tìm và debug binary trong hàm `main()` để dịch ngược ra flag
- Hàm main
```c=
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[256]; // [rsp+20h] [rbp-118h] BYREF
memset(buf, 0, sizeof(buf));
sub_1400012E0("Input : ", argv, envp);
sub_140001340("%256s", buf);
if ( (unsigned int)sub_140001000(buf) )
puts("Correct");
else
puts("Wrong");
return 0;
}
```
- Chúng ta thấy rằng chương trình bắt nhập một chuỗi string sau đó trả về "Correct" nếu hàm `sub_14001000` đúng và "Wrong" nếu hàm sai
-Hàm sub_140001000
```c=
_BOOL8 __fastcall sub_140001000(const char *Buf1)
{
int i; // [rsp+20h] [rbp-18h]
int v3; // [rsp+24h] [rbp-14h]
v3 = strlen(Buf1);
if ( (v3 + 1) % 8 )
return 0LL;
for ( i = 0; i < v3 + 1; i += 8 )
sub_1400010A0(&Buf1[i]);
return memcmp(Buf1, &Buf2_, 0x19uLL) == 0;
}
```
- Nhìn vào đoạn code trên, mình thấy để trả về flag phải gọi thêm 1 hàm nữa, vậy hãy kiểm tra hết tất cả hàm 1 lượt nhé
- Hàm `sub_1400010A0`
```c=
__int64 __fastcall sub_1400010A0(unsigned __int8 *a1)
{
__int64 result; // rax
unsigned __int8 v2; // [rsp+0h] [rbp-48h]
int j; // [rsp+4h] [rbp-44h]
int i; // [rsp+8h] [rbp-40h]
char I_am_KEY[16]; // [rsp+10h] [rbp-38h] BYREF
strcpy(I_am_KEY, "I_am_KEY");
result = *a1;
v2 = *a1;
for ( i = 0; i < 16; ++i )
{
for ( j = 0; j < 8; ++j )
{
v2 = __ROR1__(a1[((_BYTE)j + 1) & 7] + byte_140004020[(unsigned __int8)I_am_KEY[j] ^ v2], 5);
a1[((_BYTE)j + 1) & 7] = v2;
}
result = (unsigned int)(i + 1);
}
return result;
}
```
- Hàm `sub_1400010A0` thực hiện như sau:
```c=
answer[i]==ROR(a1[((j+1)&7)] + byte_140004020[key[j]^ v2],5)
a1[((j+1)&7)] + byte_140004020[key[j] ^ v2]==ROL(answer[i],5)
a1[((j+1)&7)]==ROL(answer[i],5)−byte_14004020[key[j] ^ v2] //lệnh sau khi đã chuyển đổi
```
Nói tóm gọn : 2 hàm trên thực hiện mã hóa từng block 8 byte bằng phép XOR với khóa, tra bảng hằng, cộng và dịch vòng bit (ROL/ROR), sau đó so sánh kết quả với một giá trị cố định để xác thực input.
-Code reversed của mình:
```c=
#include <bits/stdc++.h>
using namespace std;
int v5[8] = {
'I','_','a','m','_','K','E','Y'
};
/* AES S-box */
int byte_140004020[256] = {
99,124,119,123,242,107,111,197,48,1,
103,43,254,215,171,118,202,130,201,125,
250,89,71,240,173,212,162,175,156,164,
114,192,183,253,147,38,54,63,247,204,
52,165,229,241,113,216,49,21,4,199,
35,195,24,150,5,154,7,18,128,226,
235,39,178,117,9,131,44,26,27,110,
90,160,82,59,214,179,41,227,47,132,
83,209,0,237,32,252,177,91,106,203,
190,57,74,76,88,207,208,239,170,251,
67,77,51,133,69,249,2,127,80,60,
159,168,81,163,64,143,146,157,56,245,
188,182,218,33,16,255,243,210,205,12,
19,236,95,151,68,23,196,167,126,61,
100,93,25,115,96,129,79,220,34,42,
144,136,70,238,184,20,222,94,11,219,
224,50,58,10,73,6,36,92,194,211,
172,98,145,149,228,121,231,200,55,109,
141,213,78,169,108,86,244,234,101,122,
174,8,186,120,37,46,28,166,180,198,
232,221,116,31,75,189,139,138,112,62,
181,102,72,3,246,14,97,53,87,185,
134,193,29,158,225,248,152,17,105,217,
142,148,155,30,135,233,206,85,40,223,
140,161,137,13,191,230,66,104,65,153,
45,15,176,84,187,22
};
uint8_t unk_140004000[32] = {
0x7E,0x7D,0x9A,0x8B,0x25,0x2D,0xD5,0x3D,
0x03,0x2B,0x38,0x98,0x27,0x9F,0x4F,0xBC,
0x2A,0x79,0x00,0x7D,0xC4,0x2A,0x4F,0x58,
0,0,0,0,0,0,0,0
};
int ROL(int x, int n) {
return (x << n) | (x >> (8 - n));
}
/*
answer[i]==ROR(a1[((j+1)&7)] + byte_140004020[key[j]⊕v2],5)
a1[((j+1)&7)] + byte_140004020[key[j]⊕v2]==ROL(answer[i],5)
a1[((j+1)&7)]==ROL(answer[i],5)−byte_14004020[key[j]⊕v2]
*/
void solve(uint8_t a[8]) {
for (int i = 0; i < 16; i++) {
for (int j = 7; j >= 0; j--) {
uint8_t v2 = a[(j + 1) & 7];
a[(j + 1) & 7] = (ROL(v2, 5) - byte_140004020[v5[j] ^ a[j & 7]])& 0xFF ;
}
}
}
int main() {
for (int off = 0; off < 24; off += 8) {
solve(unk_140004000 + off);
}
for (int i = 0; i < 24; i++) {
cout << (char)unk_140004000[i];
}
cout << endl;
}
```
Flag: DH{Reverse__your__brain_;)}