x
This website is using cookies. We use cookies to ensure that we give you the best experience on our website. More info. That's Fine
HPC:Factor Logo 
 
Latest Forum Activity

wincepeinfo - A tool to get information about Windows CE exe files

1 2
Karpour Page Icon Posted 2020-11-16 8:05 PM
#
Avatar image of Karpour
Subscribers
H/PC Philosopher

Posts:
439
Location:
Austria
Status:
So in my quest to make sorting easier, and another quest to learn how to write proper POSIX tools, I started making a little CLI tool that prints information from a PE header to the console, mostly for plugging it into shell scripts:

Here's how the output looks for now (this is a CE2.0 binary, i believe)

.\wcepeinfo.exe  -j .\sisensyo.exe 
{ 
"Machine": "0x0166",
"MachineName": "R4000",
"Timestamp": 887997231,
"Date": "1998-02-20",
"NumberOfSymbols": 0,
"NumberOfSections": 7,
"SizeOfOptionalHeader": 224,
"PointerToSymbolTable": "0x00000000",
"Characteristics": {
"IMAGE_FILE_RELOCS_STRIPPED": false,
"IMAGE_FILE_EXECUTABLE_IMAGE": true,
"IMAGE_FILE_LINE_NUMS_STRIPPED": true,
"IMAGE_FILE_LOCAL_SYMS_STRIPPED": true,
"IMAGE_FILE_AGGRESSIVE_WS_TRIM": false,
"IMAGE_FILE_LARGE_ADDRESS_AWARE": false,
"IMAGE_FILE_BYTES_REVERSED_LO": false,
"IMAGE_FILE_32BIT_MACHINE": true,
"IMAGE_FILE_DEBUG_STRIPPED": false,
"IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP": false,
"IMAGE_FILE_NET_RUN_FROM_SWAP": false,
"IMAGE_FILE_SYSTEM": false,
"IMAGE_FILE_DLL": false,
"IMAGE_FILE_UP_SYSTEM_ONLY": false,
"IMAGE_FILE_BYTES_REVERSED_HI": false,
}
"Magic": "0x010B",
"MajorLinkerVersion": 5,
"MinorLinkerVersion": 10,
"LinkerVersion": "5.10",
"SizeOfCode": 11264,
"SizeOfInitializedData": 28160,
"SizeOfUninitializedData": 0,
"AddressOfEntryPoint": 14656,
"BaseOfCode": 4096,
"BaseOfData": 16384,
"ImageBase": 65536,
"SectionAlignment": 4096,
"FileAlignment": 512,
"MajorOperatingSystemVersion": 4,
"MinorOperatingSystemVersion": 0,
"OperatingSystemVersion": "4.0",
"MajorImageVersion": 0,
"MinorImageVersion": 0,
"OperatingSystemVersion": "0.0",
"MajorSubsystemVersion": 1,
"MinorSubsystemVersion": 0,
"SubsystemVersionVersion": "0.0",
"SizeOfImage": 61440,
"SizeOfHeaders": 1024,
"CheckSum": 0,
"Subsystem": 9,
"DllCharacteristics": 0,
"SizeOfStackReserve": 1048576,
"SizeOfStackCommit": 4096,
"SizeOfHeapReserve": 1048576,
"SizeOfHeapCommit": 4096,
"LoaderFlags": 0,
"NumberOfRvaAndSizes": 16,
}


It's mostly raw data, except some of the strings that I generate from the data, like the date I create from the 32-bit unix timestamp!

One issue I have is that I don't seem to be able to get the proper OS version from this?

"MajorOperatingSystemVersion": 4,
"MinorOperatingSystemVersion": 0,

Shouldn't this be 2 and 0 for Windows CE 2.0?

Anyway, one thing I'd still like to add is listing required DLLs , but that seems less simple than just reading the header, I'll figure it out!
 Top of the page
