pythoncmemorystack

How do I read a struct contents in a running process?


I compiled a C binary on a linux machine and executed it, in that binary I have a struct called Location defined as follows

typedef struct 
{
    size_t x;
    size_t y;
} Location;

and here is my main function

int main(void)
{
    srand(0);
    Location loc;
    while (1)
    {
        loc.x = rand()%10;
        loc.y = rand()%10;
        sleep(2);
    }
    return 0;
}

How do I monitor the values of x and y?

There are some limitations to consider

Things I tried


Solution

  • We know the location is located in the stack somewhere, open maps file calculated stack size, start and end address, then open memory file in bytes mode and read stack bytes, loop over the bytes until you find a bytes sequence that maps to a given struct.

    PS I have to add a third attribute to struct for sake of making the struct easier to find, will remove it in my actual code.

    import sys
    import ctypes
    
    
    
    class Location(ctypes.Structure):
        _fields_ = [
            ("x", ctypes.c_size_t),
            ("y", ctypes.c_size_t),
            ("z", ctypes.c_size_t)
        ]
    
    
    
    pid = sys.argv[1]
    
    with open(f"/proc/{pid}/maps", "r") as f:
        lines = f.readlines()
    
    for line in lines:
        if "[stack]" in line:
            start, end = line.split()[0].split("-")
    
    start = int(start, 16)
    end = int(end, 16)
    
    loc_size = ctypes.sizeof(Location)
    
    with open (f"/proc/{pid}/mem", "rb") as f:
        f.seek(start)
        data = f.read(end-start)
    
    print (len(data))
    for i in range(0, len(data), loc_size):
        chunk = data[i:i+loc_size]
        if len (chunk) < loc_size:
            continue
        location = Location.from_buffer_copy(chunk)
        if location.z == 1337:
            print (f"\tx: {location.x}")
            print (f"\ty: {location.y}")
            print (f"\tz: {location.z}")