Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/26: Рейтинг темы: голосов - 26, средняя оценка - 4.50
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21

Сплайсинг (хук)

29.11.2014, 20:36. Показов 4931. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть библиотека с модифицированной функцией для сплайсинга
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
BOOL WINAPI DllMain(
  _In_  HINSTANCE hinstDLL,
  _In_  DWORD fdwReason,
  _In_  LPVOID lpvReserved
)
{
    DWORD call_addr;
    DWORD old_protect = 0;
    BYTE* jump;
    DWORD* jump_addr;
 
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            call_addr = (DWORD)GetProcAddress(GetModuleHandle("some_lib.dll"), "some_func");
            if (!VirtualProtect((void*)call_addr, 10, PAGE_EXECUTE_READWRITE, &old_protect))
                return FALSE;
            addr = call_addr + 5;
            jump = (BYTE*)call_addr;
            jump_addr = (DWORD*)(jump + 1);
            *jump = 0xE9;
            *jump_addr = (DWORD)Hook_Func - (call_addr + 5);
            VirtualProtect((void*)call_addr, 10, old_protect, &old_protect);
        break;
    }
    return TRUE;
}

и приложение для инжекта библиотеки в процесс
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int CALLBACK WinMain(
  _In_  HINSTANCE hInstance,
  _In_  HINSTANCE hPrevInstance,
  _In_  LPSTR lpCmdLine,
  _In_  int nCmdShow
)
{
    PROCESS_INFORMATION procInfo = StartProcess("app.exe");
    hProc = procInfo.hProcess;
    Inject(procInfo.dwProcessId, "hook.dll");
    
    return 0;
}

При запуске app.exe получается так, что библиотека инжектится быстрее чем загружается some_lib.dll и естественно хук не срабатывает. Как и где нужно сделать Wait?
я вижу это так - приложение останавливает загрузку той программы, которая вызывает some_lib.dll (причём на адресе этой some_lib.dll), посылает команду Inject и ждёт ответа от хука.

для более понятного объяснения я напишу пример кода программы, которая вызывает some_lib.dll и в которую нужно проинжектить хук
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void foo()
{
    ...
    HMODULE hMod = LoadLibrary("some_lib.dll");
    // после загрузки some_lib.dll мне сразу нужно загрузить свою библиотеку
    // LoadLibrary("hook.dll");
    GetProcAddress(hMod, "some_func");
    ...
}
 
int WINAPI WinMain(...)
{
    ...
    foo();
    ...
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.11.2014, 20:36
Ответы с готовыми решениями:

Хук клавиатуры
Нужно написать глобальный хук для клавиатуры. Сам хук у меня уже есть, но не могу никак проверить введено ли ключевое слово. Например, если...

Хук на процесс
Добрый день. Подскажите, как установить хук на отдельный процесс, к примеру на Mozilla Firefox. А если есть возможность, приведите...

Хук создания окна
сам хук я установил public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam) это функция хука по каким параметрам и...

18
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.11.2014, 21:07
Лучший ответ Сообщение было отмечено _lunar_ как решение

Решение

Пара вариантов, на выбор:

1. Запустить процесс с флагом DEBUG_PROCESS (отладка), затем
дождаться с помощью WaitForDebugEvent загрузки нужной dll и
после этого поставить хук.

2. Запустить из DllMain поток, и уже из него ставить хук.
Поток начнет работать только после того, как будут проинициализированы
точки входа всех статически слинкованных dll.

3. Похукать ntdll!LdrLoadDll и из нее ловить загружаемые dll.

Лично я за вариант 2 как наиболее безопасный (к моменту запуска функции
потока нужная dll гарантированно будет загружена и проинициализирована).
1
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21
29.11.2014, 22:09  [ТС]
2 вариант вроде то, что нужно. Спасибо, буду пробовать.

