Сейчас на форуме: tyns777, zds, JustLife, 2nd, morgot, Rio, CDK123 (+4 невидимых)

 eXeL@B —› Программирование —› Хук API в стартующем процессе
Посл.ответ Сообщение

Ранг: 481.4 (мудрец), 109thx
Активность: 0.180
Статус: Участник
Тот самый :)

Создано: 18 сентября 2009 10:10 · Поправил: Hexxx
· Личное сообщение · #1

Мне нужно захучить функцию DirectInput8Create, для того чтобы иметь возможность подменять результаты некоторых функций IDirectInput8. Но, я хочу это сделать так чтобы моя программа, стартовала указанную и хучила DirectInput8Create только в ней. Глобальный хук мне не нужен. Проблема в том, что DirectInput8Create может быть в импорте, а может быть, что вызывается через LoadLibrary - GetProcAddress. Поэтому хук импорта отпадает. Можно конечно прописаться в AppInitDlls, но мне этот метод ненравится, если моя DLL что-то будет делать не так, система ляжет.

Вся фигня в том, что DirectInput8Create обычно всего один раз на старте программы вызывается и все, дальше уже ничего не сделать.

Есть идеи как можно направлено хучить функцию в указаном процессе во время его старта?

-----
Реверсивная инженерия - написание кода идентичного натуральному





Ранг: 238.8 (наставник), 67thx
Активность: 0.20
Статус: Участник
CyberHunter

Создано: 18 сентября 2009 10:32
· Личное сообщение · #2

Создавай приостановленный процесс, выделяй в нем память и переключай EP в контексте на нее, далее туда записывай загрузчик который загрузит необходимую dll и установит хук (обработчик там же в загрузчике отдельной функцией) далее отдать управление на OEP

-----
Nulla aetas ad discendum sera




Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 18 сентября 2009 10:59
· Личное сообщение · #3

Посмотри AdvApiHook by MsRem




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 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.




Ранг: 42.1 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 18 сентября 2009 11:33
· Личное сообщение · #5

Если глобально - то Flint и ARCHANGEL правы.

Но, если нужна именно DirectInput8Create: Посмотри дизасм: она читает данные с реестра и, если нужно, подгружает dinput8d.dll (типа - debug версию). Потом идёт попытка вызвать функцию DirectInput8Create из dinput8d.dll. НО-если функции DirectInput8Create там нету, dinput8d.dll из памяти не выгружается!
Напиши свою dinput8d.dll, запиши правильный ключ в реестре, а из своей DllMain() поставишь хуки/поменяешь значения в памяти.




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 18 сентября 2009 11:39
· Личное сообщение · #6

Продолжим рубрику "с фанатизмом". Можно править таблицу импорта, т.е. добавить туда свой IMAGE_IMPORT_DESCRIPTOR, это делается для того, чтоб билиотека, в которой мы желаем перехватить функцию, грузилась статически. Тогда можно не заморачиваться с базонезависимостью.

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 481.4 (мудрец), 109thx
Активность: 0.180
Статус: Участник
Тот самый :)

Создано: 18 сентября 2009 16:19 · Поправил: Hexxx
· Личное сообщение · #7

Спасибо. Мне вариант флинта понравился.

Моя идея немного модифицированная. Запускаем процесс в suspended. Пишем свой код, который загрузит нужный хук. Патчим EP джампом на свой код. А в конце своего код, а делаем возврат к EP. Отпускаем процесс.

-----
Реверсивная инженерия - написание кода идентичного натуральному





Ранг: 605.2 (!), 341thx
Активность: 0.470.25
Статус: Модератор
Research & Development

Создано: 18 сентября 2009 19:29
· Личное сообщение · #8

в целевом процессе до выполнения EP вызываешь такой код:

* LoadLibrary для Dinput8.dll - библиотека подгружается в память
* хукаешь DirectInput8Create
* отпускаешь процесс

всё

-----
EnJoy!





Ранг: 241.9 (наставник), 107thx
Активность: 0.140.01
Статус: Участник

Создано: 18 сентября 2009 19:40 · Поправил: Nightshade
· Личное сообщение · #9

Удалено




Ранг: 241.9 (наставник), 107thx
Активность: 0.140.01
Статус: Участник

Создано: 18 сентября 2009 19:43
· Личное сообщение · #10

Лучше меняй в новом процессе eip на свой код, а в конце пиши джамп на оеп. Или просто меняй еп на свой код. Потом в памяти можно поменять назад, если заботит крк. Вставлять джамп на свой код на еп - значит заморачиватся с анализом длин команд. Проще изменить еп.
Можно хучить импорт и грузить библу вручную. Можно хучить экспорт. Можно положить библу с прописаннным хуком в папку, но ты привяжешься к винде.



Ранг: 18.6 (новичок)
Активность: 0.010
Статус: Участник

