Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.07.19;
Скачать: CL | DM;

Вниз

Реализация JumpHook на Delphi   Найти похожие ветки 

 
@!!ex ©   (2009-05-18 12:44) [0]

Если кому нибудь нужно:
unit uJmpHook;

interface
Uses Windows, SysUtils;

const
 THookJump_LEN = 5;

type
THookJump = class
// Create a relative jump to hook an existing api call.
// is this 5 bytes in 64 bit mode as well?
// NOTE: NOT for use in hooking an interface or a vtable. that doesnt require a jump.
protected
 m_Func:Pointer;
public
Constructor Create(pFunc:POinter);
Function  IsHookInstalled():boolean;
Function  InstallHook( pFuncNew:Pointer ):boolean;
Procedure RemoveHook();
Procedure SwapOld( );
Procedure SwapReset( );
public
m_dwOldProtection:Cardinal;   // used by VirtualProtect()
m_OldCode:array[0..THookJump_LEN-1] of byte; // what was there previous.
m_Jump:array[0..THookJump_LEN-1] of byte;  // what do i want to replace it with.
end;

implementation

{ THookJump }

constructor THookJump.Create(pFunc:POinter);
begin
 m_Func:=pFunc;
 m_dwOldProtection:=0;
 m_Jump[0] := 0;
end;

function THookJump.InstallHook(pFuncNew: Pointer): boolean;
var
 dwNewProtection:cardinal;
 dwAddr:cardinal;
begin
if ( m_Func = nil ) then begin
   Result:=false;
   Exit;
 end;

if ( IsHookInstalled() and not  CompareMem(m_Func, @m_Jump[0], sizeof(m_Jump))) then begin

   Result:=true;
   Exit;
 end;

m_Jump[0] := 0;

dwNewProtection := PAGE_EXECUTE_READWRITE;
if ( not VirtualProtect( m_Func, 8, dwNewProtection, @m_dwOldProtection)) then begin
   Result:=false;
   Exit;
 end;

// unconditional JMP to relative address is 5 bytes.
m_Jump[0] := $e9;
 dwAddr := (integer(pFuncNew) - integer(m_Func) - sizeof(m_Jump));
//DEBUG_TRACE(("JMP %08x" LOG_CR, dwAddr ));
CopyMemory(@m_Jump[1], @dwAddr, sizeof(dwAddr));

CopyMemory(@m_OldCode[0], m_Func, sizeof(m_OldCode));
CopyMemory(m_Func, @m_Jump[0], sizeof(m_Jump));

Result:=true;
end;

function THookJump.IsHookInstalled: boolean;
begin
 Result:=( m_Jump[0] <> 0 );
end;

procedure THookJump.RemoveHook();
var
 dwOldProtection:cardinal;
begin
 if (m_Func = nil) then
 Exit;
if ( not IsHookInstalled()) then // was never set!
 Exit;
try
 CopyMemory(m_Func, @m_OldCode[0], sizeof(m_OldCode)); // SwapOld(pFunc)
 dwOldProtection := 0;
 VirtualProtect(m_Func, 8, m_dwOldProtection, @dwOldProtection ); // restore protection.
 m_Jump[0] := 0; // destroy my jump. (must reconstruct it)
except
 end;
end;

procedure THookJump.SwapOld();
begin
 CopyMemory(m_Func,@m_OldCode[0],sizeof(m_OldCode));
end;

procedure THookJump.SwapReset();
begin
if ( not IsHookInstalled()) then
 Exit;
CopyMemory(m_Func, @m_Jump[0], sizeof(m_Jump));
end;

end.


 
@!!ex ©   (2009-05-18 12:47) [1]

Основан на коде Taksi.
Спасибо разработчикам, их сорсы мне во многом помогли. Сам не допер бы до половины идей(и хук здесь самая простая часть)


 
@!!ex ©   (2009-05-18 13:04) [2]

Кстати, тут не хватает деструктора. В нем нужно делать RemoveHook();


 
Игорь Шевченко ©   (2009-05-18 13:15) [3]


> dwNewProtection := PAGE_EXECUTE_READWRITE


