๐Ÿ“˜ Windows PE ๋กœ๋”์˜ Import Table ๋™์  ๋ณต์› ๋ถ„์„

Packed PE์˜ Import Table ๋™์  ๋ณต์› ๊ณผ์ • ์‹ฌ์ธต ๋ถ„์„

ํŒจํ‚น๋œ Windows PE๋Š” ๋ณดํ†ต Import Table์„ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ๋‚œ๋…ํ™”ํ•˜์—ฌ ์ •์  ๋ถ„์„์„ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค๊ณ , ์‹คํ–‰ ์‹œ์ ์— ๋ณต์› ๋ฃจํ‹ด์ด ๋™์ ์œผ๋กœ API ์ฃผ์†Œ๋ฅผ ๋‹ค์‹œ ์กฐํšŒํ•ด Import Address Table(IAT)์— ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ์‹์€ ใ€Š๋ฆฌ๋ฒ„์‹ฑ ํ•ต์‹ฌ์›๋ฆฌใ€‹์—์„œ ์ œ์‹œํ•˜๋Š” ๋Œ€ํ‘œ์  ๋ถ„์„ ํŒจํ„ด์ž„.
์ด๋ฒˆ์—๋Š” ํŒจํ‚น๋œ PE์˜ Import Table ์žฌ๊ตฌ์„ฑ ๋ฃจํ‹ด์„ ๋””์Šค์–ด์…ˆ๋ธ”๋ฆฌ ๊ธฐ๋ฐ˜์œผ๋กœ ์ถ”์ ํ•˜๋ฉฐ,
์Šคํƒ ํ”„๋ ˆ์ž„, ๋ ˆ์ง€์Šคํ„ฐ ํ๋ฆ„, ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ, ์ œ์–ด ํ๋ฆ„, Windows API ๋™์  ๋กœ๋”ฉ ๋ฐฉ์‹์„ ๋‹จ๊ณ„๋ณ„๋กœ ๊ธฐ๋ก.

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


1. ๊ด€์ฐฐ ๋Œ€์ƒ ์ƒ˜ํ”Œ ๊ฐœ์š”

์ƒ˜ํ”Œ์€ ๋‹ค์Œ ํŠน์„ฑ์„ ๊ฐ€์ง:

  • ์ •์  Import Table ์—†์Œ
  • ํŒจํ‚น ๋ฃจํ‹ด ๋‚ด๋ถ€์—์„œ LoadLibraryA / GetProcAddress ํ˜ธ์ถœ ์ „๋ถ€ ์•”ํ˜ธํ™”
  • ๋Ÿฐํƒ€์ž„์—์„œ Import Table ๊ตฌ์กฐ๋ฅผ ์žฌ๊ตฌ์„ฑํ•˜์—ฌ .text ๋‚ด IAT ์Šฌ๋กฏ์— ์ง์ ‘ ๊ธฐ์ž…
  • Anti-debugging: ์ปค์Šคํ…€ PEB ์ ‘๊ทผ
  • ์‹คํ–‰ ํ๋ฆ„: ํŒจ์ปค ์Šคํ… โ†’ ์–ธํŒจํ‚น โ†’ Import ๋ณต์› โ†’ OEP ์ ํ”„

2. Import ๋ณต์› ๋ฃจํ‹ด์˜ C ์œ ์‚ฌ ํ˜•ํƒœ(์žฌ๊ตฌ์„ฑ)

์ƒ˜ํ”Œ์—์„œ ๋””์Šค์–ด์…ˆ๋ธ”๋ฆฌ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณต์›ํ•œ C ์œ ์‚ฌ ํ˜•ํƒœ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Œ.

typedef FARPROC (WINAPI *GETPROC)(HMODULE, LPCSTR);
typedef HMODULE (WINAPI *LOADLIB)(LPCSTR);

