Сравнение списка модулей из PEB и VAD
От: -prus-  
Дата: 04.08.14 14:39
Оценка:
Всем привет!

Мне необходимо сравнить два списка загруженных в процесс модулей. Первый список беру из PEB процесса, а второр из списка VAD'ов процесса, как описано здесь.
Проблема заключается в том, что на x64 платформах для 32-битных процессов способ через VAD показывает мне модули, которых нету в списке PEB.
Например (жирным показаны модули, которых в PEB нет),

conime.exe

DLL — C:\Windows\SysWOW64\conime.exe
DLL — C:\Windows\system32\ntdll.dll
DLL — C:\Windows\system32\wow64.dll
DLL — C:\Windows\system32\wow64win.dll
DLL — C:\Windows\system32\wow64cpu.dll
DLL — C:\Windows\SysWOW64\ntdll.dll
DLL — C:\Windows\syswow64\kernel32.dll
DLL — C:\Windows\syswow64\ADVAPI32.dll
DLL — C:\Windows\syswow64\RPCRT4.dll
DLL — C:\Windows\syswow64\Secur32.dll
DLL — C:\Windows\syswow64\GDI32.dll
DLL — C:\Windows\syswow64\USER32.dll
DLL — C:\Windows\syswow64\msvcrt.dll
DLL — C:\Windows\syswow64\ole32.dll
DLL — C:\Windows\syswow64\OLEAUT32.dll
DLL — C:\Windows\system32\UxTheme.dll
DLL — C:\Windows\syswow64\IMM32.dll
DLL — C:\Windows\syswow64\MSCTF.dll
DLL — C:\Windows\syswow64\LPK.DLL
DLL — C:\Windows\syswow64\USP10.dll
DLL — C:\Windows\syswow64\CLBCatQ.DLL
DLL — C:\Windows\SysWOW64\uxtheme.dll

dseo13b.exe

DLL — C:\css\dseo13b.exe
DLL — C:\Windows\system32\ntdll.dll
DLL — C:\Windows\system32\wow64.dll
DLL — C:\Windows\system32\wow64win.dll
DLL — C:\Windows\system32\wow64cpu.dll
DLL — C:\Windows\SysWOW64\ntdll.dll
DLL — C:\Windows\syswow64\kernel32.dll
DLL — C:\Windows\syswow64\USER32.dll
DLL — C:\Windows\syswow64\GDI32.dll
DLL — C:\Windows\syswow64\ADVAPI32.dll
DLL — C:\Windows\syswow64\RPCRT4.dll
DLL — C:\Windows\syswow64\Secur32.dll
DLL — C:\Windows\system32\ShimEng.dll
DLL — C:\Windows\system32\apphelp.dll
DLL — C:\Windows\AppPatch\AcGenral.DLL
DLL — C:\Windows\syswow64\SHLWAPI.dll
DLL — C:\Windows\syswow64\msvcrt.dll
DLL — C:\Windows\system32\UxTheme.dll
DLL — C:\Windows\system32\WINMM.dll
DLL — C:\Windows\syswow64\ole32.dll
DLL — C:\Windows\syswow64\OLEAUT32.dll
DLL — C:\Windows\system32\OLEACC.dll
DLL — C:\Windows\system32\NETAPI32.dll
DLL — C:\Windows\syswow64\PSAPI.DLL
DLL — C:\Windows\system32\MSACM32.dll
DLL — C:\Windows\system32\VERSION.dll
DLL — C:\Windows\syswow64\SHELL32.dll
DLL — C:\Windows\system32\sfc.dll
DLL — C:\Windows\system32\sfc_os.dll
DLL — C:\Windows\syswow64\SETUPAPI.dll
DLL — C:\Windows\system32\USERENV.dll
DLL — C:\Windows\system32\dwmapi.dll
DLL — C:\Windows\syswow64\urlmon.dll
DLL — C:\Windows\syswow64\iertutil.dll
DLL — C:\Windows\system32\MPR.dll
DLL — C:\Windows\system32\IMM32.DLL
DLL — C:\Windows\syswow64\MSCTF.dll
DLL — C:\Windows\syswow64\LPK.DLL
DLL — C:\Windows\syswow64\USP10.dll
DLL — C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.6002.18005_none_5cb72f96088
b0de0\comctl32.dll
DLL — C:\Users\9335~1\AppData\Local\Temp\~vis0002\vise32ex.dll
DLL — C:\Windows\syswow64\comdlg32.dll
DLL — C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.6001.18000_none_886786f450
a74a05\COMCTL32.dll
DLL — C:\Windows\system32\PROPSYS.dll
DLL — C:\Windows\syswow64\CLBCatQ.DLL
DLL — C:\Windows\SysWOW64\propsys.dll
DLL — C:\Windows\SysWOW64\uxtheme.dll
DLL — C:\Windows\SysWOW64\sfc_os.dll
DLL — C:\Windows\SysWOW64\dwmapi.dll
DLL — C:\Windows\SysWOW64\mpr.dll
DLL — C:\Windows\SysWOW64\userenv.dll
DLL — C:\Windows\SysWOW64\oleacc.dll
DLL — C:\Windows\SysWOW64\netapi32.dll
DLL — C:\Windows\SysWOW64\winmm.dll
DLL — C:\Windows\SysWOW64\shimeng.dll
DLL — C:\Windows\SysWOW64\apphelp.dll
DLL — C:\Windows\SysWOW64\msacm32.dll
DLL — C:\Windows\SysWOW64\sfc.dll
DLL — C:\Windows\SysWOW64\version.dll
DLL — C:\Windows\SysWOW64\imm32.dll


