Windows предоставляет несколько возможностей для перехвата ф-ций, для целей верификации, отладки или логгирования, это технология shim, hot-patch, application verifier(чтото наверняка еще забыл), про application verifier сегодняшняя заметка. Про него уже ктото писал, но мне было интересно разобраться самому. Что есть application verifier описано в http://msdn.microsoft.com/en-us/library/ms220948%28v=vs.90%29.aspx.
Если совсем кратко, то application verifier это технология поддерживаемая нативным лоадером PE файлов, позволяющая грузиться перед kernel32.dll и до обработки лоадером импортов и TLS.
Чтобы зарегистрировать дллку провайдера нужно прописаться в реестр следующим образом:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\calc.exe]
"GlobalFlag"="0x02000100"
"VerifierDebug"="0xffffffff"
"VerifierDlls"="test.dll"
test.dll нужно запихнуть в windows/system32.
Лоадер при запуске calc.exe будет подгружать все дллки провайдеров, которые для него описаны, а их entries помещать в список AVrfpVerifierProvidersList. Первая длл в этом списке всегда будет "verifier.dll". Далее, лоадер будет обходить этот список и загружать все длл в нем, вызывая их точки входа с reason равной DLL_PROCESS_VERIFIER. Если открыть "verifier.dll", то можно будет увидеть:
BOOL __stdcall DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID context)
{
...
if ( fdwReason == 4 ) // DLL_PROCESS_VERIFIER
{
if ( context )
*(_DWORD *)context = &dword_5B1F6258;
}
...
}
.data:5B1F6258 dd 1Ch // id ( на хп и вин7 id различаются )
.data:5B1F625C dd offset off_5B1F6208 // ссылка на другую структуру ( см. ниже )
.data:5B1F6260 dd 0
.data:5B1F6264 dd 0
.data:5B1F6208 off_5B1F6208 dd offset aNtdll_dll ; "ntdll.dll" // имя длл ( капитан очевидность приветствует вас :) )
.data:5B1F620C dd 0
.data:5B1F6210 dd 0
.data:5B1F6214 dd offset off_5B1F6008 // ссылка на еще одну структуру с ф-циями ( см. ниже )
.data:5B1F6008 off_5B1F6008 dd offset aNtallocatevirt ; "NtAllocateVirtualMemory" // имя ф-ции
.data:5B1F600C dd 0
.data:5B1F6010 dd offset sub_5B1F2366 // ф-ция которой лоадер заместит NtAllocateVirtualMemory
.data:5B1F6014 dd offset aNtfreevirtualm ; "NtFreeVirtualMemory"
.data:5B1F6018 dd 0
.data:5B1F601C dd offset sub_5B1F23F8
Таким образом, в точке входа дллки вашего провайдера нужно создать эти структуры и передать их лоадеру, это даст возможность подмены ф-ций своими. Таким образом, если shim дает возможность перехвата ф-ций легальным способом на уровне win api, то application verifier, поддерживаемый загрузчиком, дает возможность перехватывать ф-ции на уровне native.
Если совсем кратко, то application verifier это технология поддерживаемая нативным лоадером PE файлов, позволяющая грузиться перед kernel32.dll и до обработки лоадером импортов и TLS.
Чтобы зарегистрировать дллку провайдера нужно прописаться в реестр следующим образом:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\calc.exe]
"GlobalFlag"="0x02000100"
"VerifierDebug"="0xffffffff"
"VerifierDlls"="test.dll"
test.dll нужно запихнуть в windows/system32.
Лоадер при запуске calc.exe будет подгружать все дллки провайдеров, которые для него описаны, а их entries помещать в список AVrfpVerifierProvidersList. Первая длл в этом списке всегда будет "verifier.dll". Далее, лоадер будет обходить этот список и загружать все длл в нем, вызывая их точки входа с reason равной DLL_PROCESS_VERIFIER. Если открыть "verifier.dll", то можно будет увидеть:
BOOL __stdcall DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID context)
{
...
if ( fdwReason == 4 ) // DLL_PROCESS_VERIFIER
{
if ( context )
*(_DWORD *)context = &dword_5B1F6258;
}
...
}
.data:5B1F6258 dd 1Ch // id ( на хп и вин7 id различаются )
.data:5B1F625C dd offset off_5B1F6208 // ссылка на другую структуру ( см. ниже )
.data:5B1F6260 dd 0
.data:5B1F6264 dd 0
.data:5B1F6208 off_5B1F6208 dd offset aNtdll_dll ; "ntdll.dll" // имя длл ( капитан очевидность приветствует вас :) )
.data:5B1F620C dd 0
.data:5B1F6210 dd 0
.data:5B1F6214 dd offset off_5B1F6008 // ссылка на еще одну структуру с ф-циями ( см. ниже )
.data:5B1F6008 off_5B1F6008 dd offset aNtallocatevirt ; "NtAllocateVirtualMemory" // имя ф-ции
.data:5B1F600C dd 0
.data:5B1F6010 dd offset sub_5B1F2366 // ф-ция которой лоадер заместит NtAllocateVirtualMemory
.data:5B1F6014 dd offset aNtfreevirtualm ; "NtFreeVirtualMemory"
.data:5B1F6018 dd 0
.data:5B1F601C dd offset sub_5B1F23F8
Таким образом, в точке входа дллки вашего провайдера нужно создать эти структуры и передать их лоадеру, это даст возможность подмены ф-ций своими. Таким образом, если shim дает возможность перехвата ф-ций легальным способом на уровне win api, то application verifier, поддерживаемый загрузчиком, дает возможность перехватывать ф-ции на уровне native.
Т.е. по умолчанию загружается verifier.dll?
ОтветитьУдалитьВместо неё можно указать любую другую библиотеку, например test.dll?
verifier.dll это длл верифаера, она помещается в список длл и загружается автоматически лоадером ( имя захардкожено ). Все остальные зарегистрированные дллки будут вызваны после verifier.dll.
ОтветитьУдалить