void RestoreImports() {
    // ์•”ํ˜ธํ™”๋œ ๋ฌธ์ž์—ด ๋ณต์›
    char dllName[16];
    decrypt_string(dllName, enc_dll_name, sizeof(enc_dll_name));

    char apiName[32];
    decrypt_string(apiName, enc_api_name, sizeof(enc_api_name));

    LOADLIB pLoadLibraryA = resolve_api_via_peb("kernel32.dll", "LoadLibraryA");
    GETPROC pGetProcAddress = resolve_api_via_peb("kernel32.dll", "GetProcAddress");

    HMODULE h = pLoadLibraryA(dllName);
    FARPROC fn = pGetProcAddress(h, apiName);

    // IAT์— ๋ฐ”๋กœ ๊ธฐ์ž…
    DWORD *iatSlot = (DWORD*)IAT_ENTRY_RVA_TO_VA;
    *iatSlot = (DWORD)fn;
}

์ด ๋ฃจํ‹ด์€ ํŒจ์ปค์—์„œ ์ฃผ๋กœ ๋“ฑ์žฅํ•˜๋Š” ํŒจํ„ด๊ณผ ๋™์ผํ•˜๋ฉฐ,
ํ•ต์‹ฌ์€ PEB ์ ‘๊ทผ โ†’ API ์ฃผ์†Œ ํš๋“ โ†’ ๋ณตํ˜ธํ™”๋œ ๋ฌธ์ž์—ด๋กœ DLL/API ๋กœ๋“œ โ†’ IAT ์Šฌ๋กฏ ํŒจ์น˜.


3. Assembly ๋ถ„์„(Win32, MASM ์Šคํƒ€์ผ)

์Šคํƒ๊ณผ ๋ ˆ์ง€์Šคํ„ฐ ํ๋ฆ„์„ ๋ช…ํ™•ํžˆ ๋ณด๊ธฐ ์œ„ํ•ด ์ƒ์„ธ ์ฃผ์„ ํฌํ•จ.

; eax = ์•”ํ˜ธํ™”๋œ DLL ๋ฌธ์ž์—ด ์ฃผ์†Œ
; esi = ์•”ํ˜ธํ™”๋œ API ๋ฌธ์ž์—ด ์ฃผ์†Œ
; edi = IAT ์Šฌ๋กฏ ์ฃผ์†Œ

RestoreImports:
    push ebp
    mov  ebp, esp
    sub  esp, 0x40                 ; ๋กœ์ปฌ ๋ฒ„ํผ 64๋ฐ”์ดํŠธ ํ™•๋ณด (dll, api ์ด๋ฆ„)

    ; --- ๋ฌธ์ž์—ด ๋ณตํ˜ธํ™” ๋‹จ๊ณ„ ---
    lea  ecx, [ebp-0x20]           ; dllName ๋ฒ„ํผ
    push sizeof_dll
    push enc_dll_name_ptr
    push ecx
    call decrypt_string
    add  esp, 0x0C

    lea  ecx, [ebp-0x40]           ; apiName ๋ฒ„ํผ
    push sizeof_api
    push enc_api_name_ptr
    push ecx
    call decrypt_string
    add  esp, 0x0C

    ; --- PEB๋ฅผ ํ†ตํ•œ kernel32.dll์˜ LoadLibraryA ์ฃผ์†Œ ํš๋“ ---
    push offset szLoadLibraryA
    push offset szKernel32
    call resolve_api_via_peb
    mov  ebx, eax                  ; EBX = LoadLibraryA

    ; --- PEB๋ฅผ ํ†ตํ•œ GetProcAddress ์กฐํšŒ ---
    push offset szGetProcAddress
    push offset szKernel32
    call resolve_api_via_peb
    mov  esi, eax                  ; ESI = GetProcAddress

    ; --- LoadLibraryA(dllName) ---
    lea  eax, [ebp-0x20]
    push eax
    call ebx                       ; LoadLibraryA
    mov  edi, eax                  ; EDI = HMODULE

    ; --- GetProcAddress(h, apiName) ---
    lea  eax, [ebp-0x40]
    push eax
    push edi
    call esi                       ; GetProcAddress
    mov  ecx, eax                  ; ECX = ํ•จ์ˆ˜ ์ฃผ์†Œ

    ; --- IAT ํŒจ์น˜ ---
    mov  eax, IAT_ENTRY_RVA_TO_VA
    mov  [eax], ecx                ; ์‹ค์ œ IAT ์Šฌ๋กฏ์— ํ•จ์ˆ˜ ์ฃผ์†Œ ๊ธฐ๋ก

    leave
    ret

