Форум: "Потрепаться";
Текущий архив: 2002.04.15;
Скачать: [xml.tar.bz2];
ВнизГоловоломка на знание принципа работы компилятора Object Pascal Найти похожие ветки
← →
Алексей Петров (2002-03-06 08:41) [10]> Shaman_Naydak
Таким образом вы многое повытаскиваете. А еще если к вашей искалке добавить проход по ParentClass до TObject вы сможете очень хороший кусок иерархии объектов выкусить.
Расскажу свою мысль. В общем vuk решение уже называл по сути и я коротко на нее как-то намекал в форуме :)
Но как обещал, идея хаккерская и к сожалению код, её реализующий, может потребовать модификации при переходе с версии на версию.
Идея:
Для того, чтоб создать экземпляр класса нужно найти его VMT. Далее адрес VMT класса заносим в переменную типаclass of ...
и спомощью этой переменной можно вызвать виртуальный констуктор (потому только TComponent, как и подметил Shaman_Naydak). Основная сложность - вытащить список VMT-ов.
Несколько наблюдений по структуре exe-файла "made by Delphi":
1. В памяти (конкретно в сегменте кода) описания объектов лежат последовательно без пустот и вкрапления прочей информации (не считая выравнивания на двойное слово).
2. TObject хранится всегда самым первым. И ссылку на его VMT у нас уже есть:Pointer(TObject)
Собственно оснавная сложность: понять, сколько байт нужно пропустить, чтоб попасть на следующий объект.
Перый подход: Минимальный размер VMT - -vmtSelfPtr = 76 (для D5) - это размер служебной информации для класса.
Прибавляем к предыдущеум указателю -vmtSelfPtr и далее проверяем не на объект ли попали. Если нет - добавляем 4 и снова проверяем, пока не найдем или пока не уйдем за пределы сегмента кода. (Предварительно стоит выяснить, где кончается нужная память с помощью VirtualQuery).
Проверка того, что поинтер может быть TClass-ом довольно проста:
1) Pointer((Ptr+vmtTypeInfo)^) обязан показывать на кусок самого exe-шника, что выясняется с помощью VirtualQuery
2) PShortString((Ptr+vmtClassName)^) должен быть и быть корректным идентификатором по синтаксису Delphi.
3) (Ptr+vmtInstanceSize)^ должен быть разумным: как минимум положительным (>=4). Можно еще ограничение наложить <1GB а можно и побольше немного
4) Pointer((Ptr+vmtParent)^) должен указывать на ранее выкопанный объект (можно проверять просто на объект по выше приведенным критериям), кроме объекта TObject у которого тут nil.
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2002.04.15;
Скачать: [xml.tar.bz2];
Память: 0.45 MB
Время: 0.004 c