Jump to content

This site uses cookies. By continuing to browse the site you are agreeing to our use of cookies. Find out more here. X
X


Photo

File + Process Imports and Exports - DLL, EXE etc

DLL File Process Imports Exports Functions

  • Please log in to reply
16 replies to this topic

#1 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,371 posts

Posted 11 July 2010 - 01:07 AM

File + Process Imports/Exports Information UDFs

Posted Image
Posted Image
Forwarder String Support, C++ Name Undecorating Added!!
(Extreme case of string forwarding from wsock32.dll example in this post)


This UDF gets Function Imports and Exports for any Windows PE file (.DLL, .EXE), both 32-bit and 64-bit (unlike most programs out there), and from either a 32-bit or 64-bit Process.

I created this due to my frustration with other programs either working only *some* of the time, or having a common inability to read PE32+ (x64) file format tables properly.

There's just two functions in the main UDF - _FileGetWinPEImports or _FileGetWinPEExports. The bundled TestImportExportsList program lets you explore files on your system.
*Newly included are: _ProcessGetWinPEImports, _ProcessGetWinPEExports and TestProcessImportExportsList program (requires my Process Functions UDF).

NOTE: *Compressed* executable files will only give the Import information for the 'decompressor'. The only way to get the compressed executable's Import information is to decompress the executable.

Anyway, enjoy my hard work. Either read on for more information about some of the features, or see below for the License agreement and Download link.

Information on 'Virtual Offset of Thunk':
These address offsets you see are offsets from the base of the .DLL or .EXE file (uncompressed only!), where the actual function location of an 'Import' gets placed. All calls to these functions load addresses from these Thunk locations in order to correctly place a call to the right DLL function. (This is totally different than the old Import fixup location lists of earlier pre-NT systems). Technically, you could overwrite these Thunks with addresses to your own functions, but this is a dangerous thing to do. Its a neat tool to have though.

Forwarder functions? An explanation:

The whole 'DLLNAME.Functionname' string might be confusing to you, but here's an explanation of why an address can not and should not be returned. To better understand all this, grab a copy of DLL Export Viewer, (which doesn't report Relative/Function addresses correctly for Forwarded functions) and then follow along: *update: as of v1.50, DLL Export Viewer now reports forwarder string info (I was the one that reported the bug heh)

Okay, open up DLL Export Viewer and look at (for this example) KERNEL32.DLL - lets pick 'HeapFree', a known Forwarded function. DLL Export Viewer reports the following (on XP SP3):Relative Address: 0x0000910c, 'Loaded' address: 0x7c80910c. *Neither* is the case, though - 0x0000910c is in fact just the virtual address of the forwarder string!

Now, with my Exports function, you'll find that 'HeapFree' is reported (correctly) as a Forwarder string. What you'll see then is 'NTDLL.RtlFreeHeap'. What does that mean? It means that:
  • HeapFree is not a part of KERNEL32.DLL (and hasn't been for a while),
  • When that function is called or the address retrieved via 'GetProcAddress', the function 'RtlFreeHeap' in NTDLL.DLL is the function that's actually called (or returned as an address). Hopefully the 'DLLNAME.FunctionName' structure of a Forwarder string is starting to make sense now?
  • The address you get when you do 'GetProcAddress' does *not* correspond to what you see in DLL Export Viewer - in fact, 'HeapFree's reported address lies entirely OUTSIDE of kernel32.dll's memory space - pointing instead inside of NTDLL.DLL, at (guess what?): RtlFreeHeap.
So, on XP SP3, looking up 'HeapFree' with GetProcAddress, you get: 0x7C90FF2D. Doesn't match what was reported with DLL Export Viewer AT ALL. However - go back, and now look at NTDLL.DLL with DLL Export Viewer, and at function 'RtlFreeHeap' (following the logic of the Forwarder Function string). What is reported for RtlFreeHeap? Relative Address: 0x0000ff2d, 'Loaded' address: 0x7c90ff2d. See now how it lines up with what was reported via GetProcAddress for 'HeapFree' in KERNEL32.DLL?

So, there you have it in a nutshell - Forwarder functions are functions 'rerouted' to another DLL. The DLL's that are being rerouted to are either:
  • A.) Pre-loaded by the system (Important DLL's like NTDLL.DLL, KERNEL32.DLL, USER32.DLL, GDI32.DLL, etc - are all permanently loaded)
  • B.) Loaded upon a program's execution if the function is in its 'Imports' list, or
  • C.) Loaded upon a call to GetProcAddress. To see how this works clearly, list the modules that are loaded (my Process Functions UDF GUI can do this for you), then call GetProcAddress for 'GetServiceW' from WSOCK32.DLL, and then re-list the modules again. You'll see a new module loaded up - MSWSOCK.DLL (the location of the forwarder function). Wa-la, forwarder is set up.
Ascend4nt's AutoIT Code License agreement:
While I provide this source code freely, if you do use the code in your projects, all I ask is that:
  • If you provide source, keep the header as I have put it, OR, if you expand it, then at least acknowledge me as the original author, and any other authors I credit
  • If the program is released, acknowledge me in your credits (it doesn't have to state which functions came from me, though again if the source is provided - see #1)
  • The source on it's own (as opposed to part of a project) can not be posted unless a link to the page(s) where the code were retrieved from is provided and a message stating that the latest updates will be available on the page(s) linked to.
  • Pieces of the code can however be discussed on the threads where Ascend4nt has posted the code without worrying about further linking.


Download the ZIPs from my Site



UPDATES:

Spoiler

Edited by Ascend4nt, 26 September 2011 - 05:39 AM.

  • mLipok likes this







#2 wraithdu

wraithdu

    this noise inside my head

  • MVPs
  • 2,413 posts

Posted 11 July 2010 - 05:32 AM

Nicely done.

To ease your frustration though, you should check out DLL Export Viewer from NirSoft.

Edited by wraithdu, 11 July 2010 - 05:33 AM.


#3 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,371 posts

Posted 11 July 2010 - 09:09 AM

Thanks. I've been using DLL Export Viewer actually - But it doesn't report on Imports, and I'd rather not have to rely on using another program just for Exports.

#4 Shafayat

Shafayat

    Polymath

  • Active Members
  • PipPipPipPip
  • 245 posts

Posted 11 July 2010 - 09:36 AM

Fascinating work.

This is really going to come in handy.
[Not using this account any more. Using "iShafayet" instead]

#5 jfcby

jfcby

    Geek Problem Solver In The Making...

  • Active Members
  • PipPipPipPipPipPip
  • 330 posts

Posted 11 July 2010 - 11:08 AM

This is a very useful UDF.

Determined -- Devoted -- Delivered Make your mind up -- to seriously apply yourself -- accomplishing the desired results. **** A soft answer turneth away wrath: but grievous words stir up anger. Proverbs 15:1 KJB  *** Learning to write scripts...WMP Resumer | InstaPro Launcher | XampLabel Styles | XampPause - "HotKeySet" | XampCounter | XampSpellCheck *** Forum References Remembered... 5 Tips better coder by: Omar AlBadri (AKA - Volly) | AutoIT3/SciTE - USB by: MadSc13ntist | XSkin.au3 GUI by: Valuater AutoIT MVP | Helpful Collection Autoit Scripts: Maintained By: Volly | Windows Help 101 By: beerman & others *** My Website: Frankie-Cooper.com


#6 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,371 posts

Posted 11 July 2010 - 11:45 PM

Thanks everyone for the compliments.

I've updated the UDF after reading about Borland's TLINK32 issue. All files should report the right Import information now, though I still have yet to figure out the 'forwarding' thing with certain Exports (that return an Offset of 0).


UPDATES:
7-11-2010:
Fixed:
  • Executables linked with Borland's TLINK32.exe do not set the 'ImportLookupTableRVA' element correctly. This was easy to work around, as the 'Thunks' list also contains pointers to the same information (until an executable/DLL is loaded by the O/S, at least)
Added:
  • Imports: Extra column: Virtual Offset of Thunk ( [3] ). When an .EXE or .DLL is loaded, this is the Offset from the base of the .EXE or .DLL which will hold the actual function address. This could be used for redirection of calls (dangerous though!).
    ...
    An important note on this
    : Compressed executables are a completely different beast, and in fact the whole Import section is for the Decompressor itself, which disappears once the executable is loaded! The only way to get the actual Imports for Compressed Executables is to Decompress them first.

Edited by Ascend4nt, 12 July 2010 - 11:32 AM.


#7 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,371 posts

Posted 12 July 2010 - 03:55 AM

Sorry for the short time between updates, but I found a major issue with my code, and at the same time added something new - not even DLL Export Viewer has Forwarder-String information :blink:

Check out these examples of Forwarder strings inside DLL's (2nd example is an extreme case!)

Posted Image..Posted Image

Onto the updates:

UPDATES:
7-12-2010:
Fixed:
  • Oops, Big-time logic errors in mapping Export function names to addresses and using ordinals to look them up from pointer tables. Now everything points to where it should!
  • Ordinal #'s are now correctly calculated with the 'Base' # part of the EXPORT DIRECTORY TABLE.
Added:
  • 'Forwarder' string lookup & reporting! Not even DLL Export Viewer does this! Basically, certain function 'pointers' aren't really code offsets, but offsets to Forwarder strings. My function looks those strings up and puts them in the list instead of a phoney address.

Edited by Ascend4nt, 12 July 2010 - 04:13 AM.


#8 Fire

Fire

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 366 posts

Posted 13 July 2010 - 07:36 PM

Really Awesome work!
Thxs for share!

#9 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,371 posts

Posted 21 July 2010 - 08:16 PM

Updated!

7-21-2010:
Added:
  • C++ Function Name Undecorating/Unmangling option. For an example of what this causes function name results to be, check out something like 'msvcrt.dll'. It will report alot more than just a function name! If you choose to do the Undecorating yourself, just call the included function _WinAPI_UndecorateName().
    Example: "??3@YAXPAX@Z" becomes "void __cdecl operator delete(void *)" unmanged/undecorated
  • New _ProcessGetWinPEImportExports module (with Test program) as a separate download - requires use of my Process Functions UDF. The biggest benefits, besides looking into loaded DLL's that might not be on the disk? Addresses reported are real, and Imported function addresses are reported (as pulled from Thunk locations).


#10 aef03

aef03

    Seeker

  • Active Members
  • 33 posts

Posted 30 September 2010 - 05:42 PM

Would it be possible to use parts of this library to validate that exports of a system DLL have not been dynamically remapped within the process where my script is running?

D.

#11 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,371 posts

Posted 30 September 2010 - 06:15 PM

I'm not sure I understand. Do you mean that imports in your process (which are mapped to exports from DLL's) are being redirected to a different address than they should be? Theoretically it would be possible to check them, if the LoadLibrary/GetProcAddress API functions needed by DLLCall() were not themselves remapped to something that prevents them from working correctly.

