I just reversed some of the WOW64 Ntdll on Windows 8.1 and it seems, your code has 2 flaws:
In RTL_VERIFIER_PROVIDER_DESCRIPTOR, ProviderDlls must be set as an array of RTL_VERIFIER_DLL_DESCRIPTOR structures for each Dll you target PLUS an empty entry at the end to mark the array end.
The same thing applies to RTL_VERIFIER_DLL_DESCRIPTOR and DllThunks. There also the last entry in the array needs to be an empty structure:
From ntdll:
In RTL_VERIFIER_PROVIDER_DESCRIPTOR, ProviderDlls must be set as an array of RTL_VERIFIER_DLL_DESCRIPTOR structures for each Dll you target PLUS an empty entry at the end to mark the array end.
The same thing applies to RTL_VERIFIER_DLL_DESCRIPTOR and DllThunks. There also the last entry in the array needs to be an empty structure:
From ntdll:
Code: Select all
int __thiscall AVrfpDllLoadNotificationInternal(void *this)
{
int v1; // ebx@1
int result; // eax@2
LIST_ENTRY *v3; // edi@3
RTL_VERIFIER_DLL_DESCRIPTOR *v4; // eax@4
int v5; // edi@5
RTL_VERIFIER_DLL_DESCRIPTOR *v6; // esi@5
RTL_VERIFIER_DLL_DESCRIPTOR *v7; // ecx@5
char v8; // al@10
RTL_VERIFIER_DLL_DESCRIPTOR *v9; // [sp+Ch] [bp-Ch]@4
void *v10; // [sp+14h] [bp-4h]@4
v1 = (int)this;
if ( AVrfpEnabled )
{
v3 = AVrfpVerifierProvidersList.Flink;
while ( v3 != &AVrfpVerifierProvidersList )
{
v4 = (RTL_VERIFIER_DLL_DESCRIPTOR *)v3[2].Blink;
v3 = v3->Flink;
v10 = v3;
v9 = v4;
if ( v4->DllName )
{
v5 = 0;
v6 = v4;
v7 = v4;
do
{
if ( !(v6->DllFlags & 1) )
{
if ( _wcsicmp(*(const wchar_t **)(v1 + 48), v6->DllName) )
{
v7 = v9;
}
else
{
if ( AVrfpDebug & 4 )
DbgPrint(
"AVRF: pid 0x%X: found dll descriptor for `%ws' with verified exports \n",
NtCurrentTeb()->ClientId.UniqueProcess,
*(_DWORD *)(v1 + 48));
v8 = AVrfpDetectVerifiedExports(v6, v1);
v7 = v9;
if ( v8 )
v6->DllFlags |= 1u;
}
}
++v5;
v6 = &v7[v5];
}
while ( v6->DllName );
v3 = (LIST_ENTRY *)v10;
}
}
result = AVrfpSnapDllImports(v1);
}
else
{
result = 0;
}
return result;
}
char __fastcall AVrfpDetectVerifiedExports(RTL_VERIFIER_DLL_DESCRIPTOR *a1, int a2)
{
RTL_VERIFIER_THUNK_DESCRIPTOR *pCurrentThunk; // edi@1
char v3; // bl@1
RTL_VERIFIER_THUNK_DESCRIPTOR *pNextThunk; // esi@2
int EntryIndex; // esi@10
STRING DestinationString; // [sp+Ch] [bp-14h]@4
void *v8; // [sp+14h] [bp-Ch]@4
int EntryIndex_; // [sp+18h] [bp-8h]@1
int v10; // [sp+1Ch] [bp-4h]@1
void *retaddr; // [sp+24h] [bp+4h]@4
EntryIndex_ = 0;
pCurrentThunk = a1->DllThunks;
v3 = 0;
v10 = a2;
if ( pCurrentThunk->ThunkName )
{
pNextThunk = pCurrentThunk;
do
{
if ( !pNextThunk->ThunkOldAddress )
{
RtlInitAnsiString(&DestinationString, pNextThunk->ThunkName);
if ( LdrGetProcedureAddressForCaller(*(_DWORD *)(v10 + 24), &DestinationString, 0, &v8, 1, retaddr) >= 0 )
{
pNextThunk->ThunkOldAddress = v8;
if ( AVrfpDebug & 2 )
DbgPrint("AVRF: (%ws) %s export found. \n", *(_DWORD *)(v10 + 48), pNextThunk->ThunkName);
v3 = 1;
}
else if ( AVrfpDebug & 2 )
{
DbgPrint("AVRF: warning: did not find `%s' export in %ws . \n", pNextThunk->ThunkName, *(_DWORD *)(v10 + 48));
}
}
EntryIndex = EntryIndex_ + 1;
EntryIndex_ = EntryIndex;
pNextThunk = &pCurrentThunk[EntryIndex];
}
while ( pNextThunk->ThunkName ); //Check if ThunkName in next entry != NULL
}
return v3;
}