手动解压缩Windows用户模式可执行文件时,可以轻松在其EntryPoint(或TLS)处断开,然后进行跟踪直到到达原始EntryPoint。但是,打包驱动程序无法做到这一点。

如何可靠地手动解压缩Windows驱动程序?

评论

谁不会错过所有这些中最伟大的,Softice

#1 楼

我有点喜欢您关于更改子系统的答案,尤其是如果您不喜欢内核调试的话。不过,我是Windbg的忠实粉丝。我这样做的方式是:


将内核调试器连接到VM ​​
将驱动程序入口点的第一个字节更改为INT3(0xCC)。
修正PE校验和(我很喜欢让pefile帮我完成这项工作)。
将驱动程序加载到VM中(OSR具有出色的驱动程序加载器)

内核应在驱动程序上调用DriverEntry()并为您闯入调试器。然后,您可以跟踪代码,直到找到OEP为止(无论如何)。我看到的这种方法的主要优点是,您不必伪造内核DLL或驱动程序在解压缩过程中可能会执行的调用,并且它可以在x64上运行。

评论


但是,您可能会在更新的Windows版本上碰壁。从这个意义上说,OP的答案更加通用,但是您的答案当然更加专业:) ...也不要忘记devcon满足驱动程序加载需求(DDK / WDK中的源代码附带)

– 0xC0000022L♦
13年4月2日在14:41

@ 0xC0000022L我在较新版本的Windows上没有问题;只需执行诸如启用测试签名之类的常规操作即可。诚然,我还没有在Windows 8上尝试过它。有什么变化吗?

–mrduclaw
13年4月6日在9:10

@mrduclaw我如何将驱动程序入口点的第一个字节更改为INT3?

– AminM
16年1月1日在21:39

@AminM对不起,您的回复很晚,我已经很长时间没有检查此帐户了。在IDA中打开文件,找到入口点所在的字节。在十六进制编辑器中将其打开,并将其更改为0xCC(断点)。或者,您现在可能可以直接在IDA中对其进行编辑。祝好运!

–mrduclaw
17年1月23日,下午5:51

#2 楼


将驱动程序子系统更改为GUI(将其转换为用户模式二进制文件)
清除导入的RVA,或使用一组伪内核DLL(仅32位)来启用导入加载。
在调试器中启动并像在用户模式下一样进行操作-您可能需要在到达原始EntryPoint之前模拟一些API调用。


#3 楼

用INT3修补DriverInit函数的另一种方法是在IopLoadDriver函数中放置一个断点,该函数负责调用DriverInit。在Windows XP SP3上,应该将断点添加到IopLoadDriver + 0x66a,它是call dword ptr [edi+2Ch](0x2C是_DRIVER_OBJECT.DriverInit)。


x nt!IopLoadDriver查找IopLoadDriver

添加IopLoadDriver + 0x66a处的断点
加载并启动驱动程序

其他Windows版本的偏移量:


Windows 7 Pro SP1 32位德语: nt!IopLoadDriver + 0x7eb
Windows 7 Ultimate 64位US:nt!IopLoadDriver + 0xA04
Windows 10 Pro x64 US:nt!IopLoadDriver + 0x51C(内部版本10586.420)

(如果您有其他Windows版本的偏移量,请编辑此答案)

评论


不错的信息。可以将一些零碎的零件作为反向器放在一起总是很有价值的。还要记住,通过查看ReactOS源代码,您可以很好地猜测Windows中的实现细节。

– 0xC0000022L♦
13年8月13日在20:42

#4 楼

nt!IopLoadDriver间接调用仅用于SERVICE_DEMAND启动驱动程序条目

对于引导加载驱动程序,您也需要在nt!IopInitializeBuiltInDriver间接调用上断开

您可以在消息中看到一个简短的示例此链接中的#17和#18

http://www.osronline.com/showthread.cfm?link=231280

