Enumerate modules in Win9* by reading process memory.

How can i find list of loaded modules of current process by reading process memory in Win9*.
I don't want use CreateToolhelp32Snapshot, Module32Next. I try use "Process Database Block".
Who know, how from TP9xModule get filename of module? Maybe Madshi know?
 
http:Q_20956766.html copyrighted code removed -- Lunchy>
Dook2Asked:
Who is Participating?
 
moduloConnect With a Mentor Commented:
PAQed with points refunded (130)

modulo
Community Support Moderator
0
 
MadshiCommented:
Do *NOT* post my code publically. You're violating my license agreement!!!!!!!!
0
 
Dook2Author Commented:
This from your post
http://www.experts-exchange.com/Programming/Programming_Platforms/Win_Prog/Q_20684816.html
You're self violating your license agreement :)
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

 
MadshiCommented:
Oh well, sorry then...   :-)   I didn't remember that old question.

I've commented on your question on my newsgroup. Where do you want to discuss this? Here or there?
0
 
Dook2Author Commented:
> You can enumerate modules by parsing through the system structures, but
> that's a bit on the dangerous side, because thanks to multitasking the
> linked lists can be broken while you're reading them.

> I'd suggest using a VirtualQuery loop. That works just fine for
> enumerating modules - without any danger...

Where i can find info about this structure?
I need analog this NT structure but for win9*

PTLDR_MODULE=^TLDR_MODULE;
LIST_LDR_MODULE=record
   Flink: PTLDR_MODULE;
   Blink: PTLDR_MODULE;
end;
TLDR_MODULE=packed record
  InLoadOrderModuleList:LIST_LDR_MODULE;
  InMemoryOrderModuleList:LIST_ENTRY;
  InInitOrderModuleList:LIST_ENTRY;
  BaseAddress:pointer;
  EntryPoint:pointer;
  SizeOfImage:ULONG;
  FullDllName:UNICODE_STRING;
  BaseDllName:UNICODE_STRING;
  Flags:ulong;
  LoadCount:SHORT;
  TlsIndex:SHORT;
  HashTableEntry:LIST_ENTRY;
  TimeDateStamp:ULONG ;
 end;
 TPEB_LDR_DATA=packed record
{ +0x000}  Length:ULONG;
{ +0x004}  Initialized:dword;
{ +0x008}  SsHandle:dword;
{ +0x00C}  InLoadOrderModuleList:LIST_LDR_MODULE;
{ +0x014}  InMemoryOrderModuleList:LIST_ENTRY;
{ +0x01C}  InInitOrderModuleList:LIST_ENTRY;
 end;
TPEB=packed record
{ +0x000}    InheritedAddressSpace :boolean;
{ +0x001}    ReadImageFileExecOptions : boolean;
{ +0x002}    BeingDebugged :boolean;
{ +0x003}    SpareBool:boolean;
{ +0x004}    Mutant:pointer;
{ +0x008}    ImageBaseAddress :pointer;
{ +0x00c}    Ldr:^TPEB_LDR_DATA;
   end;

I try loop through this

  TP9xModule=^T9xModule;
  T9xModule=record
    next: TP9xModule;
    prev: TP9xModule;
    d2: DWORD;
    d3: DWORD;
    gmlIndex: DWORD;
    d4: DWORD;
    d5: DWORD;
    ownerProcess: TPPDB;
    d6: pchar;
    d7: pchar;
    d8: pchar;
end;

but there is have not module name.
0
 
MadshiCommented:
Please tell me: Why do you want to use the system structures? Why not using a VirtualQuery loop as I suggested? I see not a single advantage in browsing through the system structures when enumerating modules.
0
 
Dook2Author Commented:
I know what you mean:

function GetModuleList: TModuleList;
var
  Module, Base: pointer;
  ModuleCount: integer;
  lpModuleName: array [0..MAX_PATH] of char;
  MemoryBasicInformation: TMemoryBasicInformation;
begin
  SetLength(Result, 10);
  ModuleCount := 0;
  Module := nil;
  Base := nil;
  while VirtualQueryEx(GetCurrentProcess, Module, MemoryBasicInformation, SizeOf(MemoryBasicInformation)) = SizeOf(MemoryBasicInformation) do
  begin
    if (MemoryBasicInformation.State = MEM_COMMIT) and(MemoryBasicInformation.AllocationBase <> Base) and (MemoryBasicInformation.AllocationBase = MemoryBasicInformation.BaseAddress) and (GetModuleFileName(dword(MemoryBasicInformation.AllocationBase), lpModuleName, MAX_PATH) > 0) then
    begin
      if ModuleCount = Length(Result) then SetLength(Result, ModuleCount * 2);
      Result[ModuleCount] := dword(MemoryBasicInformation.AllocationBase);
      Inc(ModuleCount);
    end;
    Base := MemoryBasicInformation.AllocationBase;
    dword(Module) := dword(Module) + MemoryBasicInformation.RegionSize;
  end;
  SetLength(result, ModuleCount);
end;

Its?
But i already make in my program for NT through this structure,
so i need and win9* through analog structure.
0
 
MadshiCommented:
Yeah, this is what I mean. Was this code written by  me? Almost looks like that...   :-)   Anyway, why not using that code? It works in both OS familes (win9x and winNT). And it's completely safe.

> But i already make in my program for NT through this structure,
> so i need and win9* through analog structure.

Why not using the VirtualQueryEx code instead? It's short, it works for all OSs and it's safe.
0
 
Dook2Author Commented:
This code from Aphex afxCodeHook .
In this case module name get from GetmodulenameEx, but if another hooked this API ?
Because name is not clear. This is not for me.
0
 
MadshiCommented:
>> This code from Aphex afxCodeHook

That's my code. He seems to have copied it from here:

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20660084.html

>> In this case module name get from GetmodulenameEx, but if another hooked this API ?

Ok, I see.

The problem with win9x is that there is a global module list and a process specific module list. The process specific module list is what you by using TP9xModule. In that record you find the element "gmlIndex". That stands for "(g)lobal(m)odule(l)istIndex". The module name can be found in the global list only. The big problem is how to get a pointer to the global module list. To be honest, currently I don't know how to.

You should try to find a copy of Matt Pietreks book about Windows 95 programming secrets. It's by far the best book about 9x system internals. A lot of my 9x code is based on this book. It contains information about the global module list. It also sais how to get a point to the list. But if I remember right, it was difficult and a bit on the unreliable side.

Unfortunately that book is out of print. You could try to find a copy on ebay. Probably you could also find the book in pdf format on the net. But of course you must not download it, because it would be illegal...   :-)
0
 
Dook2Author Commented:
Thanks for suggestion.
I found source Matt Pietreks from this book:

void InitModuleTableBase(void)
{
    // Yes, this is really disgusting!
    GDIReallyCares( GetModuleHandle(0) );
    __asm   mov     [PModuleTable], ecx
}

But this trick now not work (time go), GDIReallyCares remove from kernel32.dll (in Win95 12.11.96  this function not founded).
0
 
MadshiCommented:
Yeah, seems I remembered right. Sorry, I don't know how to get a pointer to the global module list. Perhaps disassembling GetModuleFileName or GetModuleFileHandle would help?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.