Добавлено через 17 минут
к сожалению не получилось. Сделал так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
BOOL WINAPI Hook()
{
    DWORD call_addr;
    DWORD old_protect = 0;
    BYTE* jump;
    DWORD* jump_addr;
 
    call_addr = (DWORD)GetProcAddress(GetModuleHandle("some_lib.dll"), "some_func");
    if (!VirtualProtect((void*)call_addr, 10, PAGE_EXECUTE_READWRITE, &old_protect))
        return FALSE;
    addr = call_addr + 5;
    jump = (BYTE*)call_addr;
    jump_addr = (DWORD*)(jump + 1);
    *jump = 0xE9;
    *jump_addr = (DWORD)Hook_Func - (call_addr + 5);
    VirtualProtect((void*)call_addr, 10, old_protect, &old_protect);
    return TRUE;
}
 
BOOL WINAPI DllMain(
  _In_  HINSTANCE hinstDLL,
  _In_  DWORD fdwReason,
  _In_  LPVOID lpvReserved
)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Hook, NULL, NULL, NULL);
            break;
    }
}
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.11.2014, 22:47
Цитата Сообщение от _lunar_ Посмотреть сообщение
к сожалению не получилось.
Что именно не получилось ?

Цитата Сообщение от _lunar_ Посмотреть сообщение
BOOL WINAPI Hook()
Неправильная сигнатура.
LPTHREAD_START_ROUTINE - это _stdcall-функция, которая принимает
один параметр (void *) и возвращает DWORD.
0
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21
29.11.2014, 23:05  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Что именно не получилось ?
результат такой же, как и до создания потока и запуска его из DllMain

Цитата Сообщение от Убежденный Посмотреть сообщение
Неправильная сигнатура
если я правильно понял, то так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
DWORD WINAPI Hook(LPVOID)
{
    DWORD call_addr;
    DWORD old_protect = 0;
    BYTE* jump;
    DWORD* jump_addr;
 
    call_addr = (DWORD)GetProcAddress(GetModuleHandle("some_lib.dll"), "some_func");
    VirtualProtect((void*)call_addr, 10, PAGE_EXECUTE_READWRITE, &old_protect);
    addr = call_addr + 5;
    jump = (BYTE*)call_addr;
    jump_addr = (DWORD*)(jump + 1);
    *jump = 0xE9;
    *jump_addr = (DWORD)Hook_Func - (call_addr + 5);
    VirtualProtect((void*)call_addr, 10, old_protect, &old_protect);
    ExitThread(1337);
}
 
BOOL WINAPI DllMain(
  _In_  HINSTANCE hinstDLL,
  _In_  DWORD fdwReason,
  _In_  LPVOID lpvReserved
)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Hook, NULL, NULL, NULL);
            break;
    }
    return true;
}
но опять без результата
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.11.2014, 23:11
Цитата Сообщение от _lunar_ Посмотреть сообщение
результат такой же, как и до создания потока
Dll загружается статически или динамически, через LoadLibrary ?

Добавлено через 1 минуту
И еще неплохо бы узнать, что возвращают GetModuleHandle,
GetProcAddress и VirtualProtect (и какой last error в случае ошибки).
0
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21
29.11.2014, 23:13  [ТС]
динамически, адрес меняется при каждой загрузки. Да через LoadLibrary
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.11.2014, 23:16
А, ну тогда способ 2 отметается.
Ну или можно в функции потока самому позвать LoadLibrary
0
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21
29.11.2014, 23:20  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
можно в функции потока самому позвать LoadLibrary
не совсем понял, можете поподробнее
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.11.2014, 23:24
Вместо того, чтобы ждать появления dll, можно загрузить ее самому.
1
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21
29.11.2014, 23:27  [ТС]
хм, интересно. Сейчас попробую
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.11.2014, 23:32
Если так не получится (а могут быть побочные эффекты, если приложение
рассчитывает на определенный порядок загрузки dll), советую попробовать
вариант с перехватом LdrLoadDll (ntdll.dll), он достаточно простой.
1
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21
29.11.2014, 23:40  [ТС]
да, вариант с вызовом LoadLibrary из потока тоже не сработал.
буду завтра пробовать с LdrLoadDll, правда я никогда не перехватывал LdrLoadDll так что придётся немного почитать
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.11.2014, 23:51
Цитата Сообщение от _lunar_ Посмотреть сообщение
да, вариант с вызовом LoadLibrary из потока тоже не сработал.
Он не может не сработать.
Одно из двух: либо приложение проверяет каким-то образом порядок
загрузки dll, либо, что более вероятно, одна из функций возвращает
по какой-то причине ошибку (но это не проверяется, поэтому
точная диагностика невозможна).

