๐Ÿ“˜ User-Mode Hooking Stub

Inline Patch ๊ธฐ๋ฐ˜ User-Mode API Hooking Stub ๊ตฌ์กฐ ๋ถ„์„

๋ณธ ๊ธฐ๋ก์€ ์•…์„ฑ์ฝ”๋“œ์—์„œ ๋นˆ๋ฒˆํžˆ ๊ด€์ฐฐ๋˜๋Š” Userโ€‘Mode API ํ›„ํ‚น ํŒจํ„ด ์ค‘,
๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ํ˜•ํƒœ์ธ Inline Patch(ํ”„๋กค๋กœ๊ทธ ํŒจ์น˜) ๊ธฐ๋ฐ˜ Hook Stub์˜ ๊ตฌ์กฐ๋ฅผ ๋ฆฌ๋ฒ„์‹ฑ ๊ด€์ ์—์„œ ์ •๋ฆฌํ•œ ๊ฒƒ์ด๋‹ค.
PE ๊ตฌ์กฐ, ํ•จ์ˆ˜ ํ˜ธ์ถœ ๊ทœ์•ฝ, ์Šคํƒ ํ”„๋ ˆ์ž„, ์ œ์–ด ํ๋ฆ„ ๋ถ„์„, ๊ทธ๋ฆฌ๊ณ  ๋™์  API ํš๋“ยท์•”ํ˜ธํ™” ๋ฃจํ‹ด ๋ณต์› ์ ˆ์ฐจ์™€ ์—ฐ๊ฒฐ์ง€์–ด ๊ธฐ์ˆ .

๋ฆฌ๋ฒ„์‹ฑ ๊ธฐ๋ก


1. ๊ฐœ๋…์  Hooking ๊ตฌ์กฐ(C ๊ด€์ , ๋น„์‹คํ–‰ ์˜ˆ์‹œ)

์ด ์˜ˆ์‹œ๋Š” ์‹ค์ œ๋กœ ์‹คํ–‰๋˜์ง€ ์•Š๋„๋ก ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ,
์ผ๋ฐ˜์ ์ธ ์•…์„ฑ ์ƒ˜ํ”Œ์—์„œ ๋ฐœ๊ฒฌ๋˜๋Š” ๊ตฌ์กฐ์  ํŒจํ„ด๋งŒ ๋ฐ˜์˜.

// ๊ฐœ๋…์  ์˜ˆ์‹œ โ€” ๊ตฌ์กฐ ๊ด€์ฐฐ ์ „์šฉ
unsigned char originalBytes[16];

void hook_target_function(void* target, void* hookStub) {
    // 1) ํƒ€๊นƒ ํ•จ์ˆ˜์˜ ์ฒซ 5๋ฐ”์ดํŠธ ๋ฐฑ์—…
    memcpy(originalBytes, target, 5);

    // 2) JMP hookStub ํŒจ์น˜
    DWORD rel = (DWORD)hookStub - (DWORD)target - 5;
    BYTE patch[5] = {0xE9};        // JMP rel32
    memcpy(patch + 1, &rel, 4);

    // 3) ๋ฉ”๋ชจ๋ฆฌ ๋ณดํ˜ธ ๋ณ€๊ฒฝ ํ›„ ํŒจ์น˜ ์ ์šฉ
    write_patch_conceptually(target, patch, 5);
}

ํ•ต์‹ฌ ์š”์•ฝ:

  • ํƒ€๊นƒ ํ•จ์ˆ˜์˜ ํ”„๋กค๋กœ๊ทธ๋ฅผ ๋ฎ๊ณ  JMP stub์œผ๋กœ ์ œ์–ด ํ๋ฆ„์„ ์ด๋™์‹œํ‚ด.
  • ํŒจ์น˜ ์ „ ์›๋ณธ 5๋ฐ”์ดํŠธ๋Š” ํŠธ๋žจํŽ„๋ฆฐ(๋ณต๊ตฌ์šฉ stub)์—์„œ ์‚ฌ์šฉ๋จ.
  • ๋ฉ€์›จ์–ด๋Š” ๋ณดํ†ต API๋ช… ๋ฌธ์ž์—ด์„ ์•”ํ˜ธํ™”ํ•˜์—ฌ ๋ณดํ˜ธํ•จ.

