Доброго вечера! Делал перехват вам по статье http://rsdn.org/article/baseserv/IntercetionAPI.xml 1-м методом. И... Все получилось. Вот только я никак не могу понять принцип, цитирую:
Практика показала, что вместо обычного jmp лучше применять комбинацию push xxxx ret, где xxxx - адрес заменяющей функции
Так вот, как команда push может заменить jmp? Я бы ещё понял call... Но push, она ведь просто ложит значение в стек (в данном случае - адрес функции), но каким образом она запускает эту функцию?
При вызове call выполняется две операции: на стек кладется адрес возврата и происходит переход на процедуру. Т.е. по сути push и jmp.
При возврате (ret) выполняются обратные операции: со стека снимается адрес возврата, и выполняется переход по нему. Т.е. pop и jmp.
Если сделать push, потом ret, то это будет эквивалентно push, потом pop, потом jmp. Т.е. с точки зрения стека push и pop скомпенсируют друг друга (положили на стек, потом снова сняли), и останется просто переход.
Преимущество push и ret от просто jmp может быть в том, что для jmp нужно указывать относительный адрес перехода (его еще нужно вычислить), а ret со стека берет абсолютный адрес, и переходит по нему.
Можно конечно делать косвенный переход по адресу в регистре (например, jmp [eax]), но это может не подойти, если регистры нельзя менять.
В общем, нюансов много, в разных случаях могут быть удобны разные варианты переходов.
Так ведь что делает ret? возвращает управление по адресу, сохраненному в стеке. А push этот адрес и сохраняет.
"По-моему, так" (с) Пух
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости