Carved files (analysis.carved)

analysis.carved: malcat.CarvedFiles

The analysis.carved object is a malcat.CarvedFiles instance that gives you access to all the carved files extracted by the File carving algorithm.

Note that in addition to this documentation, you can find usage examples in the sample script which is loaded when you hit F8.

What are carved files?

Malcat can list and extract two different types of sub-files:

  • The current File parsers will parse the structures of the current file and interpret their content, looking for descriptions or links to stored / packed files. These can be archive members in a ZIP file, files in an ISO image or resource items defined in a PE program for instance. These are listed inside the Virtual File System tab.

  • Malcat will run a File carving algorithm and scan the entire file range for embedded files of known types (like binwalk, but without all the FPs). This pass can identify files even in raw dumps. These are listed inside the Carved files tab.

The analysis.carved gives you access to the second category, i.e. the list of carved files. These files have been successfully parsed by one of Malcat’s File parsers.

Accessing / enumerating carved files

class malcat.CarvedFiles

This class contains all the carved files extracted by the File carving algorithm. Note that all addresses used in this class are effective addresses. See Addressing in Malcat for more details.

__iter__()

Iterate over all the carved files :: for sub in analysis.carved:

print(f”* Found sub-file ‘{sub.name}’ in .rsrc at #{analysis.map.to_phys(sub.address):x} ({sub.size} bytes): {sub.type} [{sub.category}]”)

Return type:

iterator over CarvedFile

__getitem__(interval)

Iterate over all the sub-files carved within the given interval (effective address): ::

rsrc = analysis.map[".rsrc"]
for sub in analysis.carved[rsrc.start:rsrc.end]:
    print(f"* Found sub-file '{sub.name}' in .rsrc at #{analysis.map.to_phys(sub.address):x} ({sub.size} bytes): {sub.type} [{sub.category}]")
Parameters:

interval (slice) – effective address interval

Return type:

iterator over the list of functions (CarvedFile)

__getitem__(ea)

Returns the CarvedFile containing the effective address ea.

subfile = analysis.carved[0x500]
Parameters:

ea (int) – effective address

Return type:

CarvedFile instance

Raises:

KeyError if ea does not belong to the file’s effective address space

__contains__(ea)

return True iff the effective address ea lies within a carved file

Parameters:

ea (int) – address to query

Return type:

bool

find(ea)

return the CarvedFile which starts at or contains the effective address ea, or None if no one can be found.

Parameters:

ea (int) – effective address for the query

Return type:

CarvedFile or None

find_forward(ea)

return the CarvedFile which starts at or contains the effective address ea or starts directly after ea, or None if no CarvedFile is defined beyond ea.

first_carved_file = analysis.carved.find_forward(0)
if first_carved_file is None:
    raise ValueError("No file carved!")
Parameters:

ea (int) – effective address for the query

Return type:

CarvedFile or None

find_backward(ea)

return the CarvedFile which starts at or contains the effective address ea or the first one that start before ea, or None if no CarvedFile is defined before ea.

last_carved_file = analysis.carved.find_backward(analysis.map.end)
if last_carved_file is None:
    raise ValueError("No file carved!")
Parameters:

ea (int) – effective address for the query

Return type:

CarvedFile or None

__len__()

return the number of successfully carved files

if len(analysis.carved) == 0:
    raise ValueError("No carved files!")
Return type:

int

The carved file object

class malcat.CarvedFile

This class represents one sub-file that has been extracted by the File carving algorithm.

address: int (effective address)

the start of the carved file

start: int (effective address)

same as address

end: int (effective address)

last effective address inside the carved file + 1

size: int

size in bytes of the carved file: end - start

__len__()

return the size in bytes of the carved file: end - start

name: str

nice name for the carved file, e.g. PNG.#9ee5. Sometimes a better name is given, if the carved file is part of a named structure like a PE resource.

type: str

the type of the identified file as givem by the correspondig file parser: “PE”, “BMP”, etc.

category: malcat.FileType.Category

the category fo the corresponding file’s type, i.e. if it’s a program, an archive, an image, etc. Use by some anomaly functions.

open()

open the careved object into a file that you can use with malcat.analyse(). Note that you don’t need to close the file, it happens automatically. Also the file won’t take any place in RAM.

Return type:

malcat.File

Dumping a carved object to disk

If you want to save the content of one or multiple carved objects, you can do it simply using Malcat’s File object (analysis.file):

import re

for sub in analysis.carved:
    offset = analysis.a2p(sub.address)
    data = sub.open().read()
    # data = analysis.file[offset:offset + sub.size] # equivalent
    filename = re.sub('[^\w_.)( -]', '_', sub.name)
    with open(filename, "wb") as f:
        f.write(data)