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?
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.
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 someAt 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 useintptr_t
. Andint
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 withg++ -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...