mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 11:13:57 +00:00
Support extended variant of ProcessBasicInformation (#638)
This PR fixes getting `ProcessBasicInformation`. When emulating a program that uses [ProcessPrng](https://learn.microsoft.com/ru-ru/windows/win32/seccng/processprng) function from `BCryptPrimitives.dll`, an error occurs: ``` Unimplemented syscall: NtCallbackReturn - 0x5 (raw: 0x8000005) ``` `BCryptPrimitives.dll` checks whether the running process is a [secure process](https://learn.microsoft.com/en-us/windows/win32/procthread/isolated-user-mode--ium--processes). If it is, then `iumbase.dll` is loaded. `iumbase.dll` depends on `iumdll.dll` that's like an `ntdll.dll` for secure processes, and it has its own subset of system calls with different syscall numbers. So, `0x8000005` is not `NtCallbackReturn`, it is `IumCrypto`. But why does `BCryptPrimitives.dll` get into trouble? It calls `NtQueryInformationProcess` with class `ProcessBasicInformation` and `ProcessInformationLength == 0x40`. It turned out that it is a special case and it's even documented in the aforemantioned link, look for the definition of the function `IsSecureProcess`.
This commit is contained in:
@@ -1640,6 +1640,29 @@ typedef struct _PROCESS_BASIC_INFORMATION64
|
||||
EMULATOR_CAST(std::uint64_t, HANDLE) InheritedFromUniqueProcessId;
|
||||
} PROCESS_BASIC_INFORMATION64, *PPROCESS_BASIC_INFORMATION64;
|
||||
|
||||
typedef struct _PROCESS_EXTENDED_BASIC_INFORMATION
|
||||
{
|
||||
EMULATOR_CAST(std::uint64_t, SIZE_T) Size; // Ignored as input, written with structure size on output
|
||||
PROCESS_BASIC_INFORMATION64 BasicInfo;
|
||||
union
|
||||
{
|
||||
ULONG Flags;
|
||||
struct
|
||||
{
|
||||
ULONG IsProtectedProcess : 1;
|
||||
ULONG IsWow64Process : 1;
|
||||
ULONG IsProcessDeleting : 1;
|
||||
ULONG IsCrossSessionCreate : 1;
|
||||
ULONG IsFrozen : 1;
|
||||
ULONG IsBackground : 1;
|
||||
ULONG IsStronglyNamed : 1;
|
||||
ULONG IsSecureProcess : 1;
|
||||
ULONG IsSubsystemProcess : 1;
|
||||
ULONG SpareBits : 23;
|
||||
};
|
||||
};
|
||||
} PROCESS_EXTENDED_BASIC_INFORMATION, *PPROCESS_EXTENDED_BASIC_INFORMATION;
|
||||
|
||||
typedef struct _KERNEL_USER_TIMES
|
||||
{
|
||||
LARGE_INTEGER CreateTime;
|
||||
|
||||
@@ -93,12 +93,28 @@ namespace syscalls
|
||||
c.PriorityClass = 32; // Normal
|
||||
});
|
||||
|
||||
case ProcessBasicInformation:
|
||||
return handle_query<PROCESS_BASIC_INFORMATION64>(c.emu, process_information, process_information_length, return_length,
|
||||
[&](PROCESS_BASIC_INFORMATION64& basic_info) {
|
||||
basic_info.PebBaseAddress = c.proc.peb64.value();
|
||||
basic_info.UniqueProcessId = 1;
|
||||
});
|
||||
case ProcessBasicInformation: {
|
||||
const auto init_basic_info = [&](PROCESS_BASIC_INFORMATION64& basic_info) {
|
||||
basic_info.PebBaseAddress = c.proc.peb64.value();
|
||||
basic_info.UniqueProcessId = 1;
|
||||
};
|
||||
|
||||
switch (process_information_length)
|
||||
{
|
||||
case sizeof(PROCESS_BASIC_INFORMATION64):
|
||||
return handle_query<PROCESS_BASIC_INFORMATION64>(c.emu, process_information, process_information_length, return_length,
|
||||
init_basic_info);
|
||||
case sizeof(PROCESS_EXTENDED_BASIC_INFORMATION):
|
||||
return handle_query<PROCESS_EXTENDED_BASIC_INFORMATION>(
|
||||
c.emu, process_information, process_information_length, return_length,
|
||||
[&](PROCESS_EXTENDED_BASIC_INFORMATION& ext_basic_info) {
|
||||
ext_basic_info.Size = sizeof(PROCESS_EXTENDED_BASIC_INFORMATION);
|
||||
init_basic_info(ext_basic_info.BasicInfo);
|
||||
});
|
||||
default:
|
||||
return STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
case ProcessImageInformation:
|
||||
return handle_query<SECTION_IMAGE_INFORMATION<EmulatorTraits<Emu64>>>(
|
||||
|
||||
Reference in New Issue
Block a user