Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Сканирование списков модулей, загруженных в АП тек.процесса


Страницы:   1 2 3 4

Digitman ©   (2002-09-03 12:34:00) 

К сожалению, информация о нижеследующем слишком разрозненна, неполна и противоречива.

Исх.данные :

Вот структуры для доступа к неким спискам, ассоциированным с процессом :


PListEntry = ^TListEntry;
TListEntry = packed record
FLink: PListEntry;
BLink: PListEntry;
end;

PModuleHeader = ^TModuleHeader;
TModuleHeader = packed record
dw00: DWord;
dw04: DWord;
list1,
list2,
list3: TListEntry;

end;

PProcessModuleInfo = ^TProcessModuleInfo;
TProcessModuleInfo = packed record
RecordSize: DWord;
ModuleHeader: TModuleHeader;
end;

PProcessEnvironmentBlock = ^TProcessEnvironmentBlock;
TProcessEnvironmentBlock = packed record
.....
ProcessHinstance: THandle;
ModuleInfo: PProcessModuleInfo;
Unknown2: DWord;
DefaultHeap: THandle;
.....
end;


Здесь TListEntry - управляющий заголовок элемента некоего двунаправленного списка.
Собственно элемент списка, видимо, следует сразу за заголовком (?) и формат его может быть произвольным, в зависимости от контекста.

Вопрос :

1. Назначение списков TModuleHeader.list1(,2,3)
2. Полная структура элемента списка (какого конкретно из 3-х ?), перечисляющего модули, загруженные в АП процесса, PEB которого рассматривается. В дан.случае интересен лишь handle (image base) каждого модуля.


Ученик   (2002-09-09 09:36:00) [1]

Изменения в TLDR_DATA_TABLE_ENTRY

typedef struct _LDR_MODULE
{
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList; // not used
LIST_ENTRY InInitializationOrderModuleList; // not used
PVOID BaseAddress;
ULONG EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
HANDLE SectionHandle;
ULONG CheckSum;
ULONG TimeDateStamp;
#ifdef KDBG
IMAGE_SYMBOL_INFO SymbolInfo;
#endif /* KDBG */
} LDR_MODULE, *PLDR_MODULE;

http://prdownloads.sourceforge.net/reactos/0020_source.zip?download


Digitman   (2002-09-06 16:45:00) [2]

>Ученик

А кто ж запрещает ? Вкладывай)


Ученик   (2002-09-06 15:01:00) [3]

Как получить я понимаю, но нормальный способ это описание разных структур, единственное что можно сделать, это упростить - вложить одну в другую.


Игорь Шевченко   (2002-09-06 14:50:00) [4]

Ученик © (06.09.02 14:16)

Для того, чтобы получить адрес PLDR_DATA_TABLE_ENTRY из указателя FLink списка, отличающегося от InLoadOrderModuleList, нужно от этого указателя отнять смещение соответствующей структуры TLIST_ENTRY относительно начала TLDR_DATA_TABLE_ENTRY.


Ученик   (2002-09-06 14:16:00) [5]

>Digitman © (06.09.02 14:07)
Не понял, как будет выглядеть проход по второму или третьему списку ?


Digitman   (2002-09-06 14:07:00) [6]

Ну вот же - Digitman © (06.09.02 11:45)


Ученик   (2002-09-06 13:55:00) [7]

>Digitman © (06.09.02 13:50)
Это как "С учетом смещения на пропускаемый линк" ?


Digitman   (2002-09-06 13:50:00) [8]

>Ученик

Просто дополнительная декларация нужна. С учетом смещения на пропускаемый линк. Ее и использовать для такого случая


Ученик   (2002-09-06 13:20:00) [9]

Одна и та же структура в памяти, но при обращении они все-таки разные


Digitman   (2002-09-06 13:10:00) [10]

>Игорь Шевченко (06.09.02 13:07)

Вот и я о том же)


Игорь Шевченко   (2002-09-06 13:07:00) [11]

Ученик © (06.09.02 12:45)

