在 C++ 上重命名 Win32 安全函数

Rename Win32 Functions for Security on C++

有没有办法使用#define 重命名像 GetVolumeInformationW() 这样的 win32 函数?

例如: #define abc(LPCWSTR a, LPWSTR b, ...) GetVolumeInformationW(Some argumments..)

为什么要这样做?我想在像 IDA 这样的调试程序中隐藏函数名称,有什么办法可以做到吗?

语言:C++

为此使用 #define 没有意义,因为这对二进制可执行文件的内容没有影响。使用预处理器宏只会影响您作为程序员将看到的内容,但不会影响编译器或链接器将看到的内容。有关 C++ 预处理器如何工作及其与 compiler/linker 的关系的信息,请参阅 this link

如果你不希望函数出现在Import Table of your executable, then you can instead load the function dynamically using GetProcAddress。这样,当函数被调用时,反汇编程序可能无法确定地址指向哪个函数。但是,反汇编程序将能够看到您正在使用 GetProcAddress 来做某事,只是不知道是什么。使用函数 GetProcAddress 可能会让试图破解您的软件的人产生怀疑,因为如果您试图隐藏某些东西,这是很常见的做法。

如果您不希望字符串 GetVolumeInformationW 以明文形式出现在您的可执行文件中,那么您可以以某种方式对其进行加密或混淆,例如将其反向存储,然后在将其传递给GetProcAddress。这只是如何完成的一个非常简单的示例。使用特定密钥对每个字符使用 XOR(这是 C++ 中的 ^ 运算符)进行加密,然后再次执行相同的操作进行解密,这可能是更好的解决方案,因为这将使加密文本不容易识别为文本。

您将从共享 DLL 调用函数。定义是严格的预处理器。

您要做的是创建一个散列函数来散列字符串“GetVolumeInformationW”。以及所在模块的名称。例如“Kernel32.dll”

使用 FS 或 GS​​ 寄存器获取 PEB。然后转到 PEB_LDR_DATA 列表。 运行 每个列表条目并根据您的 Kernel32 哈希字符串对 DLL 名称进行哈希处理。如果哈希值匹配,您将以相同的结构获取库的基础。

在此之后,您将跟踪导出 table。并执行与上面相同的操作,将每个导出名称与散列的“GetVolumeInformationW”字符串进行比较。找到后,您将使用函数指针调用它所在的地址。

这是唯一的方法。如果加密字符串存储在堆栈中,则加分。所以在编码时做

char[] szKernel32 = 'K', 'e', 'r', 'n'......;

此外,不要使用 GetProcAddress。它破坏了隐藏点,因为任何使用过 IDA 的人都会立即搜索 GetProcAddress.

Is there a way to rename a win32 function like GetVolumeInformationW() using #define ?

不,宏不用于该目的。您可以定义一个宏,这样 Win32 函数名称不会按字面意思出现在您的源代码 ,除了在宏定义中,但这不会重命名函数,甚至不会阻止函数名称避免出现在编译后的目标文件、库或可执行文件中。

它不能,因为 Win32 API 的函数名称是由平台头文件和(尤其是)库建立的。您不是在重建平台库,只是将现有的链接到您自己的代码,因此您的代码别无选择,只能使用 API 的函数名称来调用 API 函数。

Why do that? I want to hide the function name on debbuger programms like IDA, is there some way to did that?

混淆不是一种非常有效的防御技术。在你的软件的普通开发中,它更有可能给你带来麻烦,而不是给熟练的对手设置一个主要障碍。如果您仍然希望这样做,您可以混淆您自己的函数的名称,但是不行,您不能更改平台 API 函数的名称。