2. Hook Stub ๊ตฌ์กฐ(๋น„์‹คํ–‰ Assembly)

์‹ค์ œ ์ƒ˜ํ”Œ์—์„œ ๊ฐ€์žฅ ํ”ํžˆ ๋ณด์ด๋Š” ํ˜•ํƒœ์˜ ๊ฐœ๋…์  ๋””์Šค์–ด์…ˆ๋ธ”๋ฆฌ์ž„.
๊ตฌ์ฒด์  ์ฃผ์†Œยท์‹œ์Šคํ…œ์ฝœยทํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์ œ์™ธํ•จ.

; Hook Stub โ€” ๋น„์‹คํ–‰ ๊ฐœ๋… ์ฝ”๋“œ
; ๋ชฉ์ :
;   1) ํ˜ธ์ถœ์ž ๋ ˆ์ง€์Šคํ„ฐ/์Šคํƒ ๋ณด์กด
;   2) ์•…์„ฑ ๋กœ์ง ์ˆ˜ํ–‰
;   3) ์›๋ณธ ํ•จ์ˆ˜์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„(ํŠธ๋žจํŽ„๋ฆฐ)์œผ๋กœ ๋ณต๊ท€

HOOK_STUB:
    pushad                      ; GP ๋ ˆ์ง€์Šคํ„ฐ ์ „์ฒด ๋ณด์กด
    pushfd                      ; EFLAGS ๋ณด์กด

    ; --- ์•…์„ฑ ๋กœ์ง (์ถ•์•ฝ ์˜ˆ์‹œ) ---
    ; ์˜ˆ: API ํ˜ธ์ถœ ์ด๋ฆ„ ๋กœ๊น…, ํŒŒ๋ผ๋ฏธํ„ฐ ๋ณ€์กฐ, ์กฐ๊ฑด๋ถ€ ์ฐจ๋‹จ ๋“ฑ

    ; --- ์›๋ณธ ์ฝ”๋“œ ํŠธ๋žจํŽ„๋ฆฐ ํ˜ธ์ถœ ---
    popfd
    popad

    jmp ORIGINAL_TRAMPOLINE     ; ์›๋ณธ ์ฝ”๋“œ๋กœ ํ๋ฆ„ ๋ณต๊ท€

โ€ป pushad/popad๋Š” ๋ถ„์„์šฉ ๊ฐœ๋… ํ‘œํ˜„์ด๋ฉฐ ์‹ค์ œ ์ƒ˜ํ”Œ์€ ๋‹ค๋ฅธ ๋ ˆ์ง€์Šคํ„ฐ ๋ณด์กด ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ํ•จ.


3. Inline Patch ์ ์šฉ ์œ„์น˜ ๋ถ„์„

PE Export Table์„ ํ†ตํ•ด ์–ป์€ ํ•จ์ˆ˜ ์ฃผ์†Œ๋Š” ์‹ค์ œ ์‹คํ–‰ ๋ชจ๋“ˆ ๋‚ด๋ถ€์˜ ์‹ค์ œ ์—”ํŠธ๋ฆฌ์ด๋ฉฐ,
๋ณดํ†ต ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ”„๋กค๋กœ๊ทธ ํŒจํ„ด์„ ๊ฐ€์ง.

; Typical Win32 API Prologue
MOV EDI, EDI        ; Alignment
PUSH EBP
MOV EBP, ESP
SUB ESP, XX

์•…์„ฑ์ฝ”๋“œ๋Š” ์ด ์ƒ๋‹จ 5๋ฐ”์ดํŠธ๋ฅผ ๋ฎ์–ด ์“ฐ๋ฉฐ:

E9 XX XX XX XX      ; JMP hookStub

**์ œ์–ด ํ๋ฆ„ ์ „ํ™˜(Control Flow Detour)**์ด ์ฆ‰์‹œ ๋ฐœ์ƒ.


