2009-10-17 2 views
2

У меня есть несколько двоичных данных, которые содержат кучу функций и хотят вызвать один из них. Я знаю подпись этих функций вместе со смещением относительно начала файла. Соглашение о вызове является стандартным: __cdecl. Файл уже загружен на страницу памяти с выполнением разрешений.Как вызвать функцию из двоичных данных

Например (A, B, C являются некоторые типы)

void myFunction (A *arg1, B arg2, C arg3); // Signature 
int myOffset = 0x42; // Offset 

Как я могу указать, что myOffset указывает на myFunction?

+0

Я не эксперт, но я думаю, что если вы вызовете функцию __cdecl, стек протекает, если ваша программа ожидает __stdcall. Значение по умолчанию должно быть __stdcall –

+0

__stdcall используется для функций WINAPI. __cdecl является стандартом для других функций. См. Http://msdn.microsoft.com/en-us/library/zkwh89ks(VS.80).aspx – Etan

+0

@Etan У меня есть аналогичная проблема, интересно, как вы получили смещение от всех подпрограмм ... пожалуйста, помогите! –

ответ

6
// define a function pointer 
typedef __cdecl void (*your_function) (A *arg1, B arg2, C arg3); 
your_function ftr; 

char * memory = 0x123456; // base segment address 

fptr = (your_function)(memory + 0x42); //calculate memory address 

(*ftpr)(a,b,b); // call function 
1
((void(*)(A*,B,C))0x42)(a,b,c); 

Или что-то в этом роде. Всегда возникали проблемы с этим в первый раз. Так или иначе, если я правильно понимаю ваш вопрос.

4

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

Чтобы объявить указатель на функцию,

void (*p)(A*,B,C); 

Чтобы назначить его,

p = (void (*)(A*,B,C)))0x42; 

Для вызова функции,

p(a,b,c) or (*p)(a,b,c); 
3

Для самого вопроса: вы просто нужно добавить адрес в память загрузили двоичный код в. То есть если вы загрузили двоичный код на адрес myLoadAddress, просто добавьте его в myOffset. Однако это не позволит вам легко вызвать функцию. Если вы хотите сделать это, вы должны рассматривать его как файл библиотеки (и если на самом деле это файл библиотеки, проверьте системную функцию для загрузки библиотек, таких как LoadLibrary на Windows, затем используйте GetProcAddress для получения указателя на функцию).

// create a type for your function signature 
typedef void (*myFunc)(A *arg1, B arg2, C arg3); 
// create a pointer to your function 
myFunc myFuncPointer; 
// set the address of the function in memory 
myFuncPointer = myLoadAddress + myOffset; 
// invoke function 
myFuncPointer(A, B, C); 

При загрузке DLL при загрузке его с помощью LoadLibrary, а затем использовать GetProcAddress и типаж адрес возвращается к вашей функции указатель - т.е. myFuncPointer = (myFunc)GetProcAddress(hmodule, "myFunc"); в примере.

В POSIX он работает почти так же, но функции немного отличаются: используйте dlopen для загрузки динамической библиотеки и dlsym для извлечения символа. Programming Library Howto описывает это более подробно или просматривает страницы руководства для dlopen и dlsym. Основы одинаковы.

+0

+1 для отличного примера, если вы знакомы с posix, вам следует обновить свой ответ – mtasic85

Смежные вопросы