Полные имена модулей при получении их через VAD беру из PFILE_OBJECT + IoQueryFileDosDeviceName.
Также учитываю, что у 32-битных процессов под x64 нужно читать 2 PEB'а — 32 битный и 64 битный...

Если кто подскажет, как бы обойти данную проблему, буду крайне благодарен.

Заранее спасибо!
С уважением,
Евгений
Re: Сравнение списка модулей из PEB и VAD
От: ononim  
Дата: 04.08.14 15:15
Оценка: 10 (1)
P>Мне необходимо сравнить два списка загруженных в процесс модулей. Первый список беру из PEB процесса, а второр из списка VAD'ов процесса, как описано здесь.
Ой какой хардкор. Не проще ли тихо-мирно из юзермода получить тот же эффект через VirtualQueryEx + GetMappedFileName ? Хотя наверное если это — антималвар — то из кернела надежнее. Малоли что малвар похучил.

P>Проблема заключается в том, что на x64 платформах для 32-битных процессов способ через VAD показывает мне модули, которых нету в списке PEB.

P>Например (жирным показаны модули, которых в PEB нет),
Во-первых у 32хбитных процессов два PEB'а (32хбитный и 64хбитный), в которых два различных списка модулей. Правда 64хбитный обычно весьма куцый.
Во-первых не обязательно будет совпадение путей и/или наличия модуля в ПЕБе и реального пути откуда его загрузили. Проблемы могут доставить виртуализация — как виндовая так и сторонняя. Да и в принципе никто не мешает 'вручную' подмапить файл через CreateFileMapping(..SEC_IMAGE..) + MapViewOfFile. В PEBе его не появится, а в ядре вы регион не отличите от загруженной длл-ки.
В-третьих конкретно по syswow64\uxtheme.dll — я ее вижу во всех процессах на своей семерке. Возможно у вас баг в парсинге PEB-ldr списка.
Как много веселых ребят, и все делают велосипед...
Re[2]: Сравнение списка модулей из PEB и VAD
От: -prus-  
Дата: 04.08.14 15:23
Оценка:
Здравствуйте, ononim, Вы писали:

O>Ой какой хардкор. Не проще ли тихо-мирно из юзермода получить тот же эффект через VirtualQueryEx + GetMappedFileName ? Хотя наверное если это — антималвар — то из кернела надежнее. Малоли что малвар похучил.


