Форум: "Прочее";
Текущий архив: 2009.07.19;
Скачать: [xml.tar.bz2];
ВнизРеализация 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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.004 c