Try   HackMD

Anti-debug.Object handles & exception (p2)

Kiểm tra kernel objects handles để phát hiện.

1. OpenProcess/ntdll!NtOpenProcess

Một process mặc định không bị debug sẽ không có quyền SeDebugPrivilege trong access token của nó. Tuy nhiên, quyền SeDebugPrivilege sẽ được bật bởi trình debugger như OllyDbg hay WinDbg.
Do đó, nếu process có thể mở tiến trình csrss.exe, cũng tức là có quyền SeDebugPrivilege trong access token, hay prcess đó đang bị debug.

Với tham số là PID của tiến trình csrss.exe.

NOTE: Chỉ thành công khi chạy dưới quyền của nhóm administrators và debug privileges.

HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll")); if (hNtDll) { typedef DWORD(WINAPI* TCsrGetProcessId)(VOID); // get PID of csrss.exe TCsrGetProcessId pfnCsrGetProcessId = (TCsrGetProcessId) GetProcAddress(hNtDll, "CsrGetProcessId"); if (pfnCsrGetProcessId) { HANDLE hCsr = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pfnCsrGetProcessId()); if (hCsr != NULL) { CloseHandle(hCsr); return true; } else return false; } }

2. CloseHandle

Gọi NtClose hay CloseHandle với một handle không hợp lệ để tạo một exception EXCEPTION_INVALID_HANDLE (0xC0000008). Nếu luồng được truyền cho exception handler, chứng tỏ rằng tiến trình đang bị debug.

__try { CloseHandle((HANDLE)0xDEADBEEF); return false; } __except(GetExceptionCode() == 0xC0000008 ? 1 : 0) { // exception handler return true; }
# yara
strings:
    $1 = "NtClose" fullword ascii
    $2 = "CloseHandle" fullword ascii

3. LoadLibrary

tương tự như OpenFile. Khi một file được load sử dụng kernel32!LoadLibrary (ntdll!LdrLoadDll). Handle của loaded file sẽ được mở và lưu trong LOAD_DLL_DEBUG_INFO struct. Nếu handle này không được close bởi debbuger, file này sẽ không thể open.

Ta sẽ load file bất kỳ sử dụng LoadLibrary và cố găng mở file sử dụng CreateFile. Nếu CreateFile lỗi -> có sự hiện diện của debugger.

TCHAR filePath[] = L"C:\\Windows\\System32\\calc.exe"; LoadLibrary(filePath); return INVALID_HANDLE_VALUE == CreateFile(filePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);

4. NtQueryObject

Khi debugging session bắt đầu, một kernel object được gọi là "debug object" được tạo ra, và một handle tương ứng với object đó.

Sử dụng ntdll!NtQueryObject để truy vấn đến list các objects tồn tại, và kiểm tra số lượng handles tương ứng với debug object tồn tại.

1. Lấy list chứa thông tin các objects tồn tại
2. Sử dụng loop đẻ tìm `DebugObject`. kiểm tra số lượng handle > 0 -> đang bị debug.

Bypass:

  • Trace đến hàm check:

    • skip bằng cách set IP register.
    • patch thành NOPS.
    • Thay đổi flag check.
  • Hook các hàm và thay đổi giá trị trả về:

    • ntdll!OpenProcess: trả về NULL nếu tham số thứ 3 là csrss.exe.
    • ntdll!NtQueryObject: Nếu tham số thứ 2 là ObjectAllTypesInformation (3).
  • LoadLibrary quite hard to bypass :<

Exceptions:

1. UnhandledExceptionFilter:

Khi xảy ra exception và không có Exception Handlers (cả Structured lẫn Vectored). Hàm UnhandledExceptionFilter sẽ được gọi.

Có thể đăng ký một custom unhandled exception filter dùng kernel32!SetUnhandledExceptionFilter(). Nhưng nếu chương trình chạy dưởi một debugger, custom filter sẽ không được gọi và exception được truyền tiếp cho debugger.

LONG unhandle_exception_filter(PEXCEPTION_POINTERS pExceptionInfo) { PCONTEXT ctx = pExceptionInfo->ContextRecord; ctx->Eip += 3; // Skip \xCC\xEB\x?? return EXCEPTION_CONTINUE_EXECUTION; } bool check_UnhandledExceptionFilter() { bool bDebugged = true; SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)unhandle_exception_filter); __asm { int 3 // CC jmp near being_debugged // EB ?? } bDebugged = false; being_debugged: return bDebugged; }

2. RaiseException/ ntdll!RtlRaiseException

Các exception như DBC_CONTROL_C (0x40010005) hay DBG_RIPEVENT (0x40010007) không được chuyển tiếp đến exception handlers của tiến trình hiện tại mà được xử lí bởi debugger.

Sử dụng kernel32!RaiseException để ép xảy ra một exception cụ thể.
Nếu exception handle không được gội -> có sự tồn tại của debugger.

3. Ẩn luồng chương trình với Exception Handlers

Tạo một exception handler (structured hay vectored), raise exception và handler tương ứng sẽ tới gọi tới khác.

tags: windows-internal rev anti-debug