htonl и ntohl имеют одинаковый адрес в Windows?

Я полагаюсь на GetProcAddress() для перехвата некоторых функций. Однако я получаю ужасный результат, и, честно говоря, я действительно не знаю, что происходит.

Кажется, что этот код выведет "ЧТО ЗА ЧЕРТА?":

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(), и программа не может ничего изменить и сходит с ума.

Есть предположения? Будет ли способ обойти это? Объяснение?


person Yannick    schedule 08.02.2014    source источник


Ответы (2)


Конечно, почему бы и нет. Все, что делают функции ntohl и htonl на платформе с прямым порядком байтов, — это переворачивают все отдельные байты в целое число. Нет необходимости реализовывать эти две функции по-разному — вам не нужно беспокоиться о том, что GetProcAddress() возвращает один и тот же указатель на функцию.

Конечно, вы хотели бы убедиться, что GetProcAddress не возвращает указатель NULL.

person nos    schedule 08.02.2014
comment
Хорошо. Я понимаю, что вы имеете ввиду. Проблема в том, что при анализе двоичных файлов моя программа должна различать вызов htonl и вызов ntohl! Я полагался на это, чтобы получить некоторый указатель функции :( Есть ли способ узнать, какая запись IAT для какой функции? Причина в двоичных файлах, которые я анализирую, у обоих явно разные записи IAT - person Yannick; 08.02.2014

Если вы не используете платформу смешанного порядка байтов, такую ​​как PDP-11, преобразование с хоста к исходному порядку байтов или наоборот - это просто замена байтов или NOP, , поэтому применение ntohl или htonl к целому числу приводит к тому же результату< /а>. Поэтому компоновщик может использовать одну и ту же функцию для обоих имен.

Непонятно, почему вы хотите различать эти функции, но это совершенно ненадежно. Умные компиляторы знают, что при необходимости конвертировать htonl и ntohl в байтовую замену, что приводит к нулевой вызов функции. Пользователь также может вызывать встроенные функции компилятора, такие как _byteswap_ulong() или __builtin_bswap32() напрямую. В таких случаях, как вы можете подключить функцию?


При этом, скорее всего, это из-за оптимизации сворачивания COMDAT, который объединяет идентичные функции. Чтобы отключить его, используйте флаг /OPT:NOICF< /а>

Смотрите также

person phuclv    schedule 17.05.2019