Доброго времени суток! Помогите пожалуйста с определением недокументированных структур в x64. Мой алгоритм прекрасно работал на x32, но при попытке универсализации возникли проблемы с недокументированными структурами. Некоторые я смог нормально адаптировать к работе как на х32, так и на х64. Однако структура LDR_MODULE видимо объявлено мной неправильно, поскольку копание в памяти проходит неверно. PEB и PEB_LDR_DATA на глаз выглядят нормально. К сожалению нормального описания LDR_MODULE в интернете я не нашел, более того в большинстве ответов гагла структура объявлена неверно, а именно опущен union, и стоит три указателя вместо одного в начале структуры. Сейчас структуры объявлены следующим образом: Код (Text): typedef struct _PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; // Список модулей в порядке загрузки LIST_ENTRY InMemoryOrderModuleList; // Список модулей в порядке расположения в памяти LIST_ENTRY InInitializationOrderModuleList; // Список модулей в порядке инициализации } PEB_LDR_DATA, *PPEB_LDR_DATA; typedef struct _PEB { BOOLEAN InheritedAddressSpace; BOOLEAN ReadImageFileExecOptions; BOOLEAN BeignDebugged; BOOLEAN Spare; HANDLE Mutant; PVOID ImageBaseAddress; PPEB_LDR_DATA LoaderData; } PEB, *PPEB; typedef struct _LDR_MODULE { LIST_ENTRY ModuleList; PVOID BaseAddress; PVOID EntryPoint; ULONG SizeOfImage; USHORT FullDllNameLength; USHORT FullDllNameMaxLength; PWSTR FullDllNameBuffer; USHORT BaseDllNameLength; USHORT BaseDllNameMaxLength; PWSTR BaseDllNameBuffer; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; LIST_ENTRY HashTableEntry; ULONG TimeDateStamp; } LDR_MODULE, *PLDR_MODULE; Пожалуйста, кто знает, помогите разобраться! Заранее спасибо!
Блин. Извините за беспокойство, запостил тему на форуме и на меня просто снизошло прозрение. Вобщем разобрался сам)))) Глупый недочет в LDR_MODULE.
deLight Здесь довольно простой случай. Если,например, говорить про структуру LDR_DATA_TABLE_ENTRY (которая в этом топике называется LDR_MODULE - видимо в память о временах, когда не было wrk). И что мы видим в файле ntldr.h? Данную там структуру можно применять как на 32, так и на 64 битах. Просто поля, которые претерпевают изменения - это указатели. В ntldr.h так же даны варианты структур LDR_DATA_TABLE_ENTRY64/32, там это выглядит наглядней. Код (Text): typedef struct _LDR_DATA_TABLE_ENTRY { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; LIST_ENTRY InInitializationOrderLinks; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; USHORT LoadCount; USHORT TlsIndex; union { LIST_ENTRY HashLinks; struct { PVOID SectionPointer; ULONG CheckSum; }; }; union { struct { ULONG TimeDateStamp; }; struct { PVOID LoadedImports; }; }; struct _ACTIVATION_CONTEXT * EntryPointActivationContext; PVOID PatchInformation; } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; Насчет других изменений. В общем случае все не ограничивается размером указателя (если говорить про другие структуры). Взять ту же CONTEXT, в нее добавлены новые поля, отражающие увеличение количество регистров итд. или KUSER_SHARED_DATA с ее Wow64SharedInformation. И таких примеров немало.
Потом если, например, адрес PEB берется из fs, то на 64 это, разумеется, работать не будет, так как он расположен по адресу gs:[0x60]. И опять-таки непонятно, автор вопроса хочет работать в Compatibility mode или 64-bit mode. Я пишу именно про 64-битный режим.
Код (Text): typedef struct _PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; } PEB_LDR_DATA, *PPEB_LDR_DATA; Код (Text): typedef struct _LDR_MODULE { LIST_ENTRY ModuleList; PVOID BaseAddress; PVOID EntryPoint; #ifdef _WIN64 LONGLONG SizeOfImage; #else ULONG SizeOfImage; #endif USHORT FullDllNameLength; USHORT FullDllNameMaxLength; PWSTR FullDllNameBuffer; USHORT BaseDllNameLength; USHORT BaseDllNameMaxLength; PWSTR BaseDllNameBuffer; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; LIST_ENTRY HashTableEntry; ULONG TimeDateStamp; } LDR_MODULE, *PLDR_MODULE; lhc645, откуда вы взяли эту структуру? на практике, нет там трех листов в начале... и единственное отличие x64, которое опять же определилось на практике - в длине SizeOfImage...
определите SizeOfImage как ULONG_PTR или SIZE_T и он будет 32бита на x86 и 64бита на x64. тогда не нужно вообще различий делать
Rel Код (Text): 0:000> vertarget Windows 7 Version 7600 MP (2 procs) Free x64 Product: WinNt, suite: SingleUserTS kernel32.dll version: 6.1.7600.16385 (win7_rtm.090713-1255) Machine Name: Debug session time: Tue May 18 10:16:27.681 2010 (UTC + 4:00) System Uptime: 2 days 9:21:39.826 Process Uptime: 0 days 0:00:04.526 Kernel time: 0 days 0:00:00.000 User time: 0 days 0:00:00.015 0:000> dt ntdll!*ldr* ntdll!_PEB_LDR_DATA ntdll!_LDR_DATA_TABLE_ENTRY 0:000> dt _PEB_LDR_DATA ntdll!_PEB_LDR_DATA +0x000 Length : Uint4B +0x004 Initialized : UChar +0x008 SsHandle : Ptr64 Void +0x010 InLoadOrderModuleList : _LIST_ENTRY +0x020 InMemoryOrderModuleList : _LIST_ENTRY +0x030 InInitializationOrderModuleList : _LIST_ENTRY +0x040 EntryInProgress : Ptr64 Void +0x048 ShutdownInProgress : UChar +0x050 ShutdownThreadId : Ptr64 Void 0:000> dt _LDR_DATA_TABLE_ENTRY ntdll!_LDR_DATA_TABLE_ENTRY +0x000 InLoadOrderLinks : _LIST_ENTRY +0x010 InMemoryOrderLinks : _LIST_ENTRY +0x020 InInitializationOrderLinks : _LIST_ENTRY +0x030 DllBase : Ptr64 Void +0x038 EntryPoint : Ptr64 Void +0x040 SizeOfImage : Uint4B +0x048 FullDllName : _UNICODE_STRING +0x058 BaseDllName : _UNICODE_STRING +0x068 Flags : Uint4B +0x06c LoadCount : Uint2B +0x06e TlsIndex : Uint2B +0x070 HashLinks : _LIST_ENTRY +0x070 SectionPointer : Ptr64 Void +0x078 CheckSum : Uint4B +0x080 TimeDateStamp : Uint4B +0x080 LoadedImports : Ptr64 Void +0x088 EntryPointActivationContext : Ptr64 _ACTIVATION_CONTEXT +0x090 PatchInformation : Ptr64 Void +0x098 ForwarderLinks : _LIST_ENTRY +0x0a8 ServiceTagLinks : _LIST_ENTRY +0x0b8 StaticLinks : _LIST_ENTRY +0x0c8 ContextInformation : Ptr64 Void +0x0d0 OriginalBase : Uint8B +0x0d8 LoadTime : _LARGE_INTEGER 0:000> * x32: 0:000> dt _PEB_LDR_DATA ntdll!_PEB_LDR_DATA +0x000 Length : Uint4B +0x004 Initialized : UChar +0x008 SsHandle : Ptr32 Void +0x00c InLoadOrderModuleList : _LIST_ENTRY +0x014 InMemoryOrderModuleList : _LIST_ENTRY +0x01c InInitializationOrderModuleList : _LIST_ENTRY +0x024 EntryInProgress : Ptr32 Void +0x028 ShutdownInProgress : UChar +0x02c ShutdownThreadId : Ptr32 Void 0:000> dt _LDR_DATA_TABLE_ENTRY ntdll!_LDR_DATA_TABLE_ENTRY +0x000 InLoadOrderLinks : _LIST_ENTRY +0x008 InMemoryOrderLinks : _LIST_ENTRY +0x010 InInitializationOrderLinks : _LIST_ENTRY +0x018 DllBase : Ptr32 Void +0x01c EntryPoint : Ptr32 Void +0x020 SizeOfImage : Uint4B +0x024 FullDllName : _UNICODE_STRING +0x02c BaseDllName : _UNICODE_STRING +0x034 Flags : Uint4B +0x038 LoadCount : Uint2B +0x03a TlsIndex : Uint2B +0x03c HashLinks : _LIST_ENTRY +0x03c SectionPointer : Ptr32 Void +0x040 CheckSum : Uint4B +0x044 TimeDateStamp : Uint4B +0x044 LoadedImports : Ptr32 Void +0x048 EntryPointActivationContext : Ptr32 _ACTIVATION_CONTEXT +0x04c PatchInformation : Ptr32 Void +0x050 ForwarderLinks : _LIST_ENTRY +0x058 ServiceTagLinks : _LIST_ENTRY +0x060 StaticLinks : _LIST_ENTRY +0x068 ContextInformation : Ptr32 Void +0x06c OriginalBase : Uint4B +0x070 LoadTime : _LARGE_INTEGER Rel >на практике, нет там трех листов в начале... Голова списка 'Ldr.InInitializationOrderModuleList' указывает не на начало структуры, а на соответствующий её элемент – на _LDR_DATA_TABLE_ENTRY.InInitializationOrderLinks. И, соответственно, все последующие элементы этого списка соединены так же. Стандартная практика. Maclaud >Я тоже сейчас ищу эти настоящие структуры. Не надо ничего искать. Не нужно быть MVP, чтобы получить публичные символы MS. А далее уже выбирай любой парсер и приводи их к нужному виду.
да я знаю... у меня как раз в этом поле был косяк год назад (см. вверху темы), я просто его выделил таким образом, чтобы было заметно... окей... буду знать...
Rel Применяйте макрос CONTAINING_RECORD для получения адреса начала структуры LDR_DATA_TABLE_ENTRY. Например так Код (Text): pLte = CONTAINING_RECORD(pPebLdr->InInitializationOrderModuleList.Flink, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks); compatibility mode видимо.
>compatibility mode видимо. Логичный вывод. Но исходные данные неверны – Rel ошибается. А структура LDR_DATA_TABLE_ENTRY неизменна между x32 <-> wow. Вообще, мы верим, что раскладка структур из x32-винды совпадает с раскладкой соответствующих структур wow – за исключением, быть может, самых глубокосистемных (peb, teb).
У вас выравнивание структуры почему-то 4 байта, поэтому вам пришлось изменять размер поля SizeOfImage. Поставьте выравнивание 8 для 64 бит и не надо будет менять (взгляните на смещения в #12). Тогда можно будет использовать структуру из #8