![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сканирование списков модулей, загруженных в АП тек.процесса
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-06 09:53:00) [21]Ученик © (06.09.02 08:54)
Откуда информация по дополнениям/исправлениям ? Ссылочку не подскажете ?
Digitman (2002-09-06 09:40:00) [22]>Ученик
Все ясно. Ну, насколько я понял, ты уже определился на сей момент)
Ученик (2002-09-06 09:17:00) [23]>Digitman © (06.09.02 09:09)
Когда я влез в эту ветку, она честно говоря не пересекалась, потом выяснилось, что они пересекается на реализации GetModuleFileNameEx, там идет сканирование модулей загруженных в процесс и сравнение HInstance с TLDR_DATA_TABLE_ENTRY.DllBase
Digitman (2002-09-06 09:09:00) [24]>Ученик
Я что-то не совсем понял твою задачу.
Еще раз объясни толково - как она пересекается с той, что я описал при инициации ветки ?
Ученик (2002-09-06 08:54:00) [25]>Digitman © (05.09.02 18:09)
Спасибо, но это к сожалению, не помогло, остановился на GetModuleFileNameEx, другие варианты оказались слишком громоздкими (тоже самое делает GetModuleFileNameEx)
>All
Небольшие добавления (исправления)
_PEB_LDR_DATA = packed record
Length : Cardinal;
Initialized : LongBool;
SsHandle : THandle;
InLoadOrderModuleList : TListEntry;
InMemoryOrderModuleList : TListEntry;
InInitializationOrderModuleList: TListEntry;
end;
TPebLdrData = _PEB_LDR_DATA;
Не знаю как описано в оригинале, но это вроде элементы списка InitializationOrderModuleList
TModuleEntry = packed record
ListEntry : TListEntry;
DllBase : Ptr32;
EntryPoint : Ptr32;
SizeOfImage: Ptr32;
ImageName : TUNICODE_STRING;
end;
PModuleEntry = ^TModuleEntry;
InMemoryOrderModuleList указывает на элементы TLDR_DATA_TABLE_ENTRY
Digitman (2002-09-05 18:09:00) [26]>Ученик
FindhInstance() возвращает хэндл модуля, являющийся по сути базовым линейным адресом начала образа PE-модуля, загруженного в ВАП процесса.
Образ PE-модуля начинается с DOS-заголовка :
PImageDosHeader = ^TImageDosHeader;
{EXTERNALSYM _IMAGE_DOS_HEADER}
_IMAGE_DOS_HEADER = packed record { DOS .EXE header }
e_magic: Word; { Magic number }
e_cblp: Word; { Bytes on last page of file }
e_cp: Word; { Pages in file }
e_crlc: Word; { Relocations }
e_cparhdr: Word; { Size of header in paragraphs }
e_minalloc: Word; { Minimum extra paragraphs needed }
e_maxalloc: Word; { Maximum extra paragraphs needed }
e_ss: Word; { Initial (relative) SS value }
e_sp: Word; { Initial SP value }
e_csum: Word; { Checksum }
e_ip: Word; { Initial IP value }
e_cs: Word; { Initial (relative) CS value }
e_lfarlc: Word; { File address of relocation table }
e_ovno: Word; { Overlay number }
e_res: array [0..3] of Word; { Reserved words }
e_oemid: Word; { OEM identifier (for e_oeminfo) }
e_oeminfo: Word; { OEM information; e_oemid specific}
e_res2: array [0..9] of Word; { Reserved words }
_lfanew: LongInt; { File address of new exe header }
end;
TImageDosHeader = _IMAGE_DOS_HEADER;
{$EXTERNALSYM IMAGE_DOS_HEADER}
IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;
взято из Windows.pas
Ученик (2002-09-05 17:45:00) [27]>Digitman © (04.09.02 17:11)
Спасибо, все работает, только хотелось бы избавиться от использования PSAPI (GetModuleFileNameEx), не подскажете на какую структуру мы получаем адрес после FindHInstance ?
Digitman (2002-09-05 13:46:00) [28]Вот теперь все сходится !)
RtlEnterCriticalSection/RtlLeaveCriticalSection успешно работают и с полем LoaderLock и с полем FastPebLock.
По кр.мере - W2k, NT, XP
Игорь Шевченко (2002-09-05 13:07:00) [29]В дополнение.
В unit"е NtPEB (Игорь Шевченко © (04.09.02 09:56))
в описание структуры TPEB после поля
NtGlobalFlag : Uint4B;
должно быть добавлено поле
Reserved : Uint4B;
Ученик (2002-09-04 19:18:00) [30]>Digitman © (04.09.02 17:11)
Спасибо, попробую
Digitman (2002-09-04 17:11:00) [31]>Ученик
Для текущего процесса :
- берешь любой адрес из диапазона адресов, занимаемых телом ThreadFunc;
- выполняешь для него FindHInstance() - получаешь хэндл PE-модуля в АП процесса;
- по хэндлу ищешь любым удобным способом (тот же GetModuleFileName) имя файла модуля
Ученик (2002-09-04 16:51:00) [32]>>Игорь Шевченко © (04.09.02 16:38)
Мне нужна информация именно о модуле (скорее DLL), так как название EXE я уже получил через информацию о процессе, задача о Hook-ах установленных в системе.
Игорь Шевченко (2002-09-04 16:38:00) [33]Ученик © (04.09.02 16:22)
Все модули - это свойство процесса, а не потока. Так что модуль, загруженный одним потоком не должен ничем отличаться от модуля, загруженного другим потоком (IMHO).
Для определения EXE по процессу есть пример в кладовке EnumFunctions - функция HSGetWindowCommandLine - имя EXE"шника, создавшего процесс.
С уважением,
Ученик (2002-09-04 16:22:00) [34]>paul_shmakov © (04.09.02 16:12)
Не, это не просто так :-)
Нужна помощь, есть идентификатор Thread-а, в принципе есть TEB,
необходимо выяснить откуда этот Thread (не процесс, а модуль -EXE, DLL), киньте название какой-нибудь структуры или функции, дальше, наверно, сам найду.
Digitman (2002-09-04 16:19:00) [35]думаю, что и PEB.LoaderLock - тоже крит.секция
paul_shmakov (2002-09-04 16:12:00) [36]2 Игорь Шевченко:
"Это разные локи. PebLock блокирует доступ к PEB,
а LoaderLock блокирует доступ к PEB^.Ldr.
В разных ОС реализовано по-разному"
обидно, если так. а то все очень красиво получается.
а это точно? может все же PebLock блокирует все, включая PEB^.Ldr?
2 Ученик:
спасибо за проверку!
Игорь Шевченко (2002-09-04 15:22:00) [37]paul_shmakov © (04.09.02 14:56)
Ученик © (04.09.02 15:09)
Это разные локи. PebLock блокирует доступ к PEB,
а LoaderLock блокирует доступ к PEB^.Ldr.
В разных ОС реализовано по-разному
Ученик (2002-09-04 15:09:00) [38]NT 4.0
Peb.FastPebLockRoutine: 77F67500
RtlEnterCriticalSection: 77F67500
Peb.FastPebUnlockRoutine: 77F675D0
RtlLeaveCriticalSection: 77F675D0
Peb.FastPebLock.DebugInfo: 77FA7620
Peb.FastPebLock.LockCount: FFFFFFFF
Peb.FastPebLock.RecursionCount: 00000000
Peb.FastPebLock.OwningThread: 00000000
Peb.FastPebLock.LockSemaphore: 00000000
Ученик (2002-09-04 15:03:00) [39]Windows XP
Peb.FastPebLockRoutine: 77F7E21F
RtlEnterCriticalSection: 77F7E21F
Peb.FastPebUnlockRoutine: 77F7E300
RtlLeaveCriticalSection: 77F7E300
Peb.FastPebLock.DebugInfo: 77FC52A0
Peb.FastPebLock.LockCount: FFFFFFFF
Peb.FastPebLock.RecursionCount: 00000000
Peb.FastPebLock.OwningThread: 00000000
Peb.FastPebLock.LockSemaphore: 00000000
paul_shmakov (2002-09-04 14:56:00) [40]да, еще добавьте к предыдущей программе следующий код для проверки, что Peb.FastPebLock является TTRLCriticalSection;
TPEB
...
ProcessHeap: Pointer;
FastPebLock: PRTLCriticalSection;
FastPebLockRoutine: Pointer;
...
// а это в самый конец
PrintPointer("Peb.FastPebLock.DebugInfo:", Pointer(Peb.FastPebLock.DebugInfo));
PrintPointer("Peb.FastPebLock.LockCount:", Pointer(Peb.FastPebLock.LockCount));
PrintPointer("Peb.FastPebLock.RecursionCount:", Pointer(Peb.FastPebLock.RecursionCount));
PrintPointer("Peb.FastPebLock.OwningThread:", Pointer(Peb.FastPebLock.OwningThread));
PrintPointer("Peb.FastPebLock.LockSemaphore:", Pointer(Peb.FastPebLock.LockSemaphore));
end.
у меня выдает:
Peb.FastPebLockRoutine: 77F81B42
RtlEnterCriticalSection: 77F81B42
Peb.FastPebUnlockRoutine: 77F81B73
RtlLeaveCriticalSection: 77F81B73
Peb.FastPebLock.DebugInfo: 77FCEA80
Peb.FastPebLock.LockCount: FFFFFFFF
Peb.FastPebLock.RecursionCount: 00000000
Peb.FastPebLock.OwningThread: 00000000
Peb.FastPebLock.LockSemaphore: 00000000
из значений полей Peb.FastPebLock видно, что Peb.FastPebLock - это действительно critical section.
поэтому можно попробовать в примере Игоря:
procedure TfMain.LockLoader();
begin
CurrentPEB.FastPebLockRoutine(CurrentPEB.FastPebLock);
end;
procedure TfMain.UnlockLoader();
begin
CurrentPEB.FastPebUnlockRoutine(CurrentPEB.FastPebLock);
end;