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,987
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,987
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,669
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,987
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.234 - Cached queries : 73 - Executed queries : 8