не уверен. Я использовал PAGE_EXECUTE_WRITECOPY


 
@!!ex ©   (2009-05-18 13:36) [4]

> [3] Игорь Шевченко ©   (18.05.09 13:15)

Вроде так работает. А почему WRITECOPY?


 
Игорь Шевченко ©   (2009-05-18 13:43) [5]


> Вроде так работает. А почему WRITECOPY?


Для совместимости с win9x, по-моему.


 
Stan   (2009-05-18 17:46) [6]

А можно вкратце узнать - для чего это нужно обычно?


 
@!!ex ©   (2009-05-18 17:53) [7]


> [5] Игорь Шевченко ©   (18.05.09 13:43)

В моем случае это не актуально. А вообще спасибо за замечаени, убуд знать!

> [6] Stan   (18.05.09 17:46)

В моем случае - это получение некоторых данных из приложения + рисования в окне приложения(Direct3D).


 
@!!ex ©   (2009-05-18 18:03) [8]

Частный случай применения.
Есть игры серии Dream Day. Это Hidden Objects.
При первом запуске игра брала имя пользователя функций GetUserNameW.
Проблема в том, что английский она не понимает. А из-за кривизны программы(имя пользователя берется юникодой, а сохраняется в ANSI) мы не могли вывести русский текст корректно. Исходников естественно нет.
Тогда пришли к простому решению:
Поставили хук на GetUserNameW и проверяли, если полученное имя содержит кирилицу, то транслировали его в латиницу.
ПРиложение и не догадывалось, что имя на самом деле по русски написанное, поскольку специально для этого приложения GetUserNameW возвращала русские имена транслитом.


 
@!!ex ©   (2009-05-18 20:16) [9]

Важное замечание!
Если после установки хука приложение периодически вылетает, есть вероятность что метод перекрытый был потокобезопасным, а ваш - нет.


 
Игорь ©   (2009-05-18 20:24) [10]


> @!!ex ©


От какой это ты радости GameMaker решил поделиться кодом с народом?


 
@!!ex ©   (2009-05-18 20:28) [11]

> [10] Игорь ©   (18.05.09 20:24)

Потому что в инете кода нет(или плохо искал?) а единственная доступная вещь madCodeHook стоит 200 долларов.


 
Игорь Шевченко ©   (2009-05-18 20:33) [12]

@!!ex ©   (18.05.09 20:28) [11]

А что, советы rsdn не походят ?

Перехватчики есть у Фэнь Юаня в его знаменитой книжке про графику в Windows, меня спросил бы, я по его идеям себе на Delphi сделал.


 
@!!ex ©   (2009-05-18 20:33) [13]

> [10] Игорь ©   (18.05.09 20:24)
> От какой это ты радости GameMaker решил поделиться кодом
> с народом?

Кстати, кодом я периодически и так делюсь. Lua интерфейс недавно выкладывал.


 
Игорь ©   (2009-05-18 20:39) [14]


> @!!ex ©   (18.05.09 20:28) [11]


Искал хорошо но не нашел, а код СПАСИБО


 
Игорь ©   (2009-05-18 20:41) [15]


> Игорь ©   (18.05.09 20:39) [14]


Искал хорошо но не нашел, а за код СПАСИБО


 
test ©   (2009-05-19 10:31) [16]

Игорь ©   (18.05.09 20:24) [10]
Правильно код надо прятать, все шифровать и ни слова не пол слова про любую реализации в том числе "Hello world", чем больше велосипедов тем лучше!  
Не дай тебе бог поработать в конторе где про реализацию только под пытками.



Страницы: 1 вся ветка

Текущий архив: 2009.07.19;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.01 c
2-1243433752
Magix
2009-05-27 18:15
2009.07.19
Процедура в динамички созданном popup menu


15-1242334996
Германн
2009-05-15 01:03
2009.07.19
Registered Jack


9-1181221877
Black-Death
2007-06-07 17:11
2009.07.19
Помгите сделать простую игру на паскале.


2-1243051477
Чипырик
2009-05-23 08:04
2009.07.19
Поиск через Table и Query, в чем разница?


9-1179055650
Frol
2007-05-13 15:27
2009.07.19
Физика велосипеда