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

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)

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