4. ํŠธ๋žจํŽ„๋ฆฐ ๊ตฌ์กฐ ์ƒ์„ธ

ํŠธ๋žจํŽ„๋ฆฐ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ํ˜•์„ฑ๋จ.

; ๋น„์‹คํ–‰ ์˜ˆ์‹œ โ€” ํŠธ๋žจํŽ„๋ฆฐ
ORIGINAL_TRAMPOLINE:
    ; 1) ๋ฐฑ์—…๋œ ์›๋ณธ ๋ฐ”์ดํŠธ
    DB 55 8B EC ...             ; ์‹ค์ œ ์›๋ณธ ํ”„๋กค๋กœ๊ทธ ์ผ๋ถ€

    ; 2) ์›๋ž˜ ํ•จ์ˆ˜์˜ ๋‹ค์Œ ์ฃผ์†Œ๋กœ ์ ํ”„
    JMP [originalFunction + 5]

ํŠธ๋žจํŽ„๋ฆฐ์€ ๋ถ„์„์—์„œ ์ค‘์š”ํ•œ ์˜๋ฏธ๊ฐ€ ์žˆ์Œ:

  • API ํ›„ํ‚น ์—ฌ๋ถ€ ์‹๋ณ„ ๊ฐ€๋Šฅ
  • ์›๋ž˜ ํ•จ์ˆ˜์˜ ์‹ค์ œ ์‹œ์ž‘ ์ง€์ ์„ ํ™•์ • ๊ฐ€๋Šฅ
  • ํ›„ํ‚น ํƒ์ง€ ์ฝ”๋“œ์—์„œ ์ฃผ๋กœ ํƒ์ง€๋˜๋Š” ์ง€์ 

5. ๋™์  API ์กฐํšŒ(PEB ๋ฐ Export ํŒŒ์‹ฑ ๊ธฐ๋ฐ˜)

์•…์„ฑ์ฝ”๋“œ์˜ ํ›„ํ‚น ๋กœ์ง์€ ์ข…์ข… API๋ช…์„ ์ง์ ‘ ํฌํ•จํ•˜์ง€ ์•Š๊ณ ,
Export Directory๋ฅผ ์ง์ ‘ ํŒŒ์‹ฑํ•จ.

// ๊ฐœ๋…์  ์˜ˆ์‹œ โ€” Export ํŒŒ์‹ฑ
void* resolve_api_concept(const char* dll, const char* nameHash) {
    // 1) PEB โ†’ LDR โ†’ Module ์ฐพ๊ธฐ
    // 2) Export Directory ์กฐํšŒ
    // 3) ํ•จ์ˆ˜๋ช… ํ•ด์‹œ ๋น„๊ต
    // 4) IAT/์ฃผ์†Œ ๋ฐ˜ํ™˜
    return 0;
}

๋ถ„์„ ํฌ์ธํŠธ:

  • ๋ฌธ์ž์—ด์€ XOR, ROL ๋“ฑ ๊ฐ„๋‹จ ์•”ํ˜ธํ™”๊ฐ€ ํ”ํ•จ
  • ํ•จ์ˆ˜๋ช… ๋น„๊ต๋Š” 32๋น„ํŠธ/64๋น„ํŠธ ํ•ด์‹œ๋กœ ์ˆ˜ํ–‰
  • ์ •์  ๋ถ„์„์—์„œ๋Š” ํ•ด์‹œ ๋ฃจํ‹ด ๋ณต์› ํ•„์š”

6. Antiโ€‘Debugging๊ณผ ํ›„ํ‚น์˜ ๊ฒฐํ•ฉ ํŒจํ„ด

์ผ๋ถ€ ์•…์„ฑ์ฝ”๋“œ๋Š” ํ›„ํ‚น ์ฝ”๋“œ ๊ทผ์ฒ˜์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ anti-debug ์ฒดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•จ.

mov eax, fs:[0x30]          ; PEB
mov al, [eax+0x02]          ; BeingDebugged
test al, al
jnz  DEBUG_HANDLER          ; ๋””๋ฒ„๊ฑฐ ์กด์žฌ ์‹œ ๋ถ„๊ธฐ

