![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Выгрузка WinApi перехватчика [D7, WinXP]
KygECHuK © (2008-08-26 10:33:00)занимаюсь автоматизированным тестированием, оформил плагин для перехвата отрисовки текста. он подменяет адресса к функциям в таблице импорта, в моём случае это textOut в GDI32.dll. Всё работает хорошо, вот только что при выгрузке перхватчика с некоторойй вероятностью появлятся ошибка доступа к памяти...
Возможно кто нибудь занимался подомной проблематикой и может что нибудь посоветовать...
KygECHuK (2008-08-26 16:59:00) [161]
> Приложение чужое, заранее знать из какого потока будет осуществляться
> загрузка/выгрузка твоего модуля ты не можешь, как не можешь
> и заранее знать из каких потоков будут вызываться ф-ции,
> которые ты перехватил.
Плагин для тестировния интерфесных форм, по первому приблежению должно хватить потока, которы обработывает сообщения требуемой формы, хотя о достаточности такого подхода утверждать не берусь.
> Что и с чем ты собрался "синхронизировать", я пока не понимаю
> ..
поток, котрый выгружает библиотеку и все остальные потоки.
Сергей М. (2008-08-26 16:59:00) [162]
> при остановке стороних потоков они не будут использовать
> требуемого АП?
Разумеется не будут.
Сергей М. (2008-08-26 16:51:00) [163]Ты о каких потоках ?
Приложение чужое, заранее знать из какого потока будет осуществляться загрузка/выгрузка твоего модуля ты не можешь, как не можешь и заранее знать из каких потоков будут вызываться ф-ции, которые ты перехватил.
Что и с чем ты собрался "синхронизировать", я пока не понимаю ..
KygECHuK (2008-08-26 16:51:00) [164]С потоками мало имел дела, а по сему вопрос есть гарантия что при остановке стороних потоков они не будут использовать требуемого АП?
Т.е остановяться в этом АП , а при попыке их восстановить получим, то же исключение?
Rouse_ (2008-08-26 16:43:00) [165]
> Вот только как сделать синхронизацию с чужим потоком? Пока
> ума не приложу...
Дык как... как обычно вестимо:
Остановить все потоки процесса за исключением своего, из которого снимаешь перехватчик. Снять перехватчик и запустить потоки далее.
KygECHuK (2008-08-26 16:35:00) [166]
> А как он, модуль, у тебя вообще попадает в АП "жертвы" ?
Да, действительно.. сдесь я напутал (тока из месячного отпуска вышел :) )...
Надо будет на этим подумать
> если ты не выгружаешь модуль из АП процесса-"жертвы" вплоть
> до его завершения, то синхронизация вряд ли имеет смысл.
>
приложение в основном и работает с активным выводом текстовой информации и если перехватчик вовремя не выгрузить, это приведёт к потере производительности. И хочется сделать плагин правильно..
в купе с вашим предыдущим замечанием и моим стремлением удачно выгрузить модуль получается, что поток выгружающий библиотеку действительно придеться синхронизировать с основным потоком, чтобы оградить и АП.
То конечно умозрительный вывод, но на данный момент он мне кажеться наиболее правдоподомным....
Вот только как сделать синхронизацию с чужим потоком? Пока ума не приложу...
Сергей М. (2008-08-26 15:47:00) [167]
> под выгрузкой ловушки я подразумевал замену подстваленных
> адресов на оригинальные
Выгрузкой это назвать никак нельзя.
> насильственно ни один модуль не выгражую
А как он, модуль, у тебя вообще попадает в АП "жертвы" ?
> синхронизацией доступа к целевым функцииям?
если ты не выгружаешь модуль из АП процесса-"жертвы" вплоть до его завершения, то синхронизация вряд ли имеет смысл.
KygECHuK (2008-08-26 14:09:00) [168]
> Вне сомнения лишь одно - пока выполняется код, принадлежащий
> адр.пространству, занимаемому модулем, выгружать этот модуль
> недопустимо.
это понятно, вот только под выгрузкой ловушки я подразумевал замену подстваленных адресов на оригинальные, если я вас правильно понял.
я насильственно ни один модуль не выгражую.
Но так или иначе, возможно следует попробывать вариант с синхронизацией доступа к целевым функцииям?
Сергей М. (2008-08-26 12:54:00) [169]Вне сомнения лишь одно - пока выполняется код, принадлежащий адр.пространству, занимаемому модулем, выгружать этот модуль недопустимо.
Сергей М. (2008-08-26 12:51:00) [170]
> предполежение насчёт стека может иметь какой нибуть вес?
Скорее нет чем да.
KygECHuK (2008-08-26 12:50:00) [171]локонично :)
А моё предполежение насчёт стека может иметь какой нибуть вес?
з. ы. Сам просто только в догадках.
Сергей М. (2008-08-26 12:45:00) [172]Да.
KygECHuK (2008-08-26 12:39:00) [173]
> либо перехватывать в IAT вход в GetProcAddress с целью подмены
> оригинальных адресных значений из EAT требуемыми адресами
> точек входа.
Вы имеете ввиду следующее ?
function MyLoadLibraryA(
pszModuleName: pChar
): HMODULE; stdcall;
begin
sm_pInstance.funcEvent.ResetEvent;
// debug
sm_pInstance.funcEvent.CurFuncName := 'MyLoadLibraryA';
//
try
Result := LoadLibraryA(pszModuleName);
TModuleScope(sm_pModuleScope).LogMessage(pChar('Подгружена библиотека :' + pszModuleName));
TApiHookMgr.HackModuleOnLoad(Result, 0);
finally
sm_pInstance.funcEvent.setEvent;
end
end;
class procedure TApiHookMgr.HackModuleOnLoad(hmod: HMODULE; dwFlags: Cardinal);
var
lockMgr : TLockMgr;
i : Integer;
Hook : THookedFunction;
begin
// Если был загружен новый модуль то тоже вставим перехватчик
if ((hmod <> 0) and ((dwFlags and LOAD_LIBRARY_AS_DATAFILE) = 0)) then
begin
lockMgr := TLockMgr.Create(sm_CritSec, TRUE);
try
for i := 0 to sm_pHookedFunctions.Count - 1 do
begin
Hook := sm_pHookedFunctions[i];
Hook.ReplaceInOneModule(
Hook.CalleeModName,
Hook.pfnOrig,
Hook.pfnHook,
hmod
);
end; // for
finally
lockMgr.Free;
end;
end // if
end;
function MyGetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
var
lockMgr : TLockMgr;
pfn : pointer;
FuncHook : THookedFunction;
begin
sm_pInstance.funcEvent.ResetEvent;
// debug
sm_pInstance.funcEvent.CurFuncName := 'MyGetProcAddress';
//
try
lockMgr := TLockMgr.Create(sm_CritSec, TRUE);
try
// получение оргинального адресса функции
pfn := Pointer(TApiHookMgr.GetProcAddressWindows(hModule, lpProcName));
// попытка найти если функция была сломана
FuncHook :=
sm_pHookedFunctions.GetHookedFunction(
hModule,
lpProcName
);
if (nil <> FuncHook) then
// возаращаем адрес перехваченной функции
pfn := FuncHook.pfnHook;
Result := pfn;
finally
lockMgr.Free;
end;
finally
sm_pInstance.funcEvent.setEvent;
end;
TModuleScope(sm_pModuleScope).LogMessage(pChar('В библиотеке :' + GetModuleName(hModule) +
' запрошена функция :'+ lpProcName));
end;
Сергей М. (2008-08-26 12:23:00) [174]
> поподробней
Вызывающий модуль вправе и может получить адрес т.входа в требуемую подпрограмму вызываемого модуля и прямо в ран-тайм, т.е. с пом. a-wbb GetProcAddress, которая как раз и обращается к EAT вызываемого модуля.
Отсюда вывод - либо модифицировать EAT, либо перехватывать в IAT вход в GetProcAddress с целью подмены оригинальных адресных значений из EAT требуемыми адресами точек входа.
KygECHuK (2008-08-26 12:02:00) [175]
> Для полноценного перехвата в произвольном приложении этого
> недостаточно - необходим еще и перехват соотв.записей в
> EAT.
Здесь, пожалуйста, поподробней...
> Слишком мало инф-ции для анализа.
я в таком же положении - ошибка не имеет какойто опрелённой стабильности.
Иследуя проблему, пришел к выводу что ошибка МОЖЕТ появляться из-за того, что в момент выгрузки данна функция используется в основном потоке,
и соответсвенно при работе со стеком происходит оно..
Сергей М. (2008-08-26 11:21:00) [176]
> подменяет адресса к функциям в таблице импорта
Для полноценного перехвата в произвольном приложении этого недостаточно - необходим еще и перехват соотв.записей в EAT.
> с некоторойй вероятностью появлятся ошибка доступа к памяти
Слишком мало инф-ции для анализа.