如何用我自己的实现替换MS VC++项目中的WinAPI函数调用(名称和参数集相同)?

StackOverflow https://stackoverflow.com/questions/60641

  •  09-06-2019
  •  | 
  •  

我需要替换所有 WinAPI 调用

  • 创建文件,
  • 读取文件,
  • 设置文件指针,
  • 关闭句柄

用我自己的实现(通过蓝牙使用低级文件读取)。函数将被替换的代码是视频文件播放器,它已经可以与常规硬盘文件一起使用。如果 VideoPlayer 输入中的文件是常规 HDD 文件,则还需要视频播放器仍然可以播放 HDD 中的文件。

此类任务的最佳实践是什么?

有帮助吗?

解决方案

我建议您按照以下步骤操作:

  1. 编写一组包装函数,例如 MyCreateFile、MyReadFile 等,它们最初只是调用相应的 API 并传递相同的参数,无需修改。
  2. 使用文本编辑器搜索对原始 API 的所有调用,并将这些调用替换为对新包装器函数的调用。
  3. 测试应用程序是否仍然正常运行。
  4. 修改包装函数以适合您自己的目的。

请注意,CreateFile 是一个宏,根据是否定义了 UNICODE,它会扩展为 CreateFileW 或 CreateFileA。考虑使用 LPCTSTR 和 TCHAR 函数 这样您的应用程序就可以构建为 ANSI 或 Unicode。

请不要使用 #define,正如其他回复中所建议的那样,因为这只会导致维护问题,并且正如马克西米利安正确指出的那样,这不是最佳实践。

其他提示

您可以在自定义命名空间中编写新函数。例如

namespace Bluetooth
{
  void CreateFile(/*params*/);
  void etc...
}

然后在您的代码中,您唯一需要更改的是:

if (::CreateFile(...))
{
}

if (Bluetooth::CreateFile(...))
{
}

简单的!:)

如果您尝试拦截其他应用程序对这些 API 的调用,请考虑 少走弯路.

如果您可以编辑代码,则只需重新编写它即可使用自定义 API 来执行您想要的操作。如果做不到这一点,请使用马克西米利安的技术,但要注意这是一个维护恐怖。

如果您无法编辑代码,您可以修补导入表以将调用重定向到您自己的代码。该技术的描述可以在 本文 - 搜索标题为“通过更改导入地址表进行间谍活动”的部分。

这很危险,但如果你小心的话,你可以让它发挥作用。还请查看 微软少走弯路, ,它做同样的事情,但不需要你搞乱实际的修补。

如果你真的想劫持 API,请查看 注射器.dll (L-GPL)。

我认为这不是最佳实践,但如果您将其放入包含文件中,该文件包含您要更改的函数被调用的所有位置,那么它应该可以工作:

#define CreateFile MyCreateFile

HRESULT MyCreateFile(whatever the params are);

MyCreateFile 的实现看起来像这样:

#undef CreateFile
HRESULT MyCreateFile(NobodyCanRememberParamListsLikeThat params)
{
    if (InputIsNormalFile())
        CreateFile(params);
    else
        // do your thing
}

基本上,您可以使每个 CreateFile 调用成为 MyCreateFile 调用,您可以在其中决定是否需要使用自己的实现或原始实现。

免责声明:我认为这样做很丑陋,我不会这样做。我宁愿搜索并替换所有发生的事情或其他东西。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top