gpt4 book ai didi

C++ 检测函数是否被 Hook (32 位机器)

转载 作者:太空狗 更新时间:2023-10-29 23:11:48 28 4
gpt4 key购买 nike

当人们 Hook 一个函数时,他们通常会用分支指令修改他们想要 Hook 的函数的前几条指令到他们想做一些事情的地方,然后分支回到原来的函数并恢复它,问题在于从字面上看,没有什么是安全的。您试图隐藏的任何值都可以很容易地找到(这些值可以通过许多其他方式找到,而不仅仅是函数 Hook ,但这就是我在这个问题中关注的全部内容)

假设您在 C++ 应用程序中实现了像 MD5 这样的哈希算法(我没有,这只是问题的一个示例),只是为了这个示例假设您有一个 MD5 函数像这样

void GENERATEMD5(const char *plain, char *out);

你会这样调用它

char hashResult[33] = { 0 };//32 + 1 because of null terminator
GENERATEMD5(passwordInputBuffer, hashResult);
memset(passwordInputBuffer, 0, 32);//set password buf back to null

任何人都可以轻松地 Hook 此 GERERATEMD5() 函数,并在传递给该函数时简单地打印出参数。示例

void md5FuncHook(const char *plain, char *out)
{
md5Hook(plain, out);

console::print("Plain: %s - Hash: %s", plain, out);
}

我在考虑这个问题,但我只能想出一种方法来检测一个函数是否被 Hook (假设他们通过修改函数的前几条指令来 Hook 该函数)。那将是检查函数的前几个字节,然后确认它们是它们应该是的。例如,如果我们知道函数 GERERATEMD5() 的前几个字节是

int GERERATEMD5_Function_bytes_0 = 0x12341234;//just random bytes for the example
int GERERATEMD5_Function_bytes_1 = 0x12341234;//just random bytes for the example
int GERERATEMD5_Function_bytes_2 = 0x12341234;//just random bytes for the example
int GERERATEMD5_Function_bytes_3 = 0x12341234;//just random bytes for the example

然后我们可以做这样的事情

void checkIfGENERATEMD5HasBeenHooked()
{
int GERERATEMD5_Function_bytes_0 = 0x12341234;//just random bytes for the example
int GERERATEMD5_Function_bytes_1 = 0x12341234;//just random bytes for the example
int GERERATEMD5_Function_bytes_2 = 0x12341234;//just random bytes for the example
int GERERATEMD5_Function_bytes_3 = 0x12341234;//just random bytes for the example

int readGENERATEMD5FunctionBytes0, readGENERATEMD5FunctionBytes1, readGENERATEMD5FunctionBytes2, readGENERATEMD5FunctionBytes3;
memcpy(&readGENERATEMD5FunctionBytes0, (char *)(&GENERATEMD5 + 0x00), 0x04);
memcpy(&readGENERATEMD5FunctionBytes1, (char *)(&GENERATEMD5 + 0x04), 0x04);
memcpy(&readGENERATEMD5FunctionBytes2, (char *)(&GENERATEMD5 + 0x08), 0x04);
memcpy(&readGENERATEMD5FunctionBytes3, (char *)(&GENERATEMD5 + 0x0C), 0x04);

if(GERERATEMD5_Function_bytes_0 == readGENERATEMD5FunctionBytes0 && GENERATEMD5_Function_bytes_1 == readGENERATEMD5FunctionBytes1 && GENERATEMD5_Function_bytes_2 == readGENERATEMD5FunctionBytes2 && GENERATEMD5_Function_bytes_3 == readGENERATEMD5FunctionBytes3)
{
//our GENERATEMD5() function is clean
}
else
{
//hook detected or some other form of function modification detected
}
}

但是我尝试过的所有方法似乎都行不通。我假设的问题来自于我读取函数本身字节的位置,例如对 memcpy 的调用实际上并未读取位于 &GENERATEMD5 + OFFSET 的字节。我只是做错了什么吗?还是有更好/不同的方式来做我想完成的事情? (顺便说一句,是的,我知道攻击者在 Hook 您的函数时可能会使用许多其他 Hook 方法,除了我上面描述的方法之外,还有许多其他方法可以从您的可执行文件中获取您的敏感信息,但这个问题有与这些无关,所以请只关注问题,而不是仅仅说“这样做毫无意义”或“有简单的方法可以绕过它”等...)

最佳答案

我已经做到了。问题是加载程序会在重定位期间修改代码,因此您不能依赖操作数字段每次都是相同的值。在我的例子中,我使用了反汇编库并仅对操作码字节进行了哈希处理。我使用 BASTARD 在运行时进行反汇编,但该项目早就死了。我认为现在有更好的选择。

原则上,您可能会以不会发生重定位修正的方式编写目标函数,但这会带来更多的麻烦,而不是值得的。

关于C++ 检测函数是否被 Hook (32 位机器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49277363/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com