Exploring the x64

42
Exploring the x64 Junichi Murakami Executive Officer, Director of Research Fourteenforty Research Institute, Inc.

description

 

Transcript of Exploring the x64

Page 1: Exploring the x64

Exploring the x64

Junichi Murakami Executive Officer, Director of Research Fourteenforty Research Institute, Inc.

Page 2: Exploring the x64

Who am I?

• Junichi Murakami – @Fourteenforty Research Institute, Inc.

– Both Windows and Linux kernel development

– Reversing malware and P2P software, etc.

– Speaker at:

• Black Hat 2008 US and Japan, AVAR 2009, RSA Conference(2009-)

– Instructor at Security & Programming Camp(2006-)

2

Page 3: Exploring the x64

DISCLAIMER

• IA64

• Linux, *BSD, Mac, etc.

3

and Goal

Make clear the various weird techniques which are used under x86 on x64 environment

difficulty

Page 4: Exploring the x64

Environment

• Windows 7 x64 Edition • Visual Studio 2008 • Windbg • IDA Pro Advanced

– STD doesn’t support x64, an offering is needed!

4

Page 5: Exploring the x64

Agenda

• Windows x64

• ABI(Application Binary Interface)

• API Hooking

• Code Injection

5

Page 6: Exploring the x64

Windows x64

• Native x64 and WoW64

• Virtual Address Space

– 2^64 = 16 Exa Byte ( Exa: 10^18)

– but, limited to 16TB by Microsoft

• File/Registry reflection

• New 64-bit APIs

– IsWow64Process, GetNativeSystemInfo, etc.

6

Page 7: Exploring the x64

x86 – Process Memory Layout

7

0x0

0xffffffff (4GB)

0x7fffffff (2GB)

Kernel

User-process

0x7fffffff

0x0

ntdll.dll

kernel32.dll

MSVCR90.dll

Executable 0x00400000

Page 8: Exploring the x64

x64 – Process Memory Layout

8

0x0

0xfff`ffffffff (16TB)

0x7ff`ffffffff (8TB)

Kernel

User-process

2GB

・ ・ ・ ・ ・ ・ ・