C:Amie Page Icon Posted 2020-11-17 9:46 AM
#
Avatar image of C:Amie
Administrator
H/PC Oracle

Posts:
17,983
Location:
United Kingdom
Status:
I will offer a speculative theory that the MajorSubsystemVersion is the CE version while MajorOperatingSystemVersion is set to 4 because CE reflected Windows 4.0 (Windows 95) in its design. If they hadn't, NT 3 would have attempted to execute the binary without a clean error.

Will you be releasing this on the GitHub site?
 Top of the page
Karpour Page Icon Posted 2020-11-17 2:03 PM
#
Avatar image of Karpour
Subscribers
H/PC Philosopher

Posts:
439
Location:
Austria
Status:
You bet I will!

I think you might be right! Whats confusing me is that a lot of CE 1.0 software has a subsystem version of 4.0, I suspect though that MS didn't have any guidelines for that for CE1.0, so both OS version and subsystem were set to 4.0.
It seems that from CE2.0 and up, the windows CE version number is indeed in the subsystem version number.
 Top of the page
C:Amie Page Icon Posted 2020-11-17 2:17 PM
#
Avatar image of C:Amie
Administrator
H/PC Oracle

Posts:
17,983
Location:
United Kingdom
Status:
I suspect that confirms my hypothesis. It is mimicking Windows 95.
 Top of the page
Karpour Page Icon Posted 2020-11-18 4:58 PM
#
Avatar image of Karpour
Subscribers
H/PC Philosopher

Posts:
439
Location:
Austria
Status:
Making good progress, importing DLL names works and I'll also import function names for good measure.
I should soon be able to put a working version on GitHub!
Trying to stay close to ANSI C, so it might even compile with a CE GCC compiler.
 Top of the page
Karpour Page Icon Posted 2020-11-18 7:46 PM
#
Avatar image of Karpour
Subscribers
H/PC Philosopher

Posts:
439
Location:
Austria
Status:
DLL imports work

I found another useful thing, the VersionInfo that's embedded into some exe files. This might also be useful.
Anyway, for now the output looks like this:

 
Processing file .\testdata\balloon.exe 
{
"Machine": "0x0166",
"MachineName": "R4000",
"Timestamp": 859093012,
"Date": "1997-03-23",
"NumberOfSymbols": 0,
"NumberOfSections": 6,
"SizeOfOptionalHeader": 224,
"PointerToSymbolTable": "0x00000000",
"Characteristics": {
"IMAGE_FILE_RELOCS_STRIPPED": false,
"IMAGE_FILE_EXECUTABLE_IMAGE": true,
"IMAGE_FILE_LINE_NUMS_STRIPPED": true,
"IMAGE_FILE_LOCAL_SYMS_STRIPPED": true,
"IMAGE_FILE_AGGRESSIVE_WS_TRIM": false,
"IMAGE_FILE_LARGE_ADDRESS_AWARE": false,
"IMAGE_FILE_BYTES_REVERSED_LO": false,
"IMAGE_FILE_32BIT_MACHINE": true,
"IMAGE_FILE_DEBUG_STRIPPED": false,
"IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP": false,
"IMAGE_FILE_NET_RUN_FROM_SWAP": false,
"IMAGE_FILE_SYSTEM": false,
"IMAGE_FILE_DLL": false,
"IMAGE_FILE_UP_SYSTEM_ONLY": false,
"IMAGE_FILE_BYTES_REVERSED_HI": false,
},
"Magic": "0x010B",
"MajorLinkerVersion": 5,
"MinorLinkerVersion": 0,
"LinkerVersion": "5.0",
"SizeOfCode": 16896,
"SizeOfInitializedData": 12800,
"SizeOfUninitializedData": 0,
"AddressOfEntryPoint": 6768,
"BaseOfCode": 4096,
"BaseOfData": 24576,
"ImageBase": 65536,
"SectionAlignment": 4096,
"FileAlignment": 512,
"MajorOperatingSystemVersion": 4,
"MinorOperatingSystemVersion": 0,
"OperatingSystemVersion": "4.0",
"MajorImageVersion": 0,
"MinorImageVersion": 0,
"OperatingSystemVersion": "0.0",
"MajorSubsystemVersion": 4,
"MinorSubsystemVersion": 0,
"SubsystemVersion": "4.0",
"Win32VersionValue": "0x00000000",
"SizeOfImage": 49152,
"SizeOfHeaders": 1024,
"CheckSum": 0,
"Subsystem": 4,
"DllCharacteristics": 0,
"SizeOfStackReserve": 1048576,
"SizeOfStackCommit": 4096,
"SizeOfHeapReserve": 1048576,
"SizeOfHeapCommit": 4096,
"LoaderFlags": 0,
"NumberOfRvaAndSizes": 16,
"DLLImports": [
{
"dllName": "commctrl.dll",
"functions": [
"CommandBar_Height",
"InitCommonControls",
"CommandBar_Create",
"CommandBar_AddAdornments",
],
},
{
"dllName": "COREDLL.dll",
"functions": [
"wsprintfW",
"DrawTextW",
"DefWindowProcW",
"ExitThread",
"Random",
"LoadImageW",
"GetStockObject",
"RegisterClassW",
"CreateWindowExW",
"ShowWindow",
"UpdateWindow",
"GetMessageW",
"TranslateMessage",
"DispatchMessageW",
"SelectObject",
"PatBlt",
"Ellipse",
"InvalidateRect",
"SetTimer",
"GetClientRect",
"GetDC",
"CreateCompatibleDC",
"CreateCompatibleBitmap",
"ReleaseDC",
"DeleteDC",
"PostQuitMessage",
"BeginPaint",
"BitBlt",
"EndPaint",
"DeleteObject",
"DestroyWindow",
],
},
],
},