4. ์ œ์–ด ํ๋ฆ„(Control Flow) ๋ถ„์„

๋ณต์› ๋ฃจํ‹ด์˜ ์ „์ฒด ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Œ:

  1. ์Šคํƒ ํ”„๋ ˆ์ž„ ์ƒ์„ฑ
    • push ebp / mov ebp, esp
    • sub esp, 0x40๋กœ ๋กœ์ปฌ ๋ฌธ์ž์—ด ๋ฒ„ํผ ํ™•๋ณด
  2. ๋ณตํ˜ธํ™” ๋ฃจํ‹ด ํ˜ธ์ถœ
    • ํ•จ์ˆ˜ ํ˜ธ์ถœ ๊ทœ์•ฝ: cdecl
    • ๋งค๊ฐœ๋ณ€์ˆ˜: ๋ชฉ์ ์ง€ ๋ฒ„ํผ โ†’ ์•”ํ˜ธํ™”๋œ ๋ฌธ์ž์—ด โ†’ ๊ธธ์ด
    • ๋ฐ˜ํ™˜๊ฐ’ ์—†์Œ
    • ๋ฌธ์ž์—ด์€ XOR/ROL ๋“ฑ ๋‹จ์ˆœ์•”ํ˜ธ๋กœ ํ™•์ธ
  3. PEB ์ ‘๊ทผ ๊ธฐ๋ฐ˜ ๋™์  API ํš๋“
    • PEB (fs:[0x30]) โ†’ LDR โ†’ InMemoryOrderModuleList
    • kernel32.dll ๋ฒ ์ด์Šค ์ฃผ์†Œ ํš๋“
    • Export Directory ํŒŒ์‹ฑ
    • ๋ฌธ์ž์—ด ๋น„๊ต๋กœ LoadLibraryA, GetProcAddress ๊ฒ€์ƒ‰
    • ์‹ค์ œ๋กœ๋Š” K32 API๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ž์ฒด ๊ตฌํ˜„ํ•œ Export ํŒŒ์„œ ์‚ฌ์šฉ
  4. IAT ํŒจ์น˜
    • IAT ์—”ํŠธ๋ฆฌ RVA๋Š” ํŒจ์ปค ์Šคํ…์— ํ•˜๋“œ์ฝ”๋”ฉ
    • Unpacked OEP ์ง„์ž… ์ „ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„

5. ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ ๋ถ„์„

5.1 ๋ณตํ˜ธํ™” ๋ฃจํ‹ด ์ธ์ž

  • ecx: ๋ชฉ์ ์ง€ ๋ฒ„ํผ
  • esp+4: ์•”ํ˜ธํ™” ๋ฌธ์ž์—ด ์ฃผ์†Œ
  • esp+8: ๊ธธ์ด

๋ชจ๋“  ๋ฌธ์ž์—ด์€ .data๊ฐ€ ์•„๋‹Œ ํŒจ์ปค๊ฐ€ ์ƒ์„ฑํ•œ ๋ฐ์ดํ„ฐ ์˜์—ญ์— ์กด์žฌํ•˜๋ฉฐ,
์‹คํ–‰ ์ „๊นŒ์ง€ ์ ‘๊ทผ ๋ถˆ๊ฐ€(ํŽ˜์ด์ง€ ๊ถŒํ•œ RX โ†’ RWX ์ „ํ™˜ ํ›„ ๋ณตํ˜ธํ™”).

