重命名 Win32 函数以确保 C++ 上的安全性

问题描述 投票:0回答:4

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

例如:

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

为什么要这么做?我想在 IDA 等调试器程序上隐藏函数名称,有什么方法可以做到这一点吗?

语言:C++

c++ security obfuscation
4个回答
1
投票

为此使用

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

如果您不希望该函数出现在可执行文件的导入表中,那么您可以使用

GetProcAddress
动态加载该函数。这样,当调用函数时,反汇编程序可能无法确定地址指向哪个函数。然而,反汇编程序将能够看到您正在使用
GetProcAddress
来做什么,但它只是不知道是什么。使用该功能
GetProcAddress
可能会让试图破解您的软件的人产生怀疑,因为如果您试图隐藏某些内容,这是很常见的事情。

如果您不希望字符串

GetVolumeInformationW
以明文形式出现在可执行文件中,那么您可以以某种方式对其进行加密或混淆,例如反向存储它,然后在将其传递给
GetProcAddress
之前将其反转回来。这只是一个非常简单的例子来说明如何做到这一点。对具有特定密钥的每个字符使用 XOR(即 C++ 中的
^
运算符)进行加密,然后再次执行相同的操作进行解密,可能是一个更好的解决方案,因为这将使加密文本不被加密。易于识别为文本。


1
投票

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

不,宏不能达到这个目的。您可以定义一个宏,使得 Win32 函数名称不会按字面意思出现在“源代码中”(除了宏定义中),但这不会重命名函数,甚至不会阻止函数名称出现在编译的目标文件中,库或可执行文件。 不能,因为 Win32 API 的函数名称是由平台标头和(尤其是)库建立的。您不是重建平台库,只是将现有的库链接到您自己的代码,因此您的代码别无选择,只能使用 API 的函数名称来调用 API 函数。

为什么要这么做?我想在 IDA 等调试器程序上隐藏函数名称,有什么方法可以做到这一点吗?

混淆并不是一种非常有效的防御技术。在软件的日常开发中,它更有可能给您带来麻烦,而不是给熟练的对手带来主要障碍。如果您仍然愿意,可以混淆自己函数的名称,但不行,您不能更改平台 API 函数的名称。


1
投票

您想要做的是创建一个哈希函数来对字符串“GetVolumeInformationW”进行哈希处理。以及所在模块的名称。例如“Kernel32.dll”

使用 FS 或 GS 寄存器获取

PEB

。然后进入PEB_LDR_DATA列表。运行每个列表条目并根据 Kernel32 散列字符串散列 DLL 名称。如果哈希值匹配,您就可以获取相同结构中库的基础。 此后您将跟踪导出表。执行与上面相同的操作,将每个导出名称与散列“GetVolumeInformationW”字符串进行比较。找到后,您将使用函数指针调用它所在的地址。

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

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

另外,请勿使用

GetProcAddress

。它消除了隐藏的意义,因为任何有过 IDA 经验的人都会立即搜索

GetProcAddress
    


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.