0

Why isn't this code directly storing the assembly instructions of func into the buffer? The value of the buffer is junk and doesn't change.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
char buffer[1000];
uint64_t* addr; 

void func() { 
// here should be what the function really do
    addr = (uint64_t*)&func; 
    memcpy(buffer, &addr, 1000);  // im expecting that the instructions of func will be stored in the buffer 
    strcpy(secret, hash(secret, buffer)); // secret is previous hash of the function before it so i can make  hash chain to verify the control flow integrity  

    // also the 1000 is not the actual size for the function, i just used it here for clarification 
} 
4
  • 6
    &addr is the address of the variable addr. You want just addr. Commented Mar 16, 2024 at 13:41
  • 1
    I guess by "assembly instructions" you actually mean "machine code". Commented Mar 16, 2024 at 13:59
  • 4
    In any case, C does not define a way to do what you are trying to do. Your general approach might happen to work on some implementations, once you correct the addr / &addr mixup, but there are multiple levels of undefinedness here. Commented Mar 16, 2024 at 14:07
  • 2
    Even if you assume a Von Neumann architecture with a flat address space and a calling convention that does not use a gp register, you still run into problems when the compiler splits the function into multiple pieces and scatters them into different parts of memory. (For example, unlikely code paths like exception handling get moved out of hot pages.) All modern compilers do this. Commented Mar 16, 2024 at 15:05

1 Answer 1

1
  • There is no guarantee that the &func will reference the memory you can read.
  • There is no guarantee that memcpy will work with this reference on your platform as function pointers are not data pointers.
  • uint64_t is not the type which is guaranteed to hold the reference to the function converted to this type

But if it works, then your code copies the variable address and next bytes which follow it (and it invokes Undefined Behaviour)

void func() { 
    memcpy(buffer, (void *)&func, 1000); 
    /* ... */
}

This code invoked UB too but it might work on some platforms.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.