Сейчас на форуме: 2nd, bedop66938, -Sanchez-, barsik (+6 невидимых) |
eXeL@B —› Крэки, обсуждения —› Вызвать метод класса снаружи [Delphi] |
Посл.ответ | Сообщение |
|
Создано: 30 мая 2008 12:35 · Поправил: RUNaum · Личное сообщение · #1 Ситуация. Есть исполняемый файл, написанный на Delphi 7. Вся протекция с него снята, он чист. Используя PE Explorer (это мог быть любой иной редактор ресурсов) был проанализирован список используемых VCL компонент. Среди компонентов был встречен некий TMyComponent, исходники и бинарники которого есть в наличие. VCL компонент TMyComponent имеет метод Save() который сохраняет некоторую защищенную информацию (иным образом до нее не добраться, т.к. есть куча слоев защиты, начиная от AES (еще чем-то и еще чем-то), заканчивая компрессией редко встречаемым алго и логическими байт-операциями сверху - реверсить эти слои - безумие). Вызов этого метода позволить обойти все слои защиты и сохранить нужный для дальнейшей работы файл-ключ. Вопрос 1: Как узнать адрес процедуры Save() для ее последующего вызова? Предположения: можно по сигнатуре найти в памяти, верно? Грубовато будет, но все-таки. Либо зная offset в VMT какими-то сложными вычислениями =) Может подскажет кто. Вопрос 2: Как лучше осуществить вызов этой процедуры? Инжект в процесс и просто вызов ее по адресу в контексте вражеского процесса? Или есть иные способы? PS. Я не совсем реверсер, в привычном понимании. Многие моменты для меня темный лес, надеюсь кто-нибудь да поможет. Заранее благодарю. [Added] Проблема судя по всему будет еще в том, что мало вызвать по найденному указателю. Потребуется еще и передать, вероятно, ряд вещей. По крайней мере Sender'a точно (тут можно nil кинуть, но все таки). Надеюсь больше ничего инициализировать / придумывать не нужно? Ведь метод это не просто процедура, если вспомнить как сделана VMT / TMethod. |
|
Создано: 30 мая 2008 13:11 · Поправил: Isaev · Личное сообщение · #2 |
|
Создано: 30 мая 2008 13:16 · Поправил: RUNaum · Личное сообщение · #3 Isaev пишет: 1. Смотри таблицу импорта 2. Смотри, как она вызывается из подопытной 1. Вы вероятно не поняли ситуации. При чем здесь таблица импорта, если код TMyComponent.Save() находится в теле исполняемого файла? Это же не внешняя библиотека. Это VCL. 2. Собственно см. п. 1. В моем случае этот метод TMyComponent'a может даже и не вызываться жертвой, хотя сомнительно. [Fixed] Исправил слово "компонент" на "VCL компонент", т.к. не каждому недельфисту будет понятна терминология. Приношу свои извинения. |
|
Создано: 30 мая 2008 13:30 · Личное сообщение · #4 |
|
Создано: 30 мая 2008 13:32 · Личное сообщение · #5 |
|
Создано: 30 мая 2008 14:09 · Личное сообщение · #6 |
|
Создано: 30 мая 2008 14:42 · Личное сообщение · #7 RUNaum пишет: Вопрос 1: Как узнать адрес процедуры Save() для ее последующего вызова? Декомпиляторы, разбирающие RTTI обычно показывают все методы и свойства классов, присуствующих в исполняемом файле. RUNaum пишет: Вопрос 2: Как лучше осуществить вызов этой процедуры? Инжект в процесс и просто вызов ее по адресу в контексте вражеского процесса? Или есть иные способы? Такое впечатление, что человек совершенно не знаком с ООП. Невозможно "оторвать" объект от его данных, т.к. обычно внутри объект используете свои внутренние переменные. Для того чтобы методы объекта работали корректно - необходимо корректно проинициализировать все эти пременные. Предложить можно только один вариант - а это "дописать" само приложение (к примеру добавить пункт в меню "Save") и вызывать нужный метод класса при клике на этот пункт меню. |
|
Создано: 30 мая 2008 14:52 · Личное сообщение · #8 RUNaum пишет: Есть разница в "удаленном" вызове метода и процедуры? Разница есть. На сях, по крайней мере. Какая - не скажу, ибо сам не знаю, но при вызове метода передается какой-то дополнительный параметр. dermatolog, скорее всего ему нужно вызвать метод Save незапланированно, т.е. когда данные этим классом обработаны, в таком случае все переменные будут инициализированы программой. |
|
Создано: 30 мая 2008 15:00 · Личное сообщение · #9 |
|
Создано: 30 мая 2008 15:03 · Личное сообщение · #10 |
|
Создано: 30 мая 2008 15:17 · Личное сообщение · #11 |
|
Создано: 30 мая 2008 16:05 · Поправил: Модератор · Личное сообщение · #12 dermatog, экземпляр класса TMyComponent к моменту вызова мною Save() создан, все готово. Указатель на него есть на руках, нашел поиском в памяти. Вызвать снаружи = вызвать в момент работающего приложения, само собой. В первом посте максимально старался пояснить ситуацию. Видать хреново пояснил. Возможно вас сбило упоминание offset'a в файле, это я просто к слову сказал. Завтра отпишусь о результатах. Думаю все должно получиться через инжект и вызов. Twister, большое спасибо. То что нужно, теперь уверен хотя бы в том что делаю. |
|
Создано: 23 июня 2008 07:19 · Поправил: RUNaum · Личное сообщение · #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. |
|
Создано: 24 июня 2008 10:57 · Личное сообщение · #14 |
|
Создано: 24 июня 2008 12:54 · Личное сообщение · #15 |
|
Создано: 24 июня 2008 16:24 · Личное сообщение · #16 |
|
Создано: 25 июня 2008 04:56 · Личное сообщение · #17 |
|
Создано: 25 июня 2008 06:51 · Личное сообщение · #18 Процедура без аргументов. Указанный тобой вызов для статики (аналогичное я писал выше), верно? Для виртуал будет выглядеть как я писал ранее? sss, относительно адреса процедуры. В случае статики самым кошерным способом будет поиск по сигнатуре в памяти? или есть иные варианты? Как быть с VMT оффсетом в случае виртуала? Там не динамик, но интересно также с динамиком понять (там орд). |
|
Создано: 25 июня 2008 10:53 · Личное сообщение · #19 RUNaum если ты лезешь в конкретную программу то разницы нет - виртуальный метод или статический. Просто в отладчике ищи адрес и все. Если динамически искать в разных целевых exe то это только по сигнатуре в любом случае (ведь реализация класса может меняться и могут меняться смещения в VMT). Вот вариант для виртуальных: у тебя есть self и для него ты знаешь (находишь в отладчике) адрес виртуального метода. Далее ищи в VMT этот адрес и запоминай смещение. Если дальше у тебя есть другой self - потомок или родитель, читай адрес из VMT. Но все это только для одного exe, проанализированного олей. А вот еще увидел RUNaum пишет: Указанный тобой вызов для статики (аналогичное я писал выше), верно? А какая разница? Тебе доступен self для одного класса или целой иерархии? |
eXeL@B —› Крэки, обсуждения —› Вызвать метод класса снаружи [Delphi] |