Добрый день. Есть адрес, по которому находится процедура (в dll), мне нужно вызвать ее из exe файла (чужого), в нужном месте я могу вставить CALL переход, но dll может загрузиться по разным адресам, поэтому адрес моей функции тоже разный, возникает необходимость составить эту команду, но как? не могу понять. Я нашел, что она должна выглядеть так: |10011010|offset-low|offset-high|seg-low|seg-high| Только как получить секмент и смещение? какого размера сегмент? P.S. Простите за глупость, я в этом ничего не смыслю.
вариант номер раз. найти куда загрузилась длл и посчитать, куда надо прыгать. найти Адрес ф-ии можно с помощью функций LoadLibrary и GetProcAddress. Вариант номер 2. при загрузке длл устанавливать перехват из неё. Тогда ты точно будешь знать где находится длл. call - это e9 + offset
опкодов команды CALL ойойой как много. call eax это одно, call imm32 это уже другое... Итак, по порядку. Для начала что ты написал - это call far с заданием сегмента. Сегмент это 16 бит, смещение в 32разрядной адресации это 32 бита. то есть получакется 9A XX XX XX XX YY YY; YYYY - это сегмент, XXXXXXXX - смещение. Дальше какие еще могут быть опкоды: E8 [DW] - CALL rel16 (rel32) пример: CALL $+5 (E8 00) FF /2 - FF mod010r/m - CALL r/m16 (r/m32) пример: CALL EAX (FF D0) 9A [DD] - CALL FAR seg16:offs16 (seg16:offs32) пример: CALL FAR 1234:567890AB (9A AB 90 78 56 34 12) FF /3 - FF mod011r/m - CALL m16:16 (m16:32) пример: CALL DWORD PTR DS:[EDI] (FF 1F)
Great - Вот смотрите, я беру OllyDbg, запускаю программу, в которой хочу добавить вызов процедуры из моей dll. Я уже сделал код загрузки dll и вызова одной функции, теперь нужно сделать вызов другой функции. После загрузки моей длл в память я беру и вбиваю а OllyDbg: CALL <прямой адрес на функцию в DLL> получается: 00401DDD E8 E687E103 CALL wyext.SULf т.е. 5 байтовая команда. Понятно что она состоит из: |10011010|offset-low|offset-high|seg-low|seg-high| Но как мне из готового адреса получить сегмент и смещение в нем? Я что-то уже калькулировал-калькулировал.., так ничего и не выкалькулировал! ______ С другой сторону, я тут подумал, я же могу при загрузке Dll определить адрес и второй функции, сохранить его где-то, потом вывести в регистр и вызвать оттуда. Да, это будет проще, но мы не ищем легких путей, поэтому меня интересуют оба варианта.
хм... не совсем понял, о каком сегменте идет речь??? Я так понимаю, что ты делашь вызов не на уровне исходных кодов, а уже в готовой программе? Если так, я бы рекомендовал сделать поиск функции в таблице экспорта твоей библиотеки (у ицзелиона об этом написано, смотри васм.ру)
Я тебе второй раз говорю, что опкодов команды CALL много. И выбрал ты неподходящий для тебя Сегмент тебе указывать не нужно. И вообще указанный тобой 10011010 (b) != 0xE8. Я уже писал какой это опкод: Этот опкод обеспечивает вызов функции непосредственно задавая ее адрес. То есть CALL 0x11223344 будет - E8 44 33 22 11 Теперь понял?
нет не так. Ты смотришь не на тот вид call как написал Great E8 [DW] - CALL rel16 (rel32) пример: CALL $+5 (E8 00) т.е. e8 - опкод команды, а E687E103 (вернее 3e187e6) смещение адреса от конца команды call на который происходит прыжок. В твоём случае адрес куда будет происходить прыжок будет равен 401DDD(адрес call) + 5(размер call) + 3e187e6(смещение). = 421a5c8. проще всего для тебя будет воспользоваться командами mov eax,addr call eax // если можно eax портить тогда ничего считать не надо будет. Нужно только узнать адрес функции одним из предложенных путей. //off ппц опкод call забыл. Вот что злоупотребление hll делает.
Все понял, я просто почему-то думал, что CALL должна непосредственно установить значение в EIP, тогда как она добавляет к ней какое-то значение. Все-таки я, наверное, воспользуюсь связкой mov eax,addr call eax правда прийдется сделать перед этим еще один короткий переход, т.к. в том месте где нужно патчить не хватает нескольких байт, поищем свободное место где-нибудь рядом. Всем Спасибо. _______ P.S. Не думал что все так рьяно прийдут на помощь. Еще раз спасибо.