Да, пример, на котором отлаживаю все, хучит ZwOpenProcess, поэтому сразу решил в ядре.

O>Во-первых у 32хбитных процессов два PEB'а (32хбитный и 64хбитный), в которых два различных списка модулей. Правда 64хбитный обычно весьма куцый.


Да, это учитываю.

O>Во-первых не обязательно будет совпадение путей и/или наличия модуля в ПЕБе и реального пути откуда его загрузили. Проблемы могут доставить виртуализация — как виндовая так и сторонняя. Да и в принципе никто не мешает 'вручную' подмапить файл через CreateFileMapping(..SEC_IMAGE..) + MapViewOfFile. В PEBе его не появится, а в ядре вы регион не отличите от загруженной длл-ки.


Спасиб.
А имея на руках FILE_OBJECT тоже никак не отличить?

O>В-третьих конкретно по syswow64\uxtheme.dll — я ее вижу во всех процессах на своей семерке. Возможно у вас баг в парсинге PEB-ldr списка.


Пойду еще раз перепроверю все...

Спасибо.
С уважением,
Евгений
Re[3]: Сравнение списка модулей из PEB и VAD
От: ononim  
Дата: 04.08.14 15:34
Оценка: 5 (1)
O>>Во-первых не обязательно будет совпадение путей и/или наличия модуля в ПЕБе и реального пути откуда его загрузили. Проблемы могут доставить виртуализация — как виндовая так и сторонняя. Да и в принципе никто не мешает 'вручную' подмапить файл через CreateFileMapping(..SEC_IMAGE..) + MapViewOfFile. В PEBе его не появится, а в ядре вы регион не отличите от загруженной длл-ки.
P>Спасиб.
P>А имея на руках FILE_OBJECT тоже никак не отличить?
Врядли. LdrLoadDll — она ведь по сути делает то же самое + добавляет промапленный адрес в ldr-list. Но ничто не мешает юзермодному коду промапить и не добавлять в ldr.

O>>В-третьих конкретно по syswow64\uxtheme.dll — я ее вижу во всех процессах на своей семерке. Возможно у вас баг в парсинге PEB-ldr списка.

В PEB'е вроде несколько списков. В InitOrder'е могут запросто отсутствовать некоторые длл-ки. Думаю самое правильное — лопатить MemoryOrder.
Как много веселых ребят, и все делают велосипед...
Re[4]: Сравнение списка модулей из PEB и VAD
От: -prus-  
Дата: 04.08.14 15:51
Оценка:
Здравствуйте, ononim, Вы писали:

O>>>В-третьих конкретно по syswow64\uxtheme.dll — я ее вижу во всех процессах на своей семерке. Возможно у вас баг в парсинге PEB-ldr списка.

O>В PEB'е вроде несколько списков. В InitOrder'е могут запросто отсутствовать некоторые длл-ки. Думаю самое правильное — лопатить MemoryOrder.

В MemoryOrder вроде короткие имена модулей. Хотелось бы полный путь. Но раз это более надежный способ, то буду лопатить MemoryOrder.
Спасиб еще раз.
С уважением,
Евгений
Re[5]: Сравнение списка модулей из PEB и VAD
От: ononim  
Дата: 04.08.14 16:10
Оценка:
O>>>>В-третьих конкретно по syswow64\uxtheme.dll — я ее вижу во всех процессах на своей семерке. Возможно у вас баг в парсинге PEB-ldr списка.
O>>В PEB'е вроде несколько списков. В InitOrder'е могут запросто отсутствовать некоторые длл-ки. Думаю самое правильное — лопатить MemoryOrder.
P>В MemoryOrder вроде короткие имена модулей. Хотелось бы полный путь. Но раз это более надежный способ, то буду лопатить MemoryOrder.
P>Спасиб еще раз.
MemoryOrder и InitOrder строятся на одних и тех же LDR_DATA_TABLE_ENTRY'ов. Так что быть такого не может чтоб для одной и той же длл в одном путь коротким, а в другом — длинный.
Как много веселых ребят, и все делают велосипед...
Re[6]: Сравнение списка модулей из PEB и VAD
От: -prus-  
Дата: 05.08.14 08:21
Оценка:
Здравствуйте, ononim, Вы писали:

