PE with no imports (aka Windows version by ret addr) (last update: 2012-10-20, created: 2012-10-19) back to the list ↑
|
|||
A long time ago (in 2006) I experimented with an idea to create a working program (PE exe) with no imports whatsoever. The idea based on the fact that at least two DLL modules are always in memory - kernel32.dll and ntdll.dll (on Windows 7 there is also kernelbase.dll afair, and I think there is no ntdll.dll on Windows 98).
The question was - how to find the DLLs in memory and how to find the functions themselves. Well, if you've done some low level coding you probably know that there is a commonly used method to walk the loaded module list pointed to by TEB→PEB→list. However, I decided to use a different approach (that is actually way worse then the aforementioned method, but well, there is no shame in experimenting with random ideas, even poor ones). The idea was to correlate return address found on the stack at main image (exe) entry point (the one that points to the return of the process loading/initializing procedure) with the address of LoadLibrary and the address of GetProdAddress. Please note, that these were times before ASLR on Windows, so it was a little easier. So I created a small app that gathered this data and send it to my friends to get the addresses from the versions of Windows that they had. Here's the results I've got (most of the columns are easy to deduce; COUNT is the number of samples I've got with this result): RET LOADLIB GETPROC COUNT VERSION So a couple of things can be spotted right away: 1. Even the same exact version (as in the "VERSION" column above) of the OS can have different results, e.g.: 77E7EB69 77E805D8 77E7A5FD 4 5.1.2600 This is because of individual patches that don't change the OS version. 2. The language version of the OS also has an impact here. E.g. there are to 5.1.2600 SP1 entries in the table, one for English version of the OS, and one for Polish: 77E8141A 77E7D8B4 77E7B285 1 5.1.2600 Service Pack 1 So, to sum up the results: - It's doable for a limited amount of OSes. - If one would want the table to cover even one major version of Windows, he would have a hard time gathering the data (languages * patches * service packs * perhaps types of Windows, like "Ultimate" and "Home"). UPDATE: Ange Albertini has derived a similar method, but based on DLL timestamp instead of the return address. Pretty clever. Take a look here if you're interested. Appendix: Executable with "concealed" importsDownload (source + exe): conceal_pe.zip (don't expect this to run on your OS; the table was gathered in 2006 and is very limited)Source:
| |||
|