对main函数交叉引用,找到__scrt_common_main_seh(),initterm(&First, &Last);会进行初始化工作,执行一些特定的函数。动调跟一下就会发现Frist中的最后一个函数sub_7FF7B48E1000函数会导致我们蓝屏。
跟进去看一下会发现,程序使用DeviceIoControl对io设备”\\.\ACPI_ROOT_OBJECT”进行了请求操作,它是 Windows ACPI 设备驱动程序(通常是 ACPI.sys
)提供的一个特殊设备接口,允许用户态程序通过 IOCTL(输入/输出控制)命令与 ACPI 相关的设备进行通信。动调发现这就是导致蓝屏的原因。直接patch掉call的位置。这下就不会蓝屏了。
上面的”\\.\ACPI_ROOT_OBJECT”被赋值给了变量handle1,这个变量到时候会在main函数里用到,这也是为什么不直接putch掉整个函数的原因。
分析main函数
main函数确定了flag的格式是drat{[32bytes]}而且操作下面还有几个DeviceIoControl,分别传入了一些参数到驱动层进行处理,于是我们先分析驱动层。
这里用到了下面两个项目进行分析
用010提取嵌入在其中的驱动程序,分析可以找到操作函数。
根据不同的IOCTL,驱动程序执行不同的操作。可能要部署一下驱动调试环境。
nLidjcqSFroezwkTvpzCEVEXMGUx
驱动加载逻辑分析
虚表中最后一个函数是驱动加载函数
进去后第一个函数就是驱动加载函数
init_driver()
load_driver()
register_device()
至此驱动加载完毕。驱动在加载完毕后会删除注册表信息所以我们找不到在注册表内的信息,但是驱动已经被加载到内核运行。
动调验证一下,
xxxxxxxxxx #include <stdio.h>int main() { unsigned char mm[42] = { 0x34, 0x6C, 0x60, 0x33, 0x15, 0x3B, 0x74, 0x38, 0x5E, 0x6A, 0x53, 0x05, 0x31, 0x1C, 0x43, 0x35, 0x53, 0x58, 0x4A, 0x12, 0x39, 0x3B, 0x35, 0x5E, 0x3A, 0x21, 0x08, 0x1B, 0x44, 0x00, 0x7C, 0x26, 0x6E, 0x5D, 0x54, 0x0C, 0x01, 0x07, 0x00, 0x1F, 0x52, 0x1B }; for (int i = 41; i>=0; i–) { mm[41-i] ^= mm[(2 * i) % 42]; printf(“%c”, mm[41-i]); } }//flag{G00d_jOb_!_7h1s_i5_nOt_0nIy_junkc0d3}c
动调时发现驱动会被卸载并蓝屏,推测还有反调试。
仔细看unload()函数,这里发现,只要注册表打开成功就会把驱动卸载,???