Фундаментальные основы хакерства


Идентификация аргументов функций - часть 29


; Маленькое дополнение – функция WriteLongint

не следует соглашению PASCAL

; т.к. не до конца чистит за собой стек, оставляя указать на буфер в стеке.

; На этот шаг разработчики компилятора пошли для увеличения производительности:

; раз указатель на буфер будет нужен и другим функциям

;(по крайней мере одной из них – WriteLn), зачем его то стягивать, то опять

; лихорадочно запихивать?

; Если вы загляните в конец функции WriteLongint, вы обнаружите там RET

6,

; т.е. функция выпихивает два аргумента – два машинных слова на Longint

и один

; Word на count.

; Вот такая милая маленькая техническая деталь. Маленькая-то она, маленькая,

; но как сбивает с толку!

; (особенно, если исследователь не знаком с системой ввода-вывода Паскаля)

 

push   20h ; ' '

; Заносим в стек следующий аргумент, передаваемый функции WriteLn

; (указатель на буфер все еще находится в стеке).

 

push   0

; Нам надо вывести только одни символ

 

call   @Write$qm4Text4Char4Word ; Write(var f;c: Char; width:Word)

 

lea    di, [bp+var_100]

; Получаем указатель на локальную копию переданной функции строки

 

push   ss

push   di

; Заносим ее адрес в стек

 

push   0

; Выводить только одну строку!

 

call   @Write$qm4Textm6String4Word ; Write(var f; s: String; width: Word)

 

call   @WriteLn$qm4Text ; WriteLn(var f: Text)

; Кажется, функции не передаются никакие параметры, но на самом деле на вершине

; стека лежит указатель на буфер и ждет своего "звездного часа"

; после завершения WriteLn он будет снят со стека

 

call   @__IOCheck$qv ; Exit if error

; Проверка операции вывода на успешность

 

leave

; Закрываем кадр стека

 

retn   8

; Выталкиваем восемь байт со стека. ОК, теперь мы знаем все необходимое для

; восстановления прототипа нашей процедуры. Он выглядит так:

; MyProc(a:Byte, b:Word, c:String);

 

MyProc       endp

Листинг 69

Да, хитрым оказался Turbo-PASCAL! Анализ откомпилированной с его помощью программы преподнес нам один очень важный урок – никогда нельзя быть уверенным, что функция выталкивает все переданные ей аргументы из стека, и уж тем более нельзя определять количество аргументов по числу снимаемых из стека машинных слов!




- Начало -  - Назад -  - Вперед -