Здравствуйте. Моя проблема такова: есть программа, она грузит сначала свою длл-ку, потом ту длл-ку, которая ей была указана ключом. Так вот, когда я пытаюсь из длл-ки, которая была указана ключом (то есть загружена второй) прочитать PE-заголовок первой длл-ки, мне выдает access violation, и даже VirtualProtect отказывается менять атрибуты защиты к области памяти заголовка. Это так и должно быть или я что-то неправильно делаю (если что, указатель на заголовок длл заведомо правильный)? Может быть, попробовать делать все через ReadProcessMemory\WriteProcessMemory? Заранее спасибо.
ну да, ну да, а раки синии ). Либо неправильно задаешь, либо выходишь за границы отображения, либо вместо чтения пытаешься писать туда. Код приведи.
Вот код: Код (Text): void hook_exported_function(DWORD module, char *func_name, DWORD hook_func) { DWORD temp; PIMAGE_OPTIONAL_HEADER opt_hdr = (PIMAGE_OPTIONAL_HEADER)(module + 0x3c + sizeof(IMAGE_FILE_HEADER)); PIMAGE_EXPORT_DIRECTORY edt = (PIMAGE_EXPORT_DIRECTORY)(opt_hdr->DataDirectory[0].VirtualAddress + module); char **names = (char **)(edt->AddressOfNames + module); DWORD *funcs = (DWORD *)(edt->AddressOfFunctions + module); int i; for(i = 0; i < edt->NumberOfNames; i++) { if(!strcmp(names[i], func_name)) break; } VirtualProtect((PVOID)(edt->AddressOfFunctions + module + i), 4, PAGE_READWRITE, &temp); // сомневаюсь насчет того, нужно ли это funcs[i] = (hook_func - module); VirtualProtect((PVOID)(edt->AddressOfFunctions + module + i), 4, temp, &temp); } Собственно, ошибка возникает, когда инициализирую edt. Нееет, все заведомо правильно, это я точно знаю . Первая длл всегда грузится по адресу 0х30000000 вторая - по 0х35000000. Знаю, что закладываться на это - неправильно, но специфика конкретно этой программы такова, что эти адреса всегда свободны для длл-ок. P.S. На мой метод хука экспорта не ругайтесь, не зря я вторую длл гружу выше, чем первую, поэтому тут можно так хукать .
x_000 Код (Text): PIMAGE_OPTIONAL_HEADER opt_hdr = (PIMAGE_OPTIONAL_HEADER)(module + 0x3c + sizeof(IMAGE_FILE_HEADER)); В первой строчке уже ерунда какая-то. По смещению 3Ch хранится смещение PE-заголовка, а не его начало.
l_inc Эээ, маленькая опечатка. Это я старую функцию выложил, в новой писал Код (Text): (module + (DWORD)*(module + 0x3c) + sizeof(IMAGE_FILE_HEADER) , но тоже ничего не работает. Не читается даже MZ-сигнатура.
и во вторых. Дай код, в котором грузишь модуль и получаешь его базу. Что-то подсказывает, что ошибка там.
intel_x128 Да, насчет четырех байтов - это я оплошал, спасибо за замечание. А база модуля конкретно в этой программе всегда постоянная - 0х30000000. К слову о получении базы модуля - вроде как GetModuleHandle выдает как раз указатель на начало образа? Или я не прав?
x_000 Прав. Поэтому чтобы не гадать, дай кусок кода, которым получаешь базу образа. И кусок кода, где вызываешь функцию.
Ничего особенного в этом куске нет, вот он: Код (Text): HMODULE hMainDll = GetModuleHandle("main.dll"); hook_exported_function((DWORD)hMainDll, "CreateInterface", (DWORD)CreateInterfaceHook); Сейчас попробую сделать чтение\запись через Read\WriteProcessMemory.
гм. Скомпилил. Работает. Скинь в пм модуль - отдебажим. Приватный функционал можешь поубирать нафиг. Наличие дебаг-символов приветствуются.
Хм, через ReadProcessMemory тоже ничего не выводит. Похоже, это уже специфика программы. Буду дальше мучаться с ее дизассемблированием. Спасибо за ответы. P.S. А существует какие-нибудь средства для процесса ограничивать права доступа своих загружаемых длл-ок?
Код (Text): char **names = (char **)(edt->AddressOfNames + module); ... for(i = 0; i < edt->NumberOfNames; i++) { if(!strcmp(names[i], func_name)) break; } Омфг, ты формат хотябы читал? В таблице имен хранятся RVA ... Естественно при names ты не попадаешь в отображение и в strcmp у тебя будет access violation. Нормализуй адреса имен функций!