Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перехват АПИ функций, а толком -то ничего и нет:) 
:(
    Опции темы
Coocky
Дата 6.3.2007, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: нет
Всего: 62



Привет. Нужно перехватит функции создания и запись в файл..
Вообщем с теорией знаком, но НЕ ФИГА не работает. Есть куча примеров (и даже Рихтер).
Все с ошибками и все не работают. Может кто-то подсказать либо пример, либо выложить простенький примерик. Очень надо.. Уже второй день парюсь. Что б не писал. Инет кишма кишит примерами на делфи, а на С++ не рабочие либо не внятные отрывки.
Спасибо


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
Coocky
Дата 6.3.2007, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: нет
Всего: 62



Вижу желающих много, хорошо. Давайте подумаем вместе smile)
Итак, создадим длл, которая будет ставить хуки на прцессы. Код ТУПО передрал с Делфятины, потомы возможны ошибки..
Код

DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    // Remove this if you use lpReserved
    UNREFERENCED_PARAMETER(lpReserved);

    if (dwReason == DLL_PROCESS_ATTACH)
    {
        TRACE0("Iject2.DLL Initializing!\n");
        
        // Extension DLL one-time initialization
        if (!AfxInitExtensionModule(Iject2DLL, hInstance))
            return 0;

        new CDynLinkLibrary(Iject2DLL);

    SetGlobalHook();// Устанавливаем хук
    SetHook();
   
    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        TRACE0("Iject2.DLL Terminating!\n");

        // Terminate the library before destructors are called
        AfxTermExtensionModule(Iject2DLL);
    }
    return 1;   // ok
}


int WINAPI NewMessageBoxExA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType,WORD wLanguageId)
{
  lpText="Byfet";// Тут меняем текст на свой
  return MessageBoxEx(hWnd, lpText, lpCaption, uType, wLanguageId);
}


int WINAPI NewMessageBoxExW(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType,WORD wLanguageId)
{
    DWORD Written ;
    WriteProcessMemory(INVALID_HANDLE_VALUE, MbwAdr, &OldMbw, sizeof(OldCode), &Written);
    pText="Byfet";// Тут меняем текст на свой
    int result= MessageBoxEx(hWnd, lpText, lpCaption, uType, wLanguageId);
    WriteProcessMemory(INVALID_HANDLE_VALUE, MbwAdr,&JmpMbw, sizeof(far_jmp),& Written);

  return result;
}


void  SetHook()
{
  // Это метода джампа, путем подмены адреса нужной функции на адрес своей и обратно
HMODULE hUser32;
DWORD Bytes;
hUser32 = GetModuleHandle("user32.dll");
MbwAdr = GetProcAddress(hUser32, "MessageBoxExW");
MbaAdr = GetProcAddress(hUser32, "MessageBoxExA");
  ReadProcessMemory(INVALID_HANDLE_VALUE, MbwAdr, &OldMbw, sizeof(OldCode), &Bytes);
  ReadProcessMemory(INVALID_HANDLE_VALUE, MbaAdr, &OldMba, sizeof(OldCode), &Bytes);
  JmpMbw.PuhsOp  = 0x68;
  JmpMbw.PushArg = &NewMessageBoxExW;
  JmpMbw.RetOp   = 0xC3;
  JmpMba.PuhsOp  = 0x68;
  JmpMba.PushArg = &NewMessageBoxExA;
  JmpMba.RetOp   = 0xC3;
  WriteProcessMemory(INVALID_HANDLE_VALUE, MbwAdr, &JmpMbw, sizeof(far_jmp), &Bytes);
  WriteProcessMemory(INVALID_HANDLE_VALUE, MbaAdr, &JmpMba, sizeof(far_jmp), &Bytes);
  
}


void Unhook()
{
  DWORD Bytes;
  WriteProcessMemory(INVALID_HANDLE_VALUE, MbaAdr, &OldMba, sizeof(OldCode), &Bytes);
  WriteProcessMemory(INVALID_HANDLE_VALUE, MbwAdr, &OldMbw, sizeof(OldCode), &Bytes);
}


LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam,LPARAM lParam )
{
    CallNextHookEx(0, code, wParam, lParam);// по идее должны попасть сюда

    return 0;
}


DWORD WINAPI SetGlobalHookProc(LPVOID lpParam)
{
  SetWindowsHookEx(WH_GETMESSAGE, &GetMsgProc, NULL, 0); //Заходим сюда и ждем.Кстати отсюда я еще не разу не выходил :)
  Sleep(INFINITE);
  return 0;
}


void SetGlobalHook()
{
  
HANDLE hMutex;
DWORD TrId;

hMutex = CreateMutex(NULL, false, "AdvareHook");

  if (GetLastError() == 0)
  {
    CreateThread(NULL, 0, SetGlobalHookProc, NULL, 0, &TrId);
  }

  else
  {
    CloseHandle(hMutex);
  }

}



Вот в принципе и все.
Осталось заставить заработать DllMain
Для этого в своем экзешнике пишем
Код

 LoadLibrary("Iject2.dll");
  Sleep(INFINITE);

Вот и все, для начала,но у меня не работает. В коментариях к коду в либе я написал то место, где замираю

Это сообщение отредактировал(а) Coocky - 6.3.2007, 13:38


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
Coocky
Дата 7.3.2007, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: нет
Всего: 62



Хорошо, опять молчим. Ну что ж, я нашел перехват функций с помощью библиотеки detours ,позже выложу библиотеку и исходники, для тех, кто не смог скачать с сайта мелкософтных или кто скачал, но не смог скомпилировать.. Теперь другой вопрос-КАК МНЕ ВНЕДРИТЬ своюю длл в нужный ЧУЖОЙ процесс? Знаю, статей много, но у меня не работает. Ну уж я точно не попадаю на точку останова в DllMain при отладке свое dll.
А может и не долен попадать? Реально ли так отлаживать? 


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
W4FhLF
Дата 7.3.2007, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 12
Всего: 121



Цитата(Coocky @  6.3.2007,  12:58 Найти цитируемый пост)
Вообщем с теорией знаком, но НЕ ФИГА не работает.


Значит с теорией не знакомsmile Если тебе понятен весь процесс, то причём здесь примеры из сети? Надо было писать самому. 


Цитата(Coocky @  6.3.2007,  13:35 Найти цитируемый пост)
Итак, создадим длл, которая будет ставить хуки на прцессы


Ну не на процессы, а в данном случае на функции MessageBoxA/MessageBoxW. Такая библиотека будет подгружена во все ОКОННЫЕ приложений, а так же будет подгружаться по все вновь созданные ОКОННЫЕ приложения.

Цитата(Coocky @  7.3.2007,  10:34 Найти цитируемый пост)
Теперь другой вопрос-КАК МНЕ ВНЕДРИТЬ своюю длл в нужный ЧУЖОЙ процесс?


Что тебе известно о чужом процессе? В любом случае для непорсдественно внедрения нужно знать PID, найти его по имени процесса труда не составляет(CreateToolhelp32Snapshot & TH32CS_SNAPPROCESS), далее всё стандартно. Создаём базонезависимый участок кода, который будет подгружать нашу dll, записываем этот код в чужой процесс и запускаем на удалённое выполнение. 

По каким-то конкретно моментам есть вопросы?
Есть примеры на Delphi, но я так понял тебя они не устраивают, тогда я могу помочь с примерами на ассемблере, когда-то писал такое для своего снифера, надо?smile


Цитата(Coocky @  7.3.2007,  10:34 Найти цитируемый пост)
А может и не долен попадать? Реально ли так отлаживать? 


Этот процесс я отлаживал следующим образом:
Загружал процесс-жертву в отладчик, стартовал её. После чего ставил прерывание на загрузку нового модуля(DLL), далее в своём процессе я нажимал кнопочку аля "внедрить DLL в чужой процесс(этим процессом естественно был процесс-жертва)" и в отладчике прерывался на события "New module is loaded", т.е. моя dll была загружена в адресное пространство процесса-жертвы, но DllMain ещё не выполнилась, т.о. после этого я просто ставил прерывание на DllMain и запускал процесс дальше на выполнение. После чего мог спокойно отлаживать процедуру установки хука. 
Отладить процедуру перехвата функции ещё проще. Нужно просто поставить прерывание на функцию, которую собираешься перехватить. Как известно на её начало ставится переходник в функцию перехвата, а значит прервавшись на начале функции мы спокойно переходим в функцию перехвата и отлаживаем её.
Но это всё конечно требует определённых навыков и знаний. 



--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
piritus
Дата 8.3.2007, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 226
Регистрация: 3.1.2007
Где: Сибирь

Репутация: нет
Всего: 3



одно из решений
код написан КК (Крисом Касперски)
у него для MessageBox, но думаю, что можно переделать под свои нужды:

Код

/*----------------------------------------------------------------------------
 *
 *      универсальнй перехватчик API-функций (см. так же kpnc-hack.c)
 *      ====================================
 *                                           
 *                                             криска ака мыщъх
-----------------------------------------------------------------------------*/
#include <windows.h>

#define JUMP_SZ            0x69         // must be >= sizeof(jump)

#define _INSTALL_THUNK_      jump
#define _UNINSTALL_THUNK_   buff

DWORD saved;                        // сюда записыватся адрес возврата

char my_string[]="hacked";               // строка для вывода в заголвок

char buff[JUMP_SZ], *p; jump(); _do_asm();   // объявляем переменные



// наш thunk
//============================================================================
// получаем управление до вызова перехватываемой API-функции
// здесь можем делать что угодно с параметрами и т.д.
 __declspec( naked ) thunk()
{
__asm{
   push offset _UNINSTALL_THUNK_      ; снимаем thunk с функции
   call _do_asm
   add esp,4

   
   pop [saved]                     ; подменяем ret_addr на post_exit
   push offset post_exit


   ; "боевая нагрузка" до вызоза функции
   ; ========================================================================
   ; подменяем строку заголовка и меняем тип диалогового окна
pre_run:
   mov eax, offset my_string
   ;mov [esp+12], offset my_string                              
   mov [esp+12], eax
   mov [esp+10h], 1                                            


   mov eax,[p]                     ; вызываем перехваченную функцию as is
   jmp eax

   ; "боевая нагрузка" после вызова функции
   ;=========================================================================
   ; ничего не делаем (добавьте сюда собственный код)
post_exit:
   
   push offset _INSTALL_THUNK_         ; снова устанавливаем thunk на функцию
   call _do_asm
   add esp,4
   
   push [saved]                  ; возвращаемся туда,откуда нас вызывали
   retn
   }
}

// код, внедряющийся в начало API-функции и передающий управление на thunk
//============================================================================
__declspec( naked ) jump()
{
   __asm
   {
      ; можно сразу дать jmp thunk, но лениво вычислять смещение
      ; однако, следует учитывать, что в некоторых случаях мы имеем
      ; всего лишь 5 команд для внедрения, jmp туда влезет, а вот
      ; mov eax/jmp eax уже нет
      mov eax, offset thunk         
      jmp eax   
   }
}

// устанавливет/удаляет thunk
//============================================================================
 __declspec( naked )  _do_asm(char *src)
{
__asm
{
      ; сохраняем регистры
      push ecx            
      push esi   
      push edi

      ; резервируем место под локальные переменные
      push esp            ; резервируем место под old-old (hack!!!)
      push eax            ; резервируем место под old

      ; вызываем VirtualProtect(p,0x1000,PAGE_READWRITE, &old);
      ; присваивая себе атриубут записи
      push esp            ; &old
      push PAGE_READWRITE      ; нелзя PAGE_EXECUTE_READWRITE!
      push 0x1000            ; size
      push [p]            ; указатель на регион
      call ds:VirtualProtect

      ; копируем дв. словами
      mov ecx, JUMP_SZ/4      ; size в дв. словах
      mov esi, [esp+18h]      ; src
      mov edi, [p]         ; dst
      rep movsd            ; копируем!
   
      ; вызываем VirtualProtect(p,0x1000,old,&old-old),восстанавливая атриубы
      ; (в принципе, чтобы постоянно не менять атрибуты туда-сюда, достаточно
      ; присвоиить WRITE один раз и так и оставить)
      push esp            ; old (hack!!!)
      push 1000h            ; size
      push [p]            ; указатель на регион
      call ds:VirtualProtect   

      pop eax               ; выталкиваем old
      ;pop eax            ; old-old уже вытолкнут v_prot

      ; восстанавливаем регистры
      pop edi         
      pop esi
      pop ecx

      ; выходим
      retn               
   }
}


// демонстрационный вызов MessageBoxA, подтержающий перехват
demo(){ MessageBox(0, "==[ demo ]==","not hacked yet",0); }

main()
{
   // получаем адрес MessageBoxA
   p = (char*)GetProcAddress(LoadLibrary("USER32.DLL"), "MessageBoxA");

   // копируем оригинальное содержимое MessageBoxA в свое тело
   memcpy(buff, p, JUMP_SZ);

   // MessageBoxA до перехвата
   demo();   

   // устанавливаем перехватчик
    _do_asm(_INSTALL_THUNK_);

   // MessageBoxA после перехвата
   demo();

   // удаляем перехватчик
   _do_asm(_UNINSTALL_THUNK_);

   // MessageBoxA после удаления перехватчика
   demo();

}

--------------------
PM MAIL ICQ   Вверх
Coocky
Дата 12.3.2007, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: нет
Всего: 62



Цитата(W4FhLF @  7.3.2007,  15:28 Найти цитируемый пост)
Ну не на процессы, а в данном случае на функции MessageBoxA/MessageBoxW. Такая библиотека будет подгружена во все ОКОННЫЕ приложений, а так же будет подгружаться по все вновь созданные ОКОННЫЕ приложения.

Да нет! ИМЕНО на ПРОЦЕЕСЫ. С помощью хуков мы заставим длл внедрится во все ПРОЦЕССЫ!! smile 

Цитата(W4FhLF @  7.3.2007,  15:28 Найти цитируемый пост)
Этот процесс я отлаживал следующим образом:

Я уже разобрался
Цитата

Что тебе известно о чужом процессе? В любом случае для непорсдественно внедрения нужно знать PID, найти его по имени процесса труда не составляет(CreateToolhelp32Snapshot & TH32CS_SNAPPROCESS), далее всё стандартно. Создаём базонезависимый участок кода, который будет подгружать нашу dll, записываем этот код в чужой процесс и запускаем на удалённое выполнение. 

По каким-то конкретно моментам есть вопросы?

Примере есть в инете, но там нет выравнивания структуры. Я тоже разобрался. Вообщем разобрался САМ... smile 
Вот рабочий код
Код


Вот рабочий код внедрения в процесс .Обратите внимание на #pragma pack(1) и #pragma pack()


BOOL OpenProcessin(DWORD dwProcessId, CString Dll_name)
{
LPTHREAD_START_ROUTINE Memory;
DWORD Code;
DWORD BytesWritten;
DWORD hreadId;
HANDLE hThread;
HMODULE hKernel32;
DWORD ThreadId;

#pragma pack(1)

struct Inject
{
BYTE PushCommand;
DWORD PushArgument;
WORD CallCommand;
DWORD CallAddr;
BYTE PushExitThread;
DWORD ExitThreadArg;
WORD CallExitThread;
DWORD CallExitThreadAddr;
void*AddrLoadLibrary;
void*AddrExitThread;
TCHAR LibraryName[MAX_PATH];
 
};

#pragma pack()

Inject in;
TCHAR ModulePath [MAX_PATH];

BOOL Result = FALSE;
HANDLE hProcess=NULL;
hProcess = OpenProcess(
                       PROCESS_CREATE_THREAD   |
                       PROCESS_VM_OPERATION    |
                       PROCESS_VM_WRITE,
                       FALSE, dwProcessId);
Memory =(LPTHREAD_START_ROUTINE) VirtualAllocEx(hProcess, NULL, sizeof(Inject),
          MEM_COMMIT, PAGE_EXECUTE_READWRITE);

        if (Memory ==NULL) 
        {
return FALSE;
        }

Code = (DWORD)(Memory);
        //инициализация внедряемого кода:
        in.PushCommand    = 0x68;
        in.PushArgument   = Code + 0x1E;
        in.CallCommand    = 0x15FF;
        in.CallAddr       = Code + 0x16;
        in.PushExitThread = 0x68;
        in.ExitThreadArg  = 0;
        in.CallExitThread = 0x15FF;
        in.CallExitThreadAddr = Code + 0x1A;
hKernel32 = GetModuleHandle("kernel32.dll");
        in.AddrLoadLibrary = GetProcAddress(hKernel32, "LoadLibraryA");
        in.AddrExitThread = GetProcAddress(hKernel32, "ExitThread");
        lstrcpy(in.LibraryName, Dll_name.GetBuffer());
        //записать машинный код по зарезервированному адресу
        WriteProcessMemory(hProcess, Memory, &in, sizeof(Inject), &BytesWritten);
        //выполнить машинный код
hThread = CreateRemoteThread(hProcess, NULL, 0, Memory, NULL, 0, &ThreadId);
        if (hThread ==NULL)
        {
          return FALSE;
        }
        CloseHandle(hThread);
Result = TRUE;
        
 return Result;
}


Эту функцию нужно вызвать первой, для получения доступа


BOOL SetDebugePrivilegie(void)
{
 
HANDLE hToken;
LUID SeDebugNameValue;
TOKEN_PRIVILEGES tkp;
DWORD ReturnLength;
BOOL Result=FALSE;
  //Добавляем привилегию SeDebugPrivilege
  //Получаем токен нашего процесса
  OpenProcessToken(INVALID_HANDLE_VALUE, TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken);
  //Получаем LUID привилегии
  if (!LookupPrivilegeValue(NULL, "SeDebugPrivilege", &SeDebugNameValue))
  {
    CloseHandle(hToken);
  return FALSE;
  }
  tkp.PrivilegeCount= 1;
  tkp.Privileges[0].Luid = SeDebugNameValue;
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  //Добавляем привилегию к процессу
  AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES),
    &tkp, &ReturnLength);
  if (GetLastError() != ERROR_SUCCESS) 
  {
    return FALSE;
  }
Result=TRUE;
  return Result;
}



Это сообщение отредактировал(а) Coocky - 12.3.2007, 16:14


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
dumb
Дата 13.3.2007, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 27
Всего: 158



произошла небольшая путаница со смысловой нагрузкой слова "хук"... smile

Цитата(Coocky @  12.3.2007,  16:11 Найти цитируемый пост)
С помощью хуков мы заставим длл внедрится во все ПРОЦЕССЫ!!

нет. чтобы убедиться, в DLL_PROCESS_ATTACH сделай вывод куда-либо(OutputDebugString/MessageBox/log-file) pid'ов(GetCurrentProcessId), например.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0563 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.