Get import table of a running process

Hello,

I know the handle of an running process (  hProcess := OpenProcess(AccessRights, FALSE, PID); ) and I want to know which DLL files it have loaded. I do not want to know which DLL is in the process space of this running process (injected DLLs can be also in the process space, but injected DLLs are not loaded from a process, because injected DLLs are injected to the process.)
That means I can not use EnumProcessModules or Module32First, because these functions also enumerate the injected DLLs.
A solution could be to get the import table of this running process and look for the DLLs which the process is using. How can I do this? The .exe file of the running process is compressed, so I have to get the import table from the process in memory - not from the .exe file.
The solution should work on Windows NT (Win9x would be fine).

Thanky you for your answer for this difficult question
Ben

BTW: I think, here you can found something similar: Look for "function GetProcAddress32" at http://www.delphipages.com/news/detaildocs.cfm?ID=17
or look for "FindCallerModuleHandle" on http://groups.google.com

bengoreAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

GloomyFriarCommented:
In a "running process" there is no differences between "loaded" and "injected" DLLs.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
GloomyFriarCommented:
"import table" may contain not all DLLs. How about DLLs loaded by LoadLibrary?
0
GloomyFriarCommented:
Could you tell more detailed what do you want to make?
0
Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

bengoreAuthor Commented:
GloomyFriar, thank you for your comments.
How about DLLs linked static (not loaded by LoadLibrary). Is there a way to get this DLLs via "import table"?
0
bengoreAuthor Commented:
More details? I have a DLL file. I want to know if a processes (somethimes with comressed .exe files) needs this DLL file (static linked).
0
DaFoxCommented:
In Jeffrey Richter's book there is a DLL called ImgWalk.dll (lists all DLLs used by a process).

Markus
0
bengoreAuthor Commented:
DaFox, I think ImgWalk.dll use EnumProcessModules or Module32First and enumerate also injected DLLs.
0
DaFoxCommented:
>> I think ImgWalk.dll use EnumProcessModules or Module32First

nope, it uses VirtualQuery that fills the MEMORY_BASIC_INFORMATION structure.

>> injected DLLs

that's right, and therefore it also gets dynamically loaded dlls.

Markus
0
GloomyFriarCommented:
>How about DLLs linked static (not loaded by LoadLibrary). Is there a way to get this DLLs via "import table"?
Yes of course.
You just need to open the exe file and read its PE header.
0
GloomyFriarCommented:
Something like that (it work with running exe, but you can do the same with a file):

function FindUsablePage(hProcess: THANDLE; PProcessBase: pointer): pointer;
var peHdrOffset: DWORD;
    cBytesMoved: DWORD;
    ntHdr: IMAGE_NT_HEADERS;
    pSection: ^IMAGE_SECTION_HEADER;
    i: ULONG;
    tmpPtr: PBYTE;
    section: IMAGE_SECTION_HEADER;
    SecName: string;
begin
   Result := nil;

   // Read in the offset of the PE header within the debuggee
   tmpPtr := PBYTE(PProcessBase);
   inc(tmpPtr, $3C);
   if ReadProcessMemory(ProcessInformation.hProcess,
                        tmpPtr,
                        @peHdrOffset,
                        sizeof(peHdrOffset),
                        cBytesMoved) = False then Exit;

   // Read in the IMAGE_NT_HEADERS.OptionalHeader.BaseOfCode field
   tmpPtr := PBYTE(PProcessBase);
   inc(tmpPtr, peHdrOffset);
   if ReadProcessMemory(ProcessInformation.hProcess,
                        tmpPtr, @ntHdr, sizeof(ntHdr),
                        cBytesMoved) = False then Exit;

   tmpPtr := PBYTE(PProcessBase);
   inc(tmpPtr, peHdrOffset + 4 + sizeof(ntHdr.FileHeader) +
       ntHdr.FileHeader.SizeOfOptionalHeader);
   pSection := pointer(tmpPtr);//(PIMAGE_SECTION_HEADER)

  for i:=0 to Pred(ntHdr.FileHeader.NumberOfSections) do begin
     //{IMAGE_SECTION_HEADER section;
     if ReadProcessMemory(ProcessInformation.hProcess,
                          pSection, @section, sizeof(section),
                          cBytesMoved) = False then Exit;
     // OutputDebugString( "trying section:
     // OutputDebugString( section.Name )'
     // OutputDebugString( "\r\n" )'

     SecName := StrPas(@section.Name[0]);
     // If it's writeable, and not the .idata section, we'll go with it
     if(((section.Characteristics and IMAGE_SCN_MEM_WRITE) <> 0) and
        (StrLComp(@section.Name[0], '.idata', 6) <> 0)) then begin
         OutputDebugString(PChar('using section.' + StrPas(@section.Name[0]) + #10 + #13));
        Result := pointer(DWORD(PProcessBase) + section.VirtualAddress);
        //Exit;
     end;
     Inc(pSection); // Not this section. Advance to next section.
  end;
end;
0
GloomyFriarCommented:
0
GloomyFriarCommented:
Here is the code that read exports, but it's rather easy to make it read imports.
If any problems I'll can help tomorrow.

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20079575.html
0
bengoreAuthor Commented:
Hi GloomyFriar, thank you for your FindUsablePage source and the other links. I will check it.

> You just need to open the exe file and read its PE header.
This is not usefull, if the .exe file is compressed.
0
GloomyFriarCommented:
>This is not usefull, if the .exe file is compressed.
Which compressor is used?
Are you sure that import sections is changed by the compressor?
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.