# IHateDebugger

- Trước hết để bypass hàm **TlsCallback_0** tránh thoát chương trình em sẽ chỉnh lại giá trị thanh ghi EAX thành 0 khi DEBUG.

- Do nó chạy 2 lần do **TlsCallback_1** nên em chỉnh thành 0 tiếp và đi tới hàm main , à trước khi vậy em có đặt breakpoint tại hàm main chỗ điều kiện if rồi.

- Tại đây để bypass tránh `Debugger detected!` em sẽ tiếp tục làm tương tự ở trên là thay đổi giá trị thanh ghi EAX thành 0.

- Lúc phỏng vấn thì em có được anh Minh An hint chỗ asm hàm xử lí ngoại lệ . Em có xem lại thì ở chỗ hàm xử lí `RaiseException` thì nếu không có debugger thì nó sẽ rơi xuống hàm **sub_7FF67CEC54A0** và **sub_7FF67CECF010**.

- Để tới hàm này trước hết ta phải cho phần xử lí ngoại lệ SEH cho chương trình tự xử lí đã.

- Do em đang debug thì phần ngoại lệ này sẽ đưa cho debug trước khi tới SEH , để cho chương trình tự xử lí thì em có thêm mã ngoại lệ (`0E001DEADh`) vào option của debugger của IDA và set pass cho chương trình tự xử lí ngoại lệ.

- Sau khi em pass được phần ngoại lệ thì cũng tới được hàm **sub_7FF7E46754A0** em xem qua thì hàm này nó xor một cái gì đó mà em không rõ sao đó nó lại gọi hàm đó thêm một lần nữa để xor tiếp , em nghĩ cái này để phục hồi lại một hàm gì đó.

