---
# System prepended metadata

title: IHateDebugger

---

# 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}`