Python 从传递给DeviceIoControl()的句柄中检索设备名称
我正在连接WindowsAPI(使用Python设备)。 是否有方法检索作为此API的第一个参数传递的设备句柄对应的设备名称Python 从传递给DeviceIoControl()的句柄中检索设备名称,python,windows,winapi,driver,device-driver,Python,Windows,Winapi,Driver,Device Driver,我正在连接WindowsAPI(使用Python设备)。 是否有方法检索作为此API的第一个参数传递的设备句柄对应的设备名称 BOOL WINAPI DeviceIoControl( _In_ HANDLE hDevice, <---------- This one _In_ DWORD dwIoControlCode, _In_opt_ LPVOID lpInBuffer, _In_
BOOL WINAPI DeviceIoControl(
_In_ HANDLE hDevice, <---------- This one
_In_ DWORD dwIoControlCode,
_In_opt_ LPVOID lpInBuffer,
_In_ DWORD nInBufferSize,
_Out_opt_ LPVOID lpOutBuffer,
_In_ DWORD nOutBufferSize,
_Out_opt_ LPDWORD lpBytesReturned,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);
你知道吗?你如何调用这些函数?您试图获取关于哪个设备的信息?你是真的在挂接这个函数,还是只是想调用这个函数?(Hook的意思非常具体,一般来说,你不能从用户模式中钩住驱动程序。)当你说“我无法让它工作”时,你能告诉我们它是如何失败的吗?这是不是给了你一个错误?返回意料之外的东西?还有别的吗?@theB:你不能从用户模式钩住驱动程序,但你可以钩住DeviceIoControl()API调用,所以我认为假设OP的意思与他说的完全一致是相当安全的。另一方面,更明智的做法是先尝试获取自己打开的句柄的设备路径,然后再从钩子内部尝试。@HarryJohnston-我是基于可用的资源,例如,回想起来,它忽略了一些不太受支持的方法。不过,对于全局拦截低级(ish)系统调用,并通过python解释器对其进行过滤,我仍然会保持警惕。@theB:这个问题混淆了两种完全不同的钩子。然而,API挂钩并没有得到正式支持(尽管微软确实出售软件来实现),这绝对是真的,而且它肯定不是完全安全的,在Python这样的解释性语言环境中尝试实现API挂钩对我来说就像一场等待发生的噩梦。我只是指出它确实存在。:-)默认的
restype
是c_int
(即int
),这很好,因为NTSTATUS
是有符号的(警告和错误是负值)。使常数签名,例如NTSTATUS=c_long代码>STATUS\u INFO\u LENGTH\u MISMATCH=NTSTATUS(0xC0000004).value
。如何调用这些函数?您试图获取关于哪个设备的信息?你是真的在挂接这个函数,还是只是想调用这个函数?(Hook的意思非常具体,一般来说,你不能从用户模式中钩住驱动程序。)当你说“我无法让它工作”时,你能告诉我们它是如何失败的吗?这是不是给了你一个错误?返回意料之外的东西?还有别的吗?@theB:你不能从用户模式钩住驱动程序,但你可以钩住DeviceIoControl()API调用,所以我认为假设OP的意思与他说的完全一致是相当安全的。另一方面,更明智的做法是先尝试获取自己打开的句柄的设备路径,然后再从钩子内部尝试。@HarryJohnston-我是基于可用的资源,例如,回想起来,它忽略了一些不太受支持的方法。不过,对于全局拦截低级(ish)系统调用,并通过python解释器对其进行过滤,我仍然会保持警惕。@theB:这个问题混淆了两种完全不同的钩子。然而,API挂钩并没有得到正式支持(尽管微软确实出售软件来实现),这绝对是真的,而且它肯定不是完全安全的,在Python这样的解释性语言环境中尝试实现API挂钩对我来说就像一场等待发生的噩梦。我只是指出它确实存在。:-)默认的restype
是c_int
(即int
),这很好,因为NTSTATUS
是有符号的(警告和错误是负值)。使常数签名,例如NTSTATUS=c_long代码>状态信息长度不匹配=NTSTATUS(0xC0000004)。值
。
class LSA_UNICODE_STRING(Structure):
"""Represent the LSA_UNICODE_STRING on ntdll."""
_fields_ = [
("Length", USHORT),
("MaximumLength", USHORT),
("Buffer", LPWSTR),
]
class PUBLIC_OBJECT_TYPE_INFORMATION(Structure):
"""Represent the PUBLIC_OBJECT_TYPE_INFORMATION on ntdll."""
_fields_ = [
("Name", LSA_UNICODE_STRING),
("Reserved", ULONG * 22),
]
class OBJECT_NAME_INFORMATION (Structure):
"""Represent the OBJECT_NAME_INFORMATION on ntdll."""
_fields_ = [
("Name", LSA_UNICODE_STRING),
]
STATUS_INFO_LENGTH_MISMATCH = 0xC0000004
STATUS_BUFFER_OVERFLOW = 0x80000005L
STATUS_INVALID_HANDLE = 0xC0000008L
STATUS_BUFFER_TOO_SMALL = 0xC0000023L
STATUS_SUCCESS = 0
def GetProcessHandle(pid, handle):
"""Get a handle for the process with the given pid"""
try:
hProcess = OpenProcess(win32con.PROCESS_DUP_HANDLE, 0, pid)
dupHandle = DuplicateHandle(hProcess, handle, GetCurrentProcess(), 0, 0, win32con.DUPLICATE_SAME_ACCESS)
return dupHandle
except ApiError,(errno, errctx, errmsg):
if errno in (
winerror.ERROR_ACCESS_DENIED,
winerror.ERROR_INVALID_PARAMETER,
winerror.ERROR_INVALID_HANDLE,
winerror.ERROR_NOT_SUPPORTED
):
return None
else:
raise
def GetTypeInfo(handle):
""" Get the handle type information """
public_object_type_information = PUBLIC_OBJECT_TYPE_INFORMATION()
size = DWORD(sizeof(public_object_type_information))
NtQueryObject = windll.ntdll.NtQueryObject
while True:
result = NtQueryObject(handle, 2, byref(public_object_type_information), size, None)
print result
if result == STATUS_SUCCESS:
return public_object_type_information.Name.Buffer
elif result == STATUS_INFO_LENGTH_MISMATCH:
size = DWORD(size.value * 4)
resize(public_object_type_information, size.value)
elif result == STATUS_INVALID_HANDLE:
return "[invalid handle]"
#print "invalid handle"
#return "INVALID HANDLE: {0}".format(hex(handle))
else:
return "[error]"
def GetNameInfo(handle):
""" Get the handle name information """
object_name_information = OBJECT_NAME_INFORMATION()
size = DWORD(sizeof(object_name_information))
NtQueryObject = windll.ntdll.NtQueryObject
while True:
result = NtQueryObject(handle, 1, byref(object_name_information), size, None)
print result
if result == STATUS_SUCCESS:
return object_name_information.Name.Buffer
elif result in (STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL, STATUS_INFO_LENGTH_MISMATCH):
size = DWORD(size.value * 4)
resize(object_name_information, size.value)
else:
return "[name retrieval error]"
def GetDeviceInfo(targetPid, handle):
#currentPid = os.getpid()
dupHandle = GetProcessHandle(targetPid, handle)
if dupHandle is None:
print "Duplicate handle failed"
else:
typeInfo = GetTypeInfo(int(dupHandle))
nameInfo = GetNameInfo(int(dupHandle))
print "type = {0} - name = {1}".format(typeInfo, nameInfo)