Создано: 18 сентября 2009 19:53 · Поправил: uinor
· Личное сообщение · #11

Если не говорить концептуально, а стремиться только к реализации:

У madshi.net был, кстати, пример хука для DX. madHooks - удобная вещь (если Delphi/Builder, но вроде умеет и с остальным).

+ Возможно вот --> это <-- поможет.



Ранг: 512.7 (!), 360thx
Активность: 0.270.03
Статус: Модератор

Создано: 18 сентября 2009 20:30
· Личное сообщение · #12

DirectX Logger у rustema (black_ninja) можно посмотреть



Ранг: 481.4 (мудрец), 109thx
Активность: 0.180
Статус: Участник
Тот самый :)

Создано: 19 сентября 2009 16:48
· Личное сообщение · #13

Nightshade пишет:
Лучше меняй в новом процессе eip на свой код, а в конце пиши джамп на оеп. Или просто меняй еп на свой код. Потом в памяти можно поменять назад, если заботит крк. Вставлять джамп на свой код на еп - значит заморачиватся с анализом длин команд. Проще изменить еп.

А я что написал?

sendersu пишет:
DirectX Logger у rustema (black_ninja) можно посмотреть

Если с сорцами то интересно. А где взять?

-----
Реверсивная инженерия - написание кода идентичного натуральному




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 20 сентября 2009 17:44
· Личное сообщение · #14

ARCHANGEL
Зачем же такие извращения. Отладчик получит сообщение при проецировании файловой секции. Туда записывайте останов и всё на этом.
Hexxx
Вобщем если импорт динамический, тогда необходимо отслеживать LdrGetProcedureAddress(). Например шим-нотификация(g_pfnSE_GetProcAddress, LdrInitShimEngineDynamic()). Или точек останова на загрузчик поставить.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 21 сентября 2009 04:58
· Личное сообщение · #15

Hexxx пишет:
Патчим EP джампом на свой код. А в конце своего код, а делаем возврат к EP. Отпускаем процесс.

Это не совсем надежно, т.к. до исполнения EP могут исполняться TLS и загружаться статически импортируемые dll программы, откуда может быть вызван DirectInput8Create. Для надежного хука нужно инжектировать кусок базонезависимого кода и править EIP первого потока процесса до его запуска.
Базонезависимый код, используя только ф-и ntdll, перехватывает NtMapViewOfSection для отслеживания загрузки dll, и патчит экспорты dinput8.dll сразу после создания соответствующей ей секции.
Для работы базонезависимому коду потребуется как минимум адреса NtMapViewOfSection и NtProtectVirtualMemory, которые можно взять простым GetProcAddress в своём процессе.

Внимание: использование чего-либо кроме ntdll недопустимо, ибо вносит непредсказуемые глюки. Запускать процесс под отладкой не советую, оно может и проще, но не универсально, т.к. игра может содержать антиотладку.

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 74.1 (постоянный), 34thx
Активность: 0.030
Статус: Участник

Создано: 21 сентября 2009 08:42
· Личное сообщение · #16

А если просто закинуть в папку с прогой свою dinput.dll С экспортом? Прокси длл короче
А из нее уже подгружать оригинальную




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 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.




Ранг: 74.1 (постоянный), 34thx
Активность: 0.030
Статус: Участник

Создано: 21 сентября 2009 11:41
· Личное сообщение · #18

ARCHANGEL Под задачу ТС вполне подойдет метод прокси-длл



Ранг: 309.8 (мудрец), 21thx
Активность: 0.170
Статус: Участник

Создано: 21 сентября 2009 12:50
· Личное сообщение · #19

> Люди, которые это написали, слышали вообще про Windows File Protection, порядок поиска динамических модулей для загрузки, проактивную защиту антивирусов
Какой-то поток сознания Клерк всё верно сказал, создание секции это самый удобный момент.
Или можно прочитать ключ Shell из реестра и похукатьв процессе шела функции запуска процесса.

-----
Shalom ebanats!




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 21 сентября 2009 16:21
· Личное сообщение · #20

ARCHANGEL
Существует 7 событий при которых отладчику доставляется сообщение. Проецирование секции одно из таких событий. Другое это если срабатывает точка останова.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 21 сентября 2009 17:21
· Личное сообщение · #21

ARCHANGEL пишет:
Могут, но это, к счастью, не очень часто происходит.

ИМХО если делать, то надо делать правильно, а не надеяться на авось. В серьезном продукте всякие "не очень часто" всегда вылезают в огромный гимор.

ARCHANGEL пишет:
Смелое, но мне кажется, безосновательное утверждение. Ничего не мешает, используя, Debug API, остановиться на начале TLS Callback, т.к. первый int3 лежит в недрах загрузчика и срабатывает раньше этого колбэка, и раньше нехороших DllEntryPoint'ов нехороших билиотек. А после перехвата отладчик можно (и нужно) отсоединить.

