volatilityfoundation / volatility3

Volatility 3.0 development
http://volatilityfoundation.org/
Other
2.72k stars 463 forks source link

linux_find_file plugin from vol2 to vol3,please #1203

Closed tanghengliang closed 1 month ago

tanghengliang commented 4 months ago

We need to export the file through inode address and convert it from the vol2 method def to_paddr(self): mem_map_addr = self.obj_vm.profile.get_symbol("mem_map") mem_section_addr = self.obj_vm.profile.get_symbol("mem_section")

    if mem_map_addr:
        # FLATMEM kernels, usually 32 bit
        mem_map_ptr = obj.Object("Pointer", offset = mem_map_addr, vm = self.obj_vm, parent = self.obj_parent)

    elif mem_section_addr:
        mem_map_ptr_addr = self.obj_vm.profile.get_symbol("vmemmap_base")
        if mem_map_ptr_addr:
            # (later) ASLR kernels
            mem_map_ptr = obj.Object("unsigned long", offset = mem_map_ptr_addr, vm = self.obj_vm)
        else:
            # this is hardcoded in the kernel - VMEMMAPSTART, usually 64 bit kernels
            mem_map_ptr = 0xffffea0000000000
    else:
        debug.error("phys_addr_of_page: Unable to determine physical address of page. NUMA is not supported at this time.\n")

    phys_offset = (self.obj_offset - mem_map_ptr) / self.obj_vm.profile.get_obj_size("page")

    phys_offset = phys_offset << 12

    return phys_offset

Convert to vol3 format as follows:     def to_paddr(self, page_offset):         """Converts the virtual address of a page to a physical address."""         # try:         kernel_module = self.context.modules[self.config['kernel']]         symbol_table_name = kernel_module.symbol_table_name         object_name_prefix = symbol_table_name + constants.BANG         symbol_space = self.context.symbol_space

        mem_map_addr = None         if symbol_space.has_symbol(object_name_prefix + 'mem_map'):

            mem_map_addr = symbol_space.get_symbol(object_name_prefix + 'mem_map')         mem_section_addr = None         if symbol_space.has_symbol(object_name_prefix + 'mem_section'):             mem_section_addr = symbol_space.get_symbol(object_name_prefix + 'mem_section')

        if mem_map_addr and mem_map_addr.address:             mem_map_ptr = objects.Pointer(kernel_module,offset=mem_map_addr.address)             # # FLATMEM kernels, usually 32 bit             # mem_map_ptr = self.context.object(object_type="pointer", layer_name=kernel_module.layer_name,             #                                   offset=mem_map_addr.address)         elif mem_section_addr:             vmemmap_base_addr = None             if symbol_space.has_symbol(object_name_prefix + 'vmemmap_base'):                 vmemmap_base_addr = symbol_space.get_symbol(object_name_prefix + 'vmemmap_base')             if vmemmap_base_addr:                 # mem_map_ptr = self.context.object(object_name_prefix + "pointer",                 #                                   layer_name=kernel_module.layer_name,                 #                                   offset=vmemmap_base_addr.address)                 mem_map_ptr = self.context.object(object_name_prefix + "unsigned long", layer_name=kernel_module.layer_name,                                                   offset=vmemmap_base_addr.address)

            else:                 mem_map_ptr = 0xffffea0000000000         else:             vollog.error(                 "to_paddr: Unable to determine physical address of page)

Unable to obtain the real physical address,error message as follows 4ca52777868359625c0ac995bc2132e

How to solve the problem of exporting Linux files without obtaining physical addresses!Thanks

ikelos commented 4 months ago

You haven't provided enough of the error message to know exactly where in your code the problem is, but one of the pointers you're using comes out as 0, which can't be read and is therefore throwing that issue.

atcuno commented 4 months ago

@tanghengliang this is being converted as part of the effort from our core team. It should be ready within the next few weeks.

tanghengliang commented 3 months ago

@atcuno Thank you for your reply. When importing Linux files, I have debugged to obtain the physical address of the file in memory. The code is as follows:

`def to_paddr(self, page_offset): """Converts the virtual address of a page to a physical address.""" try: kernel_module = self.context.modules[self.config['kernel']] symbol_table_name = kernel_module.symbol_table_name object_name_prefix = symbol_table_name + constants.BANG symbol_space = self.context.symbol_space

        vmemmap_base_addr = None
        mem_map_addr = None
        if symbol_space.has_symbol(object_name_prefix + 'mem_map'):
            mem_map_addr = symbol_space.get_symbol(object_name_prefix + 'mem_map')
        mem_section_addr = None
        if symbol_space.has_symbol(object_name_prefix + 'mem_section'):
            mem_section_addr = symbol_space.get_symbol(object_name_prefix + 'mem_section')

        if mem_map_addr and mem_map_addr.address:
            mem_map_ptr = self.context.object(object_type="pointer", layer_name=kernel_module.layer_name,
                                              offset=mem_map_addr.address)
        elif mem_section_addr:
            vmemmap_base_addr = None
            if symbol_space.has_symbol(object_name_prefix + 'vmemmap_base'):
                # vmemmap_base_addr2 = symbol_space.get_symbol(object_name_prefix + 'vmemmap_base')
                vmemmap_base_addr = kernel_module.object_from_symbol('vmemmap_base')
                pass
            if vmemmap_base_addr:
                # pass
                mem_map_ptr = vmemmap_base_addr
                # mem_map_ptr = self.context.object(object_name_prefix + "long unsigned int",
                #                                   layer_name=kernel_module.layer_name,
                #                                   offset=vmemmap_base_addr.address)
                pass

            else:
                mem_map_ptr = 0xffffea0000000000
        else:
            vollog.error(
                "to_paddr: Unable to determine physical address of page. NUMA is not supported at this time.\n")
            return None

            # Calculate the physical offset
        page_size = kernel_module.get_type("page").size
        relative_offset = page_offset - mem_map_ptr
        phys_offset = relative_offset // page_size

        phys_offset = phys_offset << 12

        return phys_offset
    except (exceptions.SymbolError, AttributeError, exceptions.InvalidAddressException) as e:
        vollog.debug(f"Error calculating physical address: {e}")
        return None`

After obtaining the physical address, read the file content by accessing the address through the memory layer: phys_layer_name = 'memory_layer' phys_layer = self.context.layers[phys_layer_name] data = phys_layer.read(phys_addr, 4096, pad=False)

atcuno commented 1 month ago

This functionality is now included in the linux.pagecache.* plugins.