Добрый день, к сожалению у меня нету платформы x64, так что проверить самостоятельно не могу. Может ли мне кто-то подсказать, как загрузчику удаётся обработать релоки в такой конструкции volatile struct q{ ... } Hello; volatile struct p { DWORD m; } variable = { (DWORD)&Hello }; Обрабатывая релоки в ручную, IMAGE_REL_BASED_DIR64 предполагает в этом [(DWORD)&Hello] месте прибавить 64х битный адрес, в то время как поле 32х битное. Спасибо! ( в приложении я прикрепил функцию, которую я написал для этой задачи )
Вообще variable = { (DWORD)&Hello } выглядит как динамическая инициализация. Тогда при использовании rip-relative адресации в этом месте не будет релоков вообще: Код (Text): lea rax, [rip + Hello] mov dword [rip + varialbe], eax
спасибо за ваш ответ, но всё же, она там есть. в приложении я прикрепил файл, в котором используется такая структура. Дело в том, что это не динамическая инициализация. вот код, который генерируется компилятором Visual Studio 2008: (обратите внимание на то, что адреса указаны, как FLAT) Код (Text): ?m_Thunks@@3RCU_IMAGE_THUNK_DATA64@@C DQ FLAT:?m_NameList@@3PAUimport_by_name_s@@A ; m_Thunks DQ FLAT:?m_NameList@@3PAUimport_by_name_s@@A+22 DQ FLAT:?m_NameList@@3PAUimport_by_name_s@@A+44 DQ 0000000000000000H ?m_Thunks2@@3RCU_IMAGE_THUNK_DATA64@@C DQ FLAT:?m_NameList@@3PAUimport_by_name_s@@A+176 ; m_Thunks2 DQ 0000000000000000H ?m_NameList@@3PAUimport_by_name_s@@A DW 00H ; m_NameList DB 'GetModuleHandleA', 00H ORG $+3 DW 00H DB 'LoadLibraryA', 00H ORG $+7 DW 00H DB 'GetProcAddress', 00H ORG $+5 DW 00H DB 'FreeLibrary', 00H ORG $+8 DW 00H DB 'VirtualAlloc', 00H ORG $+7 DW 00H DB 'VirtualProtect', 00H ORG $+5 DW 00H DB 'KERNEL32.DLL', 00H ORG $+7 DW 00H DB 'USER32.DLL', 00H ORG $+9 DW 00H DB 'EnumChildWindows', 00H ORG $+3 ORG $+2 ?ProtectionFlags@@3PAY111HA DD 01H ; ProtectionFlags DD 08H DD 02H DD 04H DD 010H DD 080H DD 020H DD 040H ?m_IID@@3RCU_IMAGE_IMPORT_DESCRIPTOR@@C DD FLAT:?m_Thunks@@3RCU_IMAGE_THUNK_DATA64@@C ; m_IID DD 00H DD 00H DD FLAT:?m_NameList@@3PAUimport_by_name_s@@A+134 DD FLAT:?m_Thunks@@3RCU_IMAGE_THUNK_DATA64@@C DD FLAT:?m_Thunks2@@3RCU_IMAGE_THUNK_DATA64@@C DD 00H DD 00H DD FLAT:?m_NameList@@3PAUimport_by_name_s@@A+156 DD FLAT:?m_Thunks2@@3RCU_IMAGE_THUNK_DATA64@@C DD 00H ORG $+16 inject ENDS
Ага, мы так и восприняли на самом деле. Хм... Посмотрели в VS2008: Вариант1. Код (Text): struct A {} a; struct B { DWORD dummy; // sizeof(dummy) == _4_ }; volatile B b = {(DWORD)&a}; Переменная b инициализируется динамически (не во время компиляции). Именно с использованием rip-relative адресации, без релоков. Вариант2. Код (Text): struct A {} a; struct B { size_t dummy; // sizeof(dummy) == _8_ }; volatile B b = {(size_t)&a}; Переменная b инициализируется статически (во время компиляции). Нужны релоки. Но в этом случае и размер поля == 64бита. В приложенном коде ничего не понятно Имелась в виду m_Thunks[] = { {(ULONGLONG)&m_NameList[id_GetModuleHandle]}, ... }? Но sizeof(ULONGLONG) == 8. Размер поля 64бита.
Если нет реальной машины, заюзай QEMU. Ось может и не потянет (А может и запуститься, я не проверял), но легко переводится в 64 битный режим и можно дальше тестить ваши релоки самостоятельно) А вообще купите Pentium D или Amd Athlon X2 64 простенький. Дешево и сердито.