Спасибо, теперь все ясно. Это одна и та же структура (TLDR_DATA_TABLE_ENTRY) просто из разных списков она видна с разными смещениями, так, чтобы нужный ListEntry был всегда в начале.
То есть, в InMemoryOrderModuleList находятся адреса InMemoryOrderLinks и так далее.


Ученик   (2002-09-06 12:45:00) [12]

Структуры обрезал (пока не уверен, в дальнейших полях)

TLDR_DATA_TABLE_ENTRY_1 = packed record
InLoadOrderModuleList : TListEntry;
InMemoryOrderModuleList : TListEntry;
InInitializationOrderModuleList: TListEntry;
DllBase : DWord;
EntryPoint : DWord;
SizeOfImage : DWord;
FullDllName : TNtUnicodeString;
BaseDllName : TNtUnicodeString;
Flags : DWord;
end;
PLDR_DATA_TABLE_ENTRY_1 = ^TLDR_DATA_TABLE_ENTRY_1;

TLDR_DATA_TABLE_ENTRY_2 = packed record
ListEntry : TListEntry;
dwUnknown1 : DWord;
dwUnknown2 : DWord;
DllBase : DWord;
EntryPoint : DWord;
SizeOfImage : DWord;
FullDllName : TNtUnicodeString;
BaseDllName : TNtUnicodeString;
Flags : DWord;
end;
PLDR_DATA_TABLE_ENTRY_2 = ^TLDR_DATA_TABLE_ENTRY_2;

TLDR_DATA_TABLE_ENTRY_3 = packed record
ListEntry : TListEntry;
DllBase : DWord;
EntryPoint : DWord;
SizeOfImage: DWord;
ImageName : TNtUnicodeString;
BaseName : TNtUnicodeString;
Flags : DWord;
end;
PLDR_DATA_TABLE_ENTRY_3 = ^TLDR_DATA_TABLE_ENTRY_3;


procedure TForm1.BuildModulesList1;
var
pModule : PLDR_DATA_TABLE_ENTRY_1;
LdrData : PPebLdrData;
begin
ListView.Clear;
LdrData := GetCurrentPeb.Ldr;
pModule := PLDR_DATA_TABLE_ENTRY_1(LdrData.InLoadOrderModuleList.FLink);
repeat
DisplayModule1(pModule);
pModule := PLDR_DATA_TABLE_ENTRY_1(pModule.InLoadOrderModuleList.Flink);
until pModule = @LdrData.InLoadOrderModuleList;
end;

procedure TForm1.BuildModulesList2;
var
pModule : PLDR_DATA_TABLE_ENTRY_2;
LdrData : PPebLdrData;
begin
ListView.Clear;
LdrData := GetCurrentPeb.Ldr;
pModule := PLDR_DATA_TABLE_ENTRY_2(LdrData.InMemoryOrderModuleList.FLink);
repeat
DisplayModule2(pModule);
pModule := PLDR_DATA_TABLE_ENTRY_2(pModule.ListEntry.Flink);
until pModule = @LdrData.InMemoryOrderModuleList;
end;

procedure TForm1.BuildModulesList3;
var
pModule : PLDR_DATA_TABLE_ENTRY_3;
LdrData : PPebLdrData;
begin
ListView.Clear;
LdrData := GetCurrentPeb.Ldr;
pModule := PLDR_DATA_TABLE_ENTRY_3(LdrData.InInitializationOrderModuleList.FLink);
repeat
DisplayModule3(pModule);
pModule := PLDR_DATA_TABLE_ENTRY_3(pModule.ListEntry.Flink);
until pModule = @LdrData.InInitializationOrderModuleList;
end;


Игорь Шевченко   (2002-09-06 12:40:00) [13]

Ученик © (06.09.02 12:13)

