Русский / Russian English / Английский

Сейчас на форуме: (+1 невидимый пользователь)
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS ·

 eXeL@B —› Крэки, обсуждения —› Вызвать метод класса снаружи [Delphi]
Посл.ответ Сообщение

Ранг: 25.1 (посетитель)
Статус: Участник

Создано: 30 мая 2008 12:35 · Поправил: RUNaum New!
Цитата · Личное сообщение · #1

Ситуация.

Есть исполняемый файл, написанный на Delphi 7. Вся протекция с него снята, он чист. Используя PE Explorer (это мог быть любой иной редактор ресурсов) был проанализирован список используемых VCL компонент.

Среди компонентов был встречен некий TMyComponent, исходники и бинарники которого есть в наличие. VCL компонент TMyComponent имеет метод Save() который сохраняет некоторую защищенную информацию (иным образом до нее не добраться, т.к. есть куча слоев защиты, начиная от AES (еще чем-то и еще чем-то), заканчивая компрессией редко встречаемым алго и логическими байт-операциями сверху - реверсить эти слои - безумие). Вызов этого метода позволить обойти все слои защиты и сохранить нужный для дальнейшей работы файл-ключ.

Вопрос 1: Как узнать адрес процедуры Save() для ее последующего вызова?

Предположения: можно по сигнатуре найти в памяти, верно? Грубовато будет, но все-таки. Либо зная offset в VMT какими-то сложными вычислениями =) Может подскажет кто.

Вопрос 2: Как лучше осуществить вызов этой процедуры? Инжект в процесс и просто вызов ее по адресу в контексте вражеского процесса? Или есть иные способы?

PS. Я не совсем реверсер, в привычном понимании. Многие моменты для меня темный лес, надеюсь кто-нибудь да поможет. Заранее благодарю.

[Added]
Проблема судя по всему будет еще в том, что мало вызвать по найденному указателю. Потребуется еще и передать, вероятно, ряд вещей. По крайней мере Sender'a точно (тут можно nil кинуть, но все таки). Надеюсь больше ничего инициализировать / придумывать не нужно? Ведь метод это не просто процедура, если вспомнить как сделана VMT / TMethod.


Ранг: 756.2 (! !)
Статус: Участник
Student

Создано: 30 мая 2008 13:11 · Поправил: Isaev New!
Цитата · Личное сообщение · #2

1. Смотри таблицу импорта
2. Смотри, как она вызывается из подопытной


[Правка] Да, что-то я просмотрел... Думал dll'ка.

Ранг: 25.1 (посетитель)
Статус: Участник

Создано: 30 мая 2008 13:16 · Поправил: RUNaum New!
Цитата · Личное сообщение · #3

Isaev пишет:
1. Смотри таблицу импорта
2. Смотри, как она вызывается из подопытной


1. Вы вероятно не поняли ситуации. При чем здесь таблица импорта, если код TMyComponent.Save() находится в теле исполняемого файла? Это же не внешняя библиотека. Это VCL.

2. Собственно см. п. 1. В моем случае этот метод TMyComponent'a может даже и не вызываться жертвой, хотя сомнительно.

[Fixed]
Исправил слово "компонент" на "VCL компонент", т.к. не каждому недельфисту будет понятна терминология. Приношу свои извинения.


Ранг: 68.0 (постоянный)
Статус: Участник

Создано: 30 мая 2008 13:30 New!
Цитата · Личное сообщение · #4

1. Адрес должен DeDe показать.
2. А вызвать этот метот можно разными способами, я бы создал новую секцию, чтоб было где развернуться

Ранг: 137.9 (ветеран)
Статус: Участник

Создано: 30 мая 2008 13:32 New!
Цитата · Личное сообщение · #5

кинь прогу, попробуй DEDE.

Ранг: 25.1 (посетитель)
Статус: Участник

Создано: 30 мая 2008 14:09 New!
Цитата · Личное сообщение · #6

Dr3d. Offset процедуры в исполняемом файле у меня есть, адрес тоже есть, по сигнатуре в памяти я ее тоже могу найти. С этим действительно особых проблем нет.

