【问题标题】:htonl and ntohl have same address in windows?htonl 和 ntohl 在 Windows 中有相同的地址吗?
【发布时间】:2014-02-08 08:52:27
【问题描述】:

我依靠GetProcAddress() 来挂钩某些功能。不过我得到了一个糟糕的结果,老实说,我真的不知道发生了什么。

看来这段代码会输出"WHAT THE HELL?"

int main(void)
{
    HMODULE ws32 = LoadLibrary("WS2_32.DLL");
    if (GetProcAddress(ws32, "ntohl") ==  GetProcAddress(ws32, "htonl"))
        printf("WHAT THE HELL\n");

    return 0;
}

谁能解释一下为什么 ntohl 和 htonl 有相同的绝对地址? 问题是,当我连接到一个 DLL 并在 DLL 内部进行一些处理时,很明显在 PE 导入表内部(我解析 PE IAT),ntohl()htonl() 具有不同的地址(在 IAT 内部为说)。

所以这件事让我的程序毫无用处。 ntohl()htonl() 混淆,程序无法发挥作用而发疯。

有什么想法吗?有没有办法规避这种情况?解释?

【问题讨论】:

    标签: windows dll winsock winsock2 portable-executable


    【解决方案1】:

    当然,为什么不呢。在小端平台上,所有 ntohl 和 htonl 函数所做的就是将整数中的所有单个字节反转。不需要以不同方式实现这 2 个函数 - 您不必担心 GetProcAddress() 返回相同的函数指针。

    当然,您需要验证 GetProcAddress 不返回 NULL 指针。

    【讨论】:

    • 好吧。我明白你的意思了。问题是在解析二进制文件时,我的程序必须区分对 htonl 的调用和对 ntohl 的调用!我依靠它来获取一些函数指针:(有没有办法知道哪个 IAT 条目用于哪个函数?因为在我解析的二进制文件中,两者都有明显不同的 IAT 条目
    【解决方案2】:

    除非您在像 PDP-11 这样的 mixed-endian 平台上,否则从主机转换到本机字节序或反之亦然只是字节交换或 NOP,so applying ntohl or htonl to an integer results in the same output。因此,链接器可以选择对两个名称使用相同的函数

    不清楚为什么要区分这些功能,但它完全不可靠。智能编译器知道在必要时将htonlntohl 转换为字节交换,从而生成zero function call。用户还可以直接调用编译器内部函数,例如_byteswap_ulong()__builtin_bswap32()。在这些情况下,如何挂钩函数?


    话虽如此,这很可能是因为COMDAT folding optimizationmerges identical functions。要禁用它,请使用/OPT:NOICF flag

    另见

    【讨论】:

      猜你喜欢
      • 2012-07-10
      • 2016-08-23
      • 2013-03-29
      • 1970-01-01
      • 1970-01-01
      • 2014-07-20
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多