x 4096(0x7ff`ffffffff / 0x7fffffff )

・ ・ ・ ・ ・ ・ ・

x 4096

2GB

Page 9: Exploring the x64

x64 – Process Memory Layout(Cont.)

9

0x0

Kernel

User-process

0x0

KERNELBASE.dll

Executable 0x1`40000000

0x7fffffff

0xfff`ffffffff (16TB)

0x7ff`ffffffff (8TB)

0x7fff`fffffff

ntdll.dll

kernel32.dll

MSVCR90.dll

/DYNAMICBASE:NO

Page 10: Exploring the x64

WoW64 – Process Memory Layout

10

0x0

0xfff`ffffffff (16TB)

0x7ff`ffffffff (8TB)

Kernel

User-process

x 4096

0x7fffffff

0x0

ntdll.dll

kernel32.dll

wow64

Executable 0x00400000

ntdll32.dll

kernelbase.dll

wow64win

wow64cpu C:¥Windows¥System32¥ntdll.dll

C:¥Windows¥SysWOW64¥ntdll.dll

Page 11: Exploring the x64

ABI

• Binary Format

• Register

• Calling Convention

• Exception Handling

• Systemcall(x64, WoW64)

11

Page 12: Exploring the x64

Binary Format = PE32+

• Mostly the same as PE32

• IMAGE_NT_HEADERS.FileHeader.Machine

– 0x014c => x86

– 0x8664 => x64

12

Page 13: Exploring the x64

Binary Format(Cont.)

• Some fields were extended to 64-bits

– IMAGE_NT_HEADERS.IMAGE_OPTIONAL_HEADER

• ImageBase

• SizeOfStackReserve

• SizeOfStackCommit

• SizeOfHeapReserve

• SizeOfHeapCommit

13

Page 14: Exploring the x64

Register

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

Just a GPR, not *BasePointer*

Page 15: Exploring the x64

Calling Convention

• first 4 parameters are passed by RCX, RDX, R8, R9

– 5th and later are passed on the stack

• caller allocates register home space on the stack

• RAX is used for return values

• leaf / non-leaf function

– leaf function: never use stack

– PE32+ contains non-leaf function’s information in its EXCEPTION DIRECTORY

• Register’s volatility

– volatile: RAX, RCX, RDX, R8-R11

15

Page 16: Exploring the x64

Calling Convention

16

int foo(int a, int b, int c, int d, int e) { int x = 0; x = a + b + c + d + e * 2; return x; } int main(void) { int rc; rc = foo(1, 2, 3, 4, 5); printf("%d¥n", rc); return rc; }

rc

r9 (home)

r8 (home)

rdx (home)

rcx (home)

Low

High

retaddr

x

5th parameter

rsp

rsp

rsp

rsp

sub rsp,30h

mov dword ptr [rsp+20h],5 mov r9d,4 mov r8d,3 mov edx,2 mov ecx,1 call foo

mov dword ptr [rsp+20h],r9d mov dword ptr [rsp+18h],r8d mov dword ptr [rsp+10h],edx mov dword ptr [rsp+8h],ecx sub rsp,8h

Page 17: Exploring the x64

Exception Handling

• Table-base

– linked-list is no longer used

17

if you don’t know the classic SEH mechanism, you should check Shuichiro Suzuki’s works!

Page 18: Exploring the x64

Exception Directory and RUNTIME_FUNCTION

18

Section A

PE32+

DOS Header

DOS stub

NT FileHeader

NT Optional Header

Section Header

Section B

Section C

Export Table

Import Table

Resource Table

Exception Table

Import Address Table

・ ・ ・

・ ・ ・

Data Directory

RUNTIME_FUNCTION_ENTRY

RUNTIME_FUNCTION_ENTRY

RUNTIME_FUNCTION_ENTRY

・ ・ ・

struct _RUNTIME_FUNCTION { ULONG BeginAddress; ULONG EndAddress; ULONG UnwindData; }

Page 19: Exploring the x64

dumpbin /unwindinfo

Begin End Info Function Name

00000000 00001000 00001041 000022D4 foo

Unwind version: 1

Unwind flags: None

Size of prologue: 0x16

Count of codes: 1

Unwind codes:

16: ALLOC_SMALL, size=0x18

0000000C 00001050 00001095 000022DC main

Unwind version: 1

Unwind flags: None

Size of prologue: 0x04

Count of codes: 1

Unwind codes:

04: ALLOC_SMALL, size=0x48

19

Page 20: Exploring the x64

RUNTIME_FUNCTION.UnwindData

20

typedef struct _UNWIND_INFO { UBYTE Version : 3; UBYTE Flags : 5; UBYTE SizeOfProlog; UBYTE CountOfCodes; 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;

#define UNW_FLAG_NHANDLER 0x0 #define UNW_FLAG_EHANDLER 0x1 #define UNW_FLAG_UHANDLER 0x2 #define UNW_FLAG_CHAININFO 0x4

cf. http://www.osronline.com/article.cfm?article=469

Page 21: Exploring the x64

ExceptionData

typedef struct _SCOPE_TABLE { ULONG Count; struct { ULONG BeginAddress; ULONG EndAddress; ULONG HandlerAddress; ULONG JumpTarget; } ScopeRecord[1]; } SCOPE_TABLE, *PSCOPE_TABLE;

21

cf. http://www.osronline.com/article.cfm?article=469

Page 22: Exploring the x64

try/except

22

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; }

Page 23: Exploring the x64

try/except

23

140001000 sub rsp,28h 140001004 mov eax,64h 140001009 cdq 14000100A xor ecx,ecx 14000100C idiv eax,ecx 14000100E mov edx,eax 140001010 lea rcx,[400021B0h] 140001017 call qword ptr [40002130h] 14000101D lea rcx,[400021B4h] 140001024 call qword ptr [40002130h] 14000102A lea rcx,[400021BCh] 140001031 call qword ptr [40002130h] 140001037 lea rcx,[400021C4h] 14000103E call qword ptr [40002130h] 140001044 jmp 0000000140001054 140001046 lea rcx,[400021D0h] 14000104D call qword ptr [40002130h] 140001053 nop 140001054 xor eax,eax 140001056 add rsp,28h 14000105A ret

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

Page 24: Exploring the x64

advantages of the exception directory (RF structure)

• possible to enumerate all non-leaf functions

• possible to understand

– each function’s exception information

– each function’s usage of stack and volatile registers

24

Page 25: Exploring the x64

Systemcall x86

25

IDTR

MSR[176h]

SDT (ntoskrnl.exe)

SDT Shadow (win32k.sys)

IDT

・ ・ ・

・ ・ ・

KiSystemService

Nt* APIs

Nt* APIs (User/GDI)

SSDT

SSDT other interrupt handlers

int 0x2e or sysenter

Page 26: Exploring the x64

Systemcall x64

26

ntdll.dll NtCreateFile

kernel32.dll

CreateFileWImplementation

(CreateFileW)

kernelbase.dll CreateFileW

executable CreateFileW

mov r10,rcx mov eax,52h syscall ret nop dword ptr [rax+rax]

Page 27: Exploring the x64

Systemcall WoW64

27

ntdll32.dll NtCreateFile

kernel32.dll

CreateFileWImplementation

(CreateFileW)

kernelbase.dll CreateFileW

executable CreateFileW

mov eax,52h xor ecx,ecx lea edx,[esp+4] call dword ptr fs:[0C0h] add esp,4 ret 2Ch

Page 28: Exploring the x64

fs:[0C0h]

28

0:000:x86> dt _TEB dbgbreak!_TEB +0x000 NtTib : _NT_TIB (snip) +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB +0x034 LastErrorValue : Uint4B +0x038 CountOfOwnedCriticalSections : Uint4B +0x03c CsrClientThread : Ptr32 Void +0x040 Win32ThreadInfo : Ptr32 Void +0x044 User32Reserved : [26] Uint4B +0x0ac UserReserved : [5] Uint4B +0x0c0 WOW32Reserved : Ptr32 Void

• FS register points to TEB(Thread Environment Block)

0:000:x86> dd fs:[0C0h] 0053:000000c0 738c2320 00000411 00000000 00000000 ↑ X86SwitchTo64BitMode

Page 29: Exploring the x64

Systemcall WoW64

29

wow64cpu.dll

X86SwitchTo64BitMode

CpupReturnFromSimulatedCode

TurboDispatchJumpAddressEnd

wow64.dll

Wow64SystemServiceEx

jmp 0033:CpupReturnFromSimulatedCode

call fs:[0C0h]

Page 30: Exploring the x64

GDT (super quick interpretation)

30

Virtual Address Space • Manage memory as segment

• Kernel code/data • User code/data, etc. seg. A

seg. B

seg. C

0x0

0xff

ID seg. base limit type

0x00 A 0x0 0x3f RW

0x08 B 0x40 0x7f RE

0x10 C 0x0 0xff RE

segment selector

GDT

Page 31: Exploring the x64

Dumping GDT entries

31

kd> dg 0x00 0x60 P Si Gr Pr Lo Sel Base Limit Type l ze an es ng Flags ---- ----------------- ----------------- ---------- - -- -- -- -- -------- 0000 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000 0008 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000 0010 00000000`00000000 00000000`00000000 Code RE Ac 0 Nb By P Lo 0000029b 0018 00000000`00000000 00000000`ffffffff Data RW Ac 0 Bg Pg P Nl 00000c93 0020 00000000`00000000 00000000`ffffffff Code RE 3 Bg Pg P Nl 00000cfa 0028 00000000`00000000 00000000`ffffffff Data RW Ac 3 Bg Pg P Nl 00000cf3 0030 00000000`00000000 00000000`00000000 Code RE Ac 3 Nb By P Lo 000002fb 0038 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000 0040 00000000`00b9b080 00000000`00000067 TSS32 Busy 0 Nb By P Nl 0000008b 0048 00000000`0000ffff 00000000`0000f800 <Reserved> 0 Nb By Np Nl 00000000 0050 ffffffff`fffe0000 00000000`00003c00 Data RW Ac 3 Bg By P Nl 000004f3 0058 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000 0060 00000000`00000000 00000000`ffffffff Code RE 0 Bg Pg P Nl 00000c9a

Kernel CS(x64), Kernel DS User CS(x86), User DS

User CS(x64)

Page 32: Exploring the x64

Content of GDT[0x30]

• base: 0x000`00000000

• limite: 0x000`00000000

• type: CODE, Read, Execute and Accessed

• Privilege Level: 3(User-mode)

• L (64-bit code segment) flag: set

32

Page 33: Exploring the x64

Systemcall WoW64

33

wow64.dll

Wow64SystemServiceEx

whNtCreateFile

ntdll.dll

NtCreateFile

mov r10,rcx mov eax,52h syscall ret

Page 34: Exploring the x64

Systemcall WoW64 (return to x86)

34

ntdll.dll

NtCreateFile

wow64.dll

whNtCreateFile

Wow64SystemServiceEx

wow64cpu.dll

TurboDispatchJumpAddressEnd

CpuSimulate

mov dword ptr [r14+4],23h mov r8d,2Bh mov ss,r8w mov esp,dword ptr [r13+0C8h] mov r9d,dword ptr [r13+0BCh] mov dword ptr [r14],r9d jmp fword ptr [r14]

0:000> dd r14 00000000`0008ec70 77330056 00000023 0008ed30 00000000 ↑ ↑ offset User Code(x86)

Page 35: Exploring the x64

Demo: Direct x64 API call from WoW64

• x86 to x64

– jmp 0033:XXXXXXXX

• API call

– rax: syscall number

– rdx: pointer to parameter list

– syscall

• x64 to x86

– call 0023:XXXXXXXX

35

Page 36: Exploring the x64

API Hooking

• IAT Hooking

– possible to hook IAT on x64 in the same manner as x86

• Code Hooking

36

Page 37: Exploring the x64

Code Hooking

• basic idea is same as x86

• implementation detail is a little different

37

mov edi,edi mov ebp,esp push ebp sub esp,0xc … …

target API

mov edi,edi push ebp mov ebp,esp sub esp,8h jmp XXXXXXXX

trampoline

… … … jmp trampoline

hookfunc

push hookfunc ret nop nop

Page 38: Exploring the x64

REX prefix

• 0x40~0x4E – x86: INC and DEC inst.

– x64: REX prefix (register extension)

• ex) 0x48,0xB8,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88

