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) ๋ถ์
๋ณต์ ๋ฃจํด์ ์ ์ฒด ํ๋ฆ์ ๋ค์๊ณผ ๊ฐ์:
- ์คํ ํ๋ ์ ์์ฑ
push ebp/mov ebp, espsub esp, 0x40๋ก ๋ก์ปฌ ๋ฌธ์์ด ๋ฒํผ ํ๋ณด
- ๋ณตํธํ ๋ฃจํด ํธ์ถ
- ํจ์ ํธ์ถ ๊ท์ฝ:
cdecl - ๋งค๊ฐ๋ณ์: ๋ชฉ์ ์ง ๋ฒํผ โ ์ํธํ๋ ๋ฌธ์์ด โ ๊ธธ์ด
- ๋ฐํ๊ฐ ์์
- ๋ฌธ์์ด์ XOR/ROL ๋ฑ ๋จ์์ํธ๋ก ํ์ธ
- ํจ์ ํธ์ถ ๊ท์ฝ:
- PEB ์ ๊ทผ ๊ธฐ๋ฐ ๋์ API ํ๋
- PEB (
fs:[0x30]) โ LDR โ InMemoryOrderModuleList - kernel32.dll ๋ฒ ์ด์ค ์ฃผ์ ํ๋
- Export Directory ํ์ฑ
- ๋ฌธ์์ด ๋น๊ต๋ก
LoadLibraryA,GetProcAddress๊ฒ์ - ์ค์ ๋ก๋ K32 API๋ฅผ ์ง์ ํธ์ถํ์ง ์๊ณ ์์ฒด ๊ตฌํํ Export ํ์ ์ฌ์ฉ
- PEB (
- 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-debug | PEB BeingDebugged / INT3 ์ฒดํฌ |
โจ ๋ง๋ฌด๋ฆฌ ํ ์ค
ํจ์ปค์ Import ๋ณต์ ๋ฃจํด์ ํจํน๋ PE๋ฅผ ํด์ํ๋ ์ฒซ ๊ด๋ฌธ์ด๋ฉฐ,
PEB ๊ธฐ๋ฐ API ์กฐํ์ IAT ํจ์น๋ ์
์ฑ์ฝ๋ ๋ถ์์์ ๋ฐ๋ณต์ ์ผ๋ก ๋ง์ฃผ์น๋ ํต์ฌ ๊ตฌ์กฐ์
๋๋ค.
๐ Written by Code & Compass