【问题标题】:Read a UEFI variable into a buffer with ctypes, WinDLL and WinAPI, using GetFirmwareEnvironmentVariableW使用 GetFirmwareEnvironmentVariableW 将 UEFI 变量读入具有 ctypes、WinDLL 和 WinAPI 的缓冲区
【发布时间】:2023-03-28 09:55:01
【问题描述】:

我想使用 Python 读取 BootOrder UEFI 变量,方法是使用 kernel32.dll 函数 GetFirmwareEnvironmentVariableW。这失败了:

from ctypes import *

def errcheck(result, func, args):
    print(result)
    print(WinError(get_last_error()))

kernel32 = WinDLL('kernel32', use_last_error=True)
GetFirmwareEnvironmentVariable = kernel32.GetFirmwareEnvironmentVariableW
GetFirmwareEnvironmentVariable.restype = c_int
GetFirmwareEnvironmentVariable.argtypes = [c_wchar_p, c_wchar_p, c_void_p, c_int]
GetFirmwareEnvironmentVariable.errcheck = errcheck
buf = "                "
GetFirmwareEnvironmentVariable("BootOrder", "{8BE4DF61-93CA-11D2-AA0D-00E098032B8C}", buf, 16)
print(buf)

与:

[WinError 1] 函数错误。

我可以想象用" " 初始化buf 不是正确的做法。

如何使用ctypes 正确地将缓冲区指针传递给 WinAPI 函数?

以及如何用 Python 读取这个 UEFI 变量?

【问题讨论】:

  • create_string_buffer 似乎可以满足您的需求。像buf = cast(create_string_buffer(BUFFER_SIZE), c_void_p)) 这样的东西。 如果 那是错误的原因。经过一些快速研究后,这个错误似乎很笼统,涵盖了很多东西。
  • @Carcigenicate 你的意思是像buf = cast(create_string_buffer(1024), c_void_p) GetFirmwareEnvironmentVariable("BootOrder", "{8BE4DF61-93CA-11D2-AA0D-00E098032B8C}", buf, 1024) 这样的东西吗?那么如何阅读内容呢? print(buf) 只显示指针。您是否实现了在您的计算机上读取 UEFI 变量内容?
  • 我在尝试运行时遇到权限错误,因此无法获取有效数据。如果您在填充后将buf 转换回c_char_p,您应该能够使用buf.valuebuf.raw 来获取bytes 数据对象。
  • SE_SYSTEM_ENVIRONMENT_NAME 权限(通常)授予管理员,但默认情况下未启用。见docs.microsoft.com/en-us/windows/win32/secauthz/…。您还有更多工作要做以将 that 移植到 Python ????
  • @Carcigenicate 我找到了解决方案并发布了答案。再次感谢您的帮助。 PS:这里已经在使用了 :) github.com/josephernest/rebootnow

标签: python winapi ctypes uefi kernel32


【解决方案1】:

正如@Carcigenicate 在 cmets 中提到的,有两个部分:

  • 使用缓冲区(使用create_string_buffer 创建)将输出作为buf.raw 中的字节获取

    from ctypes import *
    kernel32 = ctypes.WinDLL('kernel32')
    GetFirmwareEnvironmentVariable = kernel32.GetFirmwareEnvironmentVariableW
    buf = ctypes.create_string_buffer(128)
    length = GetFirmwareEnvironmentVariable("BootOrder", "{8BE4DF61-93CA-11D2-AA0D-00E098032B8C}", buf, 128)
    print(buf.raw)
    
  • 获得正确的权限以获取 UEFI 变量

    import win32api, win32security
    htoken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY)
    newPrivileges = [(win32security.LookupPrivilegeValue(None, win32security.SE_SYSTEM_ENVIRONMENT_NAME), win32security.SE_PRIVILEGE_ENABLED)]
    win32security.AdjustTokenPrivileges(htoken, 0, newPrivileges)
    

【讨论】:

    猜你喜欢
    • 2021-11-21
    • 2015-07-31
    • 2019-03-16
    • 2016-03-06
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多