Page 1 of 2 12 LastLast
Results 1 to 15 of 16

Thread: All DLLs - Not in IAT?

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    78
    Blog Entries
    1

    All DLLs - Not in IAT?

    Hi All,
    I was trying to get a list of all the DLLs that are loaded by an executable using the PeFile module in Python. So I took up 'Minesweeper'. I read the PE header and got all the DLLs that minesweeper imported; and all the dependencies for each of these DLLs as well. For e.g winmine.exe had 9 DLLs in its IMPORT DIRECTORY TABLE. Of these some DLLs again had their own imports. So I got those as well. Here is my output:

    This is a list of all the DLL's imported by winmine.exe

    Code:
    ['WINMM.dll', 'GDI32.dll', 'SHELL32.dll', 'KERNEL32.dll', 'msvcrt.dll', 'RPCRT4.dll', 'ADVAPI32.dll', 'ntdll.dll', 'SHLWAPI.dll', 'USER32.dll', 'COMCTL32.dll']
    >>>
    But now when I look in Olly there are 4 or 5 more DLLs marked in red for some reason ...here is a full list...

    Code:
    Executable modules
    Base       Size       Entry      Name       File version      Path
    01000000   00020000   01003E21   winmine    5.1.2600.0 (xpcl  C:\WINDOWS\system32\winmine.exe
    5AD70000   00038000   5AD71626   UxTheme    6.00.2900.2180 (  C:\WINDOWS\system32\UxTheme.dll
    5CB70000   00026000   5CB78E39   ShimEng    5.1.2600.2180 (x  C:\WINDOWS\system32\ShimEng.dll
    6F880000   001CA000   6F8A5E1A   AcGenral   5.1.2600.2180 (x  C:\WINDOWS\AppPatch\AcGenral.DLL
    76390000   0001D000   763912C0   IMM32      5.1.2600.2180 (x  C:\WINDOWS\system32\IMM32.DLL
    769C0000   000B3000   769C15D4   USERENV    5.1.2600.2180 (x  C:\WINDOWS\system32\USERENV.dll
    76B40000   0002D000   76B42B69   WINMM      5.1.2600.2180 (x  C:\WINDOWS\system32\WINMM.dll
    77120000   0008C000   77121558   OLEAUT32   5.1.2600.2180     C:\WINDOWS\system32\OLEAUT32.dll
    773D0000   00102000   773D42B3   COMCTL32   6.0 (xpsp_sp2_rt  C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9\COMCTL32.dll
    774E0000   0013C000   774F20C1   ole32      5.1.2600.2180 (x  C:\WINDOWS\system32\ole32.dll
    77BE0000   00015000   77BE1292   MSACM32    5.1.2600.2180 (x  C:\WINDOWS\system32\MSACM32.dll
    77C00000   00008000   77C01135   VERSION    5.1.2600.2180 (x  C:\WINDOWS\system32\VERSION.dll
    77C10000   00058000   77C1F2A1   msvcrt     7.0.2600.2180 (x  C:\WINDOWS\system32\msvcrt.dll
    77D40000   00090000   77D50EB9   USER32     5.1.2600.2180 (x  C:\WINDOWS\system32\USER32.dll
    77DD0000   0009B000   77DD70D4   ADVAPI32   5.1.2600.2180 (x  C:\WINDOWS\system32\ADVAPI32.dll
    77E70000   00091000   77E76284   RPCRT4     5.1.2600.2180 (x  C:\WINDOWS\system32\RPCRT4.dll
    77F10000   00046000   77F163CA   GDI32      5.1.2600.2180 (x  C:\WINDOWS\system32\GDI32.dll
    77F60000   00076000   77F651D3   SHLWAPI    6.00.2900.2180 (  C:\WINDOWS\system32\SHLWAPI.dll
    7C800000   000F4000   7C80B436   kernel32   5.1.2600.2180 (x  C:\WINDOWS\system32\kernel32.dll
    7C900000   000B0000   7C913156   ntdll      5.1.2600.2180 (x  C:\WINDOWS\system32\ntdll.dll
    7C9C0000   00814000   7C9DFA10   SHELL32    6.00.2900.2180 (  C:\WINDOWS\system32\SHELL32.dll
    The ones marked in Bold above were not visible in the Import Directory Table in PeView or extracted by my Python code. However they were visible in LordPe and ProcessExplorer and of course Olly 1.10 too.

    Why is this? Where else does an EXE get its list of DLLs from if not from the IMPORT DIRECTORY TABLE?

    Do let me know.

    Thanks
    Arvind
    Reversing articles, primarily from a newbie perspective - http://ardsec.blogspot.com

    Latest article written - http://resources.infosecinstitute.com/author/arvind

  2. #2
    LoadLibrary()

  3. #3

    As Above...

    Of course, you should be aware that DLLs get loaded in 3 manners:-

    1. Via import table (what you saw)

    2. Delayed Load (only when necessary OR subsequent to attachment of certain other Dlls)

    3. Dynamically Loaded (Loadlibrary, attachprocess, etc.)

    You generally cannot see 2 and 3 in any tools that check the Dlls via import. Instead, you have to profile them at runtime.

    Get a software (very small, but NOT the one available in Visual Studio) called Dependency Walker.

    This software tells you all dlls --- loaded via import tables, delayed loads, dynamically loaded. And then some!

    It's a fantastic software to see what your program is REALLY doing and Calling...

    Have Phun,
    Blame Microsoft, get l337 !!

  4. #4
    Registered User
    Join Date
    Apr 2011
    Posts
    78
    Blog Entries
    1
    Thanks extremist,aimless.

    I did use Dep Walker too..thanks and it did show me everything. As did LordPe, ProcessExplorer and of course Olly. So I guess these tools use all 3 techniques you mentioned.

    How do these tools work internally though? Like for example: I know that the IMPORT_DIRECTORY structure is read and DLL imports got from there. How do tools detect the other 2 techniques and give a list of DLLs in the end?

    I'm asking because I'm trying to automate just that part using Python. For Imports I could use the PeFile module and read the PE header. What would I have to do for the rest?

    Edit: I found that Delay Loaded DLLs have a directory under IMAGE_OPTIONAL_HEADER [DELAY IMPORT DESCRIPTORS] in the PE Header whenever they are used. PEView only displays it when its used. Have attached a screenshot. The funny thing now though is that Shell32.dll has a huge number of DLLs under delayed imports. However, not all of them are used; as in loaded by winmine.exe.

    Name:  delayed_imports.jpg
Views: 507
Size:  15.3 KB

    Thanks
    Arvind
    Last edited by live_dont_exist; February 22nd, 2012 at 02:34. Reason: Additional Info got
    Reversing articles, primarily from a newbie perspective - http://ardsec.blogspot.com

    Latest article written - http://resources.infosecinstitute.com/author/arvind

  5. #5
    The "official" way is to debug the process so Windows will notify your debugger about loaded dlls
    see: CreateProcess( DEBUG_PROCESS ) or DebugActiveProcess

  6. #6
    Registered User
    Join Date
    Apr 2011
    Posts
    78
    Blog Entries
    1
    There's no way to do it through Python ..then? I have to use the Windows API..compulsorily?
    Reversing articles, primarily from a newbie perspective - http://ardsec.blogspot.com

    Latest article written - http://resources.infosecinstitute.com/author/arvind

  7. #7
    There are debugging modules for python, plus there's ctypes. What else do you need?

  8. #8
    Registered User
    Join Date
    Apr 2011
    Posts
    78
    Blog Entries
    1
    I'm not sure..I've written a total of 5 Python programs so far ... most from the Google Python class so checking. Thanks though anom.

    But my earlier question is sort of still un-answered...

    The funny thing now though is that Shell32.dll has a huge number of DLLs (say > 20) under delayed imports. However, not all of them are used; as in loaded by winmine.exe ...
    .... and only around 5 or 6 [Marked in Bold earlier]... are loaded. Now I understand the best way is to use Ctypes etc and do it the 'official' way as aqrit mentioned. That's fine and I'll do that. But what decides ...which subset of 'Delay Loaded DLLs' is loaded...and when?

    Thnx
    Arvind
    Reversing articles, primarily from a newbie perspective - http://ardsec.blogspot.com

    Latest article written - http://resources.infosecinstitute.com/author/arvind

  9. #9
    Registered User
    Join Date
    Apr 2011
    Posts
    78
    Blog Entries
    1
    Right .. so I wrote some code. It basically reads the IMPORT TABLE recursively and loads all the DLLs possible. So if winmine.exe needs kernel32.dll; it will store kernel32.dll. It will then load kernel32.dll and get its dependencies which is ntdll.dll and so on. So this works...as far as the import table is concerned.

    I then tried to repeat the same logic for the DELAYED IMPORTS. There were 2 problems I faced:

    a) I couldn't find some DLL files; due to me hardcoding the System32 path. I am guessing I have to search in some environment variable for all possible paths where DLs can be there.
    b) For whatever DLLs in the DELAY section that did get parsed; I got a huge huge list; which certainly seems to be much much more than what I can see in Olly. Looking at the previous posts here I can say that there are exactly 9 extra DLLs which I cannot explain.

    I dont think (logically) its at runtime as I've not even started the file in Olly. And other PE editors like LordPE also seem to get the exact list. So I'm leaning towards - "There is some place in the PE header from where I can deduce an exact list as in all these tools". The question is where.

    I'm attaching my code too. Any ideas? The password for the zip file is code123!

    python_code.zip
    Reversing articles, primarily from a newbie perspective - http://ardsec.blogspot.com

    Latest article written - http://resources.infosecinstitute.com/author/arvind

  10. #10
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,157
    Blog Entries
    5
    You can get the complete list of runtime dlls from the PEB.Ldr.InInitializationOrderModuleList / InLoadOrderModuleList / InMemoryOrderModuleList
    That is what you see in Olly and other apps. LordPE won't show that if you only open the exe statically.

    Here's an example for winmine (running)

    Code:
    kd> !process 0 1 winmine.exe
    PROCESS 8969c7c8
    
    kd> .process 8969c7c8
    Implicit process is now 8969c7c8
    
    0: kd> !peb
    PEB at 7ffdd000
      
        Ldr.InInitializationOrderModuleList: 001a1f28 . 001a2fa8
        Ldr.InLoadOrderModuleList:           001a1ec0 . 001a2f98
        Ldr.InMemoryOrderModuleList:         001a1ec8 . 001a2fa0
                Base TimeStamp                     Module
             1000000 3b7d8475 Aug 17 16:54:13 2001 C:\WINDOWS\system32\winmine.exe
            7c900000 4d00f27d Dec 09 10:15:09 2010 C:\WINDOWS\system32\ntdll.dll
            7c800000 49c4f482 Mar 21 10:06:58 2009 C:\WINDOWS\system32\kernel32.dll
            77c10000 4802a188 Apr 13 20:12:56 2008 C:\WINDOWS\system32\msvcrt.dll
            77dd0000 49901d48 Feb 09 07:10:48 2009 C:\WINDOWS\system32\ADVAPI32.dll
            77e70000 4c68fa8c Aug 16 04:45:00 2010 C:\WINDOWS\system32\RPCRT4.dll
            77fe0000 4a433476 Jun 25 04:25:26 2009 C:\WINDOWS\system32\Secur32.dll
            77f10000 49006fbe Oct 23 08:36:14 2008 C:\WINDOWS\system32\GDI32.dll
            7e410000 4802a11b Apr 13 20:11:07 2008 C:\WINDOWS\system32\USER32.dll
            7c9c0000 4d399bd5 Jan 21 09:44:37 2011 C:\WINDOWS\system32\SHELL32.dll
            77f60000 4b1e1b10 Dec 08 04:23:28 2009 C:\WINDOWS\system32\SHLWAPI.dll
            76b40000 4802a13c Apr 13 20:11:40 2008 C:\WINDOWS\system32\WINMM.dll
            773d0000 4c729dd1 Aug 23 12:12:01 2010 C:\WINDOWS\WinSxS\x86_Microsoft.W
    indows.Common-Controls_6595b64144ccf1df_6.0.2600.6028_x-ww_61e65202\COMCTL32.dll
    
            5cb70000 4802a114 Apr 13 20:11:00 2008 C:\WINDOWS\system32\ShimEng.dll
            6f880000 4802a098 Apr 13 20:08:56 2008 C:\WINDOWS\AppPatch\AcGenral.DLL
            774e0000 4eb0192e Nov 01 12:07:10 2011 C:\WINDOWS\system32\ole32.dll
            77120000 4d0f931f Dec 20 12:32:15 2010 C:\WINDOWS\system32\OLEAUT32.dll
            77be0000 4802a117 Apr 13 20:11:03 2008 C:\WINDOWS\system32\MSACM32.dll
            77c00000 4802a11d Apr 13 20:11:09 2008 C:\WINDOWS\system32\VERSION.dll
            769c0000 4802a11c Apr 13 20:11:08 2008 C:\WINDOWS\system32\USERENV.dll
            5ad70000 4802a11e Apr 13 20:11:10 2008 C:\WINDOWS\system32\UxTheme.dll
            76390000 4802a0e7 Apr 13 20:10:15 2008 C:\WINDOWS\system32\IMM32.DLL
            10000000 4eef85d3 Dec 19 13:43:31 2011 C:\WINDOWS\system32\guard32.dll
            4ffe0000 4802a0c4 Apr 13 20:09:40 2008 C:\WINDOWS\system32\fltlib.dll
            5cd70000 3b7dfebb Aug 18 01:35:55 2001 C:\WINDOWS\system32\serwvdrv.dll
            5b0a0000 3b7dfeb9 Aug 18 01:35:53 2001 C:\WINDOWS\system32\umdmxfrm.dll
            755c0000 4802a12d Apr 13 20:11:25 2008 C:\WINDOWS\system32\msctfime.ime
            
            
        ProcessParameters: 00020000  

    This is slightly OT, but to explain why you're seeing some of the dlls such as AcGenral.DLL and the several following dependant modules..


    Note that some of the imports you see in winmine and other specific apps are loaded by dependancies due to shimeng.dll, or the Microsoft Application Compatibility Interface.

    http://www.alex-ionescu.com/?p=39 (3 parts to the article)

    http://www.woodmann.com/forum/showthread.php?14109-Looking-for-information-on-Shims


    If you look at /%windir%/AppPatch/sysmain.sdb in a hex editor you'll see that "winmine.exe" is included there as a unicode string. As mentioned in the forum thread, the Shim Database (.sdb) file specifies the following will be applied:

    NAME="AddProcessParametersFlags"
    DLLFILE="AcGenral.DLL"
    DESCRIPTION="Add flags to Peb-ProcessParameter-Flags


    If you search for "AddProcessParametersFlags" in the following thread, we see that its purpose seems to be to apply DEP to Winmine, and will explain the
    ProcessParameters: 00020000
    line in the !peb output above

    http://technet.microsoft.com/en-us/library/bb490630.aspx

    Now if you go into Process Explorer and select View/Select Columns/Dep Status, you'll see that every MS process with DEP enabled also has AcGenral.DLL loaded. And the ones that don't, don't.


    Olly seems to order dlls by Base Address, that's a little confusing if trying to make sense of where those "9 extra DLLs" you wondered about came from. Try using TopToBottomNt by SmidgeonSoft (or maybe Dependency Walker), where you can list the dll imports by InInitializationOrderModuleList / InLoadOrderModuleList / InMemoryOrderModuleList. That should make the dependancies and _why_ a specific dll was loaded make a bit more sense.

    Cheers,
    Kayaker

  11. #11
    Registered User
    Join Date
    Apr 2011
    Posts
    78
    Blog Entries
    1
    Thanks Kayaker. I tried doing all of this in WinDBG (which is painful after using Olly all this while ). The thing though, is that those 9 'extra' DLLs seem to get loaded only after I 'run' ( g in WinDBG) winmine.exe.

    If I look at it prior to run ( !peb ) then it seems to list only a partial list (initial problem). If I run winmine and then close the app and list the PEB again, it gives the complete list. So this I guess means its not there in PEB too right from the start..and is 'handled at runtime'. My screenshots are attached too so everyone can see what exactly is going on.

    I also tried DepWalker but that seems to do things I do... get a huge list of all dependencies and not just the exact list that Olly gives. And all these dependencies are internal to each DLL. The main list only contains the DLLs that are there in the IAT...just like I earlier mentioned. For e.g IMM32.DLL is 1 which is loaded by Olly and OLEACC.DLL is NOT...but both are loaded by DepWalker (as dependencies of COMCTL32), where as in Olly ... only IMM32 is loaded and not OLEACC. Screenshot attached.

    This is another link that I refered - http://www.archivum.info/microsoft.public.windbg/2009-10/00044/Re-How-to-!list-and-t-LDR_DATA_TABLE_ENTRY.InMemoryOrderLinks.Flink.html

    So the point still remains...Is it possible to get a complete list of DLLs before starting the EXE? Like in Olly? You're right about LordPE though...I can see the list of DLLs only after I load the file; not before.

    Thanks
    Arvind
    p.s.. SmidgeonSoft hangs in my VM.
    Attached Files Attached Files
    Reversing articles, primarily from a newbie perspective - http://ardsec.blogspot.com

    Latest article written - http://resources.infosecinstitute.com/author/arvind

  12. #12
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,157
    Blog Entries
    5
    Try setting a breakpoint on the EP before pressing 'g', which by itself simply executes the program.

    > bp $exentry
    > g

    or
    > g @$exentry

    If you want to find out what the pseudo-register $exentry (Entry Point) is, you can evaluate that expression with

    > ? $exentry
    Evaluate expression: 16793121 = 01003e21



    The initial break in WinDbg is generally at
    ntdll!DbgBreakPoint
    If you step through the RET you should be in
    ntdll!LdrpInitializeProcess

    Trace down a few instructions and you should see
    ntdll!LdrpLoadShimEngine

    Step over the call and you should see in the command window the relevant shim dlls being loaded (if running Winmine or other applicable exe), or do a !peb before and after tracing over LdrpLoadShimEngine. For me there are 8 new modules loaded, starting with AcGenral.DLL and ending with UxTheme.dll.


    A little further on you should see a call to
    LdrpRunInitializeRoutines

    Again you should see some more dlls being loaded after stepping over this call (my list starts with IMM32.dll).

    So you see, there are at least 2 "places" where dlls not listed in the static PE file are loaded before ever reaching the Entry Point.


    Continue tracing and you should reach ZwContinue, stepping over it will execute the program (unless you've set the $exentry breakpoint).


    So to answer the question "Is it possible to get a complete list of DLLs before starting the EXE? Like in Olly?"
    Yes, but you will need to let the PE Loader execute at least until ZwContinue. Maybe you'll need to code a basic debugger with which you can control execution.

    Does that clear things up?

    Kayaker

  13. #13
    Registered User
    Join Date
    Apr 2011
    Posts
    78
    Blog Entries
    1
    Awesome thanks. That worked exactly like you said. So effectively this means that the OS loader, at different points, loads DLLs for different purposes [Like the ShimEng DLLs as you explained earlier] into memory; in this case the PEB. This doesn't have to be a static list, like in this case [winmine.exe].

    I tried replicating the exact same thing with Olly 1.10. I stopped at System Breakpoint and set breakpoints at exactly the same places as I'd set in WinDBG. That's addresses 7C9216B1 and 7C921739. This was nearly the same with 1 difference. In Olly, when I broke at 7C9216B1 (ShimEng) all the same DLLs got loaded except UxTheme.DLL and IMM32.DLL. When I broke again at 7C921739 UxTheme got loaded but IMM32 never got loaded at all. In WinDBG UxTheme.DLL was loaded on the first break and IMM32 on the 2nd break. But that apart everything seems similar.

    Now what aqrit said earlier and you nowmakes sense
    The "official" way is to debug the process so Windows will notify your debugger about loaded dlls. see: CreateProcess( DEBUG_PROCESS ) or DebugActiveProcess

    Effectively then, similar to these calls before EntryPoint in winmine.exe, there might be "other such calls" to load "other DLLs" in "other executables". Right? In that case, I will need to modify my code and make it totally generic, so that the 'loading' automatically happens and populates the PEB. Reading the IAT from the PE header or any other static location seems to be an incomplete way to do things.

    Am I correct?

    Thanks so much
    Arvind
    Reversing articles, primarily from a newbie perspective - http://ardsec.blogspot.com

    Latest article written - http://resources.infosecinstitute.com/author/arvind

  14. #14
    your question is even more complex than it seems - read this:
    http://en.wikipedia.org/wiki/DLL_Hell

    the 'dll hell' bugged developers since ages, and the only partial "solution" M$ found to it - you can see it in Vista/Seven, where many different copies/versions of the 'same' dlls (say MSVCxx) exists and are allocated 'on need'.
    One note: if you dynamically load an exe, remember that you might give it a chance to 'escape' your debugger and execute unwanted code, even if you think it wont happen. So, if that's malware, just dont do it (unless you do it in a VM, but then it might be that... etc.)
    I want to know God's thoughts ...the rest are details.
    (A. Einstein)
    --------
    ..."a shellcode is a command you do at the linux shell"...

  15. #15
    Registered User
    Join Date
    Apr 2011
    Posts
    78
    Blog Entries
    1
    I wrote a small blog summarizing all that I had learnt from this site and my reading. Do correct me if I am factually incorrect anywhere

    http://ardsec.blogspot.in/2012/04/exe-dependencies-read-from-peb.html
    Reversing articles, primarily from a newbie perspective - http://ardsec.blogspot.com

    Latest article written - http://resources.infosecinstitute.com/author/arvind

Similar Threads

  1. CFF Explorer Missing Many DLLs In VAD.
    By malhuntr in forum The Newbie Forum
    Replies: 1
    Last Post: January 31st, 2014, 12:00
  2. reversing DLLs with relocation table?
    By Hero in forum The Newbie Forum
    Replies: 8
    Last Post: August 24th, 2010, 22:37
  3. Unpacking DLLs and Drivers with OllyDbg
    By REBlog in forum Blogs Forum
    Replies: 0
    Last Post: October 19th, 2007, 20:27
  4. BPX on labels from dynamicly loaded DLLs
    By merbzt in forum OllyDbg Support Forums
    Replies: 1
    Last Post: April 4th, 2004, 16:01
  5. Debugging DLLs
    By Anonymous in forum OllyDbg Support Forums
    Replies: 7
    Last Post: September 2nd, 2003, 15:02

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •