Получение кода метода класса

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
djalex777
Постоялец
Постоялец
 
Сообщения: 461
Зарегистрирован: 23.03.2006 (Чт) 16:02

Получение кода метода класса

Сообщение djalex777 » 13.11.2015 (Пт) 18:35

Всем привет! Давно тут не писал, да и в целом на VB6 уже давно ничего не делаю, но тут появилась задача и соответственно из неё вопрос.

Есть некий класс Class1 с непустым методом DoIt. Нужно, чтобы в самом исполняемом файле код метода DoIt отсутствовал, а подгружался в определенный момент. И затем уже при вызове метода, исполнялся. Причем, сам код метода надо чтобы в исходном файле существовал, а уже после компиляции брался из определенного места (файла и т.п.) и в скомпилированном файле отсутствовал.

Быстро накидал подмену метода, ничего сложно тут нет. А вот с кодом не пойму - возможно ли вообще его вынуть из скомпилированного файла и потом использовать, подгружая. Пробовал сделать так - скомпилировал проект с кодом для метода DoIt, скопировал asm-код метода DoIt в отладчике и сохранил его в строку (файл). Затем сделал версию исполняемого файла уже с пустым методом DoIt и в нужный момент подменяю адрес этого метода на адрес выделенной в куче, с загруженным в неё текстом (из файла).

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

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получение кода метода класса

Сообщение ger_kar » 13.11.2015 (Пт) 20:20

А в чем вообще заключается затея? Может это можно реализовать совершенно по другому? Это что защита такая? Типа сам файл неполноценный, без куска, который загружается отдельно? Или может должны быть разные варианты в зависимости от того, что загрузится?
Если например защита, то можно метод делать не пустым, а просто это место забивать нулями или мусором, а потом его подменять на нужный код. Конечно просто так его на заменишь в рантайме, но можно это сделать изменив атрибуты защиты этого участка памяти.
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получение кода метода класса

Сообщение The trick » 13.11.2015 (Пт) 22:37

А замена указателя в виртуальной таблице не подходит?
UA6527P

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение кода метода класса

Сообщение Хакер » 13.11.2015 (Пт) 22:56

djalex777, задумка выглядит как полная глупость.
Опиши, зачем это нужно.

djalex777 писал(а):Нужно, чтобы в самом исполняемом файле код метода DoIt отсутствовал, а подгружался в определенный момент. И затем уже при вызове метода, исполнялся. Причем, сам код метода надо чтобы в исходном файле существовал, а уже после компиляции брался из определенного места (файла и т.п.) и в скомпилированном файле отсутствовал.


Ну и хорошо. Просто помести заветный код в DLL-файл, подгружай эту DLL во время выполнения и вызывай нужный код из этой DLL в нужный момент. Вопросы есть?

— Не хочу! — скажешь ты, — хочу, чтобы файл, в котором хранится фрагментик кода, не был DLL-файлом, а был крохотным файлом, в котором кроме самих инструкций ничего больше нет.

Это место, где начинает проявляться глупость затеи. Видишь ли, сходные задачи вынуждают использовать сходные методы решения. По этому Буран похож на Спейс Шаттл, а Ту-144 — на Конкорд (а не потому, что кто-то плагиатил решения).

Ты хочешь подгружать из файла в АП процесса некий код, причём так, чтобы он был способен выполняться после этого, но ты не хочешь использовать DLL, которая как раз и создавалась для решения этой задачи.

