hans7 发表于 2022-12-6 00:18

通过实例学习Windows INF文件

本帖最后由 hans7 于 2023-2-11 16:34 编辑

### 简介

> INF (文件) 安装信息是驱动程序包中的文本文件,其中包含设备安装组件在设备上安装驱动程序包时使用的所有信息。 Windows INF 文件为设备安装以下组件:
>
> - 支持设备的一个或多个驱动程序。
> - 使设备联机的设备特定的配置或设置。

**作者:(https://blog.csdn.net/hans774882968)以及(https://juejin.cn/user/1464964842528888)以及(https://www.52pojie.cn/home.php?mod=space&uid=1906177)**

本文juejin:https://juejin.cn/post/7173700541393371167

本文52pojie:https://www.52pojie.cn//thread-1723084-1-1.html

### 示例

下面展示了一个鼠标指针“方案”安装的inf文件,我们主要搞清楚这个文件所做的事情。[来源](https://www.bilibili.com/video/BV1Vv4y1o796):

```ini

signature="$CHICAGO$"


CopyFiles = Scheme.Cur
AddReg    = Scheme.Reg,Wreg


Scheme.Cur = 10,"%CUR_DIR%"


HKCU,"Control Panel\Cursors\Schemes","%SCHEME_NAME%",,"%10%\%CUR_DIR%\%pointer%,%10%\%CUR_DIR%\%help%,%10%\%CUR_DIR%\%work%,%10%\%CUR_DIR%\%busy%,%10%\%CUR_DIR%\%Cross%,%10%\%CUR_DIR%\%Text%,%10%\%CUR_DIR%\%Hand%,%10%\%CUR_DIR%\%Unavailiable%,%10%\%CUR_DIR%\%Vert%,%10%\%CUR_DIR%\%Horz%,%10%\%CUR_DIR%\%Dgn1%,%10%\%CUR_DIR%\%Dgn2%,%10%\%CUR_DIR%\%move%,%10%\%CUR_DIR%\%alternate%,%10%\%CUR_DIR%\%link%"


HKCU,"Control Panel\Cursors",,0x00020000,"%SCHEME_NAME%"
HKCU,"Control Panel\Cursors",AppStarting,0x00020000,"%10%\%CUR_DIR%\%work%"
HKCU,"Control Panel\Cursors",Arrow,0x00020000,"%10%\%CUR_DIR%\%pointer%"
HKCU,"Control Panel\Cursors",Crosshair,0x00020000,"%10%\%CUR_DIR%\%Cross%"
HKCU,"Control Panel\Cursors",Hand,0x00020000,"%10%\%CUR_DIR%\%link%"
HKCU,"Control Panel\Cursors",Help,0x00020000,"%10%\%CUR_DIR%\%Help%"
HKCU,"Control Panel\Cursors",IBeam,0x00020000,"%10%\%CUR_DIR%\%Text%"
HKCU,"Control Panel\Cursors",No,0x00020000,"%10%\%CUR_DIR%\%Unavailiable%"
HKCU,"Control Panel\Cursors",NWPen,0x00020000,"%10%\%CUR_DIR%\%Hand%"
HKCU,"Control Panel\Cursors",SizeAll,0x00020000,"%10%\%CUR_DIR%\%move%"
HKCU,"Control Panel\Cursors",SizeNESW,0x00020000,"%10%\%CUR_DIR%\%Dgn2%"
HKCU,"Control Panel\Cursors",SizeNS,0x00020000,"%10%\%CUR_DIR%\%Vert%"
HKCU,"Control Panel\Cursors",SizeNWSE,0x00020000,"%10%\%CUR_DIR%\%Dgn1%"
HKCU,"Control Panel\Cursors",SizeWE,0x00020000,"%10%\%CUR_DIR%\%Horz%"
HKCU,"Control Panel\Cursors",UpArrow,0x00020000,"%10%\%CUR_DIR%\%alternate%"
HKCU,"Control Panel\Cursors",Wait,0x00020000,"%10%\%CUR_DIR%\%busy%"
HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Runonce\Setup\","",,"rundll32.exe shell32.dll,Control_RunDLL main.cpl @0"


"正常选择.ani"
"帮助选择.ani"
"后台运行.ani"
"忙.ani"
"精确选择.ani"
"文本选择.ani"
"手写.cur"
"不可用.ani"
"垂直调整大小.ani"
"水平调整大小.ani"
"沿对角线调整大小1.ani"
"沿对角线调整大小2.ani"
"移动.ani"
"候选.ani"
"链接选择.ani"
"位置选择.ani"
"个人选择.ani"


CUR_DIR         = "Cursors\波奇酱"
SCHEME_NAME   = "波奇酱"
pointer             = "正常选择.ani"
help                = "帮助选择.ani"
work                = "后台运行.ani"
busy                = "忙.ani"
cross                = "精确选择.ani"
text                = "文本选择.ani"
hand                = "手写.cur"
unavailiable      = "不可用.ani"
vert                = "垂直调整大小.ani"
horz                = "水平调整大小.ani"
dgn1                = "沿对角线调整大小1.ani"
dgn2                = "沿对角线调整大小2.ani"
move                = "移动.ani"
alternate      = "候选.ani"
link                = "链接选择.ani"
pin         = "位置选择.ani
person      = "个人选择.ani"
```

这个文件不完整,没有替换”位置选择“和”个人选择“,下面给出我的修改版本,不妨通过WinMerge等工具来对比两者的差异:

```ini

signature="$CHICAGO$"


CopyFiles = Scheme.Cur
AddReg    = Scheme.Reg,Wreg


Scheme.Cur = 10,"%CUR_DIR%"


HKCU,"Control Panel\Cursors\Schemes","%SCHEME_NAME%",,"%10%\%CUR_DIR%\%pointer%,%10%\%CUR_DIR%\%help%,%10%\%CUR_DIR%\%work%,%10%\%CUR_DIR%\%busy%,%10%\%CUR_DIR%\%Cross%,%10%\%CUR_DIR%\%Text%,%10%\%CUR_DIR%\%Hand%,%10%\%CUR_DIR%\%Unavailiable%,%10%\%CUR_DIR%\%Vert%,%10%\%CUR_DIR%\%Horz%,%10%\%CUR_DIR%\%Dgn1%,%10%\%CUR_DIR%\%Dgn2%,%10%\%CUR_DIR%\%move%,%10%\%CUR_DIR%\%alternate%,%10%\%CUR_DIR%\%link%,%10%\%CUR_DIR%\%pin%,%10%\%CUR_DIR%\%person%"


HKCU,"Control Panel\Cursors",,0x00020000,"%SCHEME_NAME%"
HKCU,"Control Panel\Cursors",AppStarting,0x00020000,"%10%\%CUR_DIR%\%work%"
HKCU,"Control Panel\Cursors",Arrow,0x00020000,"%10%\%CUR_DIR%\%pointer%"
HKCU,"Control Panel\Cursors",Crosshair,0x00020000,"%10%\%CUR_DIR%\%Cross%"
HKCU,"Control Panel\Cursors",Hand,0x00020000,"%10%\%CUR_DIR%\%link%"
HKCU,"Control Panel\Cursors",Help,0x00020000,"%10%\%CUR_DIR%\%Help%"
HKCU,"Control Panel\Cursors",IBeam,0x00020000,"%10%\%CUR_DIR%\%Text%"
HKCU,"Control Panel\Cursors",No,0x00020000,"%10%\%CUR_DIR%\%Unavailiable%"
HKCU,"Control Panel\Cursors",NWPen,0x00020000,"%10%\%CUR_DIR%\%Hand%"
HKCU,"Control Panel\Cursors",SizeAll,0x00020000,"%10%\%CUR_DIR%\%move%"
HKCU,"Control Panel\Cursors",SizeNESW,0x00020000,"%10%\%CUR_DIR%\%Dgn2%"
HKCU,"Control Panel\Cursors",SizeNS,0x00020000,"%10%\%CUR_DIR%\%Vert%"
HKCU,"Control Panel\Cursors",SizeNWSE,0x00020000,"%10%\%CUR_DIR%\%Dgn1%"
HKCU,"Control Panel\Cursors",SizeWE,0x00020000,"%10%\%CUR_DIR%\%Horz%"
HKCU,"Control Panel\Cursors",UpArrow,0x00020000,"%10%\%CUR_DIR%\%alternate%"
HKCU,"Control Panel\Cursors",Wait,0x00020000,"%10%\%CUR_DIR%\%busy%"
HKCU,"Control Panel\Cursors",Pin,0x00020000,"%10%\%CUR_DIR%\%pin%"
HKCU,"Control Panel\Cursors",Person,0x00020000,"%10%\%CUR_DIR%\%person%"
HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Runonce\Setup\","",,"rundll32.exe shell32.dll,Control_RunDLL main.cpl @0"


"正常选择.ani"
"帮助选择.ani"
"后台运行.ani"
"忙.ani"
"精确选择.ani"
"文本选择.ani"
"手写.cur"
"不可用.ani"
"垂直调整大小.ani"
"水平调整大小.ani"
"沿对角线调整大小1.ani"
"沿对角线调整大小2.ani"
"移动.ani"
"候选.ani"
"链接选择.ani"
"位置选择.ani"
"个人选择.ani"


CUR_DIR         = "Cursors\波奇酱"
SCHEME_NAME   = "波奇酱"
pointer             = "正常选择.ani"
help                = "帮助选择.ani"
work                = "后台运行.ani"
busy                = "忙.ani"
cross                = "精确选择.ani"
text                = "文本选择.ani"
hand                = "手写.cur"
unavailiable      = "不可用.ani"
vert                = "垂直调整大小.ani"
horz                = "水平调整大小.ani"
dgn1                = "沿对角线调整大小1.ani"
dgn2                = "沿对角线调整大小2.ani"
move                = "移动.ani"
alternate      = "候选.ani"
link                = "链接选择.ani"
pin         = "位置选择.ani"
person      = "个人选择.ani"
```

根据参考链接2,`DefaultInstall`节会在右键该inf并点击安装的时候执行。命令包括`CopyFiles, AddReg`。

我们需要搞清楚`CopyFiles`指定的`Scheme.Cur`节各文件的目标文件夹和源文件夹。根据参考链接3,目标文件夹由`DestinationDirs`节指定。

> 使用 [**INF CopyFiles 指令的任何 INF**](https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/inf-copyfiles-directive) 文件中都需要 **DestinationDirs** 节,或者引用 *file-list-section*(无论是使用 **CopyFiles**、[**DelFiles**](https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/inf-delfiles-directive) 还是 [**RenFiles**](https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/inf-renfiles-directive) 指令)。

`DestinationDirs`:根据参考链接3、4,`dirid = 10`,表示Windows目录`C:\Windows`,相当于`%SystemRoot%`,`subdir = %CUR_DIR% = Cursors\波奇酱`。于是我们可以推断`%10%\%CUR_DIR%\%work%`表示`C:\Windows\Cursors\波奇酱\后台运行.ani`。

根据参考链接9,源文件夹默认是当前文件夹,但也可以通过`source-file-name`来指定:

```ini

"aero_arrow.cur","Windows默认鼠标指针/aero_arrow.cur"
```

接下来依据参考链接10分析`AddReg`对注册表的修改。

1. `Scheme.Reg`:路径`HKEY_CURRENT_USER\Control Panel\Cursors\Schemes`,`value-entry-name = %SCHEME_NAME% = 波奇酱`,无`flag`,`value`为`"%10%\%CUR_DIR%\%pointer%,%10%\%CUR_DIR%\%help%,后续的省略"`。
2. `Wreg`同理。

最后看:

```ini
HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Runonce\Setup\","",,"rundll32.exe shell32.dll,Control_RunDLL main.cpl @0"
```

根据参考链接8,`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce`作用:

> 使用 `Run` 或 `RunOnce` 注册表项使程序在用户登录时运行。 每次用户登录时,该 `Run` 密钥都会使程序运行,而 `RunOnce` 密钥使程序运行一次,然后删除该密钥。 可以为用户或计算机设置这些密钥。

根据参考链接6,`rundll32.exe`用来调用`shell32.dll`的函数`Control_RunDLL`,这个函数用来运行`.cpl`文件。又根据参考链接5,`main.cpl @0`表示鼠标属性。所以我们可以大致猜测它的功能。然后我们在参考链接7也找到了这条命令的功能:弹出显示`鼠标 属性`的对话框。`@1`表示弹出`键盘 属性`的对话框。

#### 总结

1. 以上inf文件首先把资源文件复制到`C:\Windows\Cursors\波奇酱`,然后通过写入注册表来实现鼠标指针的修改,最后弹出`鼠标 属性`的对话框。
2. 以上inf文件多次安装是没有副作用的。
3. 相比于Python,inf文件可以方便地完成一些特殊的任务,比如:读写注册表。

### 实现恢复默认鼠标指针方案的效果

其实可以在`鼠标 属性`的对话框选择原来的鼠标指针方案,这里只是展示一个简单的练手demo。

- 在当前inf文件的文件夹下建文件夹:Windows默认鼠标指针。然后把`C:\Windows\Cursors`下的相关资源复制过来。
- `Scheme.Cur`每行都添加`source-file-name`,指定源文件路径。

```ini

signature="$CHICAGO$"


CopyFiles = Scheme.Cur
AddReg    = Scheme.Reg,Wreg


Scheme.Cur = 10,"%CUR_DIR%"


HKCU,"Control Panel\Cursors\Schemes","%SCHEME_NAME%",,"%10%\%CUR_DIR%\%pointer%,%10%\%CUR_DIR%\%help%,%10%\%CUR_DIR%\%work%,%10%\%CUR_DIR%\%busy%,%10%\%CUR_DIR%\%Cross%,%10%\%CUR_DIR%\%Text%,%10%\%CUR_DIR%\%nw_pen%,%10%\%CUR_DIR%\%Unavailiable%,%10%\%CUR_DIR%\%Vert%,%10%\%CUR_DIR%\%Horz%,%10%\%CUR_DIR%\%Dgn1%,%10%\%CUR_DIR%\%Dgn2%,%10%\%CUR_DIR%\%move%,%10%\%CUR_DIR%\%alternate%,%10%\%CUR_DIR%\%link%,%10%\%CUR_DIR%\%pin%,%10%\%CUR_DIR%\%person%"


HKCU,"Control Panel\Cursors",,0x00020000,"%SCHEME_NAME%"
HKCU,"Control Panel\Cursors",AppStarting,0x00020000,"%10%\%CUR_DIR%\%work%"
HKCU,"Control Panel\Cursors",Arrow,0x00020000,"%10%\%CUR_DIR%\%pointer%"
HKCU,"Control Panel\Cursors",Crosshair,0x00020000,"%10%\%CUR_DIR%\%Cross%"
HKCU,"Control Panel\Cursors",Hand,0x00020000,"%10%\%CUR_DIR%\%link%"
HKCU,"Control Panel\Cursors",Help,0x00020000,"%10%\%CUR_DIR%\%Help%"
HKCU,"Control Panel\Cursors",IBeam,0x00020000,"%10%\%CUR_DIR%\%Text%"
HKCU,"Control Panel\Cursors",No,0x00020000,"%10%\%CUR_DIR%\%Unavailiable%"
HKCU,"Control Panel\Cursors",NWPen,0x00020000,"%10%\%CUR_DIR%\%nw_pen%"
HKCU,"Control Panel\Cursors",SizeAll,0x00020000,"%10%\%CUR_DIR%\%move%"
HKCU,"Control Panel\Cursors",SizeNESW,0x00020000,"%10%\%CUR_DIR%\%Dgn2%"
HKCU,"Control Panel\Cursors",SizeNS,0x00020000,"%10%\%CUR_DIR%\%Vert%"
HKCU,"Control Panel\Cursors",SizeNWSE,0x00020000,"%10%\%CUR_DIR%\%Dgn1%"
HKCU,"Control Panel\Cursors",SizeWE,0x00020000,"%10%\%CUR_DIR%\%Horz%"
HKCU,"Control Panel\Cursors",UpArrow,0x00020000,"%10%\%CUR_DIR%\%alternate%"
HKCU,"Control Panel\Cursors",Wait,0x00020000,"%10%\%CUR_DIR%\%busy%"
HKCU,"Control Panel\Cursors",Pin,0x00020000,"%10%\%CUR_DIR%\%pin%"
HKCU,"Control Panel\Cursors",Person,0x00020000,"%10%\%CUR_DIR%\%person%"
HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Runonce\Setup\","",,"rundll32.exe shell32.dll,Control_RunDLL main.cpl @0"


"aero_arrow.cur","Windows默认鼠标指针/aero_arrow.cur"
"aero_helpsel.cur","Windows默认鼠标指针/aero_helpsel.cur"
"aero_working.ani","Windows默认鼠标指针/aero_working.ani"
"aero_busy.ani","Windows默认鼠标指针/aero_busy.ani"
"cross_im.cur","Windows默认鼠标指针/cross_im.cur"
"beam_im.cur","Windows默认鼠标指针/beam_im.cur"
"aero_pen.cur","Windows默认鼠标指针/aero_pen.cur"
"aero_unavail.cur","Windows默认鼠标指针/aero_unavail.cur"
"aero_ns.cur","Windows默认鼠标指针/aero_ns.cur"
"aero_ew.cur","Windows默认鼠标指针/aero_ew.cur"
"aero_nwse.cur","Windows默认鼠标指针/aero_nwse.cur"
"aero_nesw.cur","Windows默认鼠标指针/aero_nesw.cur"
"aero_move.cur","Windows默认鼠标指针/aero_move.cur"
"aero_up.cur","Windows默认鼠标指针/aero_up.cur"
"aero_link.cur","Windows默认鼠标指针/aero_link.cur"
"aero_pin.cur","Windows默认鼠标指针/aero_pin.cur"
"aero_person.cur","Windows默认鼠标指针/aero_person.cur"


CUR_DIR         = "Cursors\Windows默认qwq"
SCHEME_NAME   = "Windows 默认qwq~"
pointer             = "aero_arrow.cur"
help                = "aero_helpsel.cur"
work                = "aero_working.ani"
busy                = "aero_busy.ani"
cross                = "cross_im.cur"
text                = "beam_im.cur"
nw_pen                = "aero_pen.cur"
unavailiable      = "aero_unavail.cur"
vert                = "aero_ns.cur"
horz                = "aero_ew.cur"
dgn1                = "aero_nwse.cur"
dgn2                = "aero_nesw.cur"
move                = "aero_move.cur"
alternate      = "aero_up.cur"
link                = "aero_link.cur"
pin         = "aero_pin.cur"
person      = "aero_person.cur"
```

### 另一款鼠标指针inf文件分析

今天(230211)看到了[另一款鼠标指针](https://www.bilibili.com/video/BV1qA411B771)(~~卡哇伊捏~~)。其inf文件有细微的差异。

``列举的路径变成了`%24%\%CUR_DIR%\%pointer%`。读了本文以后再查阅下面的参考资料,你一定能快速找到实际的路径。

``的最后一条命令变成了`HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Runonce\Setup\","",,"rundll32.exe shell32.dll,Control_RunDLL main.cpl,,1"`,这里`,,1`和`@0`的作用相同,但我还没有查到相关资料。
### 参考资料

1. INF 节摘要:https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/summary-of-inf-sections
2. INF DefaultInstall 节:https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/inf-defaultinstall-section
3. INF DestinationDirs 节:https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/inf-destinationdirs-section
4. 使用 Dirids:https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/using-dirids
5. 控制面板cpl大全:https://www.jianshu.com/p/678174cc3c8b
6. 揭秘rundll32中的攻防对抗:https://zhuanlan.zhihu.com/p/451532819
7. 介绍SHELL命令调用系统rundll32.exe的所有命令:https://www.cnblogs.com/conquer/archive/2006/11/07/553457.html
8. 运行和 RunOnce 注册表项:https://learn.microsoft.com/zh-cn/windows/win32/setupapi/run-and-runonce-registry-keys
9. INF CopyFiles 指令:https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/inf-copyfiles-directive
10. INF AddReg 指令:https://learn.microsoft.com/zh-cn/windows-hardware/drivers/install/inf-addreg-directive

miraak 发表于 2022-12-6 00:32

好文章!

hk9186 发表于 2022-12-6 05:45

回复支持一下

huangjiloqw 发表于 2022-12-6 08:03

这个厉害了,一般接触不到

zj1977lsz 发表于 2022-12-6 08:35

虽然看不懂,但是觉得蛮厉害的样子

GTR022 发表于 2022-12-6 08:48

太深奥 有初级教学就更好了
页: [1]
查看完整版本: 通过实例学习Windows INF文件