mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-08-17 20:35:40 +02:00
150 lines
4.8 KiB
Python
150 lines
4.8 KiB
Python
import argparse
|
|
import lzma
|
|
import os
|
|
import subprocess
|
|
import tempfile
|
|
from typing import List, Dict, Optional
|
|
|
|
import requests
|
|
import rpmfile
|
|
from debian import debfile
|
|
|
|
DWARF2JSON = "./dwarf2json"
|
|
|
|
|
|
class Downloader:
|
|
|
|
def __init__(self, url_lists: List[List[str]]) -> None:
|
|
self.url_lists = url_lists
|
|
|
|
def download_lists(self, keep=False):
|
|
for url_list in self.url_lists:
|
|
print("Downloading files...")
|
|
files_for_processing = self.download_list(url_list)
|
|
self.process_files(files_for_processing)
|
|
if not keep:
|
|
for fname in files_for_processing.values():
|
|
if fname:
|
|
os.unlink(fname)
|
|
|
|
def download_list(self, urls: List[str]) -> Dict[str, str]:
|
|
processed_files = {}
|
|
for url in urls:
|
|
print(f" - Downloading {url}")
|
|
data = requests.get(url)
|
|
with tempfile.NamedTemporaryFile() as archivedata:
|
|
archivedata.write(data.content)
|
|
archivedata.seek(0)
|
|
if url.endswith(".rpm"):
|
|
processed_files[url] = self.process_rpm(archivedata)
|
|
elif url.endswith(".deb"):
|
|
processed_files[url] = self.process_deb(archivedata)
|
|
|
|
return processed_files
|
|
|
|
def process_rpm(self, archivedata) -> Optional[str]:
|
|
rpm = rpmfile.RPMFile(fileobj=archivedata)
|
|
member = None
|
|
extracted = None
|
|
for member in rpm.getmembers():
|
|
if "vmlinux" in member.name or "System.map" in member.name:
|
|
print(f" - Extracting {member.name}")
|
|
extracted = rpm.extractfile(member)
|
|
break
|
|
if not member or not extracted:
|
|
return None
|
|
with tempfile.NamedTemporaryFile(
|
|
delete=False, prefix="vmlinux" if "vmlinux" in member.name else "System.map"
|
|
) as output:
|
|
print(f" - Writing to {output.name}")
|
|
output.write(extracted.read())
|
|
return output.name
|
|
|
|
def process_deb(self, archivedata) -> Optional[str]:
|
|
deb = debfile.DebFile(fileobj=archivedata)
|
|
member = None
|
|
extracted = None
|
|
for member in deb.data.tgz().getmembers():
|
|
if member.name.endswith("vmlinux") or "System.map" in member.name:
|
|
print(f" - Extracting {member.name}")
|
|
extracted = deb.data.get_file(member.name)
|
|
break
|
|
if not member or not extracted:
|
|
return None
|
|
with tempfile.NamedTemporaryFile(
|
|
delete=False, prefix="vmlinux" if "vmlinux" in member.name else "System.map"
|
|
) as output:
|
|
print(f" - Writing to {output.name}")
|
|
output.write(extracted.read())
|
|
return output.name
|
|
|
|
def process_files(self, named_files: Dict[str, str]):
|
|
"""Runs the dwarf2json binary across the files"""
|
|
print("Processing Files...")
|
|
for i in named_files:
|
|
if named_files[i] is None:
|
|
print(f"FAILURE: None encountered for {i}")
|
|
return
|
|
args = [DWARF2JSON, "linux"]
|
|
output_filename = "unknown-kernel.json"
|
|
for named_file in named_files:
|
|
prefix = "--system-map"
|
|
if "System" not in named_files[named_file]:
|
|
prefix = "--elf"
|
|
output_filename = (
|
|
"./"
|
|
+ "-".join((named_file.split("/")[-1]).split("-")[2:])[:-4]
|
|
+ ".json.xz"
|
|
)
|
|
args += [prefix, named_files[named_file]]
|
|
print(f" - Running {args}")
|
|
proc = subprocess.run(args, capture_output=True)
|
|
|
|
print(f" - Writing to {output_filename}")
|
|
with lzma.open(output_filename, "w") as f:
|
|
f.write(proc.stdout)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(
|
|
description="Takes a list of URLs for Centos and downloads them"
|
|
)
|
|
parser.add_argument(
|
|
"-f",
|
|
"--file",
|
|
dest="filename",
|
|
metavar="FILENAME",
|
|
help="Filename to be read",
|
|
required=True,
|
|
)
|
|
parser.add_argument(
|
|
"-d",
|
|
"--dwarf2json",
|
|
dest="dwarfpath",
|
|
metavar="PATH",
|
|
default=DWARF2JSON,
|
|
help="Path to the dwarf2json binary",
|
|
required=True,
|
|
)
|
|
parser.add_argument(
|
|
"-k",
|
|
"--keep",
|
|
dest="keep",
|
|
action="store_true",
|
|
help="Keep extracted temporary files after completion",
|
|
default=False,
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
DWARF2JSON = args.dwarfpath
|
|
|
|
with open(args.filename) as f:
|
|
lines = f.readlines()
|
|
|
|
urls = []
|
|
for i in range(len(lines) // 2):
|
|
urls += [[lines[2 * i].strip(), lines[(2 * i) + 1].strip()]]
|
|
|
|
d = Downloader(urls)
|
|
d.download_lists(keep=args.keep)
|