这是一个休眠脚本(略作编辑为使用gc(从条件开始而不是按建议使用go)可以一直等待,并且会在内核调试会话中加载任何驱动程序时打印出!drvobj详细信息
该命令应该在一行中

.foreach /pS 1 /ps 10 ( place { # call*dword*ptr*\[*\+*\] nt!IopInitializeBuiltinDriver} ) {bu place ".printf  \"%msu\n\", poi(esp+4);r $t0 = poi(esp); gu; !drvobj $t0 2;gc"}
.foreach /pS 1 /ps 10 ( place { # call*dword*ptr*\[*\+*\] nt!IoploadDriver} ) {bu place ".printf  \"%msu\n\", poi(esp+4);r $t1 = poi(esp); gu; !drvobj $t1 2;gc"}


xp sp3 vm

在已连接的kd会话中
执行sxe ibp; .reboot
kd将在重新启动时请求初始中断(相当于boot.ini中的/ break开关)


运行此脚本时

$$>a< "thisscript.extension"


除了打印所有系统驱动程序入口点及其驱动程序对象

(如果需要)加载另一个驱动程序时,也会打印其详细信息

在目标vm中打开的sysinternals dbgview的示例输出

check mark the enable kernel capture (ctrl+k) <时会调用dbgv.sys入口点

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\DBGV
*** ERROR: Module load completed but symbols could not be loaded for Dbgv.sys
Driver object (ffbd6248) is for:
 \Driver\DBGV
DriverEntry:   f6d89185 Dbgv
DriverStartIo: 00000000 
DriverUnload:  00000000 
AddDevice:     00000000 

Dispatch routines:
[00] IRP_MJ_CREATE                      f6d87168    Dbgv+0x1168
[01] IRP_MJ_CREATE_NAMED_PIPE           804fa87e    nt!IopInvalidDeviceRequest
[02] IRP_MJ_CLOSE                       f6d87168    Dbgv+0x1168
[03] IRP_MJ_READ                        804fa87e    nt!IopInvalidDeviceRequest
[04] IRP_MJ_WRITE                       804fa87e    nt!IopInvalidDeviceRequest
[05] IRP_MJ_QUERY_INFORMATION           804fa87e    nt!IopInvalidDeviceRequest
[06] IRP_MJ_SET_INFORMATION             804fa87e    nt!IopInvalidDeviceRequest
[07] IRP_MJ_QUERY_EA                    804fa87e    nt!IopInvalidDeviceRequest
[08] IRP_MJ_SET_EA                      804fa87e    nt!IopInvalidDeviceRequest
[09] IRP_MJ_FLUSH_BUFFERS               804fa87e    nt!IopInvalidDeviceRequest
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION    804fa87e    nt!IopInvalidDeviceRequest
[0b] IRP_MJ_SET_VOLUME_INFORMATION      804fa87e    nt!IopInvalidDeviceRequest
[0c] IRP_MJ_DIRECTORY_CONTROL           804fa87e    nt!IopInvalidDeviceRequest
[0d] IRP_MJ_FILE_SYSTEM_CONTROL         804fa87e    nt!IopInvalidDeviceRequest
[0e] IRP_MJ_DEVICE_CONTROL              f6d87168    Dbgv+0x1168
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL     804fa87e    nt!IopInvalidDeviceRequest
[10] IRP_MJ_SHUTDOWN                    804fa87e    nt!IopInvalidDeviceRequest
[11] IRP_MJ_LOCK_CONTROL                804fa87e    nt!IopInvalidDeviceRequest
[12] IRP_MJ_CLEANUP                     804fa87e    nt!IopInvalidDeviceRequest
[13] IRP_MJ_CREATE_MAILSLOT             804fa87e    nt!IopInvalidDeviceRequest
[14] IRP_MJ_QUERY_SECURITY              804fa87e    nt!IopInvalidDeviceRequest
[15] IRP_MJ_SET_SECURITY                804fa87e    nt!IopInvalidDeviceRequest
[16] IRP_MJ_POWER                       804fa87e    nt!IopInvalidDeviceRequest
[17] IRP_MJ_SYSTEM_CONTROL              804fa87e    nt!IopInvalidDeviceRequest
[18] IRP_MJ_DEVICE_CHANGE               804fa87e    nt!IopInvalidDeviceRequest
[19] IRP_MJ_QUERY_QUOTA                 804fa87e    nt!IopInvalidDeviceRequest
[1a] IRP_MJ_SET_QUOTA                   804fa87e    nt!IopInvalidDeviceRequest
[1b] IRP_MJ_PNP                         804fa87e    nt!IopInvalidDeviceRequest