Edited by Karpour 2020-11-18 8:33 PM
 Top of the page
CE Geek Page Icon Posted 2020-11-19 1:46 AM
#
Avatar image of CE Geek
Global Moderator
H/PC Oracle

Posts:
12,668
Location:
Southern California
Status:
Is this an app to be run on the PC? SKTools came out with a similar app to be run on-device some time ago, called PEInfo:

http://s-k-tools.com/index.html?m_util.html

I have versions that run on ARM and MIPS devices running CE 3.0 or higher.
 Top of the page
Karpour Page Icon Posted 2020-11-19 10:13 AM
#
Avatar image of Karpour
Subscribers
H/PC Philosopher

Posts:
439
Location:
Austria
Status:
I'm writing this mostly to get some insight into PE, but also to help automate sorting through gigantic amounts of software i gathered over the past 20 years!
Once it's release-ready, i'll make sure to provide a windows build here

The VersionInfo metadata is still giving me a bit of a headache, I can't seem to find good info on how to parse that, but I'll get there.

My next project after this would be wincecabinfo, which would do the same but for cab installer files!
 Top of the page
Karpour Page Icon Posted 2020-11-19 6:22 PM
#
Avatar image of Karpour
Subscribers
H/PC Philosopher

Posts:
439
Location:
Austria
Status:
Ouff, not getting any further here. So what I need to do is do my own implementation of GetFileVersionInfoA in winver.h.
I can't find any specification though on where that section is located and what the format is, even though....

Nevermind, I just thought of checking the ReactOS source, since of course they need to do an open source implementation of this function and voila, there it is!

https://doxygen.reactos.org/d1/db1/dll_2win32_2version_2version_8c_source.html
 Top of the page
smb_gaiden Page Icon Posted 2020-11-19 6:29 PM
#
Avatar image of smb_gaiden
Factorite (Elite)

Posts:
212
Status:
Quote
Karpour - 2020-11-18 11:46 AM

DLL imports work



