思路来自国外一个EFI引导制作工具
使用NtQuerySystemInformation 功能号为90 SystemLoadImage | 0x40
返回的结构体未知 有知道的朋友可以告诉下我
我通过IDA得到一个结构体
typedef struct
{
int v1;
int v2;
int v3;
int v4;
int v67;
DWORD nSize;
int v62;
}SYSTEMINFORMATION,*PSYSTEMINFOMATION;
查询完 如果v67 等于1 是BIOS 等于2是EFI
代码:
#include <Windows.h>
#include <stdio.h>
#include <process.h>
typedef LONG NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation, // 0 Y N
SystemProcessorInformation, // 1 Y N
SystemPerformanceInformation, // 2 Y N
SystemTimeOfDayInformation, // 3 Y N
SystemNotImplemented1, // 4 Y N
SystemProcessesAndThreadsInformation, // 5 Y N
SystemCallCounts, // 6 Y N
SystemConfigurationInformation, // 7 Y N
SystemProcessorTimes, // 8 Y N
SystemGlobalFlag, // 9 Y Y
SystemNotImplemented2, // 10 Y N
SystemModuleInformation, // 11 Y N
SystemLockInformation, // 12 Y N
SystemNotImplemented3, // 13 Y N
SystemNotImplemented4, // 14 Y N
SystemNotImplemented5, // 15 Y N
SystemHandleInformation, // 16 Y N
SystemObjectInformation, // 17 Y N
SystemPagefileInformation, // 18 Y N
SystemInstructionEmulationCounts, // 19 Y N
SystemInvalidInfoClass1, // 20
SystemCacheInformation, // 21 Y Y
SystemPoolTagInformation, // 22 Y N
SystemProcessorStatistics, // 23 Y N
SystemDpcInformation, // 24 Y Y
SystemNotImplemented6, // 25 Y N
SystemLoadImage, // 26 N Y
SystemUnloadImage, // 27 N Y
SystemTimeAdjustment, // 28 Y Y
SystemNotImplemented7, // 29 Y N
SystemNotImplemented8, // 30 Y N
SystemNotImplemented9, // 31 Y N
SystemCrashDumpInformation, // 32 Y N
SystemExceptionInformation, // 33 Y N
SystemCrashDumpStateInformation, // 34 Y Y/N
SystemKernelDebuggerInformation, // 35 Y N
SystemContextSwitchInformation, // 36 Y N
SystemRegistryQuotaInformation, // 37 Y Y
SystemLoadAndCallImage, // 38 N Y
SystemPrioritySeparation, // 39 N Y
SystemNotImplemented10, // 40 Y N
SystemNotImplemented11, // 41 Y N
SystemInvalidInfoClass2, // 42
SystemInvalidInfoClass3, // 43
SystemTimeZoneInformation, // 44 Y N
SystemLookasideInformation, // 45 Y N
SystemSetTimeSlipEvent, // 46 N Y
SystemCreateSession, // 47 N Y
SystemDeleteSession, // 48 N Y
SystemInvalidInfoClass4, // 49
SystemRangeStartInformation, // 50 Y N
SystemVerifierInformation, // 51 Y Y
SystemAddVerifier, // 52 N Y
SystemSessionProcessesInformation // 53 Y N
} SYSTEM_INFORMATION_CLASS;
typedef struct
{
int v1;
int v2;
int v3;
int v4;
int v67;
DWORD nSize;
int v62;
}SYSTEMINFORMATION,*PSYSTEMINFOMATION;
typedef NTSTATUS
(NTAPI *ZWQUERYSYSTEMINFORMATION)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
//g_
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;
#define ERROR 0
#define EFI 1
#define NO_EFI 2
int GetEFIState()
{
ULONG ulSize;
ULONG* pSystemInfor;
NTSTATUS ntStatus;
HMODULE hHanlde;
PSYSTEMINFOMATION lpSystem;
ulSize = 0x14;
pSystemInfor = NULL;
ZwQuerySystemInformation = NULL;
//由于ZwQueryObject和ZwQuerySystemInformation是未导出的函数,需要动态加载Ntdll,dll,然后通过函数GetProcAddress
//得到它们的函数地址,由于这个dll一般的进程都会在创建的时候加载,所以省略加载,直接获取其模块地址
hHanlde = GetModuleHandle(L"ntdll.dll");
if (NULL == hHanlde)
{
//加载Ntdll.dll失败
printf("hANDLE IS NULL\n");
return ERROR;
}
//获取ZwQuerySystemInformation函数地址
ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hHanlde, "NtQuerySystemInformation");
if (NULL == ZwQuerySystemInformation)
{
//获取ZwQuerySystemInformation函数地址失败
printf("ZwQuerySystemInformation is null!\n");
return ERROR;
}
//获取系统所有句柄信息
do
{
//申请内存
pSystemInfor = (ULONG*)malloc(ulSize);
if (NULL == pSystemInfor)
{
return ERROR;
}
ntStatus = ZwQuerySystemInformation((SYSTEM_INFORMATION_CLASS)(SystemLoadImage|0x40), pSystemInfor, ulSize, NULL);
if (!NT_SUCCESS(ntStatus))
{
//空间不足继续申请。
free(pSystemInfor);
ulSize = ulSize * 2;
//为防止ZwQuerySystemInformation一直失败,程序陷入死循环,当申请的空间超过64M时则返回失败
if (ulSize > 0x4000000)
{
printf("buff is long!\n");
return ERROR;
}
}
} while (!NT_SUCCESS(ntStatus));
//转换数据结构类型
lpSystem = (PSYSTEMINFOMATION)pSystemInfor;
if (NULL == lpSystem)
{
return ERROR;
}
int ret = ERROR;
if (lpSystem->v67 != 2)
{
//printf("not efi!\n");
ret = NO_EFI;
}
else
{
//printf("efi!\n");
ret = EFI;
}
//释放申请的空间
free(lpSystem);
return ret;
}
void main()
{
int ret = GetEFIState();
if (ret != ERROR)
{
if (ret == 1)
printf("efi!\n");
else
printf("no efi!\n");
}
else
{
printf("error!\n");
}
getchar();
}