Skip to main content
Glama
0xhackerfren

Frida Game Hacking MCP

by 0xhackerfren

get_scan_results

Retrieve current memory scan results with values to identify and analyze game data patterns during reverse engineering.

Instructions

Get current scan results with values.

Args:
    limit: Maximum results to return (default: 20)

Returns:
    List of addresses and their current values.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The handler function for the 'get_scan_results' MCP tool. It reads the current values from memory addresses stored in the scan state using Frida scripts, unpacks them according to the scan value type, and returns a list of results with addresses, values, and hex representations.
    @mcp.tool()
    def get_scan_results(limit: int = 20) -> Dict[str, Any]:
        """
        Get current scan results with values.
        
        Args:
            limit: Maximum results to return (default: 20)
        
        Returns:
            List of addresses and their current values.
        """
        global _session
        
        if not _session.scan_state.scan_active:
            return {"error": "No active scan. Use scan_value() first."}
        
        if not _session.is_attached():
            return {"error": "Not attached. Use attach() first."}
        
        try:
            value_type = _session.scan_state.value_type
            value_size = _get_value_size(value_type)
            addresses = _session.scan_state.results[:limit]
            
            if not addresses:
                return {"total": len(_session.scan_state.results), "shown": 0, "results": []}
            
            addr_list = ", ".join(f'"{hex(a)}"' for a in addresses)
            
            script_code = f"""
            var addresses = [{addr_list}];
            var size = {value_size};
            var results = [];
            
            for (var i = 0; i < addresses.length; i++) {{
                try {{
                    var data = Memory.readByteArray(ptr(addresses[i]), size);
                    var hex = '';
                    var bytes = new Uint8Array(data);
                    for (var j = 0; j < bytes.length; j++) {{
                        hex += ('0' + bytes[j].toString(16)).slice(-2);
                    }}
                    results.push({{address: addresses[i], hex: hex}});
                }} catch (e) {{
                    results.push({{address: addresses[i], error: e.toString()}});
                }}
            }}
            send(JSON.stringify(results));
            """
            
            result_data = []
            def on_message(message, data):
                if message['type'] == 'send':
                    result_data.append(message['payload'])
            
            script = _session.session.create_script(script_code)
            script.on('message', on_message)
            script.load()
            script.unload()
            
            if not result_data:
                return {"error": "Failed to get results"}
            
            import json
            raw_results = json.loads(result_data[0])
            
            results = []
            for r in raw_results:
                if 'error' not in r:
                    try:
                        current_value = _unpack_value(bytes.fromhex(r['hex']), value_type)
                        results.append({"address": r['address'], "value": current_value, "hex": r['hex']})
                    except:
                        pass
            
            return {
                "total": len(_session.scan_state.results),
                "shown": len(results),
                "value_type": value_type,
                "results": results
            }
        
        except Exception as e:
            return {"error": f"Failed to get results: {str(e)}"}
  • Dataclass that maintains the scan state (results list, value type, last values, active status) used by get_scan_results and other scan tools.
    @dataclass
    class ScanState:
        """Tracks memory scan state for Cheat Engine-style scanning."""
        value_type: str = ""
        results: List[int] = field(default_factory=list)
        last_values: Dict[int, Any] = field(default_factory=dict)
        scan_active: bool = False
  • Helper function to unpack memory bytes into the appropriate value type (int, float, string), used in get_scan_results to convert hex data to readable values.
    def _unpack_value(data: bytes, value_type: str) -> Any:
        """Unpack bytes to value based on type."""
        formats = {
            "int8": "<b", "uint8": "<B",
            "int16": "<h", "uint16": "<H",
            "int32": "<i", "uint32": "<I",
            "int64": "<q", "uint64": "<Q",
            "float": "<f", "double": "<d"
        }
        fmt = formats.get(value_type)
        if fmt:
            return struct.unpack(fmt, data)[0]
        elif value_type == "string":
            return data.split(b'\x00')[0].decode('utf-8', errors='replace')
        return struct.unpack("<i", data)[0]
  • Helper function to determine the byte size of the scan value type, used to read the correct amount of memory in get_scan_results.
    def _get_value_size(value_type: str) -> int:
        """Get byte size for value type."""
        sizes = {
            "int8": 1, "uint8": 1,
            "int16": 2, "uint16": 2,
            "int32": 4, "uint32": 4,
            "int64": 8, "uint64": 8,
            "float": 4, "double": 8
        }
        return sizes.get(value_type, 4)
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It mentions returning 'current scan results with values' and a list of addresses, but lacks details on permissions, rate limits, data freshness, or error handling. For a read operation in a scanning context, this is insufficient behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and concise, with a clear purpose statement followed by 'Args' and 'Returns' sections. Every sentence adds value without redundancy, making it easy to parse and front-loaded with essential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (retrieving scan results), no annotations, and an output schema (implied by 'Returns'), the description is minimally adequate. It covers the purpose and parameter but lacks behavioral details and usage context. With output schema handling return values, it meets baseline completeness but has clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds meaningful context for the single parameter: 'limit: Maximum results to return (default: 20)'. This clarifies the parameter's purpose beyond the schema's basic type and title. With 0% schema description coverage, the description fully compensates, but since there's only one parameter, it's not a perfect 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Get current scan results with values.' It specifies the verb ('Get') and resource ('current scan results'), making it understandable. However, it doesn't differentiate from sibling tools like 'scan_changed' or 'scan_unchanged', which might retrieve similar data, so it's not a perfect 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. With siblings like 'scan_changed', 'scan_unchanged', and 'scan_value' that might retrieve scan-related data, there's no indication of context, prerequisites, or exclusions for this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/0xhackerfren/frida-game-hacking-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server