Probably the best thing for you to do is to use UPX or some other compression utility which makes it more difficult for someone to get and remap the imports for your app.

I would also say that its possible to do using compiled machine code that goes through the PEB and module lists, but machine code still requires a DLLCall() to use from AutoIt..

#12 aef03

aef03

    Seeker

  • Active Members
  • 33 posts

Posted 01 October 2010 - 01:18 AM

I'm actually trying to detect when aclayers.dll might be redirecting registry writes.

#13 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,371 posts

Posted 01 October 2010 - 03:10 AM

Not sure what aclayers is, but sounds easy enough. Use DLLCall to call 'GetProcAddress' for the different registry API calls, and compare those returned values to the process's loaded addresses for those API calls. If there's a difference, then they are being redirected. You can even go further to see where the module address is located by comparing it against the loaded modules' start and 'end' (start+size) addresses.

#14 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,371 posts

Posted 06 December 2010 - 01:25 AM

First off, you mean 33.4KB uncompressed (for the File Import/Exports info).

Secondly, NirSoft's DLL Export Viewer incorrectly reports the code address, because that function doesn't actually exist in kernel32.dll. In the PE, it gives an offset that points to a 'forwarder' string. That means that "NTDLL.RtlAddVectoredExceptionHandler" tells you where the function really exists - in NTDLL.DLL, as the function name RtlAddVectoredExceptionHandler. Read my first post, hopefully that will help you understand what forwarding is, and why NirSoft's program reports bad information.

#15 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,371 posts

Posted 24 June 2011 - 01:08 AM

How about that - Nirsoft actually listened to feedback :huh2:
DLL Export Viewer finally has forwarder string information reported correctly as of v1.50.

On another note.. I've noticed some .EXE files are putting Imports all over - inside different sections of the PE. wth? Anyway.. causes the program to crash currently, so if anyone sees a crash, this is most likely whats happening. I'd call it non-standard, but Windows handles it fine, as do some other PE viewers (some crash though). That was a very annoying bugger to track down.

What this means is that I need to search for the right section and recalculate RVA Offsets for each and every Import. What a pain.. Anyhoo.. that's on my to-do list for the next version. Just thought I'd at least log the problem here in the meantime and tell y'all to update your copy of DLL Export Viewer as well ;)

#16 mailro

mailro

    Seeker

  • Active Members
  • 21 posts

Posted 24 September 2011 - 05:42 PM

Any sample code how you use export functions of a dll to my own script would appreciated?
Thanks

Edited by mailro, 24 September 2011 - 06:37 PM.


#17 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,371 posts

Posted 24 September 2011 - 11:26 PM

You'd need to figure that out for yourself. If you are planning on calling a function in a DLL, you need to know what parameters it takes, as well as the return value. If its a standard Microsoft DLL, you can find the documentation for the function on MSDN. Any other DLL's, you need to know who made it and then check their website for info on calling the functions. I think WinAPIOverride32 lets you explore how certain DLL functions are called, though the program seems to crash more than anything for me.





Also tagged with one or more of these keywords: DLL, File, Process, Imports, Exports, Functions

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users