Creating a memory dump that keeps same addresses as RAM, so pointers are still valid

427 Views Asked by At

I am using API Monitor v2 to debug and reverse engineer a 32bits application running on Windows 10 but I'm having some issues figuring out a std::set object values, I'm trying to dump the memory to a file so I can better look at the object with assistance of Hex Workshop structures.

While inside API Monitor's "Memory Editor" I can see the entire process memory and all pointers are valid but dumping the memory with ProcDump gives me an unaligned file, I tried padding, but it didn't work that well...

I've also tried github.com/glmcdona/Process-Dump but it creates one file for each .dll which is not useful for me in this situation where I have to navigate the memory... Is the solution using another tool? IDA seems overkill, Ollydbg feels counter intuitive, I could try Ghidra... Or maybe there is some technique to padding the mem dump?

Ps. The program has been frozen by API Monitor using a breakpoint, so this isn't the case of the memory simply changing.

1

There are 1 best solutions below

0
gistix On

In the end all I wanted to do was figure out what values where written in a std::set variable. I haven't really used a debugger before and having to learn how to do so for such a simple task felt wrong, I ended up writing a small Python script to extract the values stored in the set.

import struct

class Node(object):
    STRUCT = '<IIIHHHI'

    def __init__(self, f):
        size = struct.calcsize(Node.STRUCT)

        self.bin = f.read(size)

        self.left, self.right, self.parent, self.unk, self.unk2, self.value, self.unk3 = struct.unpack(Node.STRUCT, self.bin)

        # Print the values 
        print(self.value)

    def __eq__(self, other):
        return self.left == other.left and self.right == other.right and self.parent == other.parent

    def __repr__(self):
        return f'{self.rb}, {self.value}'

    def __contains__(self, item):
        print('__contains__')

    def read_related(self, f, nodes):
        # If node not in list (uses our defined '__eq__' for comparison)
        if self not in nodes:
            nodes.append(self)

            if self.left != 0x0:
                f.seek(self.left)
                Node(f).read_related(f, nodes)

            if self.right != 0x0:
                f.seek(self.right)
                Node(f).read_related(f, nodes)

            if self.parent != 0x0:
                f.seek(self.parent)
                Node(f).read_related(f, nodes)

def main():
    with open('Program.DMP', 'rb') as f:
        f.seek(0x04d79888) # First node address

        nodes = []

        node = Node(f)

        node.read_related(f, nodes)

        # Doesn't print everything?
        '''for node in nodes:
            print(node.bin.hex(), node.unk, node.value)'''

if __name__ == '__main__':
    main()

You have to make sure that the memory dump section where the set resides has the same start address as it does in memory.