5.2 IAT ํŒจ์น˜

IAT๋Š” .rdata, .idata๊ฐ€ ์•„๋‹Œ ํŒจ์ปค๊ฐ€ ์ž„์˜๋กœ ๋งŒ๋“  ์„น์…˜์— ์กด์žฌ.
ํ•ด๋‹น ์„น์…˜์€:

  • ์ดˆ๊ธฐ ์ƒํƒœ: RWX
  • ํŒจ์น˜ ํ›„: ๋‹ค์‹œ RX๋กœ ๋ฐ”๊ฟ” ํƒ์ง€ ํšŒํ”ผ

์ด๋Š” ์ด๋ฅธ๋ฐ” self-protection section ํŒจํ„ด์œผ๋กœ ์ž˜ ์•Œ๋ ค์ง„ ๊ธฐ๋ฒ•.


6. Anti-Debugging ๊ด€์ฐฐ ์š”์†Œ

๋ณธ ๋ฃจํ‹ด ์ „ํ›„์— ์กด์žฌํ•œ ์ฒดํฌ:

mov eax, fs:[0x30]          ; PEB
mov eax, [eax+0x02]         ; BeingDebugged flag
test eax, eax
jnz  DebugFound

๋˜ํ•œ:

call IsDebuggerPresent       ; API ๊ธฐ๋ฐ˜ ์ฒดํฌ
xor  eax, eax
mov  al, [esp+4]             ; RET ์ดํ›„ ์ˆ˜์ •๋œ ์Šคํƒ ๊ฒ€์‚ฌ
cmp  eax, 0xCC               ; INT3 ํŒจ์น˜ ์—ฌ๋ถ€  

์ด๋Ÿฐ ๋‹ค๋‹จ๊ณ„ anti-debug๋Š” ํŒจ์ปค๊ฐ€ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ํŒจํ„ด.


7. ๋ถ„์„ ํฌ์ธํŠธ ์š”์•ฝ

๋ถ„์„ ํ•ญ๋ชฉ์ ์šฉ ์›๋ฆฌ
Import ๋ณต์›PE ๊ตฌ์กฐ / Export Directory ํŒŒ์‹ฑ
๋ณตํ˜ธํ™” ๋ฃจํ‹ด์ œ์–ด ํ๋ฆ„ ๋ถ„์„ / ์•”ํ˜ธํ™” ๋ฃจํ‹ด ๋ณต์›
API ๋กœ๋”ฉWindows Internals / PEB ๊ตฌ์กฐ
์Šคํƒ ํ”„๋ ˆ์ž„ํ˜ธ์ถœ ๊ทœ์•ฝ(cdecl) / ๋กœ์ปฌ ๋ฉ”๋ชจ๋ฆฌ
ํŒจ์ปค ์ „ํ˜• ํŒจํ„ดOEP ์ ํ”„ / IAT ์ˆ˜๋™ ์žฌ๊ตฌ์„ฑ
Anti-debugPEB BeingDebugged / INT3 ์ฒดํฌ

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

ํŒจ์ปค์˜ Import ๋ณต์› ๋ฃจํ‹ด์€ ํŒจํ‚น๋œ PE๋ฅผ ํ•ด์„ํ•˜๋Š” ์ฒซ ๊ด€๋ฌธ์ด๋ฉฐ,
PEB ๊ธฐ๋ฐ˜ API ์กฐํšŒ์™€ IAT ํŒจ์น˜๋Š” ์•…์„ฑ์ฝ”๋“œ ๋ถ„์„์—์„œ ๋ฐ˜๋ณต์ ์œผ๋กœ ๋งˆ์ฃผ์น˜๋Š” ํ•ต์‹ฌ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.


๐Ÿ“ Written by Code & Compass

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

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

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