У меня проблема с обходными узлами. Обход, как вы все знаете, может перемещаться только между 5 байтами пространства (например, «jmp» и 4-байтовый адрес). Из-за этого невозможно иметь функцию «hook» в классе (методе), вы не можете указать «этот» указатель, потому что просто недостаточно места (here's проблема более подробно объяснена). Таким образом, я весь день занимался мозговым штурмом для решения, и теперь мне нужны ваши мысли по этому вопросу, поэтому я не начинаю проект на 3-5 дней, не зная, возможно ли это или нет.C++ и FULLY динамические функции
У меня было 3 цели изначально, я хотел, чтобы функции «hook» были методами класса, я хотел, чтобы весь подход был объектно-ориентированным (без статических функций или глобальных объектов), а наихудшая/сложная часть полностью динамичный. Это мое (теоретически) решение; с сборкой можно изменять функции во время выполнения (идеальным примером является любой метод обхода). Так как я могу динамически изменять функции, не должен ли я также динамически их создавать? Например; Я выделяю память, скажем ~ 30 байт (через malloc/new). Невозможно было бы просто заменить все байты двоичными числами, соответствующими различным операторам сборки (например, 0xE9 - «jmp»), а затем вызвать адрес напрямую (поскольку он будет содержать функцию)?
ПРИМЕЧАНИЕ. Я знаю заранее, что возвращаемое значение и все аргументы для всех функций, которые я хочу объединить, и поскольку я использую GCC, соглашение thiscall практически идентично _cdecl.
Так что это моя мысль/скоро будущая реализация; Я создаю класс «Function». Этот конструктор принимает переменное количество аргументов (кроме первого аргумента, который описывает возвращаемое значение целевой функции).
Каждый аргумент - это описание аргументов, которые получит крючок (размер, и является ли это указателем или нет). Итак, допустим, я хочу создать класс Function для int * RandomClass::IntCheckNum(short arg1);
. Тогда мне просто нужно было сделать вот так: Function func(Type(4, true), Type(4, true), Type(2, false));
. Где «Тип» определяется как Type(uint size, bool pointer)
. Затем через сборку я мог динамически создавать функцию (обратите внимание: все это будет использовать соглашение о вызове _cdecl), так как я могу рассчитать количество аргументов и общий размер.
EDIT: В примере, Type(4, true)
является возвращаемым значением (целое *), то scond Type(4, true)
является RandomClass «это» указателем и Type(2, false)
описывает первый аргумент (короткий arg1).
С помощью этой реализации я мог бы легко использовать методы класса как обратные вызовы, но для этого потребуется обширный код сборки (который я даже не особо ощущал). В конце концов, единственной нединамичной вещью будут методы в моем классе обратного вызова (для которых также потребуются предварительные и последующие обратные вызовы).
Так что я хотел знать; Это возможно? Сколько потребуется этой работы, и я нахожусь здесь над головой?
EDIT: Извините, если я представил все немного нечеткое, но если есть что-то, что вы хотите более подробно объяснить, спросите!
EDIT2: Я также хотел бы знать, могу ли я найти шестнадцатеричные значения для всех операторов сборки где-нибудь? Список поможет тонну! И/или если можно как-то «сохранить» asm («»); код по адресу памяти (который я очень сомневаюсь).
Зачем использовать обходные пути? Не можете ли вы использовать чистое решение на C++, такое как 'std :: function', или я что-то упускаю? –
Не так, как я мог помочь вам просто прояснить ситуацию. Вы хотите перезаписывать функцию в классе? (Я имею в виду, что вы можете изменить их во время выполнения). Если это так, я думаю, что (когда это будет сделано) возможно откроет гигантские возможности для программирования ИИ на языке C++. +1 – akaltar
@akaltar Это известно как [генетическое программирование] (http://en.wikipedia.org/wiki/Genetic_programming) и на самом деле не нуждается в перезаписываемых функциях вообще. –