get_process_info
Extract and visualize the complete process execution tree from Joe Sandbox malware analysis reports to understand how malicious processes spawn and interact during runtime.
Instructions
Extract and return the full process tree for a specific analysis run from a Joe Sandbox report.
This tool traverses the execution tree recorded during dynamic analysis and returns a structured
process hierarchy, showing which processes spawned others, with their respective attributes.
Each process node includes:
- name: Process executable name
- pid: Process ID
- cmdline: Full command-line invocation
- path: File path of the executable
- has_exited: Boolean flag indicating if the process terminated
- children: List of child processes (if any), recursively structured
- targetid: purely internal field, ignore this when replying to the user
The result can be large and deeply nested, depending on the behavior of the sample. To improve
readability, consider representing the tree using indentation or a UNIX-style `tree` layout. If the cmd args are not too long, consider displaying them as well, e.g.:
parent.exe (1000) - "C:\Program Files\Parent\parent.exe"
├── child1.exe (1001) - "C:\Program Files\Parent\child1.exe --option"
│ └── grandchild1.exe (1002) - "grandchild1.exe /silent"
└── child2.exe (1003) - "child2.exe --config config.yaml --verbose"
├── grandchild2.exe (1004) - "grandchild2.exe"
└── grandchild3.exe (1005) - "grandchild3.exe --debug --log-level=info"
Args:
webid (required): Submission ID of the analysis.
run (default: 0): Index of the sandbox run to inspect (from the `runs` array in analysis info).
Returns:
Dictionary representing the root-level processes and their child process trees.
If parsing or report retrieval fails, returns an error dictionary with a reason.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| webid | Yes | ||
| run | No |
Implementation Reference
- jbxmcp/tools.py:410-462 (handler)The main handler function for the get_process_info tool. It fetches the Joe Sandbox XML report using get_or_fetch_report, extracts the process tree using extract_process_tree, handles errors, and returns the structured process hierarchy.@mcp.tool() async def get_process_info(webid: str, run: int=0) -> Dict[str, Any]: """ Extract and return the full process tree for a specific analysis run from a Joe Sandbox report. This tool traverses the execution tree recorded during dynamic analysis and returns a structured process hierarchy, showing which processes spawned others, with their respective attributes. Each process node includes: - name: Process executable name - pid: Process ID - cmdline: Full command-line invocation - path: File path of the executable - has_exited: Boolean flag indicating if the process terminated - children: List of child processes (if any), recursively structured - targetid: purely internal field, ignore this when replying to the user The result can be large and deeply nested, depending on the behavior of the sample. To improve readability, consider representing the tree using indentation or a UNIX-style `tree` layout. If the cmd args are not too long, consider displaying them as well, e.g.: parent.exe (1000) - "C:\Program Files\Parent\parent.exe" ├── child1.exe (1001) - "C:\Program Files\Parent\child1.exe --option" │ └── grandchild1.exe (1002) - "grandchild1.exe /silent" └── child2.exe (1003) - "child2.exe --config config.yaml --verbose" ├── grandchild2.exe (1004) - "grandchild2.exe" └── grandchild3.exe (1005) - "grandchild3.exe --debug --log-level=info" Args: webid (required): Submission ID of the analysis. run (default: 0): Index of the sandbox run to inspect (from the `runs` array in analysis info). Returns: Dictionary representing the root-level processes and their child process trees. If parsing or report retrieval fails, returns an error dictionary with a reason. """ try: root = await get_or_fetch_report(webid, run) if root is None: return {"error": f"Could not retrieve or parse report for submission ID '{webid}' run {run}"} try: proc_tree = extract_process_tree(root) except Exception as e: return {"error": f"Could not reconstruct process tree for submission ID {webid} run {run}"} return proc_tree except Exception as e: return { "error": f"Failed to extract process tree for submission ID '{webid}' run {run}. " f"Reason: {str(e)}" }
- jbxmcp/core.py:264-288 (helper)Supporting function that recursively parses the XML report's process elements to construct the nested dictionary representing the process tree, which is the core output of the tool.def extract_process_tree(process_elements) -> Dict[str, Any]: """ Reconstructs a process tree as a nested json array from the xml report """ def process_node(proc_elem): # Extract key attributes attrs = proc_elem.attrib node = { "name": attrs.get("name"), "pid": attrs.get("pid"), "cmdline": attrs.get("cmdline"), "path": attrs.get("path"), "targetid": attrs.get("targetid"), "has_exited": attrs.get("hasexited") == "true" } # Recursively extract children children = proc_elem.findall("./process") if children: node["children"] = [process_node(child) for child in children] return node process_elements = process_elements.findall("./behavior/system/startupoverview/process") return [process_node(p) for p in process_elements]
- jbxmcp/core.py:100-134 (helper)Helper function that retrieves the Joe Sandbox analysis report as XML ElementTree, either from cache or by downloading from the API, used by the handler to access the process data.async def get_or_fetch_report(webid: str, run: int=0) -> Optional[ET.Element]: """ Get a report from the cache or fetch it from the API. Args: webid: The webid of the report to retrieve. run: The analysis run index of the report to retrieve, default: 0 Returns: The report as an XML Element, or None if it couldn't be retrieved. """ cache_key = f"{webid}-{run}" cached = await report_cache.get(cache_key) if cached: xml_stream = io.BytesIO(cached) xml_tree = ET.parse(xml_stream) return xml_tree.getroot() # If not in cache, fetch from API def blocking_download(): client = get_client() _, data = client.analysis_download(webid=webid, type='xml', run=run) return data try: data = await asyncio.to_thread(blocking_download) await report_cache.set(cache_key, data) xml_stream = io.BytesIO(data) xml_tree = ET.parse(xml_stream) xml_root = xml_tree.getroot() return xml_root except Exception as e: print(f"Error fetching report for webid {webid}, run {run}: {e}") return None
- jbxmcp/server.py:19-19 (registration)Import of the tools module in the MCP server setup, which triggers registration of all @mcp.tool()-decorated functions including get_process_info via FastMCP.import jbxmcp.tools as tools