Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

  • I can't modify the binary code
  • monitoring should be done with python
  • ASLR always enabled

Things I tried

  • Reading /proc/pid/maps location stack then reading /proc/pid/mem didn't find anything
  • I used gdb to find the address of loc but it is outside the range of stack found in maps (most probably ASLR)
like image 488
Weed Cookie Avatar asked Nov 01 '25 13:11

Weed Cookie


1 Answers

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}")
like image 135
Weed Cookie Avatar answered Nov 04 '25 03:11

Weed Cookie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!