Есть разница в "удаленном" вызове метода и процедуры? Какие-то дополнительные финты ушами требуются?


Ранг: 116.6 (ветеран)
Статус: Участник

Создано: 30 мая 2008 14:42 New!
Цитата · Личное сообщение · #7

RUNaum пишет:
Вопрос 1: Как узнать адрес процедуры Save() для ее последующего вызова?

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

Такое впечатление, что человек совершенно не знаком с ООП. Невозможно "оторвать" объект от его данных, т.к. обычно внутри объект используете свои внутренние переменные. Для того чтобы методы объекта работали корректно - необходимо корректно проинициализировать все эти пременные. Предложить можно только один вариант - а это "дописать" само приложение (к примеру добавить пункт в меню "Save") и вызывать нужный метод класса при клике на этот пункт меню.


Ранг: 68.0 (постоянный)
Статус: Участник

Создано: 30 мая 2008 14:52 New!
Цитата · Личное сообщение · #8

RUNaum пишет:
Есть разница в "удаленном" вызове метода и процедуры?

Разница есть. На сях, по крайней мере.
Какая - не скажу, ибо сам не знаю, но при вызове метода передается какой-то дополнительный параметр.

dermatolog, скорее всего ему нужно вызвать метод Save незапланированно, т.е. когда данные этим классом обработаны, в таком случае все переменные будут инициализированы программой.


Ранг: 116.6 (ветеран)
Статус: Участник

Создано: 30 мая 2008 15:00 New!
Цитата · Личное сообщение · #9

Dr3d пишет:
скорее всего ему нужно вызвать метод Save незапланированно, т.е. когда данные этим классом обработаны, в таком случае все переменные будут инициализированы программой.

Я не понимаю что значит "незапланированно" )

Ранг: 11.1 (новичок)
Статус: Участник

Создано: 30 мая 2008 15:03 New!
Цитата · Личное сообщение · #10

bbs.vbstreets.ru/viewtopic.php?p=6684279

Здесь я описал, как можно вытащить данные из делфийского грида. Может чем поможет.
Но сразу скажу - универсального способа нет.


Ранг: 68.0 (постоянный)
Статус: Участник

Создано: 30 мая 2008 15:17 New!
Цитата · Личное сообщение · #11

dermatolog, незапланированно программой, и скорее всего с другими параметрами.
Размышлять можно сколько угодно, нужна практика..

RUNaum, если ничего не получится, выложи программу, поколупаемся.

Ранг: 25.1 (посетитель)
Статус: Участник

Создано: 30 мая 2008 16:05 · Поправил: Модератор New!
Цитата · Личное сообщение · #12

dermatog, экземпляр класса TMyComponent к моменту вызова мною Save() создан, все готово. Указатель на него есть на руках, нашел поиском в памяти. Вызвать снаружи = вызвать в момент работающего приложения, само собой. В первом посте максимально старался пояснить ситуацию. Видать хреново пояснил. Возможно вас сбило упоминание offset'a в файле, это я просто к слову сказал.

Завтра отпишусь о результатах. Думаю все должно получиться через инжект и вызов.

Twister, большое спасибо. То что нужно, теперь уверен хотя бы в том что делаю.

Ранг: 25.1 (посетитель)
Статус: Участник

Создано: 23 июня 2008 07:19 · Поправил: RUNaum New!
Цитата · Личное сообщение · #13

Еще раз спасибо Twister, оттолкнувшись от своей задумки и уверившись в креативе вышло следующее.

