0

I rely on GetProcAddress() to do some hooking of some functions. I get a terrible result though, and to be honest, I don't really know what's happening.

It seems that this code will output "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;
}

Could someone explain me why ntohl and htonl have the same absolute addresses? The problem is that, when I hook into a DLL and do some processing inside the DLL, it's clear that Inside the PE import table (I parse the PE IAT), ntohl() and htonl() have different addresses (Inside the IAT as said).

So this thing renders my program useless. ntohl() is confounded with htonl(), and the program cannot make the difference and goes crazy.

Any thoughts? Would there be a way to circumvent this? An explication?

phuclv
  • 37,963
  • 15
  • 156
  • 475
Yannick
  • 830
  • 7
  • 27

2 Answers2

2

Sure, why not. All the ntohl and htonl function does, on a little endian platform, is to reverse all the individual bytes in an integer. There's no need for those 2 functions to be implemented differently - you do not need to worry that GetProcAddress() returns the same function pointer.

Ofcourse, you'd want to verify that GetProcAddress doesn't return a NULL pointer.

nos
  • 223,662
  • 58
  • 417
  • 506
  • 1
    Well. I see what you mean. The problem is that when parsing the binaries, my program must differentiate between a call to htonl and a call to ntohl! I was relying on that to get some function pointer :( Is there a way to know which IAT entry is for which function? Cause in the binaries I parse, both have clearly different IAT entries – Yannick Feb 08 '14 at 18:20
0

Unless you're on a mixed-endian platform like PDP-11, converting from host to the native endianness or vice versa is simply a byte swap or a NOP, so applying ntohl or htonl to an integer results in the same output. Therefore the linker may choose to use the same function for both names

It's unclear why you want to differentiate those functions, but it's completely unreliable. Smart compilers know to convert htonl and ntohl to a byte swap if necessary, resulting in zero function call. The user can also call compiler intrinsics such as _byteswap_ulong() or __builtin_bswap32() directly. In those cases how can you hook the function?


That being said, it's likely because of COMDAT folding optimization which merges identical functions. To disable it use the /OPT:NOICF flag

See also

phuclv
  • 37,963
  • 15
  • 156
  • 475