Today I had the idea to try to manually load compiled code in C. What I had in my mind, was to read a compiled object file and store it into a buffer, get the position in the buffer of what could be the entry point, get the adress of that element, and cast it to a function pointer and call the function trough the pointer. However, I found an obstacle: how to开发者_运维知识库 get the adress of the main function (or of any arbitrary function) from the array of bytes containing the compiled code?
thank you
P.s. I know I could dynamically load using APIs, but I want to do it manually...if it is not an overwhelming effort. It is just a proof of concept project, so I have no problem to keep in simple! Thanks again!
You can search the binary for function prologues, which will give you all the functions, but you won't be able to tell which is the entry point. Hypothetically, you can also search for function calls, then assume the one that goes un-called throughout the object file is your entry point. Seems a little masochistic, but then again, so is manually loading and calling an object file instead of shelling an exe or loading a DLL, in which case there is no need to know the entry point. Here are the two functions I was talking about:
/*
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() can turn up lots of false positives, but since you'd be using it to cull your list of functions turned up by isThisAfunction(), it's unlikely to eliminate a function that isn't really being called.
Basically, I only recommend this if you really need to load a chunk of bits that you know nothing else about and call it as a function.
If your doing this with object files or link libraries, thats basically manual mapping, which you can get a pretty good read up on/reference to here(it is for windows however): http://pastebin.com/HbWNAV99 anything less than that is basically dynamic code execution of stored buffers, something a JIT would do, so that would require you to have the entry point(s) pre calculated and have the buffers memory set as executable.
精彩评论