Great job! One note for your consideration. EXE can bind to functions in libraries by ordinal instead of name. The PE header will be a bit different for that use case. If I remember correctly it is an ordinal if the high bit is set; probably check the bit with a logical and with 0x8000 or 0x80000000 depending on the field's size. To get the windows classic file manager to work on Windows RT 8.1 I had to compile and import only via ordinals, because I lacked the proper lib files to link against. Unsure if anyone built anything for Windows CE in such a way back in the day. Curious to know if you come across one as you test out your cool tool.
 Top of the page
Karpour Page Icon Posted 2020-11-19 8:15 PM
#
Avatar image of Karpour
Subscribers
H/PC Philosopher

Posts:
439
Location:
Austria
Status:
Thanks, I'm already considering import via ordinals (well, more like ignoring them since I don't think CE apps ever do that, I might just print out the hex values though to make things complete)

Making some progress with FileInfo, exiftool can also read that info so I'm looking how they do it: https://github.com/exiftool/exiftool/blob/master/lib/Image/ExifTool/EXE.pm#L990
It's perl though, which I don't speak, so the syntax looks a bit weird to me But it seems all i need to do is look for a .version section in the PE file!
 Top of the page
Karpour Page Icon Posted 2020-11-26 4:17 PM
#
Avatar image of Karpour
Subscribers
H/PC Philosopher

Posts:
439
Location:
Austria
Status:
Small status update:

Slowly working toward extracting version info, finding documentation isn't too easy, but I'm almost there. I found that the version info is one data block inside the .rsrc section of the PE file. Having some trouble calculating the actual start address of it, but slowly getting there.

The other thing is.. I could possibly detect with a PE file if it was meant to be used on HPC or PPC based on the dll imports. That is, if the PE file imports a HPC/PPC specific dll, so it would work only for a subset. Might still be useful though.

Does anyone have a list of DLLs that only exist exclusively on stock PPC/HPC windows ce?
 Top of the page
C:Amie Page Icon Posted 2020-11-27 9:05 AM
#
Avatar image of C:Amie
Administrator
H/PC Oracle

Posts:
17,983
Location:
United Kingdom
Status:
AYGShell.dll is basically going to be your go to. Whether you can estimate the version required from that from its method calls might be tricky, but for any shell app, that's basically going to be the giveaway.

This would be fairly typical of HPC2000
addrstor.dll 
adoce.dll 
adocedb.dll
adoceres.dll
adosync.dll
afd.dll
asform.dll
asyncmac.dll
atadisk.dll
boxsel.dll
calstore.dll
ceddk.dll
cefobj.dll
ceshell.dll
cespell.dll
citydb.dll
commctrl.dll
commdlg.dll
console.dll
coredll.dll
ctlpanel.dll
cxport.dll
dayview.dll
ddi.dll
dhcp.dll
fatfs.dll
fileasso.dll
find.dll
FlashFx.dll
htmlview.dll
IECEExt.dll
ieutil.dll
imap4.dll
imgdecmp.dll
inkwres.dll
InkX.dll
ircomm.dll
irdastk.dll
irsir.dll
ixresdll.dll
jscript.dll
keybddr.dll
labledit.dll
ldap.dll
mfcce300.dll
mlang.dll
mnthview.dll
mqoa.dll
msgstore.dll
mshtml.dll
msim.dll
mslim.dll
msmqd.dll
msmqrt.dll
msnsspc.dll
msxml.dll
ndis.dll
ne2000.dll
netbios.dll
netregd.dll
netui.dll
ntlmssp.dll
office.dll
ole32.dll
oleaut32.dll
olece300.dll
pacres.dll
parser.dll
pcl.dll
pcmcia.dll
pegcards.dll
pegobj.dll
pimdlg.dll
pimprint.dll
pimres.dll
pimstore.dll
pimutil.dll
ppp.dll
ppv_res.dll
prnerr.dll
prnport.dll
proxim.dll
pwd_res.dll
pwiiff.dll
pwwiff.dll
pxl_res.dll
pxl2xls.dll
pxlfile.dll
rdpapi.dll
rdpdr.dll
redir.dll
riched20.dll
richink.dll
riresdll.dll
rra_stm.dll
rsabase.dll
scard.dll
schannel.dll
secur32.dll
serial.dll
shcmdhk.dll
shdocvw.dll
shlwapi.dll
skeyekey.dll
smtp.dll
softkb.dll
sramdisk.dll
stink.dll
tapi.dll
tcpstk.dll
termctrl.dll
tnefex.dll
tnefu.dll
tnefutil.dll
toolhelp.dll
touch.dll
tsctrc.dll
uicom.dll
unimodem.dll
urlmon.dll
vbscript.dll
waveapi.dll
wavedev.dll
webview.dll
wininet.dll
winscard.dll
winsock.dll
xls2pxl.dll
xmlhlpr.dll
yearview.dll
zlibhw.dll
 Top of the page
