A preliminary exploration of Windows CE
Created: 2004-11-05 Updated: 2004-12-06
Article attribute: original
Article submission:
SAN (SAN_AT_XFOCUS.ORG)
San
Create: 2004.10.17
Update: 2004.11.09
- [1. Introduction to ARM
From the Platform Builder, Windows CE supports quite a large number of CPUs, but now the PDA, actual sales on the market, almost all ARM chips. ARM is a 32-bit microprocessor of a RISC architecture, which has 16 visible registers at a time: R0-R15. Where R0-R7 is a universal register and can do any purposes; R8-R12 is also a universal register, but when switching to the FIQ mode, use their shadow register; the last three are special registers:
R13 (SP) - Stack pointer
R14 (LR) - Link Register
R15 (PC / PSR) - Program Counter / Status Register
Idapro and debugger are represented by alias. Similar to other RISC instructions, the ARM directive mainly has branch instructions, loads, and stores instructions, etc. In addition to load and storage instructions, other instructions cannot directly operate memory, and load and store instruction operations. It is a 4-byte type, then the memory address must be required to be 4-byte alignment, which is also a relatively large part of the RISC instruction and CISC instructions, which is more troublesome when the string is operated. ARM directive a very interesting place is to directly modify access to the PC register, so if you write shellcode, you need to locate itself if you need a SPARC or POWERPC.
In addition, the byte sequence used by the default WINDOWS CE is Little-Endian.
- [2. Windows CE core structure
Windows CE is a 32-bit operating system, so its virtual memory size is 4GB (2 of 32 times). Windows CE divides the 4GB virtual memory space into low address 2GB and high address 2GB. The address space used by the application is low address 2GB, and the high address 2GB is designed for Windows CE kernel. There are some interesting information in the private / winceos / coreos / nk / inc / nkarm.h header file in Windows CE 3.0 source code:
/ * High Memory Layout
*
* This structure is mapped in at the end of the 4GB Virtual
* Address Space.
*
* 0xffd0000 - First Level Page Table (Uncached) (2nd Half IS R / O)
* 0xffd4000 - Disabled for Protection
* 0xffe0000 - Second Level Page Tables (Uncached)
* 0xffe4000 - DISABLED for Protection
* 0xffff0000 - Exception Vectors
* 0xffff0400 - Not used (r / o)
* 0xffff1000 - Disabled for Protection
* 0xffff2000 - R / O (Physical Overlaps with vectors)
* 0xffff2400 - Interrupt Stack (1K)
* 0xffff2800 - R / O (Physical Overlaps with Abort Stack & Fiq Stack)
* 0xffff3000 - DISABLED for Protection
* 0xffff4000 - R / O (Physical Memory Overlaps with Vectors & Intr. Stack & Fiq Stack)
* 0xfffff4900 - Abort Stack (2K - 256 bytes)
* 0xffff5000 - DISABLED for Protection
* 0xffff6000 - R / O (Physical Memory Overlaps with Vector & INTR. Stack)
* 0xffff6800 - Fiq Stack (256 Bytes)
* 0xffff6900 - R / O (Physical Memory Overlaps with Abort stack)
* 0xffff7000 - Disabled
* 0xffffc000 - kernel stack
* 0xffffc800 - kDataStruct
* 0xffffcc00 - Disabled for Protection (2nd level page table for 0xfff00000)
* /
Typedef struct arm_high {
Ulong firstpt [4096]; // 0xffd0000: 1st level Page Table
PageTBL APT [16]; // 0xffd4000: 2nd Level Page Tables
Char reserved2 [0x20000-0x4000-16 * sizeof (pageTBL)];
Char exvectors [0x400]; // 0xffff0000: Exception Vectors
Char reserved3 [0x2400-0x400];
Char Intrstack [0x400]; // 0xffff2400: Interrupt Stack
Char reserved4 [0x4900-0x2800];
Char Abortstack [0x700]; // 0xffff4900: Abort Stack
Char reserved5 [0x6800-0x5000];
Char FiqStack [0x100]; // 0xfffff6800: Fiq Stack
Char reserved6 [0xc000-0X6900];
Char kstack [0x800]; // 0xffffc000: kernel stack
Struct KdataStruct Kdata; // 0xfffffc800: Kernel Data Page
ARM_HIGH;
The structure of KDataStruct is very important and interesting, some similar Win32 PEB structures define various important information:
Struct kDataStruct {
LPDWORD LPVTLS; / * 0x000 Current Thread Local Storage Pointer * /
Handle Ahsys [Num_Sys_Handles]; / * 0x004 if this moves, change kapi.h * /
// Num_sys_handles == 32: public / common / sdk / inc / kfuncs.h
0x004 sh_win32
0x008 sh_curthread
0x00c sh_curproc
0x010 sh_kwin32
0x044 sh_gdi
0x048 sh_wmgr
0x04c sh_wnet
0x050 sh_comm
0x054 sh_filesys_apis
0x058 sh_shell
0x05c sh_devmgr_apis0x060 sh_tapi
0x064 sh_patcher
0x06c sh_services
Char Bresched; / * 0x084 reschedule flag * /
Char cneest; / * 0x085 kernel exception Nesting * /
Char bpoweroff; / * 0x086 True During "power off" processing * /
Char bprofileon; / * 0x087 True IF profiling enabled * /
Ulong unused; / * 0x088 unused * /
Ulong RSVD2; / * 0x08c WAS DIFFMSEC * /
PPROCESS PCURPRC; / * 0x090 Ptr To Current Process Struct * /
Pthread pcurthd; / * 0x094 ptr to current thread struct * /
DWORD dwkcres; / * 0x098 * /
Ulong Handlebase; / * 0x09c Handle Table Base Address * /
Psection asections [64]; / * 0x0A0 Section Table for Virutal Memory * /
LPEVENT AlpeInTrevents [Sysintr_max_Devices]; / * 0x1a0 * /
LPVOID AlPvinTrdata [sysintr_max_devices]; / * 0x220 * /
Ulong papiReturn; / * 0x2a0 Direct API Return Address for kernel mode * /
Uchar * pmap; / * 0x2a4 ptr to memorymap array * /
DWORD DWINDEBUGER; / * 0X2A8! 0 WHEN in Debugger * /
Pthread Pcurfpuowner; / * 0x2ac Current FPU Owner * /
PPROCESS PCPUSISIDPRC; / * 0X2B0 CURRENT ASID Proc * /
Long NMemforpt; / * 0x2b4 - Memory Used for PageTables * /
Long alpad [18]; / * 0x2b8 - Padding * /
DWORD ainfo [32]; / * 0x300 - Misc. Kernel info * /
// public / common / oak / inc / pkfuncs.h
0x300 KINX_PROCARRAY Address of Process Array
0x304 KINX_PAGESIZE SYSTEM PAGE SIZE
0x308 KINX_PFN_SHIFT SHIFT for Page # in Pte
0x30c KINX_PFN_MASK MASK for Page # in Pte
0x310 KINX_PAGEFREE # of Free Physical Pages
0x314 KINX_SYSPAGES # of Pages Used by kernel
0x318 KINX_KHEAP PTR TO KERNEL HEAP ARRAY
0x31c KINX_SECTIONS PTR TO SectionTable Array0x320 KINX_MEMINFO PTR To System MemoryInfo Struct
0x324 KINX_MODULES PTR to Module List
0x328 KINX_DLL_LOW LOWER Bound of DLL Shared Space
0x32c KINX_NUMPAGES TOTAL # of RAM PAGES
0x330 KINX_PTOC PTR TO ROM TABLE OF Contents
0x334 KINX_KDATA_ADDR KERNEL MODATE VERSION OF KDATA
0x338 KINX_GWESHEAPINFO CURRENT AMOUNT OF GWES HEAP IN USE
0x33c KINX_TIMEZONEBIAS FAST TIMEZONE BIAS INFO
0x340 KINX_PENDEVENTS BIT MASK for Pending Interrupt Events
0x344 KINX_KERNRESERVE NUBER OF KERNEL RESERVED PAGES
0x348 KINX_API_MASK Bit Mask for Registered API Sets
0x34c KINX_NLS_CP HIWORD OEM CODE Page, Loword Ansi Code Page
0x350 KINX_NLS_SYSLOC DEFAULT SYSTEM LOCALE
0x354 KINX_NLS_USERLOC DEFAULT USER LOCALE
0x358 KINX_HEAP_WASTE KERNEL HEAP WASTED SPACE
0x35c KINX_DEBUGER for use by debugger for protocol commiNICATION
0x360 KINX_APISETS APISET POINTERS
0x364 KINX_MINPAGEFREE WATER MARK OF THE minimum Number of Free Pages
0x368 KINX_CELOGSTATUS CELOG STATUS FLAGS
0x36C KINX_NKSECTION Address of Nksection
0x370 KINX_PWR_EVTS Events to Be SetAfter Power ON
0x37c KINX_NKSIG LAST Entry of Kinfo - Signature When NK Is Ready
/ * 0x380 - Interlocked API Code * /
/ * 0x400 - End * /
}
The base address of the Kernel32.dll can be locked by the PEB structure, and then look up the Windows API through the PE file structure. Under Windows CE, the role of Coredll.dll is equivalent to the Win32 kernel32.dll, because the KDataStruct structure begins at 0xffffc800, offset 0x324 AINFO [KINX_MODULES] is a pointer to the module linked list, can you find Coredll.dll by this list Module? Let's take a look at the structure of the module:
// private / winceos / coreos / nk / inc / kernel.h
Typedef struct module {
LPVOID LPSELF; / * 0x00 Self Pointer for Validation * / PModule PMOD; / * 0x04 Next Module in chain * /
LPWSTR LPSZMODNAME; / * 0x08 Module Name * /
DWORD INUSE; / * 0x0c bit vector of use * /
DWORD CALLEDFUNC; / * 0X10 Called Entry But not exit * /
Word Refcnt [MAX_PROCESSES]; / * 0x14 Reference Count Per Process * /
LPVOID BASEPTR; / * 0X54 Base Pointer Of DLL LOAD (NOT 0 based) * /
DWORD DBGFLAGS; / * 0X58 Debug Flags * /
LPDBGPARAM ZONEPTR; / * 0X5C Debug zone Pointer * /
Ulong Startip; / * 0x60 0 based entrypoint * /
OpenEXE_T OE; / * 0x64 Pointer to Executable File Handle * /
Typedef struct Openexe_t {
Union {
Int HPPFS; // PPFS HANDLE
Handle HF; // Object Store Handle
TOCENTRY * TOCPTR; / / ROM Entry Pointer
}; // 0x64
Byte filetype; // 0x68
Byte bisoid; // 0x69
Word pagemode; // 0x6a
Union {
DWORD OFFSET;
DWORD DWEXTROMATTRIB;
}; // 0x6c
Union {
Name * lpname;
Ceoid Ceoid;
}; // 0x70
} OPENEXE_T;
E32_lite E32; / * 0x74 E32 Header * /
// public / common / oak / inc / pehdr.h
TypedEf struct e32_lite {/ * pe 32-bit .exe header * /
UNSIGNED SHORT E32_OBJCNT; / * 0x74 Number of Memory Objects * /
Byte E32_cevermajor; / * 0x76 Version of CE Built for * /
BYTE E32_ceverminor; / * 0x77 Version of CE Built for * /
Unsigned long e32_stackmax; / * 0x78 maximum stack size * /
Unsigned long e32_vbase; / * 0x7c Virtual base address of module * / unsigned long e32_vsize; / * 0x80 Virtual size of the entire image * /
Unsigned long e32_sect14rva; / * 0x84 section 14 rva * /
Unsigned long e32_sect14size; / * 0x88 section 14 size * /
Struct Info E32_Unit [Lite_extra]; / * 0x8c Array Of Extra Info Units * /
Struct info {/ * extra information header block * /
Unsigned long rva; / * Virtual relative address of info * /
Unsigned long size; / * size of information block * /
}
0x8C Exp Export Table Position
0x94 Imp IMPORT TABLE POSITION Position
0x9c RES Resource Table Position
0xA4 EXC EXCEPTION TABLE POSITION
0xac Security Table Position
0xB4 FIX FIXUP TABLE POSITION Position
} E32_lite, * lpe32_list;
O32_lite * o32_ptr; / * 0xBC O32 Chain Ptr * /
DWORD DWNONOTIFY; / * 0XC0 1 Bit Per Process, Set if notifications disabled * /
Word wflags; // 0xc4
Byte btrustlevel; // 0xc6
BYTE BPADDING; // 0xC7
PModule PmodResource; / * 0xc8 Module That Contains the Resources * /
DWord rwlow; / * 0xcc base address of rw section for rom dll * /
DWord rwhigh; / * 0xd0 high address rw section for rom dll * /
PGPOOL_Q Pgqueue; / * 0xcc List of the point oowed by the module * /
Typedef struct _pgpool_q {
Word idxhead; / * head of the queue * /
Word idXTail; / * Tail of the queue * /
} PGPOOL_Q, * PPGPOOL_Q;
} Module;
Module Structure Offset 0x08 is a pointer to the module name, offset 0x04 points to the next module in the linked list, with this module name, can find the Coredll.dll we need in the module chain list. The offset 0x7c is the virtual base address of the module, and the offset 0x8c is the relative address of the export table. The PE structure and Win32 used by Windows CE are the same, then friends who write Win32 shellcode experience will naturally think about searching for the function address in the PE structure of the base address. However, when we actually commissioned with EVC, it was found that the base address found by Coredll.dll was 0x01f60000, and the memory of this address was not assigned (the debugger is question mark), the address that can be accessed is from 0x01f61000, this and Idapro disassembly Coredll .dll (from DUMP in the ROM file, Wince is not the start address of the permissions used by the files used. Windows CE may save memory without loading the 0x1000 word header structure that is the first to load files. However, there is no relationship, because we have already obtained the export table of the module from the module structure to find the function address directly from the export table directly from the export table. - [3. Windows CE demo instance
Ratter / 29A's Wince4.dust code may be to reduce the volume, the method he gives to search for the order index of the program to search into the program, then the export address table is ordered according to the address table of the export table, and then use hardcodes Indexes calculate the function address. This method makes people feel very awkward. Although the code is reduced, versatility may be discounted, and the way to search for Win32 shellcode is more common through a function name. The following code is to achieve such a function.
Armasm Test.asm
; LINK / MACHINE: ARM / SUBSYSTEM: Windowsce Test.Obj
Code32
Export WinMainCrtStartup
Area .Text, Code, ARM
Test_Start
; R11 - Base Pointer
Test_code_start proc
STMDB SP !, {R0 - R12, LR, PC}
BL get_export_section
ADR R2, MB
BL Lookup_imports
MOV R0, # 0
ADR R1, TEXT
ADR R2, TEXT
MOV R3, # 0; MB_OK
MOV LR, PC
MOV PC, R9; MessageBoxw
BL get_export_section
ADR R2, TP
BL Lookup_imports
MOV R0, # -1
MOV R1, # 0
MOV LR, PC
MOV PC, R9
Basic Wide String Compare
WSTRCMP PROC
WSTRCMP_ITERATE
LDRH R2, [R0], # 2
LDRH R3, [R1], # 2
CMP R2, # 0
CMPEQ R3, # 0
Moveq PC, LR
CMP R2, R3
BEQ WSTRCMP_ITERATE
MOV PC, LR
ENDP
Output:
; R0 - Coredll Base Addr
; R1 - Export Section Addr
Get_export_section proc
STMDB SP !, {R4 - R9, LR}
LDR R4, = 0xffffc800; kdatastruct
LDR R5, = 0x324; AINFO [KINX_MODULES] ADD R5, R4, R5
LDR R5, [R5]
R5 Now Points to First Module
MOV R6, R5
Mov r7, # 0
iTerate
LDR R0, [R6, # 8]; Get DLL Name
ADR R1, COREDLL
BL WSTRCMP; Compare with Coredll.dll
LDREQ R7, [R6, # 0x7c]; GET DLL BASE
LDREQ R8, [R6, # 0x8c]; Get Export Section RVA
Add R9, R7, R8
BEQ GOT_COREDLLBASE; is it what we're looking for?
LDR R6, [R6, # 4]
CMP R6, # 0
Cmpne R6, R5
Bne Iterate; Nope, Go ON
Got_coredllbase
MOV R0, R7
Add R1, R8, R7; YEP, We've Got ImageBase
; and export section Pointer
LDMIA SP !, {R4 - R9, PC}
ENDP
Coredll DCB "C", 0x0, "O", 0x0, "R", 0x0, "E", 0x0, "D", 0x0, "L", 0x0, "L", 0x0
DCB ".", 0x0, "d", 0x0, "l", 0x0, "l", 0x0, 0x0, 0x0
Basic String Compare
BSTRCMP Proc
BSTRCMP_ITERATE
LDRB R9, [R7], # 1
LDRB R10, [R8], # 1
CMP R9, # 0
CMPEQ R10, # 0
Moveq PC, LR
CMP R9, R10
BEQ BSTRCMP_ITERATE
MOV PC, LR
ENDP
; R0 - Coredll Base Addr
; R1 - Export Section Addr
; R2 - Function Name Addr
LOOKUP_IMPORTS PROC
STMDB SP !, {R4 - R6, LR}
LDR R4, [R1, # 0x20]; addressofnames
Add R4, R4, R0
Mov r6, # 0; counter
LOOKUP_IMPORTS_ITERATE
LDR R7, [R4], # 4
Add R7, R7, R0; Function Name Ponter
MOV R8, R2; FIND FUNCTION NAME
BL BSTRCMP
Addne R6, R6, # 1
Bne look_imports_iterate
LDR R5, [R1, # 0x24]; addressofnameordinals
Add R5, R5, R0
Add R6, R6, R6
LDRH R9, [R5, R6]; Ordinals
LDR R5, [R1, # 0x1c]; addressoffunctions
Add R5, R5, R0LDR R9, [R5, R9, LSL # 2]; Function Address RVA
Add R9, R9, R0; FUNCTION ADDRESS
LDMIA SP !, {R4 - R6, PC}
ENDP
MB DCB "MessageBoxw", 0x0
TP DCB "TerminateProcess", 0x0,0x0,0x0,0x0
ALIGN 4
Dear User, am i allowed to spread?
Text DCB "H", 0x0, "e", 0x0, "l", 0x0, "l", 0x0, "o", 0x0, "", 0x0
DCB "W", 0x0, "I", 0x0, "n", 0x0, "c", 0x0, "e", 0x0, "!", 0x0
DCB 0x0, 0x0, 0x0, 0x0
ALIGN 4
LTORG
Test_end
; the code after test_end doesn't get copied to victims
WinMainCrtStartup Proc
B Test_code_start
ENDP
First Generation Entry Point
Host_ENTRY
MVN R0, # 0
MOV PC, LR
End
The code is still more stupid, and if you can introduce the possible code of Win32 shellcode, it will look better. Ratter / 29a is only a concept virus, but the basic technique of viruses has been there, so it will not be difficult to believe that there will be more Windows CE viruses. If the author doesn't make good satisfaction, use KernelioControl to introduce the system into the bootloader mode, so you will not be doubtful for many non-professional users.
It is easy to say that it is easy to write the SHELLCODE under Windows CE. The combination of mobile phones, I believe that the buffer overflow under Windows CE will soon be popular. However, Windows CE buffer overflow can encounter several issues:
1. Windows CE is a Unicode environment that may turn the data entered by the user to Unicode format.
2. To write decoding shellcode on Windows CE, there may be some problems, first ARM does not have a xor directive, and there may be a problem with instruction cache. Not very clear how Windows CE supports Soft Interrupt Directive SWI.
3. Different versions of different vendors may have such differences, causing attack programs that cannot be universal.
However, Windows CE has now developed very mature, you can come in and see.
- [4. Reference:
ARM Assembler
http://www.heyrick.co.uk/assembler/index.html
2. Misc Notes on the xda and windows ceme
http://www.xs4all.nl/~itsme/projects/xda/
3. Windows CE 3.0 Source Code
Http://msdn.microsoft.com/embedded/prevver/ce3/download/source/default.aspx
4. Details Emerge on the first windows mobile virushttp://www.informit.com/articles/Article.asp? P = 337071
history record:
1. 2004.11.09 Fix an error in searching API code.
commercial time:
This article will be further expanded, as a section of the "Windows CE Platform Buffer Overflow Utilization Technology" in the "Network Permeation Technology" (tentative name) book of XFOCUS Security Team. Xfocus security teams will
Research on Safety Focus Technology is fully technical support for this book.