Загрузка скомпилированного кода вручную - PullRequest
3 голосов
/ 03 сентября 2011

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

спасибо

P.s. Я знаю, что могу динамически загружаться с использованием API, но я хочу сделать это вручную ... если это не слишком сложное занятие. Это всего лишь доказательство концепции проекта, поэтому у меня нет проблем с простотой! Еще раз спасибо!

Ответы [ 2 ]

1 голос
/ 23 сентября 2011

Вы можете искать в двоичном коде прологи функций, которые дадут вам все функции, но вы не сможете определить, какая точка входа.Гипотетически, вы также можете искать вызовы функций, а затем предполагать, что вызов, который не вызывается в объектном файле, является вашей точкой входа.Кажется немного мазохистским, но опять же, поэтому вручную загружается и вызывается объектный файл, а не обстреливается исполняемый файл или загружается DLL, и в этом случае нет необходимости знать точку входа.Вот две функции, о которых я говорил:

/*
 prologue:
     push ebp    ; 55
     mov ebp esp ; 8B EC

 functionCall:
     call foo    ; E8 &foo
*/
const unsigned char prologueBin[] = {0x55, 0x8B, 0xEC};
const unsigned char callOpcode = 0xE8;


inline bool isThisAfunction(unsigned char* pBin) {
    return (pBin[0] == prologueBin[0] && pBin[1] == prologueBin[1] && pBin[2] == prologueBin[2]);
};
inline bool isThisCall(unsigned char* pBin) {
    return *pBin == callOpcode;
};

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

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

0 голосов
/ 03 сентября 2011

Если вы делаете это с объектными файлами или библиотеками ссылок, это, в основном, ручное отображение, которое вы можете довольно неплохо прочитать / сослаться на него (однако для окон): http://pastebin.com/HbWNAV99 что-либо меньше, чем это в основном динамическое выполнение кода хранимых буферов, что делает JIT, поэтому вам потребуется предварительно рассчитать точку (точки) входа и установить память буфера как исполняемую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...