Если внимательно проанализировать последний пример( http://person.okey.net/~webcrazy/module.htm), то видно, что смещения там совсем другие, чем в TLDR_DATA_TABLE_ENTRY


> По всем трем спискам при использовании TListEntry в _PEB_LDR_DATA
> гуляем без проблем


Если у вас есть код, который это делает, не трудно в форум положить ?

С уважением,


Ученик   (2002-09-06 12:13:00) [14]

http://www.faqsen.de/delphi/faq.jsp?ID=505448494850494849545250
http://person.okey.net/~webcrazy/module.htm
По всем трем спискам при использовании TListEntry в _PEB_LDR_DATA гуляем без проблем


Игорь Шевченко   (2002-09-06 12:07:00) [15]

Ученик © (06.09.02 11:55)

Кроме загрузчика на этот вопрос вряд ли кто-то сможет достоверно ответить. Я могу сказать, что экперимент по обходу списка
InMemoryOrderModuleList со ссылками TLDR_DATA_TABLE_ENTRY.InMemoryOrderLinks закончился Access Violation. Из чего я сделал вывод, что структуры там могут быть другие.

С уважением,


Ученик   (2002-09-06 11:55:00) [16]

>Digitman © (06.09.02 11:45)
Тут, наверно, можно долго спорить, попробуйте пройтись по всем трем спискам с использованием одной структуры элементов (TLDR_DATA_TABLE_ENTRY), так как если использованы PListEntry, то когда берется PEB_LDR_DATA.InInitializationOrderModuleList, реально мы берем PEB_LDR_DATA.InMemoryOrderModuleList.FLink


Digitman   (2002-09-06 11:45:00) [17]

>Ученик

Тут вот что получается :

Для каждого непоследнего элемента InInitializationOrderModuleList - списка
его ListEntry.FLink указывает вот сюда :

TLDR_DATA_TABLE_ENTRY = packed record
InLoadOrderLinks : TLIST_ENTRY; //оно есть ! никуда не делось !
ListEntry.FLink -->>> InMemoryOrderLinks : TLIST_ENTRY;
InInitializationOrderLinks : TLIST_ENTRY;
DllBase : Ptr32;
EntryPoint : Ptr32;
SizeOfImage : Uint4B;
FullDllName : TUNICODE_STRING;
BaseDllName : TUNICODE_STRING;
.....
end;


Ученик   (2002-09-06 11:14:00) [18]

>Digitman © (06.09.02 10:37)
Попробуйте пройтись по InInitializationOrderModuleList с использованием PPEB_LDR_DATA


Digitman   (2002-09-06 10:37:00) [19]

>Ученик

Наверно таки ты ошибаешься - не может такого быть, чтобы элементы TModuleEntry (включающие линк-заголовок), фигурирующие в трех разных списках, имели различные (в части линк-заголовков) структуры.

Проверь еще раз :

_PEB_LDR_DATA = packed record
Length : Cardinal;
Initialized : LongBool;
SsHandle : THandle;
InLoadOrderModuleList : PListEntry; //не сама линк-структура, а указатель на нее
InMemoryOrderModuleList : PListEntry; //тоже самое
InInitializationOrderModuleList: PListEntry; //тоже самое
end;
TPebLdrData = _PEB_LDR_DATA;

TModuleEntry = packed record
//Один и тот же TModuleEntry включен в 3 различные двунаправленные списки с помощью следующих 3-х связующих структур :


InLoadOrderLinks : TLIST_ENTRY; // данный элемент описывает модуль в порядке загрузки модулей в ВАП процесса
InMemoryOrderLinks : TLIST_ENTRY; // в порядке возрастания адресов загруженных модулей размещения в ВАП процесса
InInitializationOrderLinks : TLIST_ENTRY; // в порядке инициализации модулей

DllBase : Ptr32;
EntryPoint : Ptr32;
SizeOfImage: Ptr32;
ImageName : TUNICODE_STRING;
end;
PModuleEntry = ^TModuleEntry;


Ученик   (2002-09-06 10:10:00) [20]

>Игорь Шевченко © (06.09.02 09:53)
Исправления из разных мест, поиск по PEB_LDR_DATA, добавление, (возможно структура не полная) - маленькое исследование для текущего процесса.


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо