Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Enumerate modules in Win9* by reading process memory.

Posted on 2004-04-16
14
Medium Priority
?
301 Views
Last Modified: 2010-05-18
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>
0
Comment
Question by:Dook2
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
14 Comments
 
LVL 20

Expert Comment

by:Madshi
ID: 10844114
Do *NOT* post my code publically. You're violating my license agreement!!!!!!!!
0
 

Author Comment

by:Dook2
ID: 10845125
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
 
LVL 20

Expert Comment

by:Madshi
ID: 10845942
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:Dook2
ID: 10848344
> 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
 
LVL 20

Expert Comment

by:Madshi
ID: 10848391
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
 

Author Comment

by:Dook2
ID: 10848479
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
 
LVL 20

Expert Comment

by:Madshi
ID: 10848537
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
 

Author Comment

by:Dook2
ID: 10848689
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
 
LVL 20

Expert Comment

by:Madshi
ID: 10848721
>> 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
 

Author Comment

by:Dook2
ID: 10849514
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
 
LVL 20

Expert Comment

by:Madshi
ID: 10849547
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
 

Accepted Solution

by:
modulo earned 0 total points
ID: 13284908
PAQed with points refunded (130)

modulo
Community Support Moderator
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question