Exploring the x64 村上 純一 執行役員 先端技術研究部長 (株)フォティーンフォティ技術研究所 自己紹介 • 村上 純一 – – – – (株)フォティーンフォティ技術研究所 カーネルモードでのWindows、Linuxにおける開発 セキュリティ脆弱性分析、マルウェア解析、P2P解析等 講演活動 • Black Hat 2008 US and Japan, AVAR 2009, RSA Conference(2009-) – セキュリティ&プログラミングキャンプ講師(2006-) 2 はじめに & 目標 • IA64 • Linux, *BSD, Mac, etc. x86で利用される様々なテクニックがx64ではどの ようになっているかを明確にする 難易度 3 環境 • • • • Windows 7 x64 Edition Visual Studio 2008 Windbg IDA Pro Advanced – Standard Editionは、x64未対応 4 アジェンダ • • • • Windows x64 ABI(Application Binary Interface) API Hooking Code Injection 5 Windows x64 • Native x64 およびWoW64 • 仮想メモリ空間 – 2^64 = 16 Exa Byte ( Exa: 10^18) – 実際には、最大16TBに制限されている • ファイル・レジストリリフレクション • 64-bit用の追加API – IsWow64Process, GetNativeSystemInfo, etc. 6 x86 – プロセスメモリ空間 0x0 0x0 ユーザー空間 0x00400000 実行モジュール 0x7fffffff (2GB) カーネル MSVCR90.dll kernel32.dll 0xffffffff (4GB) 0x7fffffff ntdll.dll 7 x64 – プロセスメモリ空間 0x0 2GB ユーザー空間 0x7ff`ffffffff (8TB) カーネル 0xfff`ffffffff (16TB) ・ ・ ・ x 4096(0x7ff`ffffffff / 0x7fffffff ) ・ ・ ・ ・ 2GB ・ ・ ・ x 4096 ・ ・ ・ ・ 8 x64 – プロセスメモリ空間 0x0 0x0 ユーザー空間 MSVCR90.dll kernel32.dll ntdll.dll 0x7fffffff 0x1`40000000 0x7ff`ffffffff (8TB) 実行モジュール /DYNAMICBASE:NO カーネル 0xfff`ffffffff (16TB) 0x7fff`fffffff KERNELBASE.dll 9 WoW64 – プロセスメモリ空間 0x0 0x0 x 4096 ユーザープロセス 0x7ff`ffffffff (8TB) 0x00400000 C:¥Windows¥System32¥ntdll.dll 実行モジュール wow64cpu wow64win wow64 C:¥Windows¥SysWOW64¥ntdll.dll カーネル kernel32.dll kernelbase.dll ntdll.dll ntdll32.dll 0xfff`ffffffff (16TB) 0x7fffffff 10 ABI • • • • • バイナリ形式 レジスタ 呼び出し規約 例外処理 システムコール(x64, WoW64) 11 バイナリ形式 = PE32+ • 基本的な構造は、概ねPE32と同様 • IMAGE_NT_HEADERS.FileHeader.Machine – 0x014c => x86 – 0x8664 => x64 12 バイナリ形式 • 次のフィールドサイズが64-bitsに拡張されている – IMAGE_NT_HEADERS.IMAGE_OPTIONAL_HEADER • ImageBase • SizeOfStackReserve • SizeOfStackCommit • SizeOfHeapReserve • SizeOfHeapCommit 13 レジスタ x86(32-bits) x64(64-bits) EAX RAX R8 ECX RCX R9 EDX RDX R10 EBX RBX R11 ESI RSI R12 EDI RDI R13 ESP RSP R14 EBP RBP R15 EIP RIP 14 呼び出し規約 • 始めの4つの引数は、RCX, RDX, R8, R9レジスタを利用して渡 される(5つ目以降は、スタック経由) • 呼び出し側がスタック上にレジスタ・ホーム・スペースを確保 • 返り値は、x86同様RAXレジスタ経由で返却される • リーフ関数・非リーフ関数 – リーフ関数:スタックを一切利用しない関数 – PE32+は、非リーフ関数の情報を例外ディレクトリに保存している • レジスタの揮発性 – 揮発レジスタ:RAX, RCX, RDX, R8-R11 – 不揮発レジスタを関数内で変更する場合は、スタックを利用して保 存・復元を行う必要がある 15 呼び出し規約 Low rsp rsp rsp int foo(int a, int b, int c, int d, int e) { int x = 0; x retaddr rcx (home) rdx (home) mov [rsp+20h],5 movx =dword ptr [rsp+20h],r9d a + b + c + d + e * 2; mov r9d,4 movreturn dword x; ptr [rsp+18h],r8d } mov r8d,3 ptr [rsp+10h],edx mov dword mov edx,2 ptr [rsp+8h],ecx mov dword int main(void) sub rsp,30h sub ecx,1 rsp,8h { mov rc; callintfoo r8 (home) rc = foo(1, 2, 3, 4, 5); printf("%d¥n", rc); r9 (home) 5th parameter rsp rc return rc; } High 16 例外処理 • テーブルベースでの処理 – x86で利用されていたリンクリストでの管理は廃止 参考) x86での例外処理 17 例外ディレクトリ及びRUNTIME_FUNCTION構造体 PE32+ Data Directory DOS Header Export Table DOS stub Import Table NT FileHeader Resource Table NT Optional Header Exception Table Section Header ・ ・ ・ Section A Section B Section C Import Address Table ・ ・ ・ struct _RUNTIME_FUNCTION { ULONG BeginAddress; ULONG EndAddress; ULONG UnwindData; } RUNTIME_FUNCTION_ENTRY RUNTIME_FUNCTION_ENTRY RUNTIME_FUNCTION_ENTRY ・ ・ ・ 18 dumpbin /unwindinfo Begin End Info Function Name 00000000 00001000 00001041 000022D4 Unwind version: 1 Unwind flags: None Size of prologue: 0x16 Count of codes: 1 Unwind codes: 16: ALLOC_SMALL, size=0x18 foo 0000000C 00001050 00001095 000022DC Unwind version: 1 Unwind flags: None Size of prologue: 0x04 Count of codes: 1 Unwind codes: 04: ALLOC_SMALL, size=0x48 main 19 RUNTIME_FUNCTION.UnwindData typedef struct _UNWIND_INFO { UBYTE Version : 3; #define UNW_FLAG_NHANDLER 0x0 UBYTE Flags : 5; #define UNW_FLAG_EHANDLER 0x1 UBYTE SizeOfProlog; #define UNW_FLAG_UHANDLER 0x2 UBYTE CountOfCodes; #define UNW_FLAG_CHAININFO 0x4 UBYTE FrameRegister : 4; UBYTE FrameOffset : 4; UNWIND_CODE UnwindCode[1]; union { // If (Flags & UNW_FLAG_EHANDLER) OPTIONAL ULONG ExceptionHandler; // Else if (Flags & UNW_FLAG_CHAININFO) OPTIONAL ULONG FunctionEntry; }; // If (Flags & UNW_FLAG_EHANDLER) OPTIONAL ULONG ExceptionData[]; } UNWIND_INFO, *PUNWIND_INFO; cf. http://www.osronline.com/article.cfm?article=469 20 ExceptionData typedef struct _SCOPE_TABLE { ULONG Count; struct { ULONG BeginAddress; ULONG EndAddress; ULONG HandlerAddress; ULONG JumpTarget; } ScopeRecord[1]; } SCOPE_TABLE, *PSCOPE_TABLE; cf. http://www.osronline.com/article.cfm?article=469 21 try/except int main(void) { int x = 0; __try { printf("%d¥n", 100/x); printf("foo¥n"); printf("bar¥n"); printf("baz¥n"); } __except(EXCEPTION_EXECUTE_HANDLER) { printf("catch!¥n"); } return 0; } 22 try/except Name main Unwind version: 1 Unwind flags: EHANDLER Size of prologue: 0x04 Count of codes: 1 Unwind codes 04: ALLOC_SMALL, size=0x28 Handler:0000165C __C_specific_handler Count of scope table entries: 1 Begin 00001004 End 00001046 Handler 00000001 Target 00001046 140001000 140001004 140001009 14000100A 14000100C 14000100E 140001010 140001017 14000101D 140001024 14000102A 140001031 140001037 14000103E 140001044 sub mov cdq xor idiv mov lea call lea call lea call lea call jmp rsp,28h eax,64h 140001046 14000104D 140001053 140001054 140001056 14000105A lea call nop xor add ret rcx,[400021D0h] qword ptr [40002130h] ecx,ecx eax,ecx edx,eax rcx,[400021B0h] qword ptr [40002130h] rcx,[400021B4h] qword ptr [40002130h] rcx,[400021BCh] qword ptr [40002130h] rcx,[400021C4h] qword ptr [40002130h] 0000000140001054 eax,eax rsp,28h 23 例外ディレクトリの効用 • 実行ファイル内の非リーフ関数を列挙可能 • 非リーフ関数それぞれについて: – 例外処理の情報を取得可能 – スタック及び不揮発レジスタの用途を把握可能 24 システムコール x86 int 0x2e or sysenter ・ ・ ・ MSR[176h] IDTR KiSystemService IDT other interrupt handlers SDT (ntoskrnl.exe) SSDT ・ ・ ・ SDT Shadow (win32k.sys) Nt* APIs Nt* APIs (User/GDI) SSDT 25 システムコール x64 実行モジュール CreateFileW kernel32.dll CreateFileWImplementation (CreateFileW) kernelbase.dll CreateFileW ntdll.dll mov r10,rcx mov eax,52h syscall ret nop dword ptr [rax+rax] NtCreateFile 26 システムコール WoW64 実行モジュール CreateFileW kernel32.dll CreateFileWImplementation (CreateFileW) kernelbase.dll CreateFileW ntdll32.dll NtCreateFile mov xor lea call add ret eax,52h ecx,ecx edx,[esp+4] dword ptr fs:[0C0h] esp,4 2Ch 27 fs:[0C0h] • FSレジスタは、TEB(Thread Environment Block) のアドレスを保持 0:000:x86> dt _TEB dbgbreak!_TEB +0x000 NtTib : _NT_TIB (snip) +0x02c ThreadLocalStoragePointer : Ptr32 Void 0:000:x86> dd fs:[0C0h] +0x030 ProcessEnvironmentBlock : Ptr32 _PEB 00000000 0053:000000c0 738c2320 00000411 00000000 +0x034 LastErrorValue : Uint4B ↑ +0x038 CountOfOwnedCriticalSections : Uint4B X86SwitchTo64BitMode +0x03c CsrClientThread : Ptr32 Void +0x040 Win32ThreadInfo : Ptr32 Void +0x044 User32Reserved : [26] Uint4B +0x0ac UserReserved : [5] Uint4B +0x0c0 WOW32Reserved : Ptr32 Void 28 Systemcall WoW64 call fs:[0C0h] jmp 0033:CpupReturnFromSimulatedCode wow64cpu.dll X86SwitchTo64BitMode CpupReturnFromSimulatedCode TurboDispatchJumpAddressEnd wow64.dll Wow64SystemServiceEx 29 GDT (超約) 仮想メモリ空間 0x0 seg. A • 仮想メモリ空間をセグメントとして管理 • カーネルコード、カーネルデータ • ユーザコード、ユーザデータ等 GDT seg. B seg. C ID seg. base limit type 0x00 A 0x0 0x3f RW 0x08 B 0x40 0x7f RE 0x10 C 0x0 0xff RE セグメントセレクタ 0xff 30 Windows 7(x64)でのGDTダンプ結果 kd> dg 0x00 0x60 P Si Gr Pr Lo Sel Base Limit Type l ze an es ng ---- ----------------- ----------------- ---------- - -- -- -- -0000 00000000`00000000 00000000`00000000 <Reserved> 0 NbUser By NpDS Nl Kernel CS(x64), Kernel DS User CS(x86), 0008 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 0010 00000000`00000000 00000000`00000000 Code RE Ac 0 Nb By P Lo 0018 00000000`00000000 00000000`ffffffff Data RW Ac 0 Bg Pg P Nl 0020 00000000`00000000 00000000`ffffffff Code RE 3 Bg Pg P Nl 0028 00000000`00000000 00000000`ffffffff Data RW Ac 3 Bg Pg P Nl 0030 00000000`00000000 00000000`00000000 Code RE Ac 3 Nb By P Lo 0038 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 0040 00000000`00b9b080 00000000`00000067 TSS32 Busy 0 Nb By P Nl User CS(x64) 0048 00000000`0000ffff 00000000`0000f800 <Reserved> 0 Nb By Np Nl 0050 ffffffff`fffe0000 00000000`00003c00 Data RW Ac 3 Bg By P Nl 0058 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 0060 00000000`00000000 00000000`ffffffff Code RE 0 Bg Pg P Nl Flags -------00000000 00000000 0000029b 00000c93 00000cfa 00000cf3 000002fb 00000000 0000008b 00000000 000004f3 00000000 00000c9a 31 GDT[0x30]の内容 • • • • • ベース: 0x000`00000000 リミット: 0x000`00000000 タイプ: CODE, Read, Execute and Accessed 特権レベル: 3(ユーザーモード) L (64-bitコードセグメント) flag: 1 32 システムコール WoW64 wow64.dll Wow64SystemServiceEx whNtCreateFile mov r10,rcx mov eax,52h syscall ret ntdll.dll NtCreateFile 33 システムコール WoW64 (return to x86) ntdll.dll NtCreateFile 0:000> dd r14 00000000`0008ec70 77330056 00000023 0008ed30 00000000 wow64.dll whNtCreateFile ↑ ↑ offset User Code(x86) Wow64SystemServiceEx wow64cpu.dll TurboDispatchJumpAddressEnd CpuSimulate mov mov mov mov mov mov jmp dword ptr r8d,2Bh ss,r8w esp,dword r9d,dword dword ptr fword ptr [r14+4],23h ptr [r13+0C8h] ptr [r13+0BCh] [r14],r9d [r14] 34 デモ: WoW64からのx64 APIの直接呼出し • x86からx64への遷移 – jmp 0033:XXXXXXXX • API呼び出し – rax: システムコール番号 – rdx: 引数リストのアドレス – syscall • x64からx86への遷移 – call 0023:XXXXXXXX 35 API Hooking • IAT Hooking – x86と同様の手法で実現可能 • Code Hooking 36 Code Hooking • 基本的な方法は、x86と同じ • ただし実装の詳細に若干の差異有り mov push mov ret push nop sub nop … … edi,edi hookfunc ebp,esp ebp esp,0xc 対象API … … … jmp trampoline フック関数 mov push mov sub jmp edi,edi ebp ebp,esp esp,8h XXXXXXXX トランポリンコード 37 REXプレフィックス • 0x40~0x4E – x86: INC 、DEC 命令 – x64: REX プレフィックス(レジスタ拡張) • 例) 0x48,0xB8,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88 x86: 48 B8 11 22 33 44 55 66 77 88 dec mov push ja eax eax,44332211h ebp 00004E9F x64: 48 B8 11 22 33 44 55 66 77 88 mov rax,8877665544332211h 38 Code Hooking フック関数 00000000779811E4 00000000779811EE 00000000779811EF 00000000779811F2 mov push ret … rax,7FFFFFA0028h rax 000007FFFFFA0034 000007FFFFFA0038 000007FFFFFA003B 000007FFFFFA0042 000007FFFFFA0043 000007FFFFFA004D 000007FFFFFA0051 sub xor cmp push mov xchg ret 書換えた元のコード rsp,38h r11d,r11d dword ptr [7FFFFFC0F8Ch],r11d rax rax,779811F2h rax,qword ptr [rsp] フックした関数への復帰先 39 Code Injection • • • • WoW64 からWoW64ヘのインジェクション x64からx64へのインジェクション WoW64 から x64へのインジェクション x64 からWoW64ヘのインジェクション (Fail CreateRemoteThead API) x64環境は、x86マルウェアへの魔除けになるか? 40 まとめ • • • • Windows x64 ABI(Application Binary Interface) API Hooking Code Injection 41 Special thanks • Toshiaki Ishiyama@FFR • Satoshi Tanda@FFR 42
© Copyright 2024 ExpyDoc