O>MemoryOrder и InitOrder строятся на одних и тех же LDR_DATA_TABLE_ENTRY'ов. Так что быть такого не может чтоб для одной и той же длл в одном путь коротким, а в другом — длинный.


Я как раз через MemoryOrder делал... Ща попробовал указать InitOrder и 32хбитный PEB у меня получился такой (ОС VistaSP2 x64):

dseo13b.exe

--PEB64--
DLL — C:\css\dseo13b.exe
DLL — C:\Windows\system32\ntdll.dll
DLL — C:\Windows\system32\wow64.dll
DLL — C:\Windows\system32\wow64win.dll
DLL — C:\Windows\system32\wow64cpu.dll
--PEB32--
DLL — dseo13b.exe
DLL — ntdll.dll
DLL — kernel32.dll
DLL — USER32.dll
DLL — GDI32.dll
DLL — ADVAPI32.dll
DLL — RPCRT4.dll
DLL — Secur32.dll
DLL — ShimEng.dll


При этом на WinXPx86 все норм...
С уважением,
Евгений
Re[7]: Сравнение списка модулей из PEB и VAD
От: -prus-  
Дата: 05.08.14 08:47
Оценка:
Здравствуйте, -prus-, Вы писали:

P>При этом на WinXPx86 все норм...


Возможно я где-то напорол со структурами и вместо FullDllName смещаюсь к BaseDllName в LDR_DATA_TABLE_ENTRY...
С уважением,
Евгений
Re[7]: Сравнение списка модулей из PEB и VAD
От: ononim  
Дата: 05.08.14 10:46
Оценка:
O>>MemoryOrder и InitOrder строятся на одних и тех же LDR_DATA_TABLE_ENTRY'ов. Так что быть такого не может чтоб для одной и той же длл в одном путь коротким, а в другом — длинный.
P>Я как раз через MemoryOrder делал... Ща попробовал указать InitOrder и 32хбитный PEB у меня получился такой (ОС VistaSP2 x64):

P>

P> dseo13b.exe

P>--PEB64--
P> DLL — C:\css\dseo13b.exe
P> DLL — C:\Windows\system32\ntdll.dll
P> DLL — C:\Windows\system32\wow64.dll
P> DLL — C:\Windows\system32\wow64win.dll
P> DLL — C:\Windows\system32\wow64cpu.dll
P>--PEB32--
P> DLL — dseo13b.exe
P> DLL — ntdll.dll
P> DLL — kernel32.dll
P> DLL — USER32.dll
P> DLL — GDI32.dll
P> DLL — ADVAPI32.dll
P> DLL — RPCRT4.dll
P> DLL — Secur32.dll
P> DLL — ShimEng.dll


P>При этом на WinXPx86 все норм...

Ну да, явно попадаете на BaseDllName вместо FullDllName здесь:
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;
     WORD LoadCount;
     WORD TlsIndex;
     union
     {
          LIST_ENTRY HashLinks;
          struct
          {
               PVOID SectionPointer;
               ULONG CheckSum;
          };
     };
     union
     {
          ULONG TimeDateStamp;
          PVOID LoadedImports;
     };
     _ACTIVATION_CONTEXT * EntryPointActivationContext;
     PVOID PatchInformation;
     LIST_ENTRY ForwarderLinks;
     LIST_ENTRY ServiceTagLinks;
     LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

(c)
Смещение на 2*sizeof(PVOID) намекает на то что вы забыли правильно подкорректировать смещение между LIST_ENTRY и соответствующим LDR_DATA_TABLE_ENTRY, меняя код с InInitializationOrderLinks на InMemoryOrderLinks. Либо проблемы с выравниванием.
Как много веселых ребят, и все делают велосипед...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.