@mcp.tool()
def scan_next(value: Union[int, float, str]) -> Dict[str, Any]:
"""
Narrow scan results with new value.
Args:
value: New value to search for
Returns:
Number of remaining addresses.
"""
global _session
if not _session.is_attached():
return {"error": "Not attached. Use attach() first."}
if not _session.scan_state.scan_active:
return {"error": "No active scan. Use scan_value() first."}
try:
value_type = _session.scan_state.value_type
value_size = _get_value_size(value_type)
if value_type == "string":
expected_hex = value.encode('utf-8').hex()
else:
expected_hex = _pack_value(value, value_type).hex()
addresses = _session.scan_state.results
if not addresses:
return {"success": True, "value": value, "remaining": 0}
batch_size = 1000
new_results = []
for batch_start in range(0, len(addresses), batch_size):
batch = addresses[batch_start:batch_start + batch_size]
addr_list = ", ".join(f'"{hex(a)}"' for a in batch)
script_code = f"""
var addresses = [{addr_list}];
var size = {value_size};
var expected = "{expected_hex}";
var matches = [];
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);
}}
if (hex === expected) matches.push(addresses[i]);
}} catch (e) {{ }}
}}
send(JSON.stringify(matches));
"""
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 result_data:
import json
matches = json.loads(result_data[0])
new_results.extend([int(a, 16) for a in matches])
_session.scan_state.results = new_results
_session.scan_state.last_values = {addr: value for addr in new_results}
return {
"success": True,
"value": value,
"remaining": len(new_results),
"message": f"Narrowed to {len(new_results)} addresses."
}
except Exception as e:
return {"error": f"Scan next failed: {str(e)}"}