38

48 B8 11 22 33 44 55 66 77 88 mov rax,8877665544332211h

48 dec eax B8 11 22 33 44 mov eax,44332211h 55 push ebp 66 77 88 ja 00004E9F

x86:

x64:

Page 39: Exploring the x64

Code Hooking

39

00000000779811E4 mov rax,7FFFFFA0028h 00000000779811EE push rax 00000000779811EF ret 00000000779811F2 …

000007FFFFFA0034 sub rsp,38h 000007FFFFFA0038 xor r11d,r11d 000007FFFFFA003B cmp dword ptr [7FFFFFC0F8Ch],r11d 000007FFFFFA0042 push rax 000007FFFFFA0043 mov rax,779811F2h 000007FFFFFA004D xchg rax,qword ptr [rsp] 000007FFFFFA0051 ret

hookfunc

original inst.

jump-back address

Page 40: Exploring the x64

Code Injection

• WoW64 to WoW64

• x64 to x64

• WoW64 to x64

• x64 to WoW64

40

x64 is the 魔除け(talisman) against x86 malware ?

(Fail CreateRemoteThead API)

Page 41: Exploring the x64

Conclusions

• Windows x64

• ABI(Application Binary Interface)

• API Hooking

• Code Injection

41

Page 42: Exploring the x64

Acknowledgement

• Toshiaki Ishiyama@FFR

• Satoshi Tanda@FFR

42