Нужно получить значение регистра EIP любым методом кроме (E800000000 call XXXXXXXX) вообще не используя call.
PaCHER Через SEH: 1. Установить обработчик SEH. (Сделать это позиционно-независимым методом накладно, если вообще возможно...) 2. Справоцировать исключение (xor ecx,ecx div ecx) 3. Достать EIP из контекста.
Quantum и netw0rm При SEH получается офигенная задержка. 1 Способ: - Слежение за EIP Создать новый поток, который будет читать структуру CONTEXT другого. 2 Способ: - Текущее значение EIP При старте программы EIP указывает на точку входа. Соответственно можно в любой момент времени прочитать EIP, указав метку: ;... _EIP: mov eax, offset _EIP ;... В eax сохраняется значение EIP. Так же метку можно кинуть куда угодно, чтобы прочитать EIP в другом месте.
Это сработает только в том случае если у нас exe файл да еще загружен по таму адресу который по умолчанию вписал компалятор. А если у нас динамическая библиотека. И каждый раз грузится по свободным адресам то точка входа будет пересчитыватся.
Вариации на тему BOOL GetThreadContext( HANDLE hThread, LPCONTEXT lpContext ); вызовом из самого себя.
А это практическая реализация: 1) Создаем поток который будет вызывать GetThreadContext 2) Свой поток зацикливаем на EIP - <EBFE JMP EIP> 3) Тот который опрашивал изменяет EIP = EIP + 2 и передает в TLS значение EIP. 4) Код после EIP получает значение своего EIP из TLS
PaCHER Не понятна постановка задачи. Если нужно определить EIP в своей проге, то ответ тривиальный - ставишь метку и просто грузишь ее адрес в регистр lea или mov. За dll беспокоиться нечего, т.к. все ссылки на адреса попадают в секцию релоков и автоматом пересчитываются загрузчиком Если же речь идет о внедрении кода в работающую прогу, то самый простой способ это ес-но call. Если хочется поизвращаться, то остается прерывать поток и читать CONTEXT или ломиться в TSS
Bill_Prisoner А зачем зацикливать на EIP??? По моему нету смысла - просто остановить и все - leo прав!
Можно еще через fpu, например заюзать fstenv, а в сохраненном блоке будет instruction pointer на последнюю выполненную fpu команду. Код (Text): get_eip: fldz sub esp, 28 fnstenv byte ptr [esp] mov ebp, [esp+12] ;; ebp == offset get_eip add esp, 28