int 2D                      ; Soft breakpoint ์œ ๋ฐœ ํŒจํ„ด

ํ”ํ•œ ํŒจํ„ด:

  • ํ›„ํ‚น๋œ API ํ˜ธ์ถœ ์‹œ ๋””๋ฒ„๊ฑฐ ํƒ์ง€ ์ˆ˜ํ–‰
  • ๋””๋ฒ„๊ฑฐ ๋ถ„์œ„๊ธฐ์—์„œ๋งŒ ๋‹ค๋ฅธ ํŠธ๋žจํŽ„๋ฆฐ์„ ํ˜ธ์ถœ
  • ๋ ˆ์ง€์Šคํ„ฐ ๋ณ€์กฐ๋กœ ์Šคํƒ ๋ถ•๊ดด ์œ ๋ฐœ

7. Control Flow ๊ด€์ฐฐ ํฌ์ธํŠธ

ํ•ญ๋ชฉ์ฒดํฌ ๋‚ด์šฉ
์Šคํƒ ํ”„๋ ˆ์ž„ํ”„๋กค๋กœ๊ทธ ํŒจํ„ด ํŒŒ๊ดด ์—ฌ๋ถ€, ESP ๋ณ€ํ™”
Export Table์‹ค์ œ API ์—”ํŠธ๋ฆฌ์™€ ํŒจ์น˜ ์—ฌ๋ถ€ ๋น„๊ต
IATํ›„ํ‚น๋œ API๊ฐ€ Import Table ๋Œ€์‹  Inline Patch ์‚ฌ์šฉํ•˜๋Š”์ง€
๋ฉ”๋ชจ๋ฆฌ ๋ณดํ˜ธ.text ๊ตฌ๊ฐ„์ด RWX๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€
์˜์‚ฌ ์ฝ”๋“œํŠธ๋žจํŽ„๋ฆฐ ๋‚ด jmp original+5 ์œ ๋ฌด
๋ ˆ์ง€์Šคํ„ฐ ํ๋ฆ„hook stub ์ „ํ›„ ๋ ˆ์ง€์Šคํ„ฐ ๋ณด์กด ์—ฌ๋ถ€

์ด ์ง€ํ‘œ๋“ค์€ API ํ›„ํ‚น์„ ์‹๋ณ„ํ•˜๊ณ  ํ›„ํ‚น ๋กœ์ง์ด ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ํŒ๋‹จํ•˜๋Š” ๋ฐ ์œ ์šฉํ•จ.


โœจ ๋งˆ๋ฌด๋ฆฌ ํ•œ ์ค„

Inline Patch ๊ธฐ๋ฐ˜ Userโ€‘Mode Hooking์€ ์ž‘์€ 5๋ฐ”์ดํŠธ ํ”„๋กค๋กœ๊ทธ๋ฅผ ๋ฐ”๊พธ๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ์‹œ์Šคํ…œ ํ๋ฆ„์„ ์™„์ „ํžˆ ๊ฐ€๋กœ์ฑ„๋ฉฐ,
๊ทธ ์„ธ๋ฐ€ํ•œ ํŒจํ„ด์„ ์ฝ์–ด๋‚ด๋Š” ๊ฒƒ์ด ๋ฆฌ๋ฒ„์Šค ์—”์ง€๋‹ˆ์–ด๋ง์˜ ํ•ต์‹ฌ ๊ฐ๊ฐ์„ ๋‹จ๋ จํ•˜๋Š” ์ค‘์š”ํ•œ ๊ณผ์ •์ด๋‹ค.


๐Ÿ“ Written by Code & Compass

MalClown์—์„œ ๋” ์•Œ์•„๋ณด๊ธฐ

์ง€๊ธˆ ๊ตฌ๋…ํ•˜์—ฌ ๊ณ„์† ์ฝ๊ณ  ์ „์ฒด ์•„์นด์ด๋ธŒ์— ์•ก์„ธ์Šคํ•˜์„ธ์š”.

๊ณ„์† ์ฝ๊ธฐ