![]() |
eXeL@B —› Программирование —› Хук API в стартующем процессе |
Посл.ответ | Сообщение |
|
Создано: 18 сентября 2009 10:10 · Поправил: Hexxx · Личное сообщение · #1 Мне нужно захучить функцию DirectInput8Create, для того чтобы иметь возможность подменять результаты некоторых функций IDirectInput8. Но, я хочу это сделать так чтобы моя программа, стартовала указанную и хучила DirectInput8Create только в ней. Глобальный хук мне не нужен. Проблема в том, что DirectInput8Create может быть в импорте, а может быть, что вызывается через LoadLibrary - GetProcAddress. Поэтому хук импорта отпадает. Можно конечно прописаться в AppInitDlls, но мне этот метод ненравится, если моя DLL что-то будет делать не так, система ляжет. Вся фигня в том, что DirectInput8Create обычно всего один раз на старте программы вызывается и все, дальше уже ничего не сделать. Есть идеи как можно направлено хучить функцию в указаном процессе во время его старта? ----- Реверсивная инженерия - написание кода идентичного натуральному ![]() |
|
Создано: 18 сентября 2009 10:32 · Личное сообщение · #2 |
|
Создано: 18 сентября 2009 10:59 · Личное сообщение · #3 |
|
Создано: 18 сентября 2009 11:15 · Поправил: ARCHANGEL · Личное сообщение · #4 Если с фанатизмом, то можно исрользовать простой цикл отладки, т.е. пишешь мини-отладчик, на ЕР лепишь int3, когда получаешь исключение breakpoint, а адрес, по которому оно произошло, равен ЕР+1, то это как раз оно, всё остальное - EXCEPTION_NOT_HANDLED, когда такое произошло, то если либа статически прилинкована, то она уже в АП процесса и можно перехватывать, если она подгружается динамически, то на ЕР можно внедрить базонезависимый код, который её подгрузит, а потом перехватить. Далее под ХР и старше - -DebugActiveProcessStop, в остальных - младших версиях, чистим значение DebugPort в EPROCESS целевого процесса. Где-то так... ----- Stuck to the plan, always think that we would stand up, never ran. ![]() |
|
Создано: 18 сентября 2009 11:33 · Личное сообщение · #5 Если глобально - то Flint и ARCHANGEL правы. Но, если нужна именно DirectInput8Create: Посмотри дизасм: она читает данные с реестра и, если нужно, подгружает dinput8d.dll (типа - debug версию). Потом идёт попытка вызвать функцию DirectInput8Create из dinput8d.dll. НО-если функции DirectInput8Create там нету, dinput8d.dll из памяти не выгружается! Напиши свою dinput8d.dll, запиши правильный ключ в реестре, а из своей DllMain() поставишь хуки/поменяешь значения в памяти. ![]() |
|
Создано: 18 сентября 2009 11:39 · Личное сообщение · #6 Продолжим рубрику "с фанатизмом" ![]() ----- Stuck to the plan, always think that we would stand up, never ran. ![]() |
|
Создано: 18 сентября 2009 16:19 · Поправил: Hexxx · Личное сообщение · #7 Спасибо. Мне вариант флинта понравился. Моя идея немного модифицированная. Запускаем процесс в suspended. Пишем свой код, который загрузит нужный хук. Патчим EP джампом на свой код. А в конце своего код, а делаем возврат к EP. Отпускаем процесс. ----- Реверсивная инженерия - написание кода идентичного натуральному ![]() |
|
Создано: 18 сентября 2009 19:29 · Личное сообщение · #8 |
|
Создано: 18 сентября 2009 19:40 · Поправил: Nightshade · Личное сообщение · #9 |
|
Создано: 18 сентября 2009 19:43 · Личное сообщение · #10 Лучше меняй в новом процессе eip на свой код, а в конце пиши джамп на оеп. Или просто меняй еп на свой код. Потом в памяти можно поменять назад, если заботит крк. Вставлять джамп на свой код на еп - значит заморачиватся с анализом длин команд. Проще изменить еп. Можно хучить импорт и грузить библу вручную. Можно хучить экспорт. Можно положить библу с прописаннным хуком в папку, но ты привяжешься к винде. ![]() |
|
Создано: 18 сентября 2009 19:53 · Поправил: uinor · Личное сообщение · #11 Если не говорить концептуально, а стремиться только к реализации: У madshi.net был, кстати, пример хука для DX. madHooks - удобная вещь (если Delphi/Builder, но вроде умеет и с остальным). + Возможно вот ![]() |
|
Создано: 18 сентября 2009 20:30 · Личное сообщение · #12 |
|
Создано: 19 сентября 2009 16:48 · Личное сообщение · #13 Nightshade пишет: Лучше меняй в новом процессе eip на свой код, а в конце пиши джамп на оеп. Или просто меняй еп на свой код. Потом в памяти можно поменять назад, если заботит крк. Вставлять джамп на свой код на еп - значит заморачиватся с анализом длин команд. Проще изменить еп. А я что написал? sendersu пишет: DirectX Logger у rustema (black_ninja) можно посмотреть Если с сорцами то интересно. А где взять? ----- Реверсивная инженерия - написание кода идентичного натуральному ![]() |
|
Создано: 20 сентября 2009 17:44 · Личное сообщение · #14 ARCHANGEL Зачем же такие извращения. Отладчик получит сообщение при проецировании файловой секции. Туда записывайте останов и всё на этом. Hexxx Вобщем если импорт динамический, тогда необходимо отслеживать LdrGetProcedureAddress(). Например шим-нотификация(g_pfnSE_GetProcAddress, LdrInitShimEngineDynamic()). Или точек останова на загрузчик поставить. ![]() |
|
Создано: 21 сентября 2009 04:58 · Личное сообщение · #15 Hexxx пишет: Патчим EP джампом на свой код. А в конце своего код, а делаем возврат к EP. Отпускаем процесс. Это не совсем надежно, т.к. до исполнения EP могут исполняться TLS и загружаться статически импортируемые dll программы, откуда может быть вызван DirectInput8Create. Для надежного хука нужно инжектировать кусок базонезависимого кода и править EIP первого потока процесса до его запуска. Базонезависимый код, используя только ф-и ntdll, перехватывает NtMapViewOfSection для отслеживания загрузки dll, и патчит экспорты dinput8.dll сразу после создания соответствующей ей секции. Для работы базонезависимому коду потребуется как минимум адреса NtMapViewOfSection и NtProtectVirtualMemory, которые можно взять простым GetProcAddress в своём процессе. Внимание: использование чего-либо кроме ntdll недопустимо, ибо вносит непредсказуемые глюки. Запускать процесс под отладкой не советую, оно может и проще, но не универсально, т.к. игра может содержать антиотладку. ----- PGP key ![]() |
|
Создано: 21 сентября 2009 08:42 · Личное сообщение · #16 |
|
Создано: 21 сентября 2009 09:03 · Личное сообщение · #17 Clerk пишет: Зачем же такие извращения. Отладчик получит сообщение при проецировании файловой секции. Туда записывайте останов и всё на этом. Наверное, имелось ввиду, что отладчик получает сообщение при подгрузке библиотеки. Ну, тогда да, такие извраты не требуются. Всё хорошо и гладко, пока не используются антидебаговые трюки, тогда в отладчике загрузки библиотеки можно никогда и не дождаться. ![]() Rustem пишет: А если просто закинуть в папку с прогой свою dinput.dll С экспортом? Прокси длл короче А из нее уже подгружать оригинальную Если не ошибаюсь, данный метод пришёл на этот топик из "Программирования драйверов и систем безопасности" Сорокиной и компании - вот это действительно не было людям покоя. А если библиотека, которую мы хотим заменить, системная - например, ntdll.dll? А если она просто грузится статически? Люди, которые это написали, слышали вообще про Windows File Protection, порядок поиска динамических модулей для загрузки, проактивную защиту антивирусов? Нормально работать это будет только в приложении, где требуется перехватывать функции из самопальных библиотек. ntldr пишет: ...до исполнения EP могут исполняться TLS и загружаться статически импортируемые dll программы, откуда может быть вызван DirectInput8Create. Могут, но это, к счастью, не очень часто происходит. Запускать процесс под отладкой не советую, оно может и проще, но не универсально, т.к. игра может содержать антиотладку. Смелое, но мне кажется, безосновательное утверждение. Ничего не мешает, используя, Debug API, остановиться на начале TLS Callback, т.к. первый int3 лежит в недрах загрузчика и срабатывает раньше этого колбэка, и раньше нехороших DllEntryPoint'ов нехороших билиотек. А после перехвата отладчик можно (и нужно) отсоединить. ----- Stuck to the plan, always think that we would stand up, never ran. ![]() |
|
Создано: 21 сентября 2009 11:41 · Личное сообщение · #18 |
|
Создано: 21 сентября 2009 12:50 · Личное сообщение · #19 > Люди, которые это написали, слышали вообще про Windows File Protection, порядок поиска динамических модулей для загрузки, проактивную защиту антивирусов Какой-то поток сознания ![]() Или можно прочитать ключ Shell из реестра и похукатьв процессе шела функции запуска процесса. ----- Shalom ebanats! ![]() |
|
Создано: 21 сентября 2009 16:21 · Личное сообщение · #20 |
|
Создано: 21 сентября 2009 17:21 · Личное сообщение · #21 ARCHANGEL пишет: Могут, но это, к счастью, не очень часто происходит. ИМХО если делать, то надо делать правильно, а не надеяться на авось. В серьезном продукте всякие "не очень часто" всегда вылезают в огромный гимор. ARCHANGEL пишет: Смелое, но мне кажется, безосновательное утверждение. Ничего не мешает, используя, Debug API, остановиться на начале TLS Callback, т.к. первый int3 лежит в недрах загрузчика и срабатывает раньше этого колбэка, и раньше нехороших DllEntryPoint'ов нехороших билиотек. А после перехвата отладчик можно (и нужно) отсоединить. Когда кажется, крестится надо. Единственный смысл запуска под отладкой в том, чтобы отслеживать загрузку DLL через debug евенты, а для этого процесс должен быть под отладкой постоянно, что автоматически тянет за собой многочисленные проблемы с антиотладкой, решить которые будет труднее, чем сделать по моему совету. ----- PGP key ![]() |
|
Создано: 22 сентября 2009 13:17 · Личное сообщение · #22 ntldr Покрестившись до боли в запястье, вернулся к решению вопроса. ![]() Единственный смысл запуска под отладкой в том, чтобы отслеживать загрузку DLL через debug евенты Без обид - полный бред. Зачем нужны эти ивенты, когда следует выполнить перехват функций конкретной библиотеки? Дождались один раз, пока она подгрузится, перехватили, отсоединились. А что там дальше происходит - не наши проблемы. Или имеется ввиду, что на перехватываем функцию ставится точка останова? Но зачем? Таким способом перехват делать - лишний геморрой. ----- Stuck to the plan, always think that we would stand up, never ran. ![]() |
|
Создано: 22 сентября 2009 13:34 · Личное сообщение · #23 ARCHANGEL пишет: Без обид - полный бред. Без обид, но почитайте MSDN и подучите матчасть. ARCHANGEL пишет: Зачем нужны эти ивенты, когда следует выполнить перехват функций конкретной библиотеки? Хотелось бы вам напомнить, что иногда стоит подумать, прежде чем сказать. И если чуток подумать, то станет ясно, что нельзя перехватывать ф-и библиотеки, если она еще не загружена в процесс, а загрузиться и выгрузиться любая DLL, за редким исключением, может в любой момент. Если еще немного подумать и почитать главу MSDN посвященную Debugging Events, то можно обратить внимание на LOAD_DLL_DEBUG_EVENT. Ну а если до конца включить мозги, то можно даже допереть, что использование этого евента - это единственная причина для запуска процесса под отладкой, и такой подход упрощает написание кода. Если же мы не используем LOAD_DLL_DEBUG_EVENT, то нам не нужно запускать процесс с флагом DEBUG_PROCES, и этим мы избежим множества проблем с антиотладкой, что я и пытаюсь вам растолковать. Надеюсь до вас дошло, больше повторять не буду. ----- PGP key ![]() |
|
Создано: 22 сентября 2009 13:41 · Личное сообщение · #24 |
|
Создано: 22 сентября 2009 16:46 · Личное сообщение · #25 ARCHANGEL Сосредоточтесь. Повторяю сообщение доставляется не при загрузке модуля, а при проецировании файловой секции: Code:
Как думаете что в Eip контекста - верно, адрес возврата(если быстрый, то KiFastSystemCallRet) из сервиса NtMapViewOfSection. Это обусловлено тем, что сообщение доставляется из ядра, а в трап-фрейм загружен адрес возврата есчо при сохранении состояния задачи. Никаких других сообщений при/после загрузки модуля отладчик не получит, то - единственное ![]() ![]() |
![]() |
eXeL@B —› Программирование —› Хук API в стартующем процессе |
Эта тема закрыта. Ответы больше не принимаются. |