Но тебе, видимо, невдомёк, что сама по себе задача подгрузки какого угодно кода в память сопряжена с рядом концептуальных проблем:
  • Под подгружаемый код нужно выделить память.
  • Для этого нужно знать, сколько именно памяти выделять. Можно либо смотреть на размер самого файлика (если кроме кода там ничего нет), либо хранить в файле не только код, но и служебную информацию, и в рамках этой информации хранить размер непосредственно кода.
  • Кроме того, нужно знать, какие атрибуты доступа дать страницам памяти, в которые будет записан код, взятый из файла. Какими будут эти атрибуты, будут ли это одинаковые атрибуты для всех страниц памяти, или для каждой страницы нужно установить свои атрибуты? Все эти сведения придётся либо вшить в код загрузчика, либо хранить как часть файла наряду с кодом.
  • Компиляторы имеют обыкновение генерировать процедуры не в виде непрерывным последовательностей инструкций, а в виде разрозненных фрагментов, которые могут быть перемешаны с фрагментами других процедур. Будем считать случай, когда процедура получилась нефрагментированной, частным случаем фрагментированности, но просто таким, что число фрагментов равно единицы. Тебе придётся знать, сколько именно фрагментов (1 или больше?) имеет подгружаемый код, размер каждого фрагмента и адрес, по которому нужно загрузить каждый фрагмент.
  • К моменту, когда потребуется подгрузить код из файла в память, та область памяти, куда предполагалось загрузить фрагменты кода (даже если есть только 1 фрагмент), могут оказаться заняты чем-то другим. Особенно это актуально на новых ОС из-за технологии ASLR. И тогда придётся либо засчитать всей программе тотальное поражение, либо придётся загружать фрагменты из файла по другим адресам и возможно в другом порядке, нежели адреса и порядок, которые были предусмотрены изначально. И здесь возникает проблема: в составе фрагментов наверняка есть инструкции, которые ссылаются на другие инструкции или на какие-то данные, используя абсолютные и относительные адреса. Если наши фрагменты загрузились не по тому адресу, по которому предполагалось, то придётся корректировать эти абсолютные адреса (если это были адреса инструкций внутри фрагментов) и относительные адреса (если это были инструкции, ведущие из одного фрагмента в другой (загруженный по другому смещению относительно первого фрагмента) фрагмент или во внешний (по отношению к коду, подгружаемому из фалйа) код.
  • Подгружаемый код может использовать функции, импортируемые из DLL. Если это будет вырезанный из изначального EXE-файла (скомпиливанного силами VB), то уж точно код, хранящийся в твоём файле, будет иметь множество обращений к функциям рантайма VB. Так что после загрузки тебе придётся позаботиться о том, что каждое обращение к внешней функци из подгружаемого кода вело именно туда, куда требуется. Для этого тебе придётся сделать свой собственный механизм импорта и иметь где-то таблицу импорта.
  • Некоторые люди любят экспериментировать с файлами приложений. Подменять их. Кроме того, содержимое файла может случайно измениться из-за сбоя другой программы, из-за повреждения файловой системы или из-за повреждения в результате передачи по сети. Если ты собираешься подгружать код из файла и затем выполнять его, крайне настоятельно рекомендуется проверять целостность кода перед тем, как дело дойдёт до его выполнения. Иначе повреждённый код может выполнить какие-то потенциально деструктивные действия. Поэтому стоит предусмотреть контроль целостности файла, а для этого нужно вычислять контрольную сумму содержимого файла и сверять ей с заранее известной правильной контрольной суммой файла, которые нужно хранить либо в самом файле, либо вшить в код загрузчика.

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

Но остаётся два крайних вариантиа того, где эта служебная информация может храниться и кто с ней будет работать:
  • Ты можешь использовать DLL для хранения своего кода. DLL как раз для этой задачи и разработаны. DLL-файлы как раз и хранят всю эту служебную информацию. Системный загрузчик как раз умеет загружать код и решать все вышеописанные вопросы.

    В этом случае решается ещё одна проблема: большинство инструментов (компиляторов) уже умеют делать DLL.
  • Ты можешь не использовать DLL, а всё-таки делать свой собственный файл и свой собственный механизм подгрузки.

    Но тогда:
    • Либо ты вшиваешь все служебную информацию в сам код загрузчика — и тогда отладка твоего продукта превращается в ад, потому что малейшее изменение кода будет требовать ручного пересчитывания служебной информации и внесение правок в код загрузчика.
    • Либо ты хранишь служебную информацию в самом файле вместе с кодом, но тогда ты изобретаешь велосипед, потому что уже есть DLL и механизм их подгрузки — ты будешь делать то, что уже сущетвует, но своё, менее продуманное и протестированное.

      Вдобавок, тебе в этом случае потребуется инструмент для того, чтобы вырезать код из исполняемых файлов, приготовленных другим инструментов, и генерировать на его основе свой собственный файл с кодом.

      Плюс, не нужно забывать, что в современном мире вопросу о том, какой код получит возможность попасть в АП процесса и стать исполняеым, уделяется большое внимание. Высока вероятность, что многие антивирусы увидят подгрузку левого кода в АП процесса «на правах» исполняемого, и начнут ругаться на это. Возможно когда-нибудь или даже сейчас у кого-нибудь всё настроено так, что только код, подписанный электронной подписью, способен подгружаться из файлов и становится выполняемым. PE-формат (EXE, DLL, OCX и пр.) уже имеет поддержку возможности подписать файл цифровой подписью, и системный загрузчик умеет распознавать это. Твой собственный контейнер для кода — не умеет.


Если я всё-таки ошибся, и использование обычной DLL тебе подходит — используй обычную DLL.

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

Вопрос о том, как сделать так, чтобы код метода был в исходнике как обычный код, но вырезался из исполняемого файла в процессе компиляции и помещался в другой файл — тоже разрешимый вопрос. Изучай секретные ключи компиляции, найденные мною.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

djalex777
Постоялец
Постоялец
 
Сообщения: 461
Зарегистрирован: 23.03.2006 (Чт) 16:02

Re: Получение кода метода класса

Сообщение djalex777 » 14.11.2015 (Сб) 12:07

Итак, по-порядку.

Да, это защита. Придумана не мной, моя задача реализовать. Естественно подгружаемый код берется не из файла, а загружается с сервера.
Xakep, ты будешь удивлен, но мне "вдомёк" большая часть того, что ты написал.

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

Это что за детские концептуальные проблемы? Я не спрашивал про это.

Ты хочешь подгружать из файла в АП процесса некий код, причём так, чтобы он был способен выполняться после этого, но ты не хочешь использовать DLL, которая как раз и создавалась для решения этой задачи.

Не совсем так. Не какой-то там некий код, а именно код, который уже был скомпилирован вместе с исполняемым файлом. Думается мне, что в таком случае все зависимости и прочее, должны быть в нём учтены уже автоматически. Или это не так?

Ещё раз по-поводу смысла затеи. Код пишется на VB6, в проекте множество классов, с множеством методов. Часть методов классов (в скомпилированном виде) выносится на сервер и подгружается в нужный момент. Это не изменно и именно так это должно работать. Проблемы подгрузить код и выполнить его НЕТ! Есть проблема с самим кодом - если его брать из exe напрямую, а затем попробовать его выполнить через подмену указателя в VMT на область памяти с кодом (HeapAlloc), то возникают различные ошибки. Вот с этим и проблема. Возможно ответ кроется как раз в предыдущем вопросе.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение кода метода класса

Сообщение Хакер » 14.11.2015 (Сб) 12:25

djalex777 писал(а):Xakep, ты будешь удивлен, но мне "вдомёк" большая часть того, что ты написал.

viewtopic.php?f=54&t=39188

djalex777 писал(а):Не совсем так. Не какой-то там некий код, а именно код, который уже был скомпилирован вместе с исполняемым файлом. Думается мне, что в таком случае все зависимости и прочее, должны быть в нём учтены уже автоматически. Или это не так?

Не важно. В рамках этой задачи любой код должен рассматриваться как «какой-то там некий код», потому что делать допущения — себе дороже.

Так или не так (выделенное жирным) — зависит от ряда моментов. Во-первых, куда ты собрался записывать скачиваемый с сервера код? Если прямо поверх того места, где он был изначально, то «зависимости и прочее» должны быть учтены автоматически, но только при условии, что пропатчиваемый образ не является перемещаемым: все DLL являются такими по дефолту, EXE по дефолту не являются, но запросто могут быть сделаны такими при помощи вышеописанных ключей.

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

К тому же, вставая на этот путь, ты либо раз и навсегда лишаешь себя возможности выпускать новые версии приложения, либо обязан вести чуткий учёт всех когда-либо скомпилированных версий exe-шника и хранить на сервере вырезанный фрагментик для каждой из когда-либо компилированных версий.

Но, к слову, я не знаю, подействует ли это на тебя, но подобная защита это полная шляпа. Ломается за 10 секунд: к «купленной» подключается отладчик, делается дамп пропатченного образа и выгружается в новый EXE-файл — получаем вылеченную копию.

Есть проблема с самим кодом - если его брать из exe напрямую, а затем попробовать его выполнить через подмену указателя в VMT на область памяти с кодом (HeapAlloc), то возникают различные ошибки.

И что ты собрался услышать, написав «различные ошибки»? Неужели сложно написать, что именно за ошибки возникают.

Проблем с редактированием vtable быть не должно.
Если они есть, то это следствие криворукости. Частными случаями криворукости могут быть:
  • попытка правки vtable лежащей в R-страницы без изменения атрибутов защиты на RW на время правки,
  • Попытка выделять память с помощью HeapAlloc из кучи, созданной без флага, дающего куче право на выполнение.
  • Если код записывается не туда, где он был изначально, а по новому адресу (в буфер, выделенный с помощью HeapAlloc), и в коде есть относительная адресация, понятное дело, что работать ничего не будет.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получение кода метода класса

Сообщение ger_kar » 14.11.2015 (Сб) 12:26

djalex777 писал(а):Не совсем так. Не какой-то там некий код, а именно код, который уже был скомпилирован вместе с исполняемым файлом. Думается мне, что в таком случае все зависимости и прочее, должны быть в нём учтены уже автоматически. Или это не так?
Совершенно не так. То что находится в PE(exe) файле, и то что окажется в адресном пространстве процесса, после того, как загрузчик эти данные отобразит в память - вещи совершенно разные. Загрузчик не просто берет и как есть отображает эти данные в память, а делает еще массу операций, в т.ч. пересчитывает адреса смещения и т.д. Обо всем этом как раз и пишет Хакер описывая концептуальные проблемы. Тот же рантайм может быть загружен по разным адресам и такая проблема разрешается загрузчиком в процессе отображения файла в АП процесса.
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение кода метода класса

Сообщение Хакер » 14.11.2015 (Сб) 12:34

ger_kar писал(а):Тот же рантайм может быть загружен по разным адресам и такая проблема разрешается загрузчиком в процессе отображения файла в АП процесса.


Ну положение рантайма тут особой роли не играет. Вырезанный из тела оригинального исполняемого файла фрагментик будет ссылаться либо на ячейки IAT (абсолютная адресация, требущая коррекции, если образ, подвергаемый патчингу, является перемещаемым и был перемещён), либо на jmp-thunk'и (относительная адресация, требующая коррекции всегда, кроме случая, когда код записывается туда же, откуда был изначально вырезан).
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получение кода метода класса

Сообщение ger_kar » 14.11.2015 (Сб) 12:36

Кстати про защиту. Если канал позволяет, то гораздо проще не городить огород, а вынести часть функций на сам сервер и с сервера не код подгружать, а создавать объект на сервере, ему передавать нужные данные и получать результат. Тогда точно не взломают. Или можно делать как я писал: Нужное место затирается нулями, а сам код подгружается четко на это же самое место. Но такой подход все равно не избавит от проблем с антивирусами и жутчайшим геммором при обновлении.
Бороться и искать, найти и перепрятать

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получение кода метода класса

Сообщение ger_kar » 14.11.2015 (Сб) 12:44

Хакер писал(а):Ну положение рантайма тут особой роли не играет. Вырезанный из тела оригинального исполняемого файла фрагментик будет ссылаться либо на ячейки IAT (абсолютная адресация, требущая коррекции, если образ, подвергаемый патчингу, является перемещаемым и был перемещён), либо на jmp-thunk'и (относительная адресация, требующая коррекции всегда, кроме случая, когда код записывается туда же, откуда был изначально вырезан).
Ну это если на тоже самое место, а не абы куда. А судя по первому посту, автор его пытается загрузить как раз "как получится".
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получение кода метода класса

Сообщение The trick » 14.11.2015 (Сб) 12:45

Конечно идея такой защиты для меня кажется очень неэффективной, но скажу пару слов как я бы это делал. Как-то получал заказ на программу которая вставляла произвольные фрагменты кода и данных уже в готовый EXE.
Сначала компилируешь файл как обычно с отладочными символами и с секцией релокаций.
Находишь с помощью отладчика код метода и сохраняешь эти данные в файл, а также сохраняешь информацию о настройках адресов для данного куска кода.
Потом компилируешь файл с кодом, который вместо метода содержит код загрузки данных с сервера и который настраивает релокации и запускаешь новый код используя вызов по указателю. Главное условие - чтобы никакие члены класса и другие функции которые могут быть вызваны из метода не изменялись.
Хотя если метод написан так чтобы не иметь никаких внешних обращений, т.е. базонезависимый то можно и без настройки адресов.
Последний раз редактировалось The trick 14.11.2015 (Сб) 12:49, всего редактировалось 2 раз(а).
UA6527P

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение кода метода класса

Сообщение Хакер » 14.11.2015 (Сб) 12:46

ger_kar писал(а):Ну это если на тоже самое место, а не абы куда. А судя по первому посту, автор его пытается загрузить как раз "как получится".

Куда угодно. В подгружаемом кусочке не будет прямых обращений к адресам, принадлежащим диапазону адресов, занимаемых самим рантаймом.

Поэтому базовый адрес загрузки рантайма на дело не влияет.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение кода метода класса

Сообщение Хакер » 14.11.2015 (Сб) 12:50

The trick писал(а):Сначала компилируешь файл как обычно с отладочными символами и с секцией релокаций.
Находишь с помощью отладчика код метода и сохраняешь эти данные в файл, а также сохраняешь информацию о настройках адресов для данного куска кода.

Если компиляция (как совокупный процесс, в результате которого получается конечный исполняемый файл) требует ручного вмешательства, это не компиляция, а онанизм.

Если уж вырезать куски, то надо работать с obj-файлами, а не придумывать двухпроходную компиляцию с применением отладочных символов.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получение кода метода класса

Сообщение The trick » 14.11.2015 (Сб) 12:58

Хакер писал(а):Если компиляция (как совокупный процесс, в результате которого получается конечный исполняемый файл) требует ручного вмешательства, это не компиляция, а онанизм.

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

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

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получение кода метода класса

Сообщение ger_kar » 14.11.2015 (Сб) 13:07

The trick писал(а):Хотя если метод написан так чтобы не иметь никаких внешних обращений, т.е. базонезависимый то можно и без настройки адресов.
Тогда надо писать не на VB. Я бы на PowerBasic слабал так как перенести работающий код из класса VB6 в PowerBasic достаточно просто, так как придется его адаптировать, а не писать заново.
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение кода метода класса

Сообщение Хакер » 14.11.2015 (Сб) 13:13

The trick писал(а):Хотя если метод написан так чтобы не иметь никаких внешних обращений, т.е. базонезависимый то можно и без настройки адресов.


Это невозможно, потому что даже пустой метод будет иметь пролог/эпилог, устанавливающий/снимающий SEH-хендлер и для этой цели обращающийся к jmp-thunk-у импорта __vbaExceptHandler.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получение кода метода класса

Сообщение The trick » 14.11.2015 (Сб) 13:21

Хакер писал(а):Это невозможно, потому что даже пустой метод будет иметь пролог/эпилог, устанавливающий/снимающий SEH-хендлер и для этой цели обращающийся к jmp-thunk-у импорта __vbaExceptHandler.

В этом случае можно схитрить и вызвать приватный метод который не имеет этого пролога/эпилога.
Private_method.PNG
Private_method.PNG (3.25 Кб) Просмотров: 10228
UA6527P

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получение кода метода класса

Сообщение The trick » 14.11.2015 (Сб) 13:25

ger_kar писал(а):Тогда надо писать не на VB. Я бы на PowerBasic слабал так как перенести работающий код из класса VB6 в PowerBasic достаточно просто, так как придется его адаптировать, а не писать заново.

Не придется, можно и на VB6 писать базонезависимый код, который вызывает API.
Вот пример копирования код в другой процесс без всяких настроек адресов.
Вот тоже пример базонезависимого кода, который копируется по верхним адресам и выгружает основной EXE, загружая новый.
UA6527P

djalex777
Постоялец
Постоялец
 
Сообщения: 461
Зарегистрирован: 23.03.2006 (Чт) 16:02

Re: Получение кода метода класса

Сообщение djalex777 » 14.11.2015 (Сб) 13:27

The trick писал(а):Сначала компилируешь файл как обычно с отладочными символами и с секцией релокаций.
Находишь с помощью отладчика код метода и сохраняешь эти данные в файл, а также сохраняешь информацию о настройках адресов для данного куска кода.
Потом компилируешь файл с кодом, который вместо метода содержит код загрузки данных с сервера и который настраивает релокации и запускаешь новый код используя вызов по указателю.

Вот! Именно так я и делаю. Кроме настройки адресов, видимо из-за этого и проблема. Можно подробней про это.

ger_kar писал(а):Кстати про защиту. Если канал позволяет, то гораздо проще не городить огород, а вынести часть функций на сам сервер и с сервера не код подгружать, а создавать объект на сервере, ему передавать нужные данные и получать результат. Тогда точно не взломают.

Это всем известно, да это лучший вариант. В данном случае критично быстродействие + ряд функций использует обращение к интернету, что с сервера реализОвывать мягко говоря нельзя.

Хакер писал(а):Но, к слову, я не знаю, подействует ли это на тебя, но подобная защита это полная шляпа. Ломается за 10 секунд: к «купленной» подключается отладчик, делается дамп пропатченного образа и выгружается в новый EXE-файл — получаем вылеченную копию.

Ещё раз - это не моя прихоть сделать так. По-поводу дампа, естественно это первое что приходит на ум, но не всё так просто, есть ряд проверок. В целом - да, сломать естественно можно, но нужно время, желание и уровень выше среднего.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение кода метода класса

Сообщение Хакер » 14.11.2015 (Сб) 13:33

djalex777 писал(а):Кроме настройки адресов, видимо из-за этого и проблема. Можно подробней про это.

Всё и так описано в первом моём посте.

djalex777 писал(а):По-поводу дампа, естественно это первое что приходит на ум, но не всё так просто, есть ряд проверок. В целом - да, сломать естественно можно, но нужно время, желание и уровень выше среднего.


Слушай, ты не можешь сделать элементарную вещь — подгрузить из стороннего источника кода метода и сделать так, чтобы метод выполнился. Как при этом ты можешь давать компетентную оценку тому, что всё не так просто и что нужен уровень выше среднего?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получение кода метода класса

Сообщение The trick » 14.11.2015 (Сб) 13:36

djalex777 писал(а):Вот! Именно так я и делаю. Кроме настройки адресов, видимо из-за этого и проблема. Можно подробней про это.

Компилируешь с ключом /FIXED:NO в EXE появляется таблица релокаций. Она содержит информацию об адресах, нуждающихся в правке если образ был загружен не по базовому адресу. В твоем случае ты смотришь по какому у тебя адресу находился код и при загрузке с сервера ты размещаешь его по какому-то адресу, вот разность этих адресов ты должен прибавить к каждому значению по адресу из таблицы релокаций.
UA6527P

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение кода метода класса

Сообщение Хакер » 14.11.2015 (Сб) 13:42

Почему бы не писать код просто туда, откуда он был вырезан?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получение кода метода класса

Сообщение ger_kar » 14.11.2015 (Сб) 13:44

Ну вообще такая защита конечно имеет место быть и многие её используют, но это скорее защита от банального копирования проги на другие компы, а не от самого процесса взлома, как такового.
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получение кода метода класса

Сообщение The trick » 14.11.2015 (Сб) 13:48

Хакер писал(а):Почему бы не писать код просто туда, откуда он был вырезан?

Хватит ли места? Мы здесь гадаем конечно, я так понял как-будто оп хочет загружать каждый метод только по требованию. Если код загрузки по размеру меньше чем сам метод, то в таком случае метод перезапишет код идущий далее. Если оп все-равно, то проще конечно завести отдельую функцию, которая будет загружать все методы прямо в их оригинальную позицию, тогда и настраивать ничего не нужно.
UA6527P

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение кода метода класса

Сообщение Хакер » 14.11.2015 (Сб) 13:56

Как может не хватить, если фрагмент изначально и вырезан взят из бинарника?

Кстати, никакой /FIXED:NO и изучение релоков не поможет справиться с относительными переходами, которые сломаются, если код загрузить не туда, откуда он взят.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получение кода метода класса

Сообщение The trick » 14.11.2015 (Сб) 14:00

Хакер писал(а):Как может не хватить, если фрагмент изначально и вырезан взят из бинарника?

Ну я как-бы предложил туда записать код загрузки с сервера и скомпилировать еще раз. Тот фрагмент уже не существует в коде на момент компиляции кода с загрузкой.
Хотя можно и наоборот сделать. Но там может возникнуть ситуация когда код загрузчика непоместится в метод. В принципе и тогда можно обойти вручную вставив jmp на единый кусок загрузчика.
Последний раз редактировалось The trick 14.11.2015 (Сб) 14:03, всего редактировалось 1 раз.
UA6527P

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение кода метода класса

Сообщение Хакер » 14.11.2015 (Сб) 14:02

The trick писал(а):Ну я как-бы предложил туда записать код загрузки с сервера и скомпилировать еще раз. Тот фрагмент уже не существует в коде на момент компиляции кода с загрузкой.


Это абсолютно не рабочий подход, потому что вырезаемый фрагмент должен соответствовать бинарнику, из которого он вырезается, как ключ к замку. Иначе имеющиеся в вырезаемом фрагменте отсылки к процедурам, импортируемым сущностям и переменным в секции данных перестанут быть валидными.

При второй компиляции все адреса внутри образа сдвинутся. Так что, как я написал в первом своём посте — под каждый билд исполняемого файла, под каждую жалкую единожды скомпилированную версию на сервере придётся хранить свой фрагментик.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получение кода метода класса

Сообщение The trick » 14.11.2015 (Сб) 14:04

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

Поэтому я и написал:
The trick писал(а):Главное условие - чтобы никакие члены класса и другие функции которые могут быть вызваны из метода не изменялись.


Хакер писал(а):При второй компиляции все адреса внутри образа сдвинутся. Так что, как я написал в первом своём посте — под каждый билд исполняемого файла, под каждую жалкую единожды скомпилированную версию на сервере придётся хранить свой фрагментик.

Это да, ну я так понял автору это не важно.
UA6527P

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение кода метода класса

Сообщение Хакер » 14.11.2015 (Сб) 14:07

The trick писал(а):Главное условие - чтобы никакие члены класса и другие функции которые могут быть вызваны из метода не изменялись.

Причём тут другие члены?

Если у тебя в был большой метод CSomeClass::Foo с неким секретным кодом, и ты скомпилировал проект в первый раз, а затем подменил контент метода CSomeClass::Foo на маленькую заглушку, которая только подгружает код с сервера, то даже при том, что другие функции и процедуры в твоём проекте были не тронуты, вся адресация съедет.

The trick писал(а):Это да, ну я так понял автору это не важно.

Как это может быть не важно, если после этого и абсолютная и относительная адресация внутри фрагментика станет невалидной, даже несмотря на то, что у тебя есть релоки (но эти релоки актуальны для старого layout-а исполняемого файла, а ты фрагментик, вырезанный из старого образа пытаешься вклинить в новый образ, в котором другой layout сущностей).
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

djalex777
Постоялец
Постоялец
 
Сообщения: 461
Зарегистрирован: 23.03.2006 (Чт) 16:02

Re: Получение кода метода класса

Сообщение djalex777 » 14.11.2015 (Сб) 14:09

Слушай... Как при этом ты можешь давать компетентную оценку тому, что всё не так просто и что нужен уровень выше среднего?

Слушай, ты можешь дать оценку горячая ли конфорка у плиты ни разу не обжегшись?

ты не можешь сделать элементарную вещь — подгрузить из стороннего источника кода метода и сделать так, чтобы метод выполнился.

Ты что-то перепутал, перечитай всё заново. Я не мог правильно настроить адреса.

The trick писал(а):Хватит ли места? Мы здесь гадаем конечно, я так понял как-будто оп хочет загружать каждый метод только по требованию.

Всё верно. Места не хватит.

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

    TopList