На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Помните, что у нас есть FAQ раздела Assembler и Полезные ссылки. Посмотрите, возможно, там уже имеется решение вашего вопроса.

3. Настоятельно рекомендуем обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "Ассемблер" будут отправляться в Корзину для мусора.
  3.2. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).
  3.3. Нежелательно поднимать старые темы (не обновлявшиеся более года) без веской на то причины.

Не забывайте также про главные Правила форума!

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
  
> узнать аргументы функции
    Доброго времени суток. Необходимо определить параметры функции в .dll.
    Можно ли как нибудь поставить breakpoint в dll например с помощью IDA и определить значения передающихся аргументов ???
    Как это сделать?
      НУ если именно значения - то разве что потрассировать и по мере обращения к аргументам фиксировать, что берётся и каким типом интерпретируется...
        Как выполнить эту самую трассировку? Есть .exe есть .dll
        пихаю .exe в IDA , как мне теперь найти функции этой .dll ? Если закидываю .dll их видно, короче ничего не понятно.
        Вот аргументы функции в интерпретации IDA:

        .text:00401538 var_28 = dword ptr -28h
        .text:00401538 var_18 = word ptr -18h
        .text:00401538 var_4 = dword ptr -4
        .text:00401538 arg_0 = dword ptr 8

        Добавлено
        Такс, зашёл по бреку в функцию. Как теперь посмотреть значения переменных приведённых выше, или они начнут появляться после popов ???

        Добавлено
        Как теперь значения стека связать с переменными идущими сразу же после названия процедуры (функции) ???
        .text:00401538 var_28 = dword ptr -28h
        .text:00401538 var_18 = word ptr -18h
        .text:00401538 var_4 = dword ptr -4
        .text:00401538 arg_0 = dword ptr 8

        Добавлено
        Вот взял снимок стека:
        Stack[00001250]:0018E3A8 db 0E8h ; ш
        Stack[00001250]:0018E3A9 db 0E3h ; у
        Stack[00001250]:0018E3AA db 18h
        Stack[00001250]:0018E3AB db 0
        Stack[00001250]:0018E3AC db 90h ; Р
        Stack[00001250]:0018E3AD db 0E7h ; ч
        Stack[00001250]:0018E3AE db 0AAh ; к
        Stack[00001250]:0018E3AF db 6
        Stack[00001250]:0018E3B0 db 0C0h ; L
        Stack[00001250]:0018E3B1 db 21h ; !
        Stack[00001250]:0018E3B2 db 9Ah ; Ъ
        Stack[00001250]:0018E3B3 db 4
        Stack[00001250]:0018E3B4 db 74h ; t
        Stack[00001250]:0018E3B5 db 0E7h ; ч
        Stack[00001250]:0018E3B6 db 18h
        Stack[00001250]:0018E3B7 db 0

        Получается, как я понял стек растёт в сторону уменьшения адреса. Данные пихаются старшими байтами вперёд, т.к.
        Stack[00001250]:0018E3A8 db 0E8h ; ш
        Stack[00001250]:0018E3A9 db 0E3h ; у
        Stack[00001250]:0018E3AA db 18h
        Stack[00001250]:0018E3AB db 0 <- 0 с большой вероятность что старший байт

        Какое тогда получается соглашение вызова ???

        Или что то я наврал здесь.

        Добавлено
        Попробовал перезагрузить процесс, значения аргументов не поменялись, значит это не адреса (не указатели). Почему в стек пихается старшими байтами вперёд?
          Ааа, ну всё правильно, это stdcall, главное чтобы я правильно интерпретировал стек (растёт к 0x00000000 адресу).
          Правда всё равно ничего не понятно))))
            Цитата Abraziv @
            Вот аргументы функции в интерпретации IDA:

            В интерпретации IDA аргумент всего один - arg_0 по смещению +8, а var_X по отрицательным смещениям - это локальные переменные функции.

            Цитата Abraziv @
            Как теперь значения стека связать с переменными идущими сразу же после названия процедуры (функции) ???

            Если функция имеет стандартный пролог типа (push EBP, mov EBP,ESP), то адреса аргументов и локальных переменных задаются смещениями относительно значения в регистре EBP, т.е. адрес arg_0 будет = EBP+8

            Цитата Abraziv @
            как я понял стек растёт в сторону уменьшения адреса

            Да

            Цитата Abraziv @
            Почему в стек пихается старшими байтами вперёд?

            Не "вперед", а как обычно для x86 - старшими байтами по старшим адресам (см. little endian)

            Цитата Abraziv @
            Какое тогда получается соглашение вызова ???

            Если функция имеет стандартный эпилог, то при соглашении stdcall возврат из функции осуществляется командой ret(n) X, где X - число, равное суммарному размеру всех аргументов функции (с учетом их выравнивания на 4 для x32). Если возврат осуществляется командой ret(n) без аргумента, то это либо cdecl, либо stdcall без аргументов.

            Цитата Abraziv @
            Попробовал перезагрузить процесс, значения аргументов не поменялись, значит это не адреса (не указатели)

            Это ни о чем не говорит, т.к. с одной стороны это м.б. указатель на глобальную переменную, адрес которой не изменяется от запуска к запуску, а с другой стороны некоторые значения (не указатели) также могут изменяться при перезапуске (например, всевозможные дескрипторы типа виндовых HWND и т.п.)

            PS: Ты уверен, что исследуемая dll является приватной\"самопальной" для данного приложения, а не какой-нибудь общеизвестной, для которой можно найти описания функций в интернете?
            Сообщение отредактировано: leo -
              leo спасибо за расширенный ответ и ссылку. Разобрался со всем, всё работает.

              Цитата leo @
              PS: Ты уверен, что исследуемая dll является приватной\"самопальной" для данного приложения, а не какой-нибудь общеизвестной, для которой можно найти описания функций в интернете?

              Да уверен, .dll самопальные, писал другой человек.
              Единственное, у меня получилось их использовать только через Loadlibrary(). Пытался использовать libу, но вижуал требует чтобы ссылки были вида func@4 для одного аргумента (к примеру int) и func@0 для void. Как я понял это COFF формат. В целевой dll же они просто хранятся в виде func. Как я понял это билдеровский формат OMF. Иными словами если в .def описать без @, то линкер будет ругаться, если же с @ то во время запуска напишет что не может найти func@ в .dll Как побороть проблему так и не понял.
                Цитата Abraziv @
                Как я понял это COFF формат. В целевой dll же они просто хранятся в виде func. Как я понял это билдеровский формат OMF.
                COFF и OMF - это форматы объектных модулей, к DLL они не имеют отношения.
                А чем LoadLibrary не устраивает, собственно? :)
                  Хочу разобраться, для опыта.
                    Эмм. Кстати вы не правы. Coff и OMF это не только формат объектных библиотек, это ещё формат библиотек импорта для .dll.
                      Цитата Abraziv @
                      Кстати вы не правы. Coff и OMF это не только формат объектных библиотек, это ещё формат библиотек импорта для .dll.
                      В чём тут неправда? :)
                      Библиотеки импорта генерируются на основе DLL, но не являются частью DLL.
                      Аналогия: я могу записать звук и сохранить его в WAV, MP3, OGG, Opus или ещё в какой-то формате. Но сам формат MP3 не имеет отношения к инструменту, который воспроизвёл этот звук :). Или формат ZIP не имеет отношения к EXE-файлу, который лежит в этом архиве.

                      Из obj'ей, кстати, тоже делают библиотеки, так что библиотеки - это нечто вроде "архива" obj'ей в том числе.
                        Это я конечно же понимаю. Как проблему то решить? Теория теорией, а на практике .dllки билдера и Майкрософт отличаются.
                          Цитата Abraziv @
                          если же с @ то во время запуска напишет что не может найти func@ в .dll Как побороть проблему так и не понял

                          Задать импорт функции по ординалу в виде:
                          func@4 @X
                          где X - ординал функции func, который можно узнать утилитой dumpbin /EXPORTS

                          PS: Формат def-файла допускает задание алиаса имени функции в виде func@4=func, но, говорят, что lib такую конструкцию игнорирует. Поэтому приходится использовать ординал.
                            Спасибо, попробую.
                              leo спасибо огромное, сделал через ординалы, всё отлично работает.
                              Вы настоящий спец.
                                А вот ещё вопрос:
                                Почему если в .h объявить прототип вида:
                                extern "C" void func(int);
                                то линкер будет всё равно искать декорированное имя _func, несмотря на то, что в C не используется декорирование.
                                А если же
                                extern "C" void __stdcall func(int);
                                то ищет func.

                                Правда при это в .lib они определены как func@4
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0394 ]   [ 15 queries used ]   [ Generated: 28.03.24, 18:32 GMT ]