Текущий архив: 2009.10.25;
Скачать: CL | DM;
ВнизВыгрузка WinApi перехватчика Найти похожие ветки
← →
KygECHuK © (2008-08-26 10:33) [0]занимаюсь автоматизированным тестированием, оформил плагин для перехвата отрисовки текста. он подменяет адресса к функциям в таблице импорта, в моём случае это textOut в GDI32.dll. Всё работает хорошо, вот только что при выгрузке перхватчика с некоторойй вероятностью появлятся ошибка доступа к памяти...
Возможно кто нибудь занимался подомной проблематикой и может что нибудь посоветовать...
← →
Сергей М. © (2008-08-26 11:21) [1]
> подменяет адресса к функциям в таблице импорта
Для полноценного перехвата в произвольном приложении этого недостаточно - необходим еще и перехват соотв.записей в EAT.
> с некоторойй вероятностью появлятся ошибка доступа к памяти
Слишком мало инф-ции для анализа.
← →
KygECHuK © (2008-08-26 12:02) [2]
> Для полноценного перехвата в произвольном приложении этого
> недостаточно - необходим еще и перехват соотв.записей в
> EAT.
Здесь, пожалуйста, поподробней...
> Слишком мало инф-ции для анализа.
я в таком же положении - ошибка не имеет какойто опрелённой стабильности.
Иследуя проблему, пришел к выводу что ошибка МОЖЕТ появляться из-за того, что в момент выгрузки данна функция используется в основном потоке,
и соответсвенно при работе со стеком происходит оно..
← →
Сергей М. © (2008-08-26 12:23) [3]
> поподробней
Вызывающий модуль вправе и может получить адрес т.входа в требуемую подпрограмму вызываемого модуля и прямо в ран-тайм, т.е. с пом. a-wbb GetProcAddress, которая как раз и обращается к EAT вызываемого модуля.
Отсюда вывод - либо модифицировать EAT, либо перехватывать в IAT вход в GetProcAddress с целью подмены оригинальных адресных значений из EAT требуемыми адресами точек входа.
← →
KygECHuK © (2008-08-26 12:39) [4]
> либо перехватывать в 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:45) [5]Да.
← →
KygECHuK © (2008-08-26 12:50) [6]локонично :)
А моё предполежение насчёт стека может иметь какой нибуть вес?
з. ы. Сам просто только в догадках.
← →
Сергей М. © (2008-08-26 12:51) [7]
> предполежение насчёт стека может иметь какой нибуть вес?
Скорее нет чем да.
← →
Сергей М. © (2008-08-26 12:54) [8]Вне сомнения лишь одно - пока выполняется код, принадлежащий адр.пространству, занимаемому модулем, выгружать этот модуль недопустимо.
← →
KygECHuK © (2008-08-26 14:09) [9]
> Вне сомнения лишь одно - пока выполняется код, принадлежащий
> адр.пространству, занимаемому модулем, выгружать этот модуль
> недопустимо.
это понятно, вот только под выгрузкой ловушки я подразумевал замену подстваленных адресов на оригинальные, если я вас правильно понял.
я насильственно ни один модуль не выгражую.
Но так или иначе, возможно следует попробывать вариант с синхронизацией доступа к целевым функцииям?
← →
Сергей М. © (2008-08-26 15:47) [10]
> под выгрузкой ловушки я подразумевал замену подстваленных
> адресов на оригинальные
Выгрузкой это назвать никак нельзя.
> насильственно ни один модуль не выгражую
А как он, модуль, у тебя вообще попадает в АП "жертвы" ?
> синхронизацией доступа к целевым функцииям?
если ты не выгружаешь модуль из АП процесса-"жертвы" вплоть до его завершения, то синхронизация вряд ли имеет смысл.
← →
KygECHuK © (2008-08-26 16:35) [11]
> А как он, модуль, у тебя вообще попадает в АП "жертвы" ?
Да, действительно.. сдесь я напутал (тока из месячного отпуска вышел :) )...
Надо будет на этим подумать
> если ты не выгружаешь модуль из АП процесса-"жертвы" вплоть
> до его завершения, то синхронизация вряд ли имеет смысл.
>
приложение в основном и работает с активным выводом текстовой информации и если перехватчик вовремя не выгрузить, это приведёт к потере производительности. И хочется сделать плагин правильно..
в купе с вашим предыдущим замечанием и моим стремлением удачно выгрузить модуль получается, что поток выгружающий библиотеку действительно придеться синхронизировать с основным потоком, чтобы оградить и АП.
То конечно умозрительный вывод, но на данный момент он мне кажеться наиболее правдоподомным....
Вот только как сделать синхронизацию с чужим потоком? Пока ума не приложу...
← →
Rouse_ © (2008-08-26 16:43) [12]
> Вот только как сделать синхронизацию с чужим потоком? Пока
> ума не приложу...
Дык как... как обычно вестимо:
Остановить все потоки процесса за исключением своего, из которого снимаешь перехватчик. Снять перехватчик и запустить потоки далее.
← →
Сергей М. © (2008-08-26 16:51) [13]Ты о каких потоках ?
Приложение чужое, заранее знать из какого потока будет осуществляться загрузка/выгрузка твоего модуля ты не можешь, как не можешь и заранее знать из каких потоков будут вызываться ф-ции, которые ты перехватил.
Что и с чем ты собрался "синхронизировать", я пока не понимаю ..
← →
KygECHuK © (2008-08-26 16:51) [14]С потоками мало имел дела, а по сему вопрос есть гарантия что при остановке стороних потоков они не будут использовать требуемого АП?
Т.е остановяться в этом АП , а при попыке их восстановить получим, то же исключение?
← →
KygECHuK © (2008-08-26 16:59) [15]
> Приложение чужое, заранее знать из какого потока будет осуществляться
> загрузка/выгрузка твоего модуля ты не можешь, как не можешь
> и заранее знать из каких потоков будут вызываться ф-ции,
> которые ты перехватил.
Плагин для тестировния интерфесных форм, по первому приблежению должно хватить потока, которы обработывает сообщения требуемой формы, хотя о достаточности такого подхода утверждать не берусь.
> Что и с чем ты собрался "синхронизировать", я пока не понимаю
> ..
поток, котрый выгружает библиотеку и все остальные потоки.
← →
Сергей М. © (2008-08-26 16:59) [16]
> при остановке стороних потоков они не будут использовать
> требуемого АП?
Разумеется не будут.
← →
Сергей М. © (2008-08-26 17:05) [17]Приложение-то дельфийское ?
← →
KygECHuK © (2008-08-26 17:09) [18]
> Разумеется не будут.
Что то я не понимаю...
А как тогда система реагирует на suspend
и что будет если такой поток востановить. он что будет переинициализован?
ЗЫ
дико извиняюсь за свою некомпетентность в этой области
← →
KygECHuK © (2008-08-26 17:10) [19]
> Приложение-то дельфийское ?
Да
← →
Сергей М. © (2008-08-26 17:21) [20]
> как тогда система реагирует на suspend
Система просто перестает выделять потоку кванты процессорного времени.
Соответственно ни одна машинструкция им не выполняется.
> что будет если такой поток востановить. он что будет переинициализован?
Нет, не будет.
Упрощенно говоря, система продолжит квантование потока. Поток возобновит выполнение машинструкций начиная с инструкции, следующей за той которая была исполнена поледней на момент предшествующей его приостановки системой.
Если приложение дельфийское и для реализации GUI-интерфейса оно использует исключительно VCL-формы/контролы, можно практически со 100%-й уверенностью утверждать, что вызовы ф-ции TextOut осуществляются в основном потоке.
Крайне маловероятно, что какому-то идиоту взбредет в голову месить в одном проекте VCL-формы/контролы и создание/работа с окнами/контролами непосредственно через WinAPI)
Впрочем, этот довольно легко выяснить.
← →
Сергей М. © (2008-08-26 17:24) [21]Любопытно, а как ты определяешь, в каком потоке загружается/выгружается твой плагин-модуль ?
Подозреваю, что логика твоя в этой части неверна ..
← →
Rouse_ © (2008-08-26 17:31) [22]
> а как ты определяешь, в каком потоке загружается/выгружается
> твой плагин-модуль ?
Дык эта... тормозим все что не GetCurrentThreadId в нашем процессе и всего делов :)
← →
KygECHuK © (2008-08-26 17:32) [23]
> Любопытно, а как ты определяешь, в каком потоке загружается/выгружается
> твой плагин-модуль ?Подозреваю, что логика твоя в этой части
> неверна ..
Я пока ничего не брался определять, только советуюсь как поступить дальше
с подомным исключением.
Но предполагаю стоит вызвать GetCurrentThreadId внутри потока а по Id уже ориентироваться далее.
← →
Сергей М. © (2008-08-26 20:24) [24]
> предполагаю стоит вызвать GetCurrentThreadId внутри потока
> а по Id уже ориентироваться далее
Ну вот получил ты Id тек.треда.
Рассказывай про твои дальнейшие действия ..
← →
KygECHuK © (2008-08-26 22:41) [25]
> Ну вот получил ты Id тек.треда.Рассказывай про твои дальнейшие
> действия ..
* Предчуствие неладного
Беру текущий процесс и перечисляю все его потоки и сравниваю их Id c id текущего потока при помощи Toolhelp32...
← →
Сергей М. © (2008-08-26 22:58) [26]
> Предчуствие неладного
Уже радует ..
Рассказывай как ты получил ID ОСНОВНОГО треда текущего процесса
← →
KygECHuK © (2008-08-26 23:47) [27]
> Рассказывай как ты получил ID ОСНОВНОГО треда текущего процесса
* Чё то мне совсем сыкотно
а зачем мне определять ID ОСНОВНОГО треда текущего процесса? Или в этом есть принципиальный момент?
← →
Сергей М. © (2008-08-27 08:17) [28]
> зачем мне определять ID ОСНОВНОГО треда текущего процесса?
Почем мне знать зачем оно тебе надо ?)
Цитирую тебя:
> функция используется в основном потоке
> синхронизировать с основным потоком
Раз ты этим озаботился, значит ты все же как-то определяешь, что такой-то поток является именно основным, а не дополнительным ?
Вот я и спрашиваю как ты это делаешь)
← →
KygECHuK © (2008-08-27 09:39) [29]
> Почем мне знать зачем оно тебе надо ?)
Действительно....
Надёжней будет приостонавливать все потоки кроме, того что восстанавливает адреса.
Ну а если мне потребуется взять основной поток, то я просто использую GetWindowThreadProcessId от требуемого окна, ибо Delphi и VCL
Вас интересует что я имею под понятием "основной поток"? Ну наверно тот поток в котором изначально инициализирован обработчик сообщений.
← →
Сергей М. © (2008-08-27 09:46) [30]А что, собственно, ты тестируешь-то ? Цель какая ?
← →
KygECHuK © (2008-08-27 10:03) [31]
> А что, собственно, ты тестируешь-то ?
АИС
> Цель какая ?
найти всемозможный ошибки расчётов, вывода инвормации и передачи данных... то есть регресивное тестирование каждой новой версии продукта.
Данный плагин необходим для сбора текстовой информации из элементов управления не просходящих от TWinControl
← →
Сергей М. © (2008-08-27 10:14) [32]А что, подсистема поддержки плагинов у этой самой "АИС" не позволяет передавать в плагины требуемую тебе инф-цию ?
← →
KygECHuK © (2008-08-27 10:26) [33]
> А что, подсистема поддержки плагинов у этой самой "АИС"
> не позволяет передавать в плагины требуемую тебе инф-цию
> ?
У АИС нет такой подсисетмы - плагин для Системы теирования.
И большая часть жалоб и замечаний именно на отображении данных в интерфейсе, а у нашей "чудо - системы" эти значения могут отличаться от расчитанных или принятых... так что следующим этапом и будет сравнение таких между различнымы способами их вывода. Собственно говоря вот и понадобился таковой плагин.
← →
Сергей М. © (2008-08-27 10:36) [34]
> У АИС нет такой подсисетмы
Но плагины-то эта система поддерживает, раз она грузит твой плагин ?
Вот я и спрашиваю, нет ли в SDK документированных способов передать в плагин интересующую тебя инф-цию ..
← →
KygECHuK © (2008-08-27 10:47) [35]
> Но плагины-то эта система поддерживает, раз она грузит твой
> плагин ?
Плагины поддержеивает ОТДЕЛЬНАЯ сторонняя система тетсирования.
Естетественно есть способ получать данные не из интерфейса, но, как я утверждал раньше они могут отличаться от данных полученных непосредственно из интерфейса... не спрашиваёте меня как это получается у разаработчиков.
← →
Сергей М. © (2008-08-27 10:58) [36]
> ОТДЕЛЬНАЯ сторонняя система тетсирования
А как связан процесс этой системы тестирования с процессом АИС ?
Плагин-то твой, как я понимаю, грузится в АП процесса системы тестирования, а не в АП процесса АИС ..
> не спрашиваёте меня как это получается у разаработчиков
Не буду, я и так догадываюсь)
← →
KygECHuK © (2008-08-27 11:21) [37]
> А как связан процесс этой системы тестирования с процессом
> АИС ?
Опосредованно - симулирует сообщения от лица пользователя. т. е. для системы тестирования АИС черный ящик... с одной стороны очень сложно симулировать пользователя, а с другой можно находить концептуальные ошибки и создовать наиболее ёмкие тесты.
← →
Сергей М. © (2008-08-27 11:35) [38]
> для системы тестирования АИС черный ящик
Так а зачем же нужно перехватывать TextOut в процессе системы тестирования ? Не понимаю ..
> жалоб и замечаний именно на отображении данных в интерфейсе
Я так понял, что интерфейсе приложения АИС, а не интерфейсе приложения-тестера, которое грузит твой плагин ..
← →
KygECHuK © (2008-08-27 11:47) [39]
> Так а зачем же нужно перехватывать TextOut в процессе системы
> тестирования ? Не понимаю ..
Приходится его немного "сломать" не сисетму же распознования писать?
Ведь данные предоставляемые АИС во время тестирования влияют на его ход.
> Я так понял, что интерфейсе приложения АИС, а не интерфейсе
> приложения-тестера, которое грузит твой плагин ..
да именно, так, приложение - тестор чисто внутренний проект
Интерфейсное приложение - красиво звучит для этой АИС оно все вместе и в одном исполняемом файле.... весит до 60 mb.
← →
Сергей М. © (2008-08-27 12:14) [40]
> тестор чисто внутренний проект
Дельфийское ? Без исходников ?
Страницы: 1 2 3 4 5 вся ветка
Текущий архив: 2009.10.25;
Скачать: CL | DM;
Память: 0.57 MB
Время: 0.043 c