реконструкция алгоритма прoграммы написанной на Delphi

Тема в разделе "WASM.BEGINNERS", создана пользователем Psionic, 24 янв 2010.

  1. Psionic

    Psionic Member

    Публикаций:
    0
    Регистрация:
    25 сен 2008
    Сообщения:
    156
    И так, снова студент-физик нуждается в помощи, но на этот раз все серьезно. Есть некая пара программ моделирующая физические процессы, аффтар исходниками поделится не желает, но учитывая что программа бесплатна и алгоритм все равно я намерен перепесать в MVS то все легально. Я начал иследования и увидел что нужные мне функции находятся в одной DLL, но так как все написанно на Delphi, то возникают некоторые проблемы:

    1. Каким образом функции из DLL возвращают значения? (Если DLL написанна на С++ и если функция что-то вoзвращает то это происходит через регистр EAX, но в Delphi используется какое-то другое соглашение и как быть непонятно, узнал о нем только что аргументы в стеке идут в обратной последовательности чем в С++).

    2. IDA Pro (в своих изысканиях я использовал и ее) после "обявления" в листинге функции идут такие строчки
    Код (Text):
    1. var_34      = tbyte ptr -34h
    2. var_10      = tbyte ptr -10h
    3. arg_0       = tbyte ptr  8
    4. arg_C       = tbyte ptr  14h
    Это что? У меня только предположения.

    3. Каковы шансы на успех если просто пересобрать пару нужных мне функиций из листинга иды в MASM как статическую библиотеку и присоиденить к своему проэкту? Ведь из статей Касперски мне известно об ошибках в дизасемблировании, я боюсь что даже если разберусь с последовательностью аргументов для отправки в стек то все равно программа может вылетать или неверно дизассемблированная функция будет возвращать неверные значения.
     
  2. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
    2.
    Локальные переменные
    Аргументы вызываемой функции
     
  3. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
    Наиболее простое решение - это рипнуть функцию узнать, как вызывается функция (исследовать аргументы и модель вызова) затем вставить в свой проект. С помощью иды вполне реально сделать, пока крайней мере мне удавалось
     
  4. Psionic

    Psionic Member

    Публикаций:
    0
    Регистрация:
    25 сен 2008
    Сообщения:
    156
    Что значит рипнуть?
     
  5. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
    Это означает взять искомую дизассемблированную функцию и вставить в свой проект
     
  6. Psionic

    Psionic Member

    Публикаций:
    0
    Регистрация:
    25 сен 2008
    Сообщения:
    156
    Да я тоже об этом думаю (п 3.), но пока мне несовсем понятна модель вызова и куда возвращается результат. А вот с количеством и типом аргументов все ясно.
     
  7. PSR1257

    PSR1257 New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2008
    Сообщения:
    933
    Скорее всего так же или почти так же. int32/boolean/real32... - EAX, но если это double (вещественное) то в стеке сопроцессора. А вообще откройте модуль где идет вызов и посмотрите как используются результаты вызова функции из DLL.

    А ф чем будет разница - это у вас уже есть в виде DLL. Другое дело если нужно править алгоритм или переписать его.

    Тогда да - выдергиваете функцию и пытаетесь ее собрать отдельно. Помимо проблем с просто "вниканием" почти наверняка встретяться вызовы библиотечных функций которые нужно будет подлинковать или переписать на вызовы сишных функций или вообще переписать самому.

    Когда пройдете этап компиляции начинайте тестировать что получилось - вызываете оригинал и свою и сравниваете результаты. При достаточно грамотном выборе тестовых значений все допущенные ошибки исправляются быстро и код условно признается как практически равный исходному.

    Можно сразу перебивать на C переводя исходный листенг из IDA. Делфи досточно просто понимается и переводя и тут же проверяя мелкими блоками можно довольно быстро переписать не очень большую функцию. Тестирование по схеме описанной выше; тестировать можно блок за блоком по мере переписывания.

    Если будут проблемы приведите кусок своего DLL, я попробую перебить для демонстрации.
     
  8. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    tbyte это почти наверняка тип Extended.
     
  9. Psionic

    Psionic Member

    Публикаций:
    0
    Регистрация:
    25 сен 2008
    Сообщения:
    156
    у меня нет ни .lib, ни .h файла (да последнего и в природе нет :dntknw:, это же делфи, хотя зная тип и аргументы в принципе можно написать и самому но от потребности в .lib это меня не освобождает). Пока что я решил повозюкатся с этой DLL в FASM, там статическая библиотека не нужна, а поработать со стеком и проверять регистры можно вполне.
     
  10. PSR1257

    PSR1257 New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2008
    Сообщения:
    933
    DllLoadLibrary & написанный свой *.h по результатам анализа могут спасти атца русской демократии...
     
  11. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Psionic
    http://www.wasm.ru/article.php?article=1018001
     
  12. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
  13. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Psionic
    Все программы (два экзешника и длл) написаны на Дельфи 6. В обоих экзешниках импорты находятся в юните Unit1. Прототипы импортируемых функций ты можешь получить, анализируя вызовы (в списке XRefs) и сопоставляя их с кодом из длл. Функций немного, думаю справишься.
     
  14. Psionic

    Psionic Member

    Публикаций:
    0
    Регистрация:
    25 сен 2008
    Сообщения:
    156
    Со скрипом получил прототипы адресуемых через стек аргументов.
    Снова вопрос:
    Код (Text):
    1. mov ax, ds:word_491D48
    2. push    eax
    3. push    ds:dword_491D44
    4. push    ds:dword_491D40
    Это я так понимаю части одной переменной, но что это за тип тут-же целых 10 байт? Я нашел что в Делфи есть тип Extended (размер подходит), возможно это он так передается через стек, а есть ли аналогичные типы в С++? И что посоветуете если такого типа нет?
    [​IMG]
    Эта картинка результат гугления но long double на поверку в sizeof имеет 8 байт, как так?
     
  15. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Зависит от компилятора.
    MSVC long double не поддерживает, он в ней эквивалентен просто double.
    Intel C++ к примеру поддерживает (задаётся ключами), GCC вроди тоже.
     
  16. Psionic

    Psionic Member

    Публикаций:
    0
    Регистрация:
    25 сен 2008
    Сообщения:
    156
    Ну и как мне быть? Функция требует 10 байт иначе - ругань на регистр ESP, может кто-то предложить мне трюков какихнибуть?
     
  17. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Psionic
    У тебя два пути:
    1. Создать новый тип Extended (сорцы смотри у Борланда)
    2. Использовать ассемблерный листинг нужной функции.
    Кстати, непонятно, при чем здесь ругань на ESP, ведь в стек кладется 12 байт, а не 10.
     
  18. Psionic

    Psionic Member

    Публикаций:
    0
    Регистрация:
    25 сен 2008
    Сообщения:
    156
    Это уже чтото, а можно по подробнее?
     
  19. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Psionic
    Если у тебя есть инсталляция Дельфи или Билдера, посмотри модуль math.h, только все равно тебе придется писать на ассемблере. Можно еще замутить поиск в гугле, может быть найдется реализация подобных вещей для MSVC.
    У тебя есть еще вариант взять Билдер, тогда можно будет использовать тип long double.
     
  20. Psionic

    Psionic Member

    Публикаций:
    0
    Регистрация:
    25 сен 2008
    Сообщения:
    156
    Впринципе есть мысль - Я понятия не имею зачем Автор проги заюзал тип Extended, для той задачи которую он решал типа Real хватит с головой и он хорошо сочетается с типом double в С++. А что если реализовать в компиляторе с поддержкой long double библиотечку с такой фунуцией:
    Код (Text):
    1. long double func(double g)
    2. {
    3.    long double z=1;
    4.  return z*g //численное знаечение g возвращается в long double.
    5.   }
    потом вызвать это функцию из проэкта студии, но зделать это в ассемблерной вставке, чтобы в ручную извлеч все байтики переменной и потом переслать их в функицию из DLL опять же посредством ассемлерной вставки. Главное понять насколько совместимы Extended и long double.