判断当前启动模式是EFI还是BIOS

思路来自国外一个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();
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值