- Em xem tiếp hàm **sub_7FF67CECF010** thì hàm này khá lạ em thử xem phần asm thì có khá nhiều byte rác . Em có make code thì nó lại lỗi . Em có thử đặt breakpoint chỗ hàm call đó và khi đến hàm đó em vô xem lại thì mã asm đã thay đổi khả năng là hàm **sub_7FF7E46754A0** đã thực hiện xor các byte đó thành mã chính của hàm
:::spoiler sub_7FF67CECF010 gốc
```c++=
.secret:00007FF7E467F010 sub_7FF7E467F010 proc near ; CODE XREF: sub_7FF7E4674CA0+D6↑p
.secret:00007FF7E467F010 ; DATA XREF: .pdata:00007FF7E467DA74↑o
.secret:00007FF7E467F010
.secret:00007FF7E467F010 arg_0= qword ptr 8
.secret:00007FF7E467F010
.secret:00007FF7E467F010 ; FUNCTION CHUNK AT .secret:00007FF7E467F034 SIZE 000001CC BYTES
.secret:00007FF7E467F010
.secret:00007FF7E467F010 jrcxz loc_7FF7E467F034
.secret:00007FF7E467F010 sub_7FF7E467F010 endp
.secret:00007FF7E467F010
.secret:00007FF7E467F010 ; ---------------------------------------------------------------------------
.secret:00007FF7E467F012 db 0E7h
.secret:00007FF7E467F013 db 8Fh
.secret:00007FF7E467F014 db 0A3h
.secret:00007FF7E467F015 ; ---------------------------------------------------------------------------
.secret:00007FF7E467F015 db 0E3h
.secret:00007FF7E467F019 db 0E3h
.secret:00007FF7E467F01E db 43h ; C
.secret:00007FF7E467F023 db 3Bh ; ;
.secret:00007FF7E467F024 db 0E3h
.secret:00007FF7E467F028 db 68h ; h
.secret:00007FF7E467F028 ; ---------------------------------------------------------------------------
.secret:00007FF7E467F029 db 0ABh, 0ABh, 0ABh ;
```
:::
- Hàm **sub_7FF67CECF010** sau khi được xử lí thì nó sẽ call đến hàm `sub_7FF7E4674F10`
```c++=
.secret:00007FF7E467F010 ; __int64 __fastcall sub_7FF7E467F010(_QWORD)
.secret:00007FF7E467F010 sub_7FF7E467F010 db 48h ; H ; CODE XREF: sub_7FF7E4674CA0+D6↑p
.secret:00007FF7E467F010 ; DATA XREF: .pdata:00007FF7E467DA74↑o
.secret:00007FF7E467F010 sub_7FF7E467F010 endp
.secret:00007FF7E467F010
.secret:00007FF7E467F010 ; ---------------------------------------------------------------------------
.secret:00007FF7E467F012 db 4Ch ; L
.secret:00007FF7E467F013 db 24h ; $
.secret:00007FF7E467F014 db 8
.secret:00007FF7E467F015 ; ---------------------------------------------------------------------------
.secret:00007FF7E467F015 sub rsp, 28h
.secret:00007FF7E467F019 mov rcx, [rsp+30h]
.secret:00007FF7E467F01E call sub_7FF7E4674F10
.secret:00007FF7E467F023 nop
.secret:00007FF7E467F024 add rsp, 28h
.secret:00007FF7E467F028 retn
.secret:00007FF7E467F028 ; ---------------------------------------------------------------------------
.secret:00007FF7E467F029 db 0, 0, 0
```
- Em xem hàm đó thì đây khả năng là hàm xử lí chính của bài
:::spoiler sub_7FF7E4674F10
```c++=
int __fastcall sub_7FF7E4674F10(__int64 a1)
{
const char *v2; // rax
unsigned __int8 v3; // [rsp+20h] [rbp-27C8h]
char v4; // [rsp+20h] [rbp-27C8h]
int j; // [rsp+24h] [rbp-27C4h]
int m; // [rsp+28h] [rbp-27C0h]
char v7; // [rsp+2Ch] [rbp-27BCh]
char v8; // [rsp+2Dh] [rbp-27BBh]
char v9; // [rsp+2Eh] [rbp-27BAh]
char v10; // [rsp+2Fh] [rbp-27B9h]
int i; // [rsp+34h] [rbp-27B4h]
__int64 v12; // [rsp+38h] [rbp-27B0h]
int v13; // [rsp+40h] [rbp-27A8h]
size_t k; // [rsp+48h] [rbp-27A0h]
char v15; // [rsp+54h] [rbp-2794h]
size_t v16; // [rsp+70h] [rbp-2778h]
_BYTE v17[384]; // [rsp+80h] [rbp-2768h]
_BYTE v18[16]; // [rsp+200h] [rbp-25E8h] BYREF
_BYTE v19[5008]; // [rsp+210h] [rbp-25D8h] BYREF
_BYTE v20[32]; // [rsp+15A0h] [rbp-1248h] BYREF
_BYTE v21[256]; // [rsp+15C0h] [rbp-1228h] BYREF
char v22[16]; // [rsp+16C0h] [rbp-1128h] BYREF
char Destination[256]; // [rsp+16D0h] [rbp-1118h] BYREF
_BYTE v24[4096]; // [rsp+17D0h] [rbp-1018h] BYREF
if ( !(unsigned __int8)sub_7FF7E46763D0(v20) )
return puts("Key derivation failed (tampered binary?)");
sub_7FF7E4676D00(v19, v20);
sub_7FF7E4673A00(v21, v22, 0);
sub_7FF7E4673D70(v21, v22, v19);
unknown_libname_20(v18, v20);
v7 = v20[13] ^ v20[0] ^ 0xA5;
v8 = (unsigned int)sub_7FF7E4674940(v18, 1) % 0xFD + 1;
v9 = v20[7] | 1;
v10 = v20[5] % 7 + 1;
v17[0] = v7;
for ( i = 1; i < 256; ++i )
v17[i] = ((int)(unsigned __int8)v17[i - 1] >> v10) ^ (v9 + v8 * v17[i - 1]);
for ( j = 0; j < 128; ++j )
{
v15 = v17[j];
v17[j + 256] = ((v20[j & 0x1F] ^ j) + v17[(((unsigned int)sub_7FF7E4674940(v18, 3) % 7 + 2) * j + 1) % 0x100]) ^ v15;
}
memset(v24, 0, sizeof(v24));
v2 = (const char *)sub_7FF7E46762B0(a1);
strcpy_s(Destination, 0x100u, v2);
v16 = strlen(Destination);
v12 = (int)sub_7FF7E4677390(v24, 4096, "DH{");
for ( k = 0; k < v16; ++k )
{
v3 = Destination[k];
for ( m = 0; m < 16; ++m )
{
v4 = v17[(unsigned __int8)v21[((unsigned __int8)m + (unsigned __int8)k + v3) % 256]] ^ v3;
v3 = v17[(v21[(unsigned __int8)(k ^ v4)] & 0x7F) + 256] ^ v4;
v13 = m % 4;
if ( m % 4 )
{
switch ( v13 )
{
case 1:
v3 += v20[(3 * (_BYTE)m) & 0x1F] | 1;
break;
case 2:
v3 = ~v3;
break;
case 3:
v3 -= (unsigned __int8)v20[((_BYTE)k + 5 * (_BYTE)m) & 0x1F] % 11;
break;
}
}
else
{
v3 = sub_7FF7E4676EB0(v3, (unsigned int)((unsigned __int8)v20[((_BYTE)k + (_BYTE)m) & 0x1F] % 7 + 1));
}
}
v12 += (int)sub_7FF7E4677390(&v24[v12], 4096 - v12, "%02x", v3);
}
return sub_7FF7E4677390(&v24[v12], 4096 - v12, "}");
}
```
:::
- Em nghĩ nó sẽ lấy chuỗi **DH{** sau đó qua vòng lặp for và thêm vào giá trị flag và kết thúc ở cuối là **}** tất cả giá trị này sẽ được lưu vào v24 nên em có đặt breakpoint chỗ return cuối `return sub_7FF7E4677390(&v24[v12], 4096 - v12, "}");` thử xem và sau khi chạy đến em xem thử thì wao
```c++=
Stack[00005E48]:000000E6FFCFE76F db 0
Stack[00005E48]:000000E6FFCFE770 db 44h ; D
Stack[00005E48]:000000E6FFCFE771 db 48h ; H
Stack[00005E48]:000000E6FFCFE772 db 7Bh ; {
Stack[00005E48]:000000E6FFCFE773 db 61h ; a
Stack[00005E48]:000000E6FFCFE774 db 37h ; 7
Stack[00005E48]:000000E6FFCFE775 db 65h ; e
Stack[00005E48]:000000E6FFCFE776 db 35h ; 5
Stack[00005E48]:000000E6FFCFE777 db 61h ; a
Stack[00005E48]:000000E6FFCFE778 db 34h ; 4
Stack[00005E48]:000000E6FFCFE779 db 39h ; 9
Stack[00005E48]:000000E6FFCFE77A db 62h ; b
Stack[00005E48]:000000E6FFCFE77B db 64h ; d
Stack[00005E48]:000000E6FFCFE77C db 36h ; 6
Stack[00005E48]:000000E6FFCFE77D db 30h ; 0
Stack[00005E48]:000000E6FFCFE77E db 33h ; 3
Stack[00005E48]:000000E6FFCFE77F db 35h ; 5
Stack[00005E48]:000000E6FFCFE780 db 65h ; e
Stack[00005E48]:000000E6FFCFE781 db 30h ; 0
Stack[00005E48]:000000E6FFCFE782 db 39h ; 9
Stack[00005E48]:000000E6FFCFE783 db 33h ; 3
Stack[00005E48]:000000E6FFCFE784 db 36h ; 6
Stack[00005E48]:000000E6FFCFE785 db 36h ; 6
Stack[00005E48]:000000E6FFCFE786 db 30h ; 0
Stack[00005E48]:000000E6FFCFE787 db 33h ; 3
Stack[00005E48]:000000E6FFCFE788 db 36h ; 6
Stack[00005E48]:000000E6FFCFE789 db 64h ; d
Stack[00005E48]:000000E6FFCFE78A db 63h ; c
Stack[00005E48]:000000E6FFCFE78B db 30h ; 0
Stack[00005E48]:000000E6FFCFE78C db 37h ; 7
Stack[00005E48]:000000E6FFCFE78D db 30h ; 0
Stack[00005E48]:000000E6FFCFE78E db 30h ; 0
Stack[00005E48]:000000E6FFCFE78F db 32h ; 2
Stack[00005E48]:000000E6FFCFE790 db 36h ; 6
Stack[00005E48]:000000E6FFCFE791 db 66h ; f
Stack[00005E48]:000000E6FFCFE792 db 32h ; 2
Stack[00005E48]:000000E6FFCFE793 db 35h ; 5
Stack[00005E48]:000000E6FFCFE794 db 63h ; c
Stack[00005E48]:000000E6FFCFE795 db 61h ; a
Stack[00005E48]:000000E6FFCFE796 db 61h ; a
Stack[00005E48]:000000E6FFCFE797 db 30h ; 0
Stack[00005E48]:000000E6FFCFE798 db 62h ; b
Stack[00005E48]:000000E6FFCFE799 db 30h ; 0
Stack[00005E48]:000000E6FFCFE79A db 66h ; f
Stack[00005E48]:000000E6FFCFE79B db 31h ; 1
Stack[00005E48]:000000E6FFCFE79C db 39h ; 9
Stack[00005E48]:000000E6FFCFE79D db 65h ; e
Stack[00005E48]:000000E6FFCFE79E db 37h ; 7
Stack[00005E48]:000000E6FFCFE79F db 36h ; 6
Stack[00005E48]:000000E6FFCFE7A0 db 64h ; d
```
- Ghép lại các kí tự thì em tìm được flag của bài là
`DH{a7e5a49bd6035e09366036dc070026f25caa0b0f19e76d}`