I'm coding a UEFI Runtime Driver for Windows which hooks gRT->SetVariable(...)
Hooking seems to work fine but whenever I startup a user-mode application and call SetFirmwareEnvironmentVariable(...)
it reults in a Bluescreen saying UNEXCEPTED_KERNEL_MODE_TRAP
.
I cannot find any solution for this. Here are a few things iam aware of:
- I'm raising TPL
- I recalculate and set CRC32
- On
SetVirtualAddressMap(...)
i convert all my pointer
Google didn't help at all. So i really wonder what causes this Bluescreen and how i may proceed to resolve this issue.
What am i missing? Am i doing something wrong?
Here is my code:
ExchangePointerInServiceTable((VOID**)&gST->RuntimeServices->SetVariable,
(VOID*)HookedSetVariable,
(VOID**)&gOriginalSetVariable);
static
EFI_STATUS
ExchangePointerInServiceTable(
IN OUT VOID** AddressToUpdate,
IN VOID* NewPointer,
OUT VOID** OriginalPointer OPTIONAL
)
{
EFI_STATUS status;
EFI_TPL tpl;
ASSERT(*AddressToUpdate != NewPointer);
tpl = gBS->RaiseTPL(TPL_HIGH_LEVEL);
if (OriginalPointer != NULL)
{
*OriginalPointer = *AddressToUpdate;
}
*AddressToUpdate = NewPointer;
gST->Hdr.CRC32 = 0;
status = gBS->CalculateCrc32(&gST->Hdr, gST->Hdr.HeaderSize, &gST->Hdr.CRC32);
ASSERT_EFI_ERROR(status);
gBS->RestoreTPL(tpl);
return status;
}
EFI_STATUS
EFIAPI
HookedSetVariable(
IN CHAR16* VariableName,
IN EFI_GUID* VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID* Data
) {
if (StrCmp(VariableName, gStrComVarName) == 0) {
COMMUNICATION_PROTOCOL * comVarPtr = (COMMUNICATION_PROTOCOL*)Data;
switch (comVarPtr->i8OperationId) {
case COMMUNICATION_PROTOCOL_OPERATION_PING:
comVarPtr->i8OperationId = COMMUNICATION_PROTOCOL_PONG;
}
CopyMem(Data, comVarPtr, DataSize);
}
return gOriginalSetVariable(VariableName, VendorGuid, Attributes, DataSize, Data);
}
Edit: While in UEFI, other UEFI Applications correctly call the hooked SetVariable(...)
without any further problems.
This may bring it down to the problem only existing after VirtualAddressSpace has been created from the OS.