C++ How To Read First Couple Bytes Of Function? (3

2019-07-21 00:47发布

Let's say I have a function like this (completely random, I just wrote it up in like 30 seconds for an example)

bool exampleAuthetnication(char *a, char *b)
{
    bool didAuthenticate = false;
    if(strcmp(a, b) == 0)
    {
        didAuthenticate = true;
    }

    if(didAuthenticate)
    {
        return true;
    }
    else
    {
        stopExecutable();
        return false;
    }
}

How would I go about reading the first few bytes of this function?

I've come up with this

int functionByteArray[10];
for (int i = 0; i < 10; i++)
{
    functionByteArray[i] = *(int*)(((int)&exampleAuthetnication) + (0x04 * i));
}

The logic behind it being that we get the memory address of our function (in this case exampleAuthetnication()) then we cast to int pointer then dereferance to get the value of the current line of bytes we are trying to read then store in functionByteArray, but it does not seem to work properly. What am I doing wrong? Is what I'm trying to accomplish possible?

2条回答
该账号已被封号
2楼-- · 2019-07-21 01:22

C++ source code is not a list of instructions for a computer to perform; it is a collection of statements that describe the meaning of a program.

Your compiler interprets these statements and produces an actual sequence of instructions (via the assembly stage) that can actually be executed in our physical reality.

The language used to do so does not provide any facilities for examining the bytes that make up the compiled program. All of your attempts to cast function pointers and the like may randomly give you some similar data, via the magic of undefined behaviour, but the results are just that: undefined.

If you wish to examine the compiled executable, do so from outside of the program. You could use a hex editor, for example.

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-07-21 01:23

In theory (according to the C++11 standard) you cannot even cast a function pointer into a data pointer (on Harvard architectures code and data sit in different memories and different address spaces). Some operating systems or processors might also forbid reading of executable code segments (read about NX bit).

In practice, on x86-64 (or 32 bits x86) running some operating system like Linux or Windows, a function code is a sequence of bytes and can be unaligned, and sits in the (common) virtual address space of its process. So you should at least have char functionByteArray[40]; and you might use std::memcpy from <string> and do some

std::memcpy(functionByteArray, (char*)&exampleAuthetnication,
            sizeof(functionByteArray));

At last your code is wrong because -on x86-64 notably- int have not the same size as pointers (so (int)&exampleAuthetnication is losing the upper bytes of the address). You should at least use intptr_t. And int has stronger alignment constraints than the code.

BTW, you might also ask your compiler to show the generated assembler code. With GCC compile your exampleAhtetnication C++ code with g++ -O -fverbose-asm -S and look into the generated .s file.

Notice that the C++ compiler might optimize to the point of "removing" some function from the code segment (e.g. because that function has been inlined everywhere), or split the function code in several pieces, or put that exampleAhtetnication code "inside" another function...

查看更多
登录 后发表回答