Как привязаться к адресу текущей инструкции?

Тема в разделе "WASM.BEGINNERS", создана пользователем amvoz, 21 ноя 2009.

  1. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    640
    Ребята, здравствуйте. Дело такое. Пишу базонезависимый код, нахожу адрес функции GetProcAddress, дабы найти адреса остальных функций (ExitProcess и прочее)

    Чтобы моя функция нашла адрес GetProcAddress, необходимо в стек положить адрес строки "GetProcAddress"
    Но как найти этот адрес строки, если я не знаю заранее, где она будет располагаться? (Предполагается, что в ЛЮБОМ месте, где есть код)

    Я придумал плясать от регистра EIP.
    То есть открываю отладчик и вручную прописываю, например, по ЛЮБОМУ адресу ПРИМЕРНО такой код

    Код (Text):
    1. mov eax, eip
    2. add eax, 8
    3. push eax
    4. jmp метка
    5. GetProcAddress
    Надеюс, что задумка понятна. Предполагается, что после
    Код (Text):
    1. add eax, 8
    в EAX в eax будет лежать адрес строки "GetProcAddress", которая, понятно дело, будет представлена какими-ниьбудь левыми командами- но это неважно, они всё равно не будут выполнены. Просто они будут использоваться не как код, а как данные.
    Здесь: add eax, 8
    В цифре 8 я не уверен, если что подкорретирую.
    ...Но как быть с регистром EIP?

    Он вообще не даёт с собой манипулировать никоим образом! Но я не собираюсь его изменять, мне просто положить бы его значение в регистр eax, например, и всё. А если к нему не привязываться, а класть GetProcAddress по какому-нибудь заранее определённому адресу, то это уже не будут базонезависимый код!

    Спасибо. Может, авантюрно, я не знаю.
     
  2. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    amvoz
    а чем вам не нравится
    Код (Text):
    1. call zzz
    2. db 'GetProcAddress',0
    3. zzz:
    ?
     
  3. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    640
    Объясняю:
    db это директива компилятору, а я не буду компилить свой пример. Я пропишу код ГОТОВЫМИ процессорными командами в отладчике.
    Если писать так, как предлагаете Вы, это значит, что компилятор должен будет зарезервировать место для этой строки, а потом этот адрес использовать.
    Я же хочу вычислять (находить) адрес строки в ПРОЦЕССЕ выполнения кода, ибо не знаю, где он будет располагатся.
    И единственная зацепка- регистр EIP. УСЛОВНО принять его за базу и от него плясать.
     
  4. FLASH300

    FLASH300 New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2008
    Сообщения:
    72
    amvoz
    1)прочитай про формат PE
    например тут
    http://wasm.ru/article.php?article=1002001
    там где то вроде был txt с шрифтом терминал там все подробно расписано

    2)для всего этого существует dll динамически загружаемая библиотека

    3)к регистру eip обращаться на прямую нельзя нет такой команды
     
  5. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    640
    Формат PE-файлов это очень хорошо, типа повторенье мать ученья.
    Но он тут вообще не при делах. Разве что отмахнуться. Тем более, я его щас почти изучил, почти добил "От зелёного к красному".
    Динамически подгружаемая библиотека не пойдёт.
    Ещё раз: код пишу базонезависимый.

    Нахожу базу kernel32.dll (Предполагается, что KERNEL32.DLL загружена, иначе не фиг рыпаться вообще)
    В ней нахожу таблицу экспорта (это без проблем, тот самый формат PE-файлов), в ней нахожу GetProcAdress, дабы находить адреса других функций.
    Вопрос: как найти там строку (в таблице экспорта, имеется ввиду GetProcAdress)? Надо перебирать нвзания всех имеющихся функций и сравнивать со строкой GetProcAdress, которую я заранее прописал... Где?
    Необходимо на ходу найти адрес.

    Я понял на счёт регистра EIP, получается, базонезависимый код (Не зависящий от адреса загрузки не прописать?)
    Плохо.
     
  6. FLASH300

    FLASH300 New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2008
    Сообщения:
    72
    Black_mirror
    дело говорит команда Call помещает в стек адрес возврата
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    amvoz
    Нормальные отладчики вполне позволяют вписывать строку аналогично инструкциям процессора.
    Black_mirror правильно ответил. Это и есть "в процессе выполнения".
    Что-то с трудом верится. Там вся первая часть посвящена базонезависимому коду. В том числе и дельта-смещениям.
     
  8. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Как вариант (хотя Black_mirror предложил очень кошерный способ) можно сделать так:

    push 'GetP'
    push 'rocA'
    push 'ddre'
    push 'ss'
    push esp
    call func

    Главное не забыть почистить стек потом.
     
  9. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    640
    Вот именно!
    Вот именно что вся первая часть посвящена.
    А теперь посмотрите, что сказано про адрес строки GetProcAddress в первой части!
    Там сказано, что в стек нужно пложить СМЕЩЕНИЕ этой строки.

    Только вот как я его найду- вот в чём вопрос, это во-первых, а во-вторых- смещение относительно чего?
    То есть предполагается, что я знаю дельта смещение. Но я его не знаю, вот в чём вся фишка-то!

    И опять всё упирается в EIP. Знай я его, я бы и смещение нашёл.
     
  10. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Так, я, конечно, наврал -- передавать надо в обратном порядке, но суть, думаю, ясна.
     
  11. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    640
    Согласен. Только я чуть-чуть ДО ЭТОГО подумал и этот способ отсёк.
    Ибо куда прыгать-то?
    call <здесь чего писать>?

    Я же не знаю, по каким адресам какие функции располагаются!
    А для того, чтобы найти, нужна GetProcAddress. Замкнутый круг. Самое путёвое предложил Mika0x65, по-моему. Некрасиво, ну, да нече делать. Или в регистры класть такиее значения, например

    Код (Text):
    1. mov eax, 47557450
    (Соответствует GetP)
    И сравнивать со строкой- названием функции. Если соответсоват- дальше работать. Цикл. Гемморой, но что делать?
    Спасибо.
     
  12. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    640
    Только одно маленькое замечание
    Mika0x65

    call func не сканает ни за что
    Ибо вместо func должен быть адрес, указывающий на таблицу импорта. А адрес строки с имнем функци не даст ровным счётом ничего, ибо компиляции НЕ ПРЕДПОЛАГАЕТСЯ.

    Это компилятор- тот да, заменил бы словесное имя на адрес.
     
  13. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    amvoz
    Вы бы это... хоть бы над ответом-то задумались, попробовали бы предложенные варианты, прежде чем свой ответ начинать строчить. А то в основном ерунду пишете.
    Цитату в студию. В GetProcessAddress передаётся полный виртуальный адрес строки, а никакое не смещение. Вариант Black_mirror соответственно в данном случае идеально подходит.
    Вуоабсче-то если в отладчике написать call 400000h, то он тоже скомпилирует инструкцию. Также OllyDbg (который Вы очевидно подразумеваете под отладчиком) позволяет назначать метки любому адресу и самостоятельно назначает адресам экспорта соответсвующие имена. Так что call func вполне "сканает".
     
  14. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    *GetProcAddress
    *соответствующие
     
  15. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    640
    ";Вход: в стек кладется смещение имени "GetProcAddress""
    То ли я дурак, то ли что.

    Как вы не можете понять, что этот код, который я получу, например
    call <адрес>

    Выполнится только на МОЕЙ системе.
    Я и без вас знаю, что OllyDbg это может делать. Мне надо, чобы это работало на всех- ну, не считая 95 системы.
    Там не будет OllyDbg.
    А раз там не будет OllyDbg никто мне заболтивл вместо call func call <адрес> не напишет
    Ясно?
     
  16. FLASH300

    FLASH300 New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2008
    Сообщения:
    72
    push esp

    я всему этому порожаюсь чел только выучил асм и пишет вирь а на форуме ему помогают ПРАКТИЧЕСКИМИ СОВЕТАМИ
     
  17. FLASH300

    FLASH300 New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2008
    Сообщения:
    72
    amvoz
    Код (Text):
    1. Выполнится только на МОЕЙ системе.
    а поискать в адресном пространстве сигнатуру PE не судьба?

    и на самом деле не таропись сесть всегда успеем:)
     
  18. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    amvoz
    Ага... ясно... исходники тырим, статьи не читаем. Ну скажем, здесь это можно отнести к опечаткам в комментариях. С другой стороны виртуальный адрес по умолчанию численно равен смещению логического адреса в IA-32. Несмотря на то, что это вряд ли имелось в виду, на оправдание тянет.
    Мда... Везде оно выполнится, если func - метка в пределах цельного куска Вашего базонезависимого кода. Для того, чтобы это понять, читаем про формат call в x86. А просил же сначала думать, потом строчить ответ.
    В общем смотрим на второй пост в теме, медитируем, почему ответ в нём правильный. И воспринимаем эту правильность, как аксиому, не подлежащую обсуждению.
     
  19. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    640
    А как ты найдёшь сигнатуру? Смотри: когда мы искали базу kernel32.dll мы от чего отталкивались?
    Вот цитата оттуда
    "Суть метода в том, что мы каким-либо способом находим адрес произвольной процедуры в kernel32.dll."
    Вот потом ЭТОТ адрес выравнивали на величину кратную (тыщи, что ли, не помню) и от ЭТОГО адреса отмерали шаги назад, всякий раз проверяя, не начало и это dllПока не нашли начало (базу)

    Я для чего слова заглавными букавми пишу? В моём коде адрес, от которого можно было бы отталкиваться (ища PE) неизвестен!

    Вот просто: можешь написать код, который бы находил адрес, по которому он располагается, не привязываясь к другим адресам?
    То есть ничё неизвестно. Один только регистр EIP
    Близок локоть, да не укусишь.
     
  20. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    call может использоавть относительную адресацию.