🧠 问题背景:为什么不能"啥都不导库"就直接调用 RPC 接口?
因为:
- 
你想调用的是 RPC 接口函数 ,比如 RpcRemoteFindFirstPrinterChangeNotificationEx;
- 
它不是像 MessageBox()那样的普通 API,而是 运行在远程服务(如 Print Spooler)里的接口;
- 
你要调用它,需要知道: - 
它的接口 ID(UUID) 
- 
函数编号(OpNum) 
- 
参数格式(结构体、顺序等) 
 
- 
✅ 做法一:使用 Windows 自带的封装 API(推荐新手)
Windows 提供了一个封装好的 API:
BOOL FindFirstPrinterChangeNotificationEx(
    HANDLE hPrinter,
    DWORD fdwFlags,
    DWORD fdwOptions,
    LPCWSTR pszLocalMachine,
    DWORD Count,
    LPVOID pPrinterNotifyOptions,
    LPVOID pPrinterNotifyInfo
);这个函数内部会自动构造 RPC 调用,你只需要引入头文件和库即可:
#include <windows.h>
#include <winspool.h>
int main() {
    HANDLE hPrinter;
    OpenPrinter(L"PrinterName", &hPrinter, NULL); // 一般用 NULL 也行
    FindFirstPrinterChangeNotificationEx(
        hPrinter,
        PRINTER_CHANGE_ADD_JOB, // 监听什么事件
        0,
        L"\\\\127.0.0.1\\pipe\\legitname", // 诱导 spooler 去连接此路径
        0,
        NULL,
        NULL
    );
    ClosePrinter(hPrinter);
    return 0;
}这里的L"\\\\127.0.0.1\\pipe\\legitname", // 诱导 spooler 去连接此路径
其实是错的
正常就是传个ip
L"127.0.0.1"
看起来像 IP 地址,但 Windows 会自动把它当作 UNC 路径处理:
它最终会被解析成
\\127.0.0.1\pipe\spoolss
这个函数在 winspool.drv 里,编译时需要链接:
#pragma comment(lib, "winspool.lib")✅ 做法二:你手写 RPC 调用(适合深入研究漏洞)
这个就麻烦多了,你要手动:
- 
使用 .idl文件描述 spoolss 接口;
- 
编译 .idl➝.h+.c(MIDL 工具);
- 
注册并绑定 RPC 接口; 
- 
自己调用其中函数; 
👨💻 举个最简单例子:你拿到 spoolss 接口的 IDL 后会看到:
[
  uuid(12345678-1234-abcd-ef00-0123456789ab),
  version(1.0)
]
interface spoolss {
    void RpcRemoteFindFirstPrinterChangeNotificationEx(
        [in] handle_t hPrinter,
        ...
    );
}你用 rpcview 等工具就能导出这样的接口,然后用 MIDL 编译,生成对应 .h/.c 文件。
🛠 工具推荐:
- 
📦 RpcView.exe(开源):查看系统暴露的 RPC 接口、UUID、OpNum 等。
- 
🧰 MIDL.exe:微软官方的 IDL 编译器(把接口定义文件编译成.h+.c)
✅ 总结给你:
| 方法 | 优点 | 缺点 | 
|---|---|---|
| 使用 FindFirstPrinterChangeNotificationEx | 简单、直接、系统封装好了 | 不够底层 | 
| 自己写 RPC 接口代码(手撸) | 灵活、深入理解提权机制 | 麻烦、需要 RPC 基础 |