如何用我自己的实现(名称和参数设置相同)替换MS VC ++项目中的WinAPI函数调用?
我需要替换所有的WinAPI调用
- CreateFile,
- ReadFile,
- SetFilePointer,
- 关闭手柄
用我自己的实现(通过蓝牙使用低级文件读取)。
该代码将替换功能,即视频文件播放器,它已经可以与常规硬盘文件一起使用了。
同样需要的是,如果VideoPlayer输入中的文件是常规的HDD文件,则Video Player仍可以播放HDD中的文件。
这项任务的最佳实践是什么?
解决方案
回答
我认为这不是最佳做法,但是如果将其放在包含文件的位置,该文件包含在要更改的函数的每个位置,该文件应该会起作用:
#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调用,我们可以在其中决定是否需要使用自己的实现或者原始实现。
免责声明:我认为这样做很丑,我不会这样做。我宁愿搜索并替换所有出现的事件或者其他内容。
回答
如果我们试图拦截来自另一个应用程序的对这些API的调用,请考虑使用Detours。
回答
如果我们可以编辑代码,则只需重新编写代码即可使用符合我们需要的自定义API。如果失败,请使用Maximilian的技术,但要警告它是维护恐怖。
如果我们无法编辑代码,则可以修补导入表以将调用重定向到我们自己的代码。可以在本文搜索标题为"通过更改导入地址表进行间谍活动"的部分中找到此技术的说明。
这很危险,但是如果我们小心一点,就可以使它起作用。还请检查Microsoft Detours,它可以执行相同的操作,但不需要我们弄乱实际的补丁。
回答
我建议我们按照以下步骤操作:
- 编写一组包装函数,例如MyCreateFile,MyReadFile等,它们最初只是调用相应的API并传递相同的参数,且未修改。
- 使用文本编辑器搜索对原始API的所有调用,然后将其替换为对新包装函数的调用。
- 测试该应用程序仍然可以正常运行。
- 修改包装函数以适合我们自己的目的。
请注意,CreateFile是一个宏,它会根据是否定义UNICODE扩展为CreateFileW或者CreateFileA。考虑使用LPCTSTR和TCHAR函数,以便可以将应用程序构建为ANSI或者Unicode。
请不要使用#define(如此处其他答复中所建议的那样),因为这只会导致维护问题,并且正如Maximilian正确指出的那样,这不是最佳实践。
回答
我们可以只在自定义名称空间中编写新函数。例如
namespace Bluetooth { void CreateFile(/*params*/); void etc... }
然后在代码中,我们唯一需要更改的就是:
if (::CreateFile(...)) { }
到
if (Bluetooth::CreateFile(...)) { }
简单! :)
回答
如果我们确实要劫持该API,请查看printer.dll(L-GPL)。