1. Есть инжектор и dll'ка для инжекта
2. Либа реализует следующий функционал (в main'e, конечно):
- Ищем нужный VCL по окнам (FindWindowEx), получаем Handle окна.
- Используя финт ушами получаем указатель на нужный экземпляр класса (валидный, мы в том же контексте)
- Далее (если это задача Twister'a со TStringGrid) просто приводим тип и делаем нужные вызовы (проверено, работает).

Все работает без проблем, но есть один неприятный момент. Если подключенные модули к инжектируемой либе отличны версией от используемых в атакуемом приложении (изменен некоторый функционал, следовательно иные оффсеты у нужного метода) - то простого приведения типа и вызова недостаточно, по понятным причинам.

Итого:
- Имеется валидный указатель на экземпляр класса;
- Имеется несколько иная версия атакуемых модулей (но нужная функция осталась и неизменена).

Каким образом осуществить вызов?
Найти ее по сигнатуре? Получить указатель на нее, кинуть в EAX инстанс и просто вызвать (если статика)? Каким-либо образом получить оффсет ее в VMT, кинуть в EAX инстанс, получить VMT (MOV EDX, [EAX]) и вызвать CALL DWORD PTR [EDX + Offset] (если динамика)?

Знания асма хромают, чисто read only. Посоветуйте на примерах, пожалуйста. Заранее благодарен.

PS. Реализацию пишу на том же Delphi.

Ранг: 37.1 (посетитель)
Статус: Участник

Создано: 24 июня 2008 10:57 New!
Цитата · Личное сообщение · #14

RUNaum, т.е. определение класса объекта для dll не сходится с определением класса объекта в exe? Или как ?

Ранг: 25.1 (посетитель)
Статус: Участник

Создано: 24 июня 2008 12:54 New!
Цитата · Личное сообщение · #15

sss, немного расходятся. В exe используется более новая версия VCL, чем в dll. Она расширена рядом методов / полей, в следствие чего offset нужного мне метода Save() другой и вызов Save() из библиотеки выполняет совершенно иную процедуру с неверными параметрами, вследствие чего падает.

Ранг: 122.2 (ветеран)
Статус: Участник

Создано: 24 июня 2008 16:24 New!
Цитата · Личное сообщение · #16

RUNaum пишет:
Каким образом осуществить вызов?


Ты же говоришь что есть этот компонент отдельно. Напиши тестовое приложение на Delphi вызывающее этот метод и посмотри в какой код это все превращается. Так потом и вызывай сам.

Ранг: 37.1 (посетитель)
Статус: Участник

Создано: 25 июня 2008 04:56 New!
Цитата · Личное сообщение · #17

RUNaum ты же находил адрес этой функции в exe. Вызывай ее и все. Скорее всего там __fastcall поэтому пихай self в EAX и выполняй CALL MethodAddr. Функция без аргументов да?

Ранг: 25.1 (посетитель)
Статус: Участник

Создано: 25 июня 2008 06:51 New!
Цитата · Личное сообщение · #18

Процедура без аргументов. Указанный тобой вызов для статики (аналогичное я писал выше), верно? Для виртуал будет выглядеть как я писал ранее?

sss, относительно адреса процедуры. В случае статики самым кошерным способом будет поиск по сигнатуре в памяти? или есть иные варианты? Как быть с VMT оффсетом в случае виртуала? Там не динамик, но интересно также с динамиком понять (там орд).

Ранг: 37.1 (посетитель)
Статус: Участник

Создано: 25 июня 2008 10:53 New!
Цитата · Личное сообщение · #19

RUNaum если ты лезешь в конкретную программу то разницы нет - виртуальный метод или статический. Просто в отладчике ищи адрес и все. Если динамически искать в разных целевых exe то это только по сигнатуре в любом случае (ведь реализация класса может меняться и могут меняться смещения в VMT).
Вот вариант для виртуальных: у тебя есть self и для него ты знаешь (находишь в отладчике) адрес виртуального метода. Далее ищи в VMT этот адрес и запоминай смещение. Если дальше у тебя есть другой self - потомок или родитель, читай адрес из VMT. Но все это только для одного exe, проанализированного олей.

А вот еще увидел

RUNaum пишет:
Указанный тобой вызов для статики (аналогичное я писал выше), верно?


А какая разница? Тебе доступен self для одного класса или целой иерархии?
 eXeL@B —› Крэки, обсуждения —› Вызвать метод класса снаружи [Delphi]

Видеокурс ВЗЛОМ