Я пытаюсь написать некоторые функции для обнаружения сплайсинга кода DLL. Я использую сплайсинг dll-кода для обозначения изменения байтов в начале функций в загруженных dll-файлах, так что вместо перехода к полной реализации функции в dll-файле он перейдет в другое место.
Мой подход до сих пор был:
Во-первых - загружаемая информация о dll (например, база изображений загруженных dll и т. Д.) Я получаю от использования библиотек Toolhelp32.
Для каждой загруженной DLL:
- получить адрес каждой функции (rva), читая таблицу экспорта в памяти dll
- читать по 8 байт по этому адресу в памяти
- получить функцию rva из версии dll на диске
- анализировать PE-заголовок dll-on-disk, чтобы преобразовать rva в смещение файла - здесь также читается 8 байтов
- сравнить эти 8 байтов
Теперь я знаю, что делаю что-то не совсем правильно, и, возможно, я делаю концептуальную ошибку.
Я тестировал с notepad.exe, 32 бита. Сравнения успешны для большинства функций в загруженных DLL, но это имеет тенденцию находить некоторые различия.
Например:
ntdll.dll: ordinal = 00000059, rva = 0007e098, fileoffs = 0007d498, функция VA: 7c97e098
диск: 00 00 00 00 00 00 00 00
mem: e4 04 00 00 00 00 00 00
и
ntdll.dll: ordinal = 0000003d, rva = 0009d0d8, fileoffs = 0009c4d8, функция VA: 77a9d0d8
диск: a1 5c 81 f9 77 c3 90 90
mem: a1 5c 81 ad 77 c3 90 90
Кто-то сказал мне, что это как-то связано с переездом. Я не могу понять это, однако, и я не нашел никакой документации о том, как это применимо здесь.
У кого-нибудь есть информация или ссылки по этому поводу? Или кто-нибудь знает, где я терплю неудачу?
Большое спасибо заранее.
РЕДАКТИРОВАТЬ: DLL загружаются в соответствии с их предпочтительной базой изображений (при сравнении OptionalHeader.ImageBase с базовым адресом загруженного модуля в памяти).
Поэтому я застреваю, пытаясь понять, почему может быть разница - например. выше: почему 1312 функций в ntdll, кажется, совпадают, а 1313 - нет.