Как составить CALL

Тема в разделе "WASM.BEGINNERS", создана пользователем wyfinger_, 14 июл 2007.

  1. wyfinger_

    wyfinger_ New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2006
    Сообщения:
    28
    Адрес:
    Россия
    Добрый день.

    Есть адрес, по которому находится процедура (в dll), мне нужно вызвать ее из exe файла (чужого), в нужном месте я могу вставить CALL переход, но dll может загрузиться по разным адресам, поэтому адрес моей функции тоже разный, возникает необходимость составить эту команду, но как? не могу понять.

    Я нашел, что она должна выглядеть так:
    |10011010|offset-low|offset-high|seg-low|seg-high|

    Только как получить секмент и смещение? какого размера сегмент?

    P.S. Простите за глупость, я в этом ничего не смыслю.
     
  2. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    вариант номер раз. найти куда загрузилась длл и посчитать, куда надо прыгать. найти Адрес ф-ии можно с помощью функций LoadLibrary и GetProcAddress.
    Вариант номер 2. при загрузке длл устанавливать перехват из неё. Тогда ты точно будешь знать где находится длл.
    call - это e9 + offset
     
  3. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    опкодов команды 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)
     
  4. wyfinger_

    wyfinger_ New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2006
    Сообщения:
    28
    Адрес:
    Россия
    Great - Вот смотрите, я беру OllyDbg, запускаю программу, в которой
    хочу добавить вызов процедуры из моей dll. Я уже сделал код загрузки dll и
    вызова одной функции, теперь нужно сделать вызов другой функции.
    После загрузки моей длл в память я беру и вбиваю а OllyDbg:
    CALL <прямой адрес на функцию в DLL>

    получается:
    00401DDD E8 E687E103 CALL wyext.SULf

    т.е. 5 байтовая команда.

    Понятно что она состоит из:
    |10011010|offset-low|offset-high|seg-low|seg-high|

    Но как мне из готового адреса получить сегмент и смещение в нем?

    Я что-то уже калькулировал-калькулировал.., так ничего и не выкалькулировал!
    ______
    С другой сторону, я тут подумал, я же могу при загрузке Dll определить адрес и второй функции, сохранить его где-то, потом вывести в регистр и вызвать оттуда. Да, это будет проще, но мы не ищем легких путей, поэтому меня интересуют оба варианта.
     
  5. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    хм... не совсем понял, о каком сегменте идет речь??? Я так понимаю, что ты делашь вызов не на уровне исходных кодов, а уже в готовой программе? Если так, я бы рекомендовал сделать поиск функции в таблице экспорта твоей библиотеки (у ицзелиона об этом написано, смотри васм.ру)
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Я тебе второй раз говорю, что опкодов команды CALL много. И выбрал ты неподходящий для тебя
    Сегмент тебе указывать не нужно. И вообще указанный тобой 10011010 (b) != 0xE8.
    Я уже писал какой это опкод:
    Этот опкод обеспечивает вызов функции непосредственно задавая ее адрес.

    То есть CALL 0x11223344 будет - E8 44 33 22 11

    Теперь понял?
     
  7. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    нет не так. Ты смотришь не на тот вид 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 забыл.:dntknw: Вот что злоупотребление hll делает.
     
  8. wyfinger_

    wyfinger_ New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2006
    Сообщения:
    28
    Адрес:
    Россия
    Все понял, я просто почему-то думал, что CALL должна непосредственно установить значение в EIP, тогда как она добавляет к ней какое-то значение.

    Все-таки я, наверное, воспользуюсь связкой
    mov eax,addr
    call eax

    правда прийдется сделать перед этим еще один короткий переход, т.к. в том месте где нужно патчить не хватает нескольких байт, поищем свободное место где-нибудь рядом.

    Всем Спасибо.
    _______
    P.S. Не думал что все так рьяно прийдут на помощь. Еще раз спасибо.
     
  9. loleg

    loleg New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    93
    а чем не нравится
    010073A2 9A 44332211 1B>CALL FAR 001B:11223344 ; Far call

    ?