# IHateDebugger ![image](https://hackmd.io/_uploads/Bysc-ZT7Ze.png) - 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. ![image](https://hackmd.io/_uploads/ry7BnZTX-g.png) - 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. ![image](https://hackmd.io/_uploads/rk0n3Z6mWe.png) - 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. ![image](https://hackmd.io/_uploads/rJCFaZ6Qbl.png) - 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**. ![image](https://hackmd.io/_uploads/Sk3EA-67Wl.png) - Để 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í đã. ![image](https://hackmd.io/_uploads/BJWIwWTQZe.png) - 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ệ. ![image](https://hackmd.io/_uploads/SJ3V5-pQZx.png) - 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ì đó. ![image](https://hackmd.io/_uploads/BkbpeGaQ-g.png) - 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}`