На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Для обсуждения создания операционных систем (ОС) используйте раздел Обсуждаем новые идеи.

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

Не забывайте также про главные ПРАВИЛА ФОРУМА!
Участники форума, нарушающие правила, будут наказываться, а вносящие вклад в развитие форума - награждаться (DigiMoney и прочими радостями).

Приятного вам общения! ;)
Модераторы: Jin X, Qraizer
  
> узнать аргументы функции
Доброго времени суток. Необходимо определить параметры функции в .dll.
Можно ли как нибудь поставить breakpoint в dll например с помощью IDA и определить значения передающихся аргументов ???
Как это сделать?
НУ если именно значения - то разве что потрассировать и по мере обращения к аргументам фиксировать, что берётся и каким типом интерпретируется...
Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
Есть претензии ко мне как к участнику? да ради бога.
Не нравятся мои ответы? не читайте их.
В общем, берегите себя. Нервные клетки не восстанавливаются.
Как выполнить эту самую трассировку? Есть .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 не устраивает, собственно? :)
1 + 1 = 10
Хочу разобраться, для опыта.
Эмм. Кстати вы не правы. Coff и OMF это не только формат объектных библиотек, это ещё формат библиотек импорта для .dll.
Цитата Abraziv @
Кстати вы не правы. Coff и OMF это не только формат объектных библиотек, это ещё формат библиотек импорта для .dll.
В чём тут неправда? :)
Библиотеки импорта генерируются на основе DLL, но не являются частью DLL.
Аналогия: я могу записать звук и сохранить его в WAV, MP3, OGG, Opus или ещё в какой-то формате. Но сам формат MP3 не имеет отношения к инструменту, который воспроизвёл этот звук :). Или формат ZIP не имеет отношения к EXE-файлу, который лежит в этом архиве.

Из obj'ей, кстати, тоже делают библиотеки, так что библиотеки - это нечто вроде "архива" obj'ей в том числе.
1 + 1 = 10
Это я конечно же понимаю. Как проблему то решить? Теория теорией, а на практике .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
1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
0 пользователей:


[ Script Execution time: 0,2670 ]   [ 19 queries used ]   [ Generated: 24.04.17, 13:14 GMT ]