DyninstAPI on a Palm-size PC running Windows CE Chadd C. Williams Jeffrey K. Hollingsworth University of Maryland Department of Computer Science University of Maryland 1 Goal Be able to run DyninstAPI on the CE device – Host the mutatee on the CE device – Produce the runtime DLL for the CE device – Host the mutator on the CE device (failed) University of Maryland 2 Background Windows CE 2.11 – Modular embedded OS for small footprint and mobile 32-bit devices – Based on the Win32 API Casio Cassiopeia E105 – NEC VR4121 processor • 64 bit MIPS III • 32 MB storage/memory University of Maryland 3 OS/process conflicts Windows CE puts the processor into 32bit mode – Only gives access to MIPS I and MIPS II instructions – Only gives access to 32-bits of the registers Windows CE puts the processor into little-endian mode to match x86 University of Maryland 4 DyninstAPI MIPS code base DyninstAPI does work for MIPS Expects MIPS III chips with 64 bit registers and floating point registers Expects big-endian data layout Expects IRIX to be the operating system University of Maryland 5 DyninstAPI WinNT code base DyninstAPI does work for Win32 API – Uses Win32 Debug API Expects x86 chip Expects little-endian data layout Expects WinNT to be the operating system Expects debug symbols in the EXE file University of Maryland 6 DyninstAPI source code structure Architecture and OS specific code is separate Architecture specific code written to common interface Relatively easy to swap the MIPS and x86 specific code University of Maryland 7 Windows CE problems WinCE does implement a subset of Win32 API – WinCE does not fully implement the Debug API – WinCE differently implements (buggy?) the Win32 API – WinCE uses an old MIPS (o32) calling convention – WinCE does not support common C header files • <stdio.h> <assert.h> <errno.h> Visual C++ will not put debug symbols in a WinCE executable – No debug symbols provided for system libraries University of Maryland 8 Architecture Windows NT Mutator .map files MIPS code generator mutatee EXE Windows CE Mutatee libdyninstAPI_RT.dll remoteDevice interface Winsock client base tramp serial line Winsock University of Maryland 9 NT Box Produce a remoteDevice interface to manage interaction with CE device – Provide basic operations • read/write process memory • catch debug event • pause/resume thread Mutator parses the .map file for the EXE and libdyninstAPI_RT.dll University of Maryland 10 NT Box Implement necessary Debug API functions using remoteDevice interface and .map files – StackWalk() Generate MIPS II instructions – little endian – 32 bit University of Maryland 11 CE device Small client on the CE device to remotely manage mutatee – Provides the remoteDevice interface Trampoline must be created by the MIPS compiler, uploaded to NT box at run time libdyninstAPI_RT.dll University of Maryland 12 Visual C++ will not put debug symbols in a WinCE executable Debug symbols cannot be added to a WinCE EXE with Visual C++ Debug symbols are placed in external files, .pdb – A .pdb file is an undocumented proprietary format! – WinCE offers no way to access .pdb files – WinNT offers no way to access .pdb files Visual C++ will produce a .map file – Text file containing debug symbols for non-local data – Global variables must be initialized to be listed in the .map file • Causes libdyninstAPI_RT.dll to be 4MB – No type definitions – No local variables University of Maryland 13 WinCE does not fully implement the Debug API Win32 provides the Debug API to provide access to debug information – Debugger functions • StackWalk() • UnDecorateSymbolName() – Symbol handler • SymGetModuleBase() • SymGetSymbolInfo() DyninstAPI relies on these to gain debug information WinCE does not implement many of these! University of Maryland 14 Solution Use Debug API on the NT box – UnDecorateSymbolName() Implement needed functions – StackWalk() Parse .map file and use base address of EXE to determine symbol information University of Maryland 15 WinCE differently implements (buggy?) the Win32 API CreateProcess() – used to launch an application – WinNT throws two debug events • Create process • Start main() – WinCE throws one debug event • Create process – DyninstAPI relies on ‘Start main()’ to load the libdyninstAPI_RT.dll University of Maryland 16 Solution WinCE throws a debug message when loading a DLL WinCE applications always load COREDLL.DLL before starting main() – COREDLL.DLL contains LoadLibrary which is needed to load the runtime DLL – No debug symbols for COREDLL.DLL • Experimental evidence shows location of LoadLibray Watch for COREDLL.DLL debug message to start DyninstAPI University of Maryland 17 WinCE uses an old MIPS (o32) calling convention WinCE expects the caller function to correctly setup the stack to allow the callee to copy data from the argument registers to the stack DyninstAPI needs to provide the callee the stack space it requires Modified mini-tramp generation code to determine how much space the callee needs and grow/shrink the stack Need access to size of each parameter University of Maryland 18 WinCE calling convention bar sp foo(){ . bar(42,11,38,32,64); . . } … foo sp return address 42 from a0 11 from a1 38 from a2 32 from a3 64 University of Maryland Mini-tramp must allocate room on the stack after storing the registers for the callee to use 19 Conclusions Cannot easily put the mutator on the CE device – Lack of header files – No easy access to debug symbols – Limited hardware (CPU/memory) Would be nice to have better debug symbols Would be nice if the Debug API was implemented on the CE device University of Maryland 20 Conclusions It works! test1 – 32 test cases – 4 not implemented on NT – 4 not implemented on CE • needs local variable access – the rest work Serial line is a performance bottle neck – New devices have USB support University of Maryland 21 Demo Interactive demo on Wednesday University of Maryland 22