Я использую следующие типы для создания новой функции во время выполнения:
typedef int (*pfunc)(int);
union funcptr {
pfunc x;
byte* y;
};
Это позволяет мне писать инструкции в y
, а затем вызывать функцию следующим образом:
byte* p = (byte*)VirtualAllocEx(GetCurrentProcess(), 0, 1<<16, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
// Write some instructions to p
funcptr func;
func.y = p;
int ret = func.x(arg1); // Call the generated function
Очень важно знать, как C ++ готовит аргументы (соглашение о вызовах), и поэтому я посмотрел свойства проекта (Visual C ++) и вижу, что он использует __cdecl
. Он должен помещать аргументы в стек в соответствии с: http://msdn.microsoft.com/en-us/library/aa271989(v=vs.60).aspx и http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl, но когда я смотрю на сгенерированную сборку, аргумент перемещается в регистр EAX.
Я хочу быть абсолютно уверенным в том, как подготовлены аргументы. Итак, я что-то упустил из-за cdecl
или Visual C ++ оптимизирует вызов, и если да, как я могу убедиться, что это не произойдет?
С наилучшими пожеланиями, Лассе Эспехолт