Когда кажется, крестится надо. Единственный смысл запуска под отладкой в том, чтобы отслеживать загрузку DLL через debug евенты, а для этого процесс должен быть под отладкой постоянно, что автоматически тянет за собой многочисленные проблемы с антиотладкой, решить которые будет труднее, чем сделать по моему совету.

-----
PGP key <0x1B6A24550F33E44A>





Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 22 сентября 2009 13:17
· Личное сообщение · #22

ntldr
Покрестившись до боли в запястье, вернулся к решению вопроса.
Единственный смысл запуска под отладкой в том, чтобы отслеживать загрузку DLL через debug евенты
Без обид - полный бред. Зачем нужны эти ивенты, когда следует выполнить перехват функций конкретной библиотеки? Дождались один раз, пока она подгрузится, перехватили, отсоединились. А что там дальше происходит - не наши проблемы. Или имеется ввиду, что на перехватываем функцию ставится точка останова? Но зачем? Таким способом перехват делать - лишний геморрой.

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 22 сентября 2009 13:34
· Личное сообщение · #23

ARCHANGEL пишет:
Без обид - полный бред.

Без обид, но почитайте MSDN и подучите матчасть.

ARCHANGEL пишет:
Зачем нужны эти ивенты, когда следует выполнить перехват функций конкретной библиотеки?

Хотелось бы вам напомнить, что иногда стоит подумать, прежде чем сказать. И если чуток подумать, то станет ясно, что нельзя перехватывать ф-и библиотеки, если она еще не загружена в процесс, а загрузиться и выгрузиться любая DLL, за редким исключением, может в любой момент. Если еще немного подумать и почитать главу MSDN посвященную Debugging Events, то можно обратить внимание на LOAD_DLL_DEBUG_EVENT. Ну а если до конца включить мозги, то можно даже допереть, что использование этого евента - это единственная причина для запуска процесса под отладкой, и такой подход упрощает написание кода. Если же мы не используем LOAD_DLL_DEBUG_EVENT, то нам не нужно запускать процесс с флагом DEBUG_PROCES, и этим мы избежим множества проблем с антиотладкой, что я и пытаюсь вам растолковать. Надеюсь до вас дошло, больше повторять не буду.

-----
PGP key <0x1B6A24550F33E44A>





Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 22 сентября 2009 13:41
· Личное сообщение · #24

ntldr
Ну прям как на разных языках. Тут дальше спорить бесполезно, каждый всё равно останется при своём мнении, тем более, автор, думаю, уже давно определился с методом.

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 22 сентября 2009 16:46
· Личное сообщение · #25

ARCHANGEL
Сосредоточтесь. Повторяю сообщение доставляется не при загрузке модуля, а при проецировании файловой секции:
Code:
  1. NtMapViewOfSection(
  2. ...
  3.     Status = MmMapViewOfSection ((PVOID)Section,
  4.                                  Process,
  5.                                  &CapturedBase,
  6.                                  ZeroBits,
  7.                                  CommitSize,
  8.                                  &CapturedOffset,
  9.                                  &CapturedViewSize,
  10.                                  InheritDisposition,
  11.                                  AllocationType,
  12.                                  Win32Protect);
  13.  
  14.     if (!NT_SUCCESS(Status) ) {
  15.  
  16.         if ((Status == STATUS_CONFLICTING_ADDRESSES) &&
  17.             (Section->Segment->ControlArea->u.Flags.Image) &&
  18.             (Process == CurrentProcess)) {
  19.  
  20.             DbgkMapViewOfSection (Section,
  21.                                   CapturedBase,
  22.                                   CapturedOffset.LowPart,
  23.                                   CapturedViewSize);
  24.         }
  25.         goto ErrorReturn;
  26.     }
  27.  
  28.     //
  29.     // Any time the current process maps an image file,
  30.     // a potential debug event occurs. DbgkMapViewOfSection
  31.     // handles these events.
  32.     //
  33.  
  34.     if ((Section->Segment->ControlArea->u.Flags.Image) &&
  35.         (Process == CurrentProcess)) {
  36.  
  37.         if (Status != STATUS_IMAGE_NOT_AT_BASE) {
  38.             DbgkMapViewOfSection (Section,
  39.                                   CapturedBase,
  40.                                   CapturedOffset.LowPart,
  41.                                   CapturedViewSize);
  42.         }
  43.     }

Как думаете что в Eip контекста - верно, адрес возврата(если быстрый, то KiFastSystemCallRet) из сервиса NtMapViewOfSection. Это обусловлено тем, что сообщение доставляется из ядра, а в трап-фрейм загружен адрес возврата есчо при сохранении состояния задачи. Никаких других сообщений при/после загрузки модуля отладчик не получит, то - единственное .


 eXeL@B —› Программирование —› Хук API в стартующем процессе
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати