-
занимаюсь автоматизированным тестированием, оформил плагин для перехвата отрисовки текста. он подменяет адресса к функциям в таблице импорта, в моём случае это textOut в GDI32.dll. Всё работает хорошо, вот только что при выгрузке перхватчика с некоторойй вероятностью появлятся ошибка доступа к памяти...
Возможно кто нибудь занимался подомной проблематикой и может что нибудь посоветовать...
-
> подменяет адресса к функциям в таблице импорта
Для полноценного перехвата в произвольном приложении этого недостаточно - необходим еще и перехват соотв.записей в EAT.
> с некоторойй вероятностью появлятся ошибка доступа к памяти
Слишком мало инф-ции для анализа.
-
> Для полноценного перехвата в произвольном приложении этого > недостаточно - необходим еще и перехват соотв.записей в > EAT.
Здесь, пожалуйста, поподробней...
> Слишком мало инф-ции для анализа.
я в таком же положении - ошибка не имеет какойто опрелённой стабильности. Иследуя проблему, пришел к выводу что ошибка МОЖЕТ появляться из-за того, что в момент выгрузки данна функция используется в основном потоке, и соответсвенно при работе со стеком происходит оно..
-
> поподробней
Вызывающий модуль вправе и может получить адрес т.входа в требуемую подпрограмму вызываемого модуля и прямо в ран-тайм, т.е. с пом. a-wbb GetProcAddress, которая как раз и обращается к EAT вызываемого модуля.
Отсюда вывод - либо модифицировать EAT, либо перехватывать в IAT вход в GetProcAddress с целью подмены оригинальных адресных значений из EAT требуемыми адресами точек входа.
-
> либо перехватывать в IAT вход в GetProcAddress с целью подмены > оригинальных адресных значений из EAT требуемыми адресами > точек входа.
Вы имеете ввиду следующее ? function MyLoadLibraryA(
pszModuleName: pChar
): HMODULE; stdcall;
begin
sm_pInstance.funcEvent.ResetEvent;
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; finally
lockMgr.Free;
end;
end end;
function MyGetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
var
lockMgr : TLockMgr;
pfn : pointer;
FuncHook : THookedFunction;
begin
sm_pInstance.funcEvent.ResetEvent;
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;
-
Да.
-
локонично :)
А моё предполежение насчёт стека может иметь какой нибуть вес? з. ы. Сам просто только в догадках.
-
> предполежение насчёт стека может иметь какой нибуть вес?
Скорее нет чем да.
-
Вне сомнения лишь одно - пока выполняется код, принадлежащий адр.пространству, занимаемому модулем, выгружать этот модуль недопустимо.
-
> Вне сомнения лишь одно - пока выполняется код, принадлежащий > адр.пространству, занимаемому модулем, выгружать этот модуль > недопустимо.
это понятно, вот только под выгрузкой ловушки я подразумевал замену подстваленных адресов на оригинальные, если я вас правильно понял.
я насильственно ни один модуль не выгражую.
Но так или иначе, возможно следует попробывать вариант с синхронизацией доступа к целевым функцииям?
-
> под выгрузкой ловушки я подразумевал замену подстваленных > адресов на оригинальные
Выгрузкой это назвать никак нельзя.
> насильственно ни один модуль не выгражую
А как он, модуль, у тебя вообще попадает в АП "жертвы" ?
> синхронизацией доступа к целевым функцииям?
если ты не выгружаешь модуль из АП процесса-"жертвы" вплоть до его завершения, то синхронизация вряд ли имеет смысл.
-
> А как он, модуль, у тебя вообще попадает в АП "жертвы" ?
Да, действительно.. сдесь я напутал (тока из месячного отпуска вышел :) )... Надо будет на этим подумать
> если ты не выгружаешь модуль из АП процесса-"жертвы" вплоть > до его завершения, то синхронизация вряд ли имеет смысл. >
приложение в основном и работает с активным выводом текстовой информации и если перехватчик вовремя не выгрузить, это приведёт к потере производительности. И хочется сделать плагин правильно..
в купе с вашим предыдущим замечанием и моим стремлением удачно выгрузить модуль получается, что поток выгружающий библиотеку действительно придеться синхронизировать с основным потоком, чтобы оградить и АП.
То конечно умозрительный вывод, но на данный момент он мне кажеться наиболее правдоподомным....
Вот только как сделать синхронизацию с чужим потоком? Пока ума не приложу...
-
> Вот только как сделать синхронизацию с чужим потоком? Пока > ума не приложу...
Дык как... как обычно вестимо: Остановить все потоки процесса за исключением своего, из которого снимаешь перехватчик. Снять перехватчик и запустить потоки далее.
-
Ты о каких потоках ?
Приложение чужое, заранее знать из какого потока будет осуществляться загрузка/выгрузка твоего модуля ты не можешь, как не можешь и заранее знать из каких потоков будут вызываться ф-ции, которые ты перехватил.
Что и с чем ты собрался "синхронизировать", я пока не понимаю ..
-
С потоками мало имел дела, а по сему вопрос есть гарантия что при остановке стороних потоков они не будут использовать требуемого АП? Т.е остановяться в этом АП , а при попыке их восстановить получим, то же исключение?
-
> Приложение чужое, заранее знать из какого потока будет осуществляться > загрузка/выгрузка твоего модуля ты не можешь, как не можешь > и заранее знать из каких потоков будут вызываться ф-ции, > которые ты перехватил.
Плагин для тестировния интерфесных форм, по первому приблежению должно хватить потока, которы обработывает сообщения требуемой формы, хотя о достаточности такого подхода утверждать не берусь.
> Что и с чем ты собрался "синхронизировать", я пока не понимаю > ..
поток, котрый выгружает библиотеку и все остальные потоки.
-
> при остановке стороних потоков они не будут использовать > требуемого АП?
Разумеется не будут.
-
Приложение-то дельфийское ?
-
> Разумеется не будут.
Что то я не понимаю... А как тогда система реагирует на suspend и что будет если такой поток востановить. он что будет переинициализован?
ЗЫ дико извиняюсь за свою некомпетентность в этой области
-
> Приложение-то дельфийское ?
Да
|