Karpour Page Icon Posted 2020-11-30 4:13 PM
#
Avatar image of Karpour
Subscribers
H/PC Philosopher

Posts:
439
Location:
Austria
Status:
Thanks C, I'll look into tackling this after the versioninfo..

Boy, what did I get myself into. It turns out just parsing the versioninfo is 3x as much work as parsing all the previous stuff combined.

The path to get there is:

Dos Header -> PE Header -> PE Optional Header -> Image Data directory -> Image section header -> 3 layers of Resource directories -> Resource Directory Entry -> Versioninfo object -> StringFileInfo Object -> StringTable -> [all the Versioninfo strings]



I'm almost there though! Now I just hope that many Windows CE PEs actually include the versioninfo resource. At least software from 1996-1998 doesn't, but I think that versioninfo didn't really exist back then. I think a lot of CE3.0 Software should have embedded version info.
 Top of the page
Karpour Page Icon Posted 2020-12-01 11:55 AM
#
Avatar image of Karpour
Subscribers
H/PC Philosopher

Posts:
439
Location:
Austria
Status:
I did it!


Here's an example output from an app that contains versioninfo.

Bad example actually, this is bSquare htmledit, but actually it looks like most of the code is recycled from an app called "TarotDeck". The PE even contains a lot of tarot-related strings.
Anyway, versioninfo works