"Портянка" WinAPI-вызовов, где нет ни одного "if" с проверкой успешности -
не самый лучший способ что-то сделать.

В первую очередь данный код нужно улучшить в плане
обработки ошибок:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
HMODULE const hModule = GetModuleHandle(...);
 
if (NULL == hModule)
{
    LOG_ERROR(last error такой-то);
    return;
}
 
PVOID Addr = GetProcAddress(...);
 
if (NULL == Addr)
{
    LOG_ERROR(last error такой-то);
    return;
}
 
if (FALSE == VirtualProtect(...))
{
    LOG_ERROR(last error такой-то);
    return;
}
 
// ...
Здесь вы точно будете знать, почему "не работает".
1
286 / 192 / 56
Регистрация: 25.12.2012
Сообщений: 640
02.12.2014, 16:50
Да тут проще всего приатачить вашу dll к нужной dll и все дела. Для этого даже программы есть , делается как дважды два проще простого.
0
120 / 142 / 46
Регистрация: 31.10.2014
Сообщений: 721
Записей в блоге: 1
02.12.2014, 17:00
Как вариант использовать Microsoft Detours Library

Хуки это просто

Пример
0
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21
03.12.2014, 20:18  [ТС]
Цитата Сообщение от maxillion Посмотреть сообщение
Да тут проще всего приатачить вашу dll к нужной dll и все дела.
боюсь вы не совсем поняли что требуется. Мне не нужен способ хука, мне нужно проинжектить dll в определённый момент в определённое место. Напишите как буду благодарен, а уж как это реализовать я разберусь сам.
0
286 / 192 / 56
Регистрация: 25.12.2012
Сообщений: 640
03.12.2014, 21:46
Я не понимаю зачем ждать загрузки some_lib.dll и потом её править, если можно сразу её модифицировать (или в вашем случае нельзя сразу ?). Создаёте dll цепляете её к some_lib.dll (путём правки таблицы импорта ) . Это гарантирует что в момент выполнения DllMain (вашей dll) some_lib.dll будет уже загружен.

Добавлено через 7 минут
К стати вариант хука у вас не самый лучший. Я бы на вашем месте модифицировал таблицу импорта, переписать пришлось бы только один DWORD.

Добавлено через 30 минут
Как вариант можно похукать LdrpLoadImportModule.
1
120 / 142 / 46
Регистрация: 31.10.2014
Сообщений: 721
Записей в блоге: 1
04.12.2014, 04:51
Может использовать Microsoft Detours ?

Хуки — это просто

пример
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.12.2014, 04:51
Помогаю со студенческими работами здесь

Хук, скрытие окна
установил хук на окно. заметил следующее. используя функцию ShowWindows если я хочу задать стиль отличный от SW_HIDE то всё проходит. а...

Не срабатывает хук WH_GETMESSAGE
не могу понять, почему не срабатывают ловушки, помогите, пожалуйста библиотека HookDll HookDll.h #include <Windows.h> ...

Хук на события сохранения
Здравствуйте, уважаемые форумчане! Не могу разобраться вот с такой задачей: необходимо перехватывать запись любых файлов на жесткий...

Перехват (хук) функции
Всем привет. Есть exe c кодом: #include <iostream> #include <Windows.h> int sum(int a, int b) { return a + b; } int...

Хук перестает работать
собственно хук на событие клавы LRESULT CALLBACK KeyboardProc(int nCode, DWORD wParam, DWORD lParam) { switch(wParam) { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru