2025-03-10
Halo's Gate — Unhooking ntdll via Syscall 번호 동적 복구
EDR이 ntdll을 후킹한 환경에서 인접한 stub을 읽어 올바른 SSN을 복구하는 기법을 분석합니다.
syscallevasionwindows-internals
개요
Hell's Gate는 ntdll.dll의 syscall stub에서 SSN(System Service Number)을 런타임에 읽어 직접 syscall을 호출하는 기법이다. 그런데 EDR이 해당 stub 앞에 jmp <hook> 패치를 심으면 mov eax, <SSN> 명령이 덮어씌워져 SSN 추출이 실패한다.
Halo's Gate는 이를 우회하기 위해, 후킹된 stub의 인접 함수에서 SSN을 읽어 ±1씩 가감하여 원하는 함수의 SSN을 복구한다.
Syscall Stub 구조
정상 상태의 NtAllocateVirtualMemory stub:
4C 8B D1 mov r10, rcx
B8 18 00 00 00 mov eax, 0x18 ; SSN = 0x18
0F 05 syscall
C3 ret
EDR 후킹 후:
E9 XX XX XX XX jmp <EDR hook> ; 첫 바이트가 0xE9로 패치됨
B8 18 00 00 00 mov eax, 0x18 ; (도달 불가)
0F 05 syscall
C3 ret
복구 로직
// stub이 후킹됐는지 확인
BOOL is_hooked(PBYTE stub) {
return stub[0] == 0xE9; // jmp 명령
}
// 인접 함수에서 SSN 복구
DWORD halos_gate(PBYTE ntdll_base, DWORD target_hash) {
// export table에서 함수 목록 순회
// target 함수 발견 시 ±1 함수 stub 확인
// 후킹 없는 인접 stub에서 SSN 읽기
// SSN ± offset 반환
}
SysWhispers3와의 차이
| 기법 | SSN 획득 방법 | 특징 |
|---|---|---|
| Hell's Gate | 직접 stub 파싱 | 후킹 시 실패 |
| Halo's Gate | 인접 stub fallback | 후킹 환경 대응 |
| SysWhispers3 | 컴파일 타임 하드코딩 | 간단하나 정적 시그니처 |
| FreshyCalls | PEB sort by address | 후킹 무관 |
결론
Halo's Gate는 단일 함수 후킹 환경에서 유효하지만, EDR이 연속된 여러 함수를 후킹하면 복구 실패 가능성이 있다. 실제 오퍼레이션에서는 FreshyCalls 또는 간접 syscall(RecycledGate)과 조합하는 것이 안정적이다.