?

Log in

No account? Create an account

Previous Entry Share Next Entry
Вызов неопределенных функций
mikelsv
Эта тема волнует меня достаточно давно. Как вызвать функцию не напрямую, имея имя и параметры, а в обход, получая информацию перед самым вызовом. С вызовом через прототип я разобрался довольно быстро и тема имени отпала. Остались параметры и начались поиски решений.
В прошлый раз исследования привели к решению вызывать функции через ассемблер. Передавая параметры в стеи и делая вызов. Тогда это решение устроило. Но вот проблема встала снова и захотелось чего-то нового.
Помощь пришла с совершенно неожиданной стороны. Те, кто пользовался функциями типа int func(...) и va_list знают, насколько оно чувствительно к параметрам и как любит падать. В общем адская штука и пользоваться ей категорически не советую. Но, как оказалось, при вызове такой функции компилятор кладет параметры с тек так же как при вызове любой другой. И это внезапно открыло новые перспективы.

#include <stdio.h>
#include <string.h>

// Берем функцию:
int test(int a, char *b, double c){
    printf("%d %s %f", a, b, c);
    return 0;
}

// Делаем прототип:
typedef int (*callfunc)(...);

// И пишем код:
int main(int args, char* arg[]){
    // параметры функции, которые хотим передать.
    double d=11; int str[4]={15, (unsigned int)"text"}; memcpy(str+2, &d, 8);

    // структура, которая будет полностью скопирована в стек. Если передавать str, то будет передан указатель, а нам нужно передать именно данные.
    struct efunc_s{ unsigned int a[4]; };

    // получаем адрес функции.
    callfunc cf=(callfunc)test;

    // Приводим в вид, который будет скопирован в стек.
    efunc_s &s=*(efunc_s*)&str;

   // вызываем функцию
    (*cf)(s);

    return 0;
}

Код прекрасно работает в MSVS 2010. К сожалению под g++ этот код работать не захотел, но думаю это не надолго. Естественно, при сборке под 64 бита. В g++ -m32 отлично работает, под 64 бита надо принять во внимание размер char*.
struct efunc_s{ unsigned int a[4]; }; может быть больше без ущерба для работы программы. Лишние данные никак не повлияют.
Наконец-то достигнут именно тот результат, который я искал.
Tags: ,