I made a github repo here: https://github.com/HPC-Factor/windows-ce-pe-info
There are some minor fixes i need to make as well as cleaning up the code, I'll post binaries soon


 
Processing file ./testdata/htmledit.exe 
{
"Machine": "0x01A2",
"MachineName": "SH3",
"Timestamp": 898474559,
"Date": "1998-06-22",
"NumberOfSymbols": 0,
"NumberOfSections": 5,
"SizeOfOptionalHeader": 224,
"PointerToSymbolTable": "0x00000000",
"Characteristics": {
"IMAGE_FILE_RELOCS_STRIPPED": true,
"IMAGE_FILE_EXECUTABLE_IMAGE": true,
"IMAGE_FILE_LINE_NUMS_STRIPPED": true,
"IMAGE_FILE_LOCAL_SYMS_STRIPPED": true,
"IMAGE_FILE_AGGRESSIVE_WS_TRIM": false,
"IMAGE_FILE_LARGE_ADDRESS_AWARE": false,
"IMAGE_FILE_BYTES_REVERSED_LO": false,
"IMAGE_FILE_32BIT_MACHINE": true,
"IMAGE_FILE_DEBUG_STRIPPED": false,
"IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP": false,
"IMAGE_FILE_NET_RUN_FROM_SWAP": false,
"IMAGE_FILE_SYSTEM": false,
"IMAGE_FILE_DLL": false,
"IMAGE_FILE_UP_SYSTEM_ONLY": false,
"IMAGE_FILE_BYTES_REVERSED_HI": false,
},
"Magic": "0x010B",
"MajorLinkerVersion": 5,
"MinorLinkerVersion": 10,
"LinkerVersion": "5.10",
"SizeOfCode": 11776,
"SizeOfInitializedData": 44544,
"SizeOfUninitializedData": 0,
"AddressOfEntryPoint": 11596,
"BaseOfCode": 1024,
"BaseOfData": 13312,
"ImageBase": 65536,
"SectionAlignment": 1024,
"FileAlignment": 512,
"MajorOperatingSystemVersion": 4,
"MinorOperatingSystemVersion": 0,
"OperatingSystemVersion": "4.0",
"MajorImageVersion": 0,
"MinorImageVersion": 0,
"ImageVersion": "0.0",
"MajorSubsystemVersion": 2,
"MinorSubsystemVersion": 0,
"SubsystemVersion": "2.0",
"Win32VersionValue": "0x00000000",
"SizeOfImage": 59392,
"SizeOfHeaders": 1024,
"CheckSum": 0,
"Subsystem": 9,
"DllCharacteristics": 0,
"SizeOfStackReserve": 1048576,
"SizeOfStackCommit": 4096,
"SizeOfHeapReserve": 1048576,
"SizeOfHeapCommit": 4096,
"LoaderFlags": 0,
"NumberOfRvaAndSizes": 16,
"DLLImports": [
{
"dllName": "commctrl.dll",
"functions": [
"CommandBands_AddBands",
"CommandBar_AddBitmap",
"CommandBar_GetMenu",
"CommandBands_AddAdornments",
"CommandBar_InsertMenubar",
"CommandBands_GetCommandBar",
"CommandBands_Create",
"InitCommonControlsEx",
"InitCommonControls",
],
},
{
"dllName": "htmlview.dll",
"functions": [
"InitHTMLControl",
],
},
{
"dllName": "COREDLL.dll",
"functions": [
"ImageList_LoadImage",
"SetWindowTextW",
"LocalFree",
"LocalAlloc",
"Sleep",
"wcsncpy",
"wcscmp",
"CharUpperBuffW",
"GetOpenFileNameW",
"ReadFile",
"ExitThread",
"SendMessageW",
"CallWindowProcW",
"RegisterClassW",
"LoadIconW",
"wcscpy",
"CreateWindowExW",
"CreateFontIndirectW",
"SetWindowLongW",
"GetWindowRect",
"PostMessageW",
"LoadImageW",
"SetFocus",
"TranslateMessage",
"TranslateAcceleratorW",
"DispatchMessageW",
"FindWindowW",
"SetForegroundWindow",
"GetMessageW",
"LoadAcceleratorsW",
"wcscat",
"wcslen",
"wcsstr",
"_wcsrev",
"GetFileSize",
"ShowWindow",
"DefWindowProcW",
"CreateFileW",
"GetSystemTime",
"MessageBoxW",
"CloseHandle",
"FindResourceW",
"DialogBoxIndirectParamW",
"LoadResource",
"GetWindowTextLengthW",
"ShellExecuteEx",
"GetWindowTextW",
"MoveWindow",
"wsprintfW",
"EnableMenuItem",
"GetClientRect",
"WriteFile",
"DestroyWindow",
"PostQuitMessage",
"DeleteObject",
"EndDialog",
"wcstombs",
"GetSaveFileNameW",
"mbstowcs",
],
},
],
"versionInfo": {
"CompanyName": "InfraRed",
"FileDescription": "InfraRed TarotDeck",
"FileVersion": "1.3",
"InternalName": "TarotDeck",
"LegalCopyright": "Copyright InfraRed 1995",
"ProductName": "InfraRed TarotDeck",
"ProductVersion": "1.3",
},
},
 Top of the page
1 2
Jump to forum:
Seconds to generate: 0.25 - Cached queries : 55 - Executed queries : 26