清淡小女子 发表于 2017-6-1 12:17:13

判断当前启动模式是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();
}


   





页: [1]
查看完整版本: 判断当前启动模式是EFI还是BIOS