Shuffling function addresses in C/C++ with MSVC

The Microsoft C/C++ compiler allows you to specify link order of functions or variables. Using the #pragma directive with either code_seg or data_seg and specifying the segment name and its sorting key, you can tell the linker how to place the object code in the final executable.

Let’s start with a simple example:

#pragma code_seg(push, ".text$EB009")
__declspec(noinline) void f1()
{
    printf("this is f1()\n");
}
#pragma code_seg(pop)


#pragma code_seg(push, ".text$EB005")
__declspec(noinline) void f2()
{
    printf("this is f2()\n");
}
#pragma code_seg(pop)


#pragma code_seg(push, ".text$EB001")
__declspec(noinline) void f3()
{
    printf("this is f3()\n");
}
#pragma code_seg(pop)

int main()
{
    f1();
    f2();
    f3();
    return 0;
}

When the code_seg pragma is used, we can specify where the subsequent code should lie (in which section in the PE file). When the section name contains the “$” sign, then the subsequent text is not part of the section name (the string prior to the “$”) and instead is used as a sorting key.

By randomizing the sorting key, you can control the layout of the functions in memory.

In the facsimile, one can randomize member functions order:

class class1_t
{
public:
    #pragma code_seg(push, ".text$EBC004")
    void f1()
    {
        printf("c1::f1()\n");
    }
    #pragma code_seg(pop)

    #pragma code_seg(push, ".text$EBC000")
    void f2()
    {
        printf("c1::f2()\n");
    }
    #pragma code_seg(pop)

    #pragma code_seg(push, ".text$EBC002")
    void f3()
    {
        printf("c1::f3()\n");
    }
    #pragma code_seg(pop)
};

Without specifying the layout for the member functions, they would have been laid out in an order similar to the following:

c1::f1              : 00401060
c1::f2              : 00401070
c1::f3              : 00401080

Notice how the addresses are consecutive and in the same order as the member functions order in the class. When the pragmas are applied, the layout looks something like this:

c1::f2              : 00401060
c1::f3              : 00401070
c1::f1              : 00401080

Notice how the layout order is now f2, f3 then f1 which is dictated by the sorting keys (.text$EBCnnn).

With some creativity, you can actually make a clean and nice system that looks like that in the end:

FUNCTION_DISLOCATE_BEGIN
void f1()
{
    printf("this is f1()\n");
}
FUNCTION_DISLOCATE_END


FUNCTION_DISLOCATE_BEGIN
void f2()
{
    printf("this is f2()\n");
}
FUNCTION_DISLOCATE_END


FUNCTION_DISLOCATE_BEGIN
void f3()
{
    printf("this is f3()\n");
}
FUNCTION_DISLOCATE_END


class class1_t
{
public:
    FUNCTION_DISLOCATE_BEGIN
    void f1()
    {
        printf("c1::f1()\n");
    }
    FUNCTION_DISLOCATE_END

    FUNCTION_DISLOCATE_BEGIN
    void f2()
    {
        printf("c1::f2()\n");
    }
    FUNCTION_DISLOCATE_END

    FUNCTION_DISLOCATE_BEGIN
    void f3()
    {
        printf("c1::f3()\n");
    }
    FUNCTION_DISLOCATE_END
};

That could be accomplished with the __pragma keyword (which can be used in macros), the __COUNTER__ macro and a pre-generated file containing the random section name sort keys.

You might also like:

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.