Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Assembler&Delphi!!!!!


Страницы:   1 2 3

4ert ©   (2006-12-27 02:01:00) 

И вновь здравствуйте!!! Хотелось бы узнать(теперь серьзно(вчера тупил)), немного об использовании assembler в delphi. Коротко о задаче. Пишу прогу, пожалуй опишу её предназначение(дабы гнусным вирусописателем не называли). Я по природе человек любопытный и меня всегда интересовал вопрос как же конкретно работает то, или иное приложение. И вот в последнии дни пришла в голову мысль написать софтину призванную помогать мне в этом. Как рашил реализовать: есть dll с функциями перехвата(путем подмены адреса APi функции), её мы подгружаем в указанный процесс), она меняет адреса всех нужных нам APi функций на адреса наших обработчиков, обработчики работают по одному принципу: получают всю возможную инфу о параметрах перехватываемой функции и отсылает главному приложению, та в свою очередь выводит всю информацию в Memo и ждет новых сообщений...
В принципе все просто(благо примеров в инете море!!!!), но вот возникла вовсе неожиданная прблема примеров в нете  много, но все, как правило, иллистрирует перехват одной конкретной функции, а у меня же их по плану ну штук сто наверно будет.С утановкой перехвата всё ништяк, с получением инфы тож, а проблема с реальным выполнением функции, то есть чтобы дать зараженному процессу все-таки выполнить то, что он хочет. В каждом перехватчике я возращаю память в исходное состояиние(до установки перехвата) и похорошему необходимо бы выполнить перехваченную функцию API, а затем установить перехватчик снова... Вот такие идеи. Сложность в том что никак не могу понять как реализовать запуск нужной функции API, причем функция запуска хотелос, чтобы была одна...Ибо обработчик для каждой API я то напишу(благо есть windows.pas), а вот писать ещё сто функций запуска для каждой API это уж слишком.....
Структура перехватчика:


function perexvat(<параметры>): integer; stdcall;
begin
<получаем параметры>
<отсылаем сообщение с параметрами>
<восстонавливаем память в исходное состояние>
<запускаем функцию CallApi>
<устанавливаем перехватчик>
end;


Мотив обращения к вам - вопрос реализации функции CallApi. Этот глобальный вопрос делится на два субвопроса:

1)как реализовать запуск функции зная её адрес(ну и естественно передать ей необходимые параметры)?

2)Как сделать чтобы функция была универсальна, т.е. была в состоянии запустить любую функцию API с любым количеством параметров и их типов?

По поводу первого вопроса я целый день рылся в инете(не без вашего пинка) и в собственных архивах. Я так понимаю едиственный верный вариант реализации CallApi это assembler, параметры передавать через стек(ведь мы даже не знаем сколько их может быть максимально!), а на вход функция должна принимать, я думаю(я знаком с assembler один день!!! А с Delphi всего четыри месяца!) массив параметров затем запускать цикл который будет делать нечто наподобии:


push parametrs[i]


пока не кончится массив, а затем делать собственно:


call addr


Вопрос к вам уважаемые Мастера: как вы думаете алгоритм(теоритически) продуман нормально? аль косячки имеются?
-------------------------------------------
Теперь о практике, забудем немного о необходимости универсальности функции, ибо не получается даже елементарное: Решил сделать тест, получится ли у меня запустить с помощью assembler API функцию MessageBoxA:
Делал так:


function asem(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
asm
push hWnd
push lpText
push lpCaption
push uType
call addr
end;


где


addr:=@MessageBoxA;


При запуске функции появляется таки messagebox но глючит, скажу я вам, его вовсе не подетски, то вместо MB_OK(а именно эта константа передаетсяв качестве uType) появляется три кнопки с надписями "повторить" "отменить" "продолжить" то текст выравне слева, то справа, то присутствует 3D эффект то нет... Короче лажа какая-то!!!! Я подозреваю, что происходит это из-за того, что я не очищаю стек, но как же быть? Ведь если я его очищаю методом который описан у всех авторов(вставляю сразу после "call"):


add        sp,8


(Насчет восмерки не уверен), то замечательный компилятор не менее замечательного Delphi 7 enterprise выдаёт ошибку примерно следующего содержания:


Project test.exe raised exception EAccessViolation with message 'Access violation at address 0012F7C8.
Write of address 0342B299'.


Как же быть? Или поповоду очистки стека я ошибаюсь?
------------------------------------------------------
Также очень бы хотелось Уважаемые Мастера услышать ваше мнение поповоде 1) и 2), а также вцелом алгоритма......

Заранее ОГРОМНЕЙШЕЕ СПАИБО!!!!!!
(надеюсь не задолбались читаь?)


ors_archangel   (2006-12-27 02:45:00) [41]

А вообще тебе обяз нужно обойтись без перепередачи параметров, потому как фунь может быть и не stdcall, а notstdcall, как-то я писал примерно такое:

  if assigned(before) then begin
     pusha;
     mov edx,@before
     mov eax,beforeParam
     call edx
     popa;
   end;
   mov save_edi,edi
   mov save_esi,esi
   mov edi,original
   pop esi // save original return address
   call edi
   push esi
   mov edi,save_edi
   mov esi,save_esi
   if assigned(after) then begin
     pusha
     mov edx,@after
     mov eax,afterParam
     call edx
     popa
   end;
   ret

здесь нам пофигу что за функция, сколько у неё  параметров и как они передаются, а зачем восстанавливать обработчик каждый раз я не понял и читать задолбался ;)
Надо коммент, пость


ors_archangel   (2006-12-27 02:32:00) [42]

Рекомендую читать замечательную справку не менее замечательного Delphi 7 Enterprise :) где, например, написано

Calling conventions
Directive Parameter order Clean-up Passes parameters in registers?
register Left-to-right Routine Yes
pascal Left-to-right Routine No
cdecl Right-to-left Caller No
stdcall Right-to-left Routine No
safecall Right-to-left Routine No

- порядок pushинга аргументов при stdcall - right-to-left, а ты сделал left-to-right


4ert   (2006-12-27 02:11:00) [43]

Сорри, конечно же не компилятор ошибку выдает :)


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо