Search code examples
c++creverse-engineering

Can I be sure that the binary code of the functions will be copied sequentially?


Sorry if this question already exist, because I hope this approach is used but i just don't know how this called. So, my purpose to execute sequence of functions from memory, for this I copied size of first and last func.

This is my first try:

source.cpp

void func1(int var1, int var2)
{
  func2();
  func3();
  //etc.
}
void func2(...){...}
void func3(...){...}
void funcn(){return 123;}//last func as border, I do not use it

//////////////////////////////////////////////////

main.cpp

#include"source.cpp"

long long size= (long long)funcn-(long long)func1;// i got size of binary code of this funcs;
// and then i can memcpy it to file or smth else and execute by adress of first

Firstly it's worked correct, but after updating my functions it's crashed. Size has become negative. Then i tried to attach it to memory hardlier:

source.cpp

extern void(*pfunc1)(int, int);
extern void(*pfuncn)();

void(*pfunc1)(int , int) = &func1;
void(*funcn)() = &funcn;

static void __declspec(noinline) func1(int var1, int var2)
{
 //the same impl
}
static void __declspec(noinline) func2(...){...}
static void __declspec(noinline) func3(...){...}
static void __declspec(noinline) funcn(...){retunr 123;}

//////////////////////////////////
main.cpp
#include"source.cpp"

long long size= (long long) pfuncn - (long long) pfunc1;
//same impl

This worked after my 1st update, but then, I had to update it again, and now this gives me wrong size. Size was near 900+ bytes. I changed some funcs, and size become 350+ bytes i haven't changed that many. I disabled optimizations and inline optimizations.

So my question is how to be sure that my func1 will be less adress then last funcn and what could change their locations in memory. Thank you for attention.


Solution

  • GCC family only!

    You can force the compiler to put the whole function to separate section. Then you can know the memory area where the funcion resides.

    int __attribute__((section(".foosection"))) foo()
    {
        /* some code here */
    }
    

    in linker script in the .text you need to add

     .text :
      {
     
          /* ... */
    
        __foosection_start = .;
         *(*foosection)
         *(.foosection*) 
         __foosection_end = .;
    
         /* .... */
    

    and in the place where you want to know or use it

    extern unsigned char __foosection_start[];
    extern unsigned char __foosection_end[];
    
    void printfoo()
    {
        printf("foosection start: %p, foosection end: %p\n ", (void *)__foosection_start, (void *)__foosection_end);
    }