8,169
社区成员
发帖
与我相关
我的任务
分享BinSentry 二进制哨兵,由 LYSHARK 独立自研,是一款运行于 Windows 平台的二进制动态调试引擎。该调试引擎从零手写开发,C++ 代码 2 万余行,实现 200 + 调试方法;原生采用 CMD 命令行 HTTP 服务器架构,专为 AI Agent 打造。配合配套 AI 智能体,能够对二进制文件、木马等恶意样本进行深层次分析,是二进制样本研究的实用工具。
哨兵可以部署到任意的虚拟机沙盒之中,并可以搭载目前流行的jev等大模型产品,AI驱动速度有质的提升,是Windows平台下AI动态调试的优质项目。
执行命令安装哨兵客户端:
Microsoft Windows [版本]
(c) 2018 Microsoft Corporation。保留所有权利。
C:\Users\Admin>pip install BinSentry==1.0.0
哨兵运行后会在后台,并默认侦听6891端口,且可以设置开机自启动。


结论:186 项接口调用,184 项 PASS,0 项 FAIL/ERROR,2 项 SKIP(谨慎跳过),所有接口均正常。
E:\win32.exeE:\win32.exe → 模块 / PE → 内存 → 寄存器 / 线程 → 断点 → 反汇编 → 栈 / 追踪 → 执行控制 → 会话管理 → 数据库,含写类操作(内存写、补丁、断点、寄存器)均做了 "写入→验证→还原",不污染目标进程| API 类 | 总数 | PASS | 说明 |
|---|---|---|---|
| BreakPointApi | 35 | 35 | 软 / 硬 / 内存 / API / 异常 / DLL 断点全套 |
| ExecutionControlApi | 28 | 28 | 单步、trace、animate、run/pause 等 |
| MemoryApi | 26 | 26 | 读写、搜索、页权限、补丁、分配 |
| ModulePeApi | 21 | 21 | 模块 / PE / 导入导出 / 符号 |
| DebugSessionApi | 15 | 15 | debug/detach/restart/stop/dump/minidump |
| 其余 6 类 | 61 | 61 | 全部通过 |
set_jit:get_jit 未返回有效 JIT 路径,为避免写注册表而跳过set_command_line:get_command_line 未返回可用值,为避免覆盖配置而跳过import json
import socket
from urllib.parse import urlparse
from typing import List, Dict, Union, Optional, Callable
from functools import wraps
def check_server_available(func: Callable) -> Callable:
"""装饰器:检测服务是否可用,不可用直接返回error json"""
@wraps(func)
def wrapper(self, *args, **kwargs):
if not self.config.is_server_available():
return json.dumps({
"status": "error",
"message": "Server unavailable"
}, ensure_ascii=False)
return func(self, *args, **kwargs)
return wrapper
def validate_hex_address(address: Union[int, str]) -> Optional[str]:
"""校验并格式化十六进制地址,返回 0xxxxx 格式字符串,非法返回None"""
if isinstance(address, int):
return hex(address)
addr_str = str(address).strip()
if not addr_str:
return None
if addr_str.startswith(('0x', '0X')):
try:
int(addr_str, 16)
return addr_str
except ValueError:
return None
try:
int(addr_str, 10)
return addr_str
except ValueError:
return None
class Config:
def __init__(self, address: str = "127.0.0.1", port: int = 6891):
self.address = address
self.port = port
self.server_addr = f"http://{address}:{port}"
self.timeout = 5
def is_server_available(self, timeout: Optional[int] = None) -> bool:
"""检测端口是否开放"""
timeout = timeout or self.timeout
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(timeout)
result = sock.connect_ex((self.address, self.port))
return result == 0
except socket.error as e:
print(f"WARNING: Server check failed: {str(e)}")
return False
class BaseHttpClient:
def __init__(self, config: Optional[Config] = None):
self.config = config or Config()
parsed_url = urlparse(self.config.server_addr)
self.address = parsed_url.hostname
self.port = parsed_url.port
self.scheme = parsed_url.scheme
self.path = parsed_url.path or '/'
self.verify_ssl = True
def custom_post(self, payload: Optional[Dict] = None, timeout: Optional[int] = None) -> str:
"""发送POST请求,payload对应BinSentry接口 {interface, params}"""
import http.client
headers = {"Content-Type": "application/json"}
body = json.dumps(payload).encode("utf-8") if payload else None
timeout = timeout or self.config.timeout
try:
if self.scheme == "https":
import ssl
context = ssl._create_unverified_context() if not self.verify_ssl else None
conn = http.client.HTTPSConnection(self.address, self.port, timeout=timeout, context=context)
else:
conn = http.client.HTTPConnection(self.address, self.port, timeout=timeout)
conn.request("POST", self.path, body=body, headers=headers)
response = conn.getresponse()
response_text = response.read().decode("utf-8", errors="ignore")
conn.close()
return response_text
except socket.timeout:
return json.dumps({"status": "error", "message": "Request timed out"}, ensure_ascii=False)
except ConnectionRefusedError:
return json.dumps({"status": "error", "message": "Connection refused by server"}, ensure_ascii=False)
except Exception as e:
return json.dumps({"status": "error", "message": f"Request failed: {str(e)}"}, ensure_ascii=False)
class SystemApi(BaseHttpClient):
"""系统与进程相关接口"""
@check_server_available
def system_info(self) -> str:
return self.custom_post({"interface": "SystemInfo", "params": {}})
@check_server_available
def process_list(self) -> str:
return self.custom_post({"interface": "ProcessList", "params": {}})
@check_server_available
def enum_windows(self, pid: int) -> str:
return self.custom_post({"interface": "EnumWindows", "params": {"pid": pid}})
@check_server_available
def is_process_elevated(self) -> str:
return self.custom_post({"interface": "IsProcessElevated", "params": {}})
@check_server_available
def enum_error_codes(self) -> str:
return self.custom_post({"interface": "EnumErrorCodes", "params": {}})
@check_server_available
def enum_exceptions(self) -> str:
return self.custom_post({"interface": "EnumExceptions", "params": {}})
@check_server_available
def help(self) -> str:
return self.custom_post({"interface": "Help", "params": {}})
@check_server_available
def get_jit(self) -> str:
return self.custom_post({"interface": "GetJIT", "params": {}})
@check_server_available
def set_jit(self, path: str) -> str:
return self.custom_post({"interface": "SetJIT", "params": {"path": path}})
@check_server_available
def get_command_line(self) -> str:
return self.custom_post({"interface": "GetCommandLine", "params": {}})
@check_server_available
def set_command_line(self, args: str) -> str:
return self.custom_post({"interface": "SetCommandLine", "params": {"args": args}})
class LogConfigApi(BaseHttpClient):
"""日志与配置数据库"""
@check_server_available
def clear_log(self) -> str:
return self.custom_post({"interface": "ClearLog", "params": {}})
@check_server_available
def logs(self) -> str:
return self.custom_post({"interface": "Logs", "params": {}})
@check_server_available
def save_log(self, path: str) -> str:
return self.custom_post({"interface": "SaveLog", "params": {"path": path}})
@check_server_available
def load_database(self, path: str) -> str:
return self.custom_post({"interface": "LoadDatabase", "params": {"path": path}})
@check_server_available
def save_database(self, path: str) -> str:
return self.custom_post({"interface": "SaveDatabase", "params": {"path": path}})
@check_server_available
def load_config(self, module: str) -> str:
return self.custom_post({"interface": "LoadConfig", "params": {"module": module}})
class SymbolVarApi(BaseHttpClient):
"""变量、参数、注释、标签、函数"""
@check_server_available
def set_var(self, name: str, value: str) -> str:
return self.custom_post({"interface": "SetVar", "params": {"name": name, "value": value}})
@check_server_available
def del_var(self, name: str) -> str:
return self.custom_post({"interface": "DelVar", "params": {"name": name}})
@check_server_available
def get_vars(self) -> str:
return self.custom_post({"interface": "GetVars", "params": {}})
@check_server_available
def add_argument(self, start: Union[int, str], end: Union[int, str] = "", name: str = "") -> str:
start_addr = validate_hex_address(start)
payload: Dict = {"start": start_addr}
if end:
payload["end"] = validate_hex_address(end)
if name:
payload["name"] = name
return self.custom_post({"interface": "AddArgument", "params": payload})
@check_server_available
def del_argument(self, start: Union[int, str]) -> str:
s = validate_hex_address(start)
return self.custom_post({"interface": "DelArgument", "params": {"start": s}})
@check_server_available
def get_arguments(self) -> str:
return self.custom_post({"interface": "GetArguments", "params": {}})
@check_server_available
def get_comments(self) -> str:
return self.custom_post({"interface": "GetComments", "params": {}})
@check_server_available
def get_labels(self) -> str:
return self.custom_post({"interface": "GetLabels", "params": {}})
@check_server_available
def get_bookmarks(self) -> str:
return self.custom_post({"interface": "GetBookMarks", "params": {}})
@check_server_available
def functions(self) -> str:
return self.custom_post({"interface": "Functions", "params": {}})
class BreakPointApi(BaseHttpClient):
"""断点:软件/硬件/内存/api/异常/dll断点"""
@check_server_available
def show_breakpoint(self) -> str:
return self.custom_post({"interface": "ShowBreakPoint", "params": {}})
@check_server_available
def show_hbreakpoint(self) -> str:
return self.custom_post({"interface": "ShowHbreakPoint", "params": {}})
@check_server_available
def show_mem_breakpoint(self) -> str:
return self.custom_post({"interface": "ShowMemBreakPoint", "params": {}})
@check_server_available
def show_api_breakpoint(self) -> str:
return self.custom_post({"interface": "ShowApiBreakPoint", "params": {}})
@check_server_available
def set_bpx_options(self, option: str, enable: int) -> str:
return self.custom_post({"interface": "SetBPXOptions", "params": {"option": option, "enable": enable}})
@check_server_available
def set_exception_bpx(self, code: str) -> str:
return self.custom_post({"interface": "SetExceptionBPX", "params": {"code": code}})
@check_server_available
def del_exception_bpx(self, code: str) -> str:
return self.custom_post({"interface": "DelExceptionBPX", "params": {"code": code}})
@check_server_available
def get_exception_bpx_list(self) -> str:
return self.custom_post({"interface": "GetExceptionBPXList", "params": {}})
@check_server_available
def set_dll_breakpoint(self, dll: str) -> str:
return self.custom_post({"interface": "SetDllBreakPoint", "params": {"dll": dll}})
@check_server_available
def del_dll_breakpoint(self, dll: str) -> str:
return self.custom_post({"interface": "DelDllBreakPoint", "params": {"dll": dll}})
@check_server_available
def get_dll_breakpoints(self) -> str:
return self.custom_post({"interface": "GetDllBreakPoints", "params": {}})
@check_server_available
def set_breakpoint(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetBreakPoint", "params": {"address": addr}})
@check_server_available
def del_breakpoint(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "DelBreakPoint", "params": {"address": addr}})
@check_server_available
def get_breakpoint_info(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "GetBreakpointInfo", "params": {"address": addr}})
@check_server_available
def get_breakpoint_type(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "GetBreakpointType", "params": {"address": addr}})
@check_server_available
def set_breakpoint_name(self, address: Union[int, str], name: str) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetBreakpointName", "params": {"address": addr, "name": name}})
@check_server_available
def set_breakpoint_singleshoot(self, address: Union[int, str], enable: int = 0) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetBreakpointSingleshoot", "params": {"address": addr, "enable": enable}})
@check_server_available
def set_breakpoint_fast_resume(self, address: Union[int, str], enable: int = 0) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetBreakpointFastResume", "params": {"address": addr, "enable": enable}})
@check_server_available
def set_breakpoint_silent(self, address: Union[int, str], enable: int = 0) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetBreakpointSilent", "params": {"address": addr, "enable": enable}})
@check_server_available
def set_breakpoint_log(self, address: Union[int, str], text: str) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetBreakpointLog", "params": {"address": addr, "text": text}})
@check_server_available
def set_breakpoint_log_file(self, address: Union[int, str], file: str) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetBreakpointLogFile", "params": {"address": addr, "file": file}})
@check_server_available
def set_breakpoint_hit_count(self, address: Union[int, str], count: int) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetBreakpointHitCount", "params": {"address": addr, "count": count}})
@check_server_available
def get_breakpoint_hit_count(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "GetBreakpointHitCount", "params": {"address": addr}})
@check_server_available
def reset_breakpoint_hit_count(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "ResetBreakpointHitCount", "params": {"address": addr}})
@check_server_available
def set_cond_breakpoint(self, address: Union[int, str], cond: str, thread: int = 0) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetCondBreakPoint", "params": {"address": addr, "cond": cond, "thread": thread}})
@check_server_available
def del_cond_breakpoint(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "DelCondBreakPoint", "params": {"address": addr}})
@check_server_available
def set_hbreakpoint(self, address: Union[int, str], len_: str = "1", flag: str = "e") -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetHbreakPoint", "params": {"address": addr, "len": len_, "flag": flag}})
@check_server_available
def del_hbreakpoint(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "DelHbreakPoint", "params": {"address": addr}})
@check_server_available
def set_mem_breakpoint(self, address: Union[int, str], flag: str = "e") -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetMemBreakPoint", "params": {"address": addr, "flag": flag}})
@check_server_available
def del_mem_breakpoint(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "DelMemBreakPoint", "params": {"address": addr}})
@check_server_available
def set_api_breakpoint(self, dll: str, api: str) -> str:
return self.custom_post({"interface": "SetApiBreakPoint", "params": {"dll": dll, "api": api}})
@check_server_available
def del_api_breakpoint(self, dll: str, api: str) -> str:
return self.custom_post({"interface": "DelApiBreakPoint", "params": {"dll": dll, "api": api}})
@check_server_available
def disable_breakpoint(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "DisableBreakpoint", "params": {"address": addr}})
@check_server_available
def enable_breakpoint(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "EnableBreakpoint", "params": {"address": addr}})
@check_server_available
def breakpoint_command(self, address: Union[int, str], command: str = "") -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "BreakpointCommand", "params": {"address": addr, "command": command}})
class DebugSessionApi(BaseHttpClient):
"""会话管理:启动调试、停止、分离、dump"""
@check_server_available
def debug(self, path: str, args: str = "", cwd: str = "") -> str:
return self.custom_post({"interface": "Debug", "params": {"path": path, "args": args, "cwd": cwd}})
@check_server_available
def set_debug(self, command: str = "Logs") -> str:
return self.custom_post({"interface": "SetDebug", "params": command})
@check_server_available
def stop(self) -> str:
return self.custom_post({"interface": "Stop", "params": {}})
@check_server_available
def detach(self) -> str:
return self.custom_post({"interface": "Detach", "params": {}})
@check_server_available
def restart(self) -> str:
return self.custom_post({"interface": "Restart", "params": {}})
@check_server_available
def dump_process(self, path: str, base: Union[int, str], size: int) -> str:
base_addr = validate_hex_address(base)
return self.custom_post({"interface": "DumpProcess", "params": {"path": path, "base": base_addr, "size": size}})
@check_server_available
def minidump(self, path: str) -> str:
return self.custom_post({"interface": "minidump", "params": {"path": path}})
@check_server_available
def status(self) -> str:
return self.custom_post({"interface": "Status", "params": {}})
class RegisterThreadApi(BaseHttpClient):
"""寄存器、线程操作"""
@check_server_available
def register(self) -> str:
return self.custom_post({"interface": "Register", "params": {}})
@check_server_available
def set_register(self, reg: str, value: str) -> str:
return self.custom_post({"interface": "SetRegister", "params": {"reg": reg, "value": value}})
@check_server_available
def threads(self) -> str:
return self.custom_post({"interface": "Threads", "params": {}})
@check_server_available
def thread_info(self, tid: int) -> str:
return self.custom_post({"interface": "ThreadInfo", "params": {"tid": tid}})
@check_server_available
def get_active_thread(self) -> str:
return self.custom_post({"interface": "GetActiveThread", "params": {}})
@check_server_available
def set_active_thread(self, tid: int) -> str:
return self.custom_post({"interface": "SetActiveThread", "params": {"tid": tid}})
@check_server_available
def get_thread_last_error(self, tid: int) -> str:
return self.custom_post({"interface": "GetThreadLastError", "params": {"tid": tid}})
@check_server_available
def get_thread_priority(self, tid: int) -> str:
return self.custom_post({"interface": "GetThreadPriority", "params": {"tid": tid}})
@check_server_available
def set_thread_priority(self, tid: int, priority: str = "NORMAL") -> str:
return self.custom_post({"interface": "SetThreadPriority", "params": {"tid": tid, "priority": priority}})
@check_server_available
def set_thread_name(self, tid: int, name: str) -> str:
return self.custom_post({"interface": "SetThreadName", "params": {"tid": tid, "name": name}})
@check_server_available
def set_flag(self, flag: str, value: int) -> str:
return self.custom_post({"interface": "SetFlag", "params": {"flag": flag, "value": value}})
class ModulePeApi(BaseHttpClient):
"""模块、PE、导入导出、符号"""
@check_server_available
def modules(self) -> str:
return self.custom_post({"interface": "Modules", "params": {}})
@check_server_available
def module_info(self, module: str) -> str:
return self.custom_post({"interface": "ModuleInfo", "params": {"module": module}})
@check_server_available
def sections(self, module: str) -> str:
return self.custom_post({"interface": "Sections", "params": {"module": module}})
@check_server_available
def pe_info(self, path: str) -> str:
return self.custom_post({"interface": "PEInfo", "params": {"path": path}})
@check_server_available
def rich_header(self, module: str) -> str:
return self.custom_post({"interface": "RichHeader", "params": {"module": module}})
@check_server_available
def tls_callbacks(self, module: str) -> str:
return self.custom_post({"interface": "TLSCallbacks", "params": {"module": module}})
@check_server_available
def relocation_list(self, module: str) -> str:
return self.custom_post({"interface": "RelocationList", "params": {"module": module}})
@check_server_available
def debug_directory(self, module: str) -> str:
return self.custom_post({"interface": "DebugDirectory", "params": {"module": module}})
@check_server_available
def import_list(self, module: str) -> str:
return self.custom_post({"interface": "ImportList", "params": {"module": module}})
@check_server_available
def export_list(self, module: str) -> str:
return self.custom_post({"interface": "ExportList", "params": {"module": module}})
@check_server_available
def get_import_address(self, module: str, name: str) -> str:
return self.custom_post({"interface": "GetImportAddress", "params": {"module": module, "name": name}})
@check_server_available
def get_export_address(self, module: str, name: str) -> str:
return self.custom_post({"interface": "GetExportAddress", "params": {"module": module, "name": name}})
@check_server_available
def gpa(self, dll: str, api: str) -> str:
return self.custom_post({"interface": "gpa", "params": {"dll": dll, "api": api}})
@check_server_available
def addr_to_module(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "AddrToModule", "params": {"address": addr}})
@check_server_available
def get_section_data(self, module: str, name: str) -> str:
return self.custom_post({"interface": "GetSectionData", "params": {"module": module, "name": name}})
@check_server_available
def get_section_info(self, module: str, name: str) -> str:
return self.custom_post({"interface": "GetSectionInfo", "params": {"module": module, "name": name}})
@check_server_available
def symbol(self, expr: str) -> str:
return self.custom_post({"interface": "Symbol", "params": {"expr": expr}})
@check_server_available
def get_symbol_info(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "GetSymbolInfo", "params": {"address": addr}})
@check_server_available
def get_function_size(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "GetFunctionSize", "params": {"address": addr}})
@check_server_available
def heaps(self) -> str:
return self.custom_post({"interface": "Heaps", "params": {}})
@check_server_available
def handles(self, max_num: int = 20) -> str:
return self.custom_post({"interface": "Handles", "params": {"max": max_num}})
@check_server_available
def seh_list(self) -> str:
return self.custom_post({"interface": "SEHList", "params": {}})
class MemoryApi(BaseHttpClient):
"""内存读写、搜索、补丁、内存分配"""
@check_server_available
def memory_info(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "MemoryInfo", "params": {"address": addr}})
@check_server_available
def regions(self) -> str:
return self.custom_post({"interface": "Regions", "params": {}})
@check_server_available
def memory(self, address: Union[int, str], size: int = 16) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "Memory", "params": {"address": addr, "size": size}})
@check_server_available
def read_memory_value(self, address: Union[int, str], size: int = 4) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "ReadMemoryValue", "params": {"address": addr, "size": size}})
@check_server_available
def write_memory(self, address: Union[int, str], hex_: str) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "WriteMemory", "params": {"address": addr, "hex": hex_}})
@check_server_available
def get_page_rights(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "GetPageRights", "params": {"address": addr}})
@check_server_available
def set_page_rights(self, address: Union[int, str], protect: str) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetPageRights", "params": {"address": addr, "protect": protect}})
@check_server_available
def set_page_memory(self, address: Union[int, str], protect: str) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetPageMemory", "params": {"address": addr, "protect": protect}})
@check_server_available
def allocate_memory(self, size: int) -> str:
return self.custom_post({"interface": "AllocateMemory", "params": {"size": size}})
@check_server_available
def free_memory(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "FreeMemory", "params": {"address": addr}})
@check_server_available
def set_memory(self, address: Union[int, str], hex_: str) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SetMemory", "params": {"address": addr, "hex": hex_}})
@check_server_available
def fill_memory(self, address: Union[int, str], size: int, value: str) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "FillMemory", "params": {"address": addr, "size": size, "value": value}})
@check_server_available
def memcpy(self, src: Union[int, str], dst: Union[int, str], size: int) -> str:
src_a = validate_hex_address(src)
dst_a = validate_hex_address(dst)
return self.custom_post({"interface": "Memcpy", "params": {"src": src_a, "dst": dst_a, "size": size}})
@check_server_available
def va_to_file_offset(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "VaToFileOffset", "params": {"address": addr}})
@check_server_available
def file_offset_to_va(self, offset: str) -> str:
return self.custom_post({"interface": "FileOffsetToVa", "params": {"offset": offset}})
@check_server_available
def get_string(self, address: Union[int, str], max_num: int = 64, type_: str = "ascii") -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "GetString", "params": {"address": addr, "max": max_num, "type": type_}})
@check_server_available
def search_memory(self, pattern: str, start: Union[int, str], size: int) -> str:
s = validate_hex_address(start)
return self.custom_post({"interface": "SearchMemory", "params": {"pattern": pattern, "start": s, "size": size}})
@check_server_available
def search_all_memory(self, pattern: str, max_num: int = 5) -> str:
return self.custom_post({"interface": "SearchAllMemory", "params": {"pattern": pattern, "max": max_num}})
@check_server_available
def search_strings(self, address: Union[int, str], size: int) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "SearchStrings", "params": {"address": addr, "size": size}})
@check_server_available
def match_pattern(self, address: Union[int, str], pattern: str, size: int) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "MatchPattern", "params": {"address": addr, "pattern": pattern, "size": size}})
@check_server_available
def hash_memory(self, address: Union[int, str], size: int, algo: str = "md5") -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "HashMemory", "params": {"address": addr, "size": size, "algo": algo}})
@check_server_available
def patch_memory(self, address: Union[int, str], hex_: str) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "PatchMemory", "params": {"address": addr, "hex": hex_}})
@check_server_available
def patches(self) -> str:
return self.custom_post({"interface": "Patches", "params": {}})
@check_server_available
def revert_patch(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "RevertPatch", "params": {"address": addr}})
@check_server_available
def delete_patch(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "DeletePatch", "params": {"address": addr}})
class DisasmXrefApi(BaseHttpClient):
"""反汇编、汇编、交叉引用"""
@check_server_available
def disassemble_at(self, address: Union[int, str], count: int = 5) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "DisassembleAt", "params": {"address": addr, "count": count}})
@check_server_available
def dissasembler(self, address: Union[int, str], count: int = 5) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "Dissasembler", "params": {"address": addr, "count": count}})
@check_server_available
def get_opcode_size(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "GetOpcodeSize", "params": {"address": addr}})
@check_server_available
def mnemonicbrief(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "mnemonicbrief", "params": {"address": addr}})
@check_server_available
def get_branch_target(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "GetBranchTarget", "params": {"address": addr}})
@check_server_available
def assemble(self, instr: str, cip: Union[int, str]) -> str:
c = validate_hex_address(cip)
return self.custom_post({"interface": "Assemble", "params": {"instr": instr, "cip": c}})
@check_server_available
def assemble_at(self, address: Union[int, str], instr: str) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "AssembleAt", "params": {"address": addr, "instr": instr}})
@check_server_available
def xrefs(self, address: Union[int, str], max_num: int = 5) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "xrefs", "params": {"address": addr, "max": max_num}})
@check_server_available
def find_ref(self, address: Union[int, str], max_num: int = 5) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "FindRef", "params": {"address": addr, "max": max_num}})
class StackTraceApi(BaseHttpClient):
"""栈、调用栈、追踪记录"""
@check_server_available
def call_stack(self, max_num: int = 16) -> str:
return self.custom_post({"interface": "CallStack", "params": {"max": max_num}})
@check_server_available
def stack(self, count: int = 8) -> str:
return self.custom_post({"interface": "Stack", "params": {"count": count}})
@check_server_available
def stack_push(self, value: str) -> str:
return self.custom_post({"interface": "StackPush", "params": {"value": value}})
@check_server_available
def stack_pop(self) -> str:
return self.custom_post({"interface": "StackPop", "params": {}})
@check_server_available
def stack_peek(self, offset: int = 0) -> str:
return self.custom_post({"interface": "StackPeek", "params": {"offset": offset}})
@check_server_available
def start_trace_record(self) -> str:
return self.custom_post({"interface": "StartTraceRecord", "params": {}})
@check_server_available
def get_trace_record(self, count: int = 5) -> str:
return self.custom_post({"interface": "GetTraceRecord", "params": {"count": count}})
@check_server_available
def stop_trace_record(self) -> str:
return self.custom_post({"interface": "StopTraceRecord", "params": {}})
@check_server_available
def jmp_history(self) -> str:
return self.custom_post({"interface": "JmpHistory", "params": {}})
@check_server_available
def last_exception(self) -> str:
return self.custom_post({"interface": "LastException", "params": {}})
@check_server_available
def eval_expr(self, expr: str) -> str:
return self.custom_post({"interface": "Eval", "params": {"expr": expr}})
@check_server_available
def show_debugger(self) -> str:
return self.custom_post({"interface": "ShowDebugger", "params": {}})
@check_server_available
def hide_debugger(self) -> str:
return self.custom_post({"interface": "HideDebugger", "params": {}})
class ExecutionControlApi(BaseHttpClient):
"""执行控制:运行、单步、暂停、run_to"""
@check_server_available
def run(self) -> str:
return self.custom_post({"interface": "Run", "params": {}})
@check_server_available
def pause(self) -> str:
return self.custom_post({"interface": "Pause", "params": {}})
@check_server_available
def e_run(self) -> str:
return self.custom_post({"interface": "ERun", "params": {}})
@check_server_available
def se_run(self) -> str:
return self.custom_post({"interface": "SERun", "params": {}})
@check_server_available
def step_in(self) -> str:
return self.custom_post({"interface": "StepIn", "params": {}})
@check_server_available
def step_over(self) -> str:
return self.custom_post({"interface": "StepOver", "params": {}})
@check_server_available
def step_out(self) -> str:
return self.custom_post({"interface": "StepOut", "params": {}})
@check_server_available
def e_step_into(self) -> str:
return self.custom_post({"interface": "EStepInto", "params": {}})
@check_server_available
def e_step_over(self) -> str:
return self.custom_post({"interface": "EStepOver", "params": {}})
@check_server_available
def e_step_out(self) -> str:
return self.custom_post({"interface": "EStepOut", "params": {}})
@check_server_available
def step_user(self) -> str:
return self.custom_post({"interface": "StepUser", "params": {}})
@check_server_available
def step_system(self) -> str:
return self.custom_post({"interface": "StepSystem", "params": {}})
@check_server_available
def skip(self, count: int = 1) -> str:
return self.custom_post({"interface": "Skip", "params": {"count": count}})
@check_server_available
def instr_undo(self) -> str:
return self.custom_post({"interface": "InstrUndo", "params": {}})
@check_server_available
def execute_command(self, command: str) -> str:
return self.custom_post({"interface": "ExecuteCommand", "params": command})
@check_server_available
def trace_into(self, count: int = 3) -> str:
return self.custom_post({"interface": "TraceInto", "params": {"count": count}})
@check_server_available
def trace_over(self, count: int = 3) -> str:
return self.custom_post({"interface": "TraceOver", "params": {"count": count}})
@check_server_available
def trace_line(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "TraceLine", "params": {"address": addr}})
@check_server_available
def run_to(self, address: Union[int, str]) -> str:
addr = validate_hex_address(address)
return self.custom_post({"interface": "RunTo", "params": {"address": addr}})
@check_server_available
def run_to_user_code(self) -> str:
return self.custom_post({"interface": "RunToUserCode", "params": {}})
@check_server_available
def debug_continue(self, status: int = 0) -> str:
return self.custom_post({"interface": "DebugContinue", "params": {"status": status}})
@check_server_available
def pause_all_threads(self) -> str:
return self.custom_post({"interface": "PauseAllThreads", "params": {}})
@check_server_available
def resume_all_threads(self) -> str:
return self.custom_post({"interface": "ResumeAllThreads", "params": {}})
@check_server_available
def thread_pause(self, tid: int) -> str:
return self.custom_post({"interface": "ThreadPause", "params": {"tid": tid}})
@check_server_available
def thread_resume(self, tid: int) -> str:
return self.custom_post({"interface": "ThreadResume", "params": {"tid": tid}})
@check_server_available
def animate_into(self, count: int = 3) -> str:
return self.custom_post({"interface": "AnimateInto", "params": {"count": count}})
@check_server_available
def animate_over(self, count: int = 3) -> str:
return self.custom_post({"interface": "AnimateOver", "params": {"count": count}})
@check_server_available
def animate_stop(self) -> str:
return self.custom_post({"interface": "AnimateStop", "params": {}})
# 统一入口类 把所有API聚合在一起
class BinSentryClient(
SystemApi,
LogConfigApi,
SymbolVarApi,
BreakPointApi,
DebugSessionApi,
RegisterThreadApi,
ModulePeApi,
MemoryApi,
DisasmXrefApi,
StackTraceApi,
ExecutionControlApi
):
def __init__(self, config: Optional[Config] = None):
super().__init__(config)
调用接口测试
from binsentry import BinSentryClient, Config
if __name__ == "__main__":
cfg = Config(address="127.0.0.1", port=6891)
client = BinSentryClient(cfg)
# 获取状态
resp = client.status()
print(resp)
# 设置断点,支持数字int或者字符串地址
resp = client.set_breakpoint(0x401000)
print(resp)
输出内容:
{"status":"success","result":{"sessionActive":false,"mode":"None","pid":0,"tid":0,"stopped":false,"firstRun":true,"softBreakpoints":0,"memoryBreakpoints":0,"
hardwareBreakpoints":0,"apiBreakpoints":0,"labels":0,"comments":0,"logCount":0,"watches":0,"bookmarks":0,"variables":0,"traceActive":false,"traceIntoActive":
false,"traceResult":"","interfaces":[{"interface":"Debug","usage":"启动调试会话: params.path = 进程路径"},{"interface":"Attach","usage":"附加进程: params.pid
= 进程ID"},{"interface":"Detach","usage":"分离调试会话"},{"interface":"Stop","usage":"终止被调试进程"},{"interface":"Status","usage":"查询调试器状态(含接口
列表)"},{"interface":"WaitStop","usage":"等待调试器停止: params.timeout = 超时秒数(默认60)"},{"interface":"Run","usage":"继续运行程序"},{"interface":"StepIn"
,"usage":"单步步入"},{"interface":"StepOver","usage":"单步步过"},{"interface":"StepOut","usage":"单步步出"},{"interface":"SetBreakPoint","usage":"设置软件断
点: address, thread(可选), temp(可选)"},{"interface":"DelBreakPoint","usage":"删除软件断点: address"},{"interface":"ShowBreakPoint","usage":"显示软件断点列表
"},{"interface":"SetMemBreakPoint","usage":"设置内存断点: address, flag(r/w/e)"},{"interface":"DelMemBreakPoint","usage":"删除内存断点: address"},{"interface
":"ShowMemBreakPoint","usage":"显示内存断点列表"},{"interface":"SetHbreakPoint","usage":"设置硬件断点: address, len(1/2/4), flag(r/w/e)"},{"interface":"DelHb
reakPoint","usage":"删除硬件断点: dr(可选, 默认全部)"},{"interface":"ShowHbreakPoint","usage":"显示硬件断点列表"},{"interface":"SetApiBreakPoint","usage":"设
置API断点: dll, api(可选--end为函数返回处)"},{"interface":"DelApiBreakPoint","usage":"删除API断点: dll, api(可选--end)"},{"interface":"ShowApiBreakPoint","us
age":"显示API断点列表"},{"interface":"SearchMemory","usage":"搜索内存: pattern(hex, ?=通配), start(可选), size(可选)"},{"interface":"PatchMemory","usage":"内
存补丁: address, hex(字节串), nop(可选)"},{"interface":"DumpProcess","usage":"转储进程(脱壳): path, entry(可选)"},{"interface":"HideDebugger","usage":"隐藏调
试器(CheckRemoteDebuggerPresent等)"},{"interface":"ShowDebugger","usage":"恢复调试器可见"},{"interface":"ThreadPause","usage":"暂停线程: tid"},{"interface":"
ThreadResume","usage":"恢复线程: tid"},{"interface":"PauseAllThreads","usage":"暂停所有线程"},{"interface":"ResumeAllThreads","usage":"恢复所有线程"},{"inter
face":"PEInfo","usage":"PE文件信息: path"},{"interface":"Register","usage":"显示寄存器"},{"interface":"SetRegister","usage":"修改寄存器: reg(eax/ebx/...), va
lue"},{"interface":"Stack","usage":"显示栈: count(可选)"},{"interface":"Memory","usage":"显示内存: address, size(可选)"},{"interface":"SetMemory","usage":"修
改内存: address, value"},{"interface":"Dissasembler","usage":"反汇编: address(可选, 默认EIP), size(可选)"},{"interface":"Modules","usage":"显示模块列表"},{"i
nterface":"Threads","usage":"显示线程列表"},{"interface":"SetDebug","usage":"执行调试命令字符串: params = \"命令行\" 或 {command: \"命令行\"}"},{"interface":
"ProcessList","usage":"进程列表: filter(可选, 名称模糊过滤)"},{"interface":"Regions","usage":"内存区域列表(VirtualQueryEx)"},{"interface":"CallStack","usage"
:"调用栈: count(可选, 默认32, StackWalk64+符号)"},{"interface":"SearchStrings","usage":"搜索进程字符串: max(可选, 默认100, ASCII+Unicode)"},{"interface":"Fil
lMemory","usage":"内存填充: address, size, value (FillEx)"},{"interface":"SetCondBreakPoint","usage":"设置条件断点: address, cond(表达式, 如 \"eax == 0x5\"),
thread(可选)"},{"interface":"DelCondBreakPoint","usage":"清除断点条件: address (转为普通断点)"},{"interface":"SetLabel","usage":"设置标签: address, name"},{
"interface":"DelLabel","usage":"删除标签: address"},{"interface":"GetLabels","usage":"显示标签列表"},{"interface":"SetComment","usage":"设置注释: address, te
xt"},{"interface":"DelComment","usage":"删除注释: address"},{"interface":"GetComments","usage":"显示注释列表"},{"interface":"Logs","usage":"查询调试日志: cou
nt(可选, 默认50)"},{"interface":"Eval","usage":"表达式求值: expr(寄存器/0x十六进制/十进制/运算, 需停止态)"},{"interface":"SetFlag","usage":"设置标志位: flag(
CF PF AF ZF SF TF IF DF OF), value(0/1)"},{"interface":"GetBranchTarget","usage":"分支指令目标地址: address (GetJumpDestinationEx)"},{"interface":"GetArgumen
ts","usage":"参数标记列表"},{"interface":"AddArgument","usage":"添加参数标记: start, end(可选), name(可选)"},{"interface":"DelArgument","usage":"删除参数标记
: start"},{"interface":"RevertPatch","usage":"还原补丁: address(恢复原字节并移除记录)"},{"interface":"DeletePatch","usage":"删除补丁记录: address(不写内存)"}
,{"interface":"ReadMemoryValue","usage":"读数值: address, size(1/2/4/8)"},{"interface":"GetThreadPriority","usage":"读线程优先级: tid"},{"interface":"SystemI
nfo","usage":"系统信息(架构/页大小/CPU/内存/OS版本)"},{"interface":"GetSectionInfo","usage":"指定节详情: module, name"},{"interface":"GetBreakpointInfo","usa
ge":"指定地址断点详情: address (软/内存/硬件)"},{"interface":"InjectDll","usage":"远程注入DLL: path (LoadLibraryA+CreateRemoteThread)"},{"interface":"HashMem
ory","usage":"内存哈希: address, size, algo(可选 md5/sha1/crc32)"},{"interface":"AddrToModule","usage":"地址归属模块: address (模块名+基址+RVA)"},{"interface
":"RunTo","usage":"运行到目标地址: address (临时断点, 命中自动移除)"},{"interface":"SetExceptionIgnore","usage":"设置异常忽略: code, ignore(0/1; 断点/单步不
可忽略)"},{"interface":"GetExceptionSettings","usage":"异常忽略列表"},{"interface":"StartTraceRecord","usage":"开始执行足迹记录(每次停止记录EIP, 上限4096)"},
{"interface":"StopTraceRecord","usage":"停止执行足迹记录"},{"interface":"GetTraceRecord","usage":"执行足迹列表"},{"interface":"GetImportAddress","usage":"导
入函数IAT地址: module, name (或 #序号)"},{"interface":"GetSectionData","usage":"节内容转储: module, name (hex, 限4KB)"},{"interface":"TraceOver","usage":"步
过跟踪: count(步数,可选), condition(表达式,可选); call 自动跳过"},{"interface":"LoadLibrary","usage":"目标进程远程加载DLL: path (返回 moduleHandle)"},{"inter
face":"FreeLibrary","usage":"目标进程远程卸载DLL: handle (LoadLibrary 返回值)"},{"interface":"gpa","usage":"远程API地址解析: dll, api 或 expr(模块:函数)"},{"
interface":"VaToFileOffset","usage":"虚拟地址->文件偏移: address"},{"interface":"FileOffsetToVa","usage":"文件偏移->虚拟地址: offset, module(可选,默认主模块)
"},{"interface":"GetPageRights","usage":"页权限查询: address (返回 rights 如 RX/RWX)"},{"interface":"SetPageRights","usage":"页权限修改: address, protect(hex
或RWX串)"},{"interface":"minidump","usage":"生成目标进程转储: path (.dmp, 含全内存)"},{"interface":"xrefs","usage":"代码引用查找: address, max(可选)"},{"inte
rface":"mnemonicbrief","usage":"指令助记符简介: address(可选,默认EIP)"},{"interface":"EnumWindows","usage":"枚举目标进程窗口: pid(可选,默认会话进程)"},{"inte
rface":"IsProcessElevated","usage":"进程提权检查: pid(可选,默认本进程)"},{"interface":"ClearLog","usage":"清空调试日志缓冲区"},{"interface":"SaveLog","usage"
:"保存日志到文件: path"},{"interface":"EnumErrorCodes","usage":"常见Win32错误码表: code(可选过滤)"},{"interface":"EnumExceptions","usage":"常见异常码表: code
(可选过滤)"},{"interface":"GetFunctionSize","usage":"函数边界: address (函数表优先, 反汇编扫描兜底)"},{"interface":"BreakpointCommand","usage":"断点命令: add
ress, command (命中时自动入队执行; 空清除)"},{"interface":"JmpHistory","usage":"跳转历史(恢复运行前记录分支指令)"},{"interface":"GetSymbolInfo","usage":"符号
详情: address (dbghelp: 名称/模块/偏移/行号)"},{"interface":"TCPConnections","usage":"目标进程 TCP 连接列表"},{"interface":"StackPush","usage":"栈压入: value
(ESP-4 写入)"},{"interface":"StackPop","usage":"栈弹出(读栈顶+ESP+4)"},{"interface":"StackPeek","usage":"栈窥视: offset (ESP+offset*4)"},{"interface":"SetTh
readName","usage":"线程命名: tid, name (SetThreadDescription)"},{"interface":"Restart","usage":"重启目标进程(分离旧会话并重新创建)"},{"interface":"SetJIT","u
sage":"设置系统JIT调试器: path (HKLM AeDebug, 需管理员)"},{"interface":"GetJIT","usage":"查询当前JIT调试器"},{"interface":"TraceLine","usage":"单步跟踪到目标
地址: address, timeout(可选, 秒)"},{"interface":"Handles","usage":"句柄列表: max(可选, NtQuerySystemInformation+对象名)"},{"interface":"FindRef","usage":"查
找引用: address(目标地址), max(可选, 反汇编扫描代码区)"},{"interface":"SearchAllMemory","usage":"全内存搜索: pattern(hex, ?=通配), max(可选)"},{"interface":"
ExportList","usage":"模块导出表: module(模块名)"},{"interface":"SetWatch","usage":"添加/更新监视: name, expr(表达式, 含 $变量)"},{"interface":"DelWatch","usa
ge":"删除监视: id 或 name"},{"interface":"GetWatches","usage":"查询监视(实时求值, 需停止态)"},{"interface":"SetVar","usage":"设置用户变量: name, value (表达
式 $name 引用)"},{"interface":"DelVar","usage":"删除用户变量: name"},{"interface":"GetVars","usage":"查询用户变量列表"},{"interface":"SetBookMark","usage":"
添加书签: address"},{"interface":"DelBookMark","usage":"删除书签: address"},{"interface":"GetBookMarks","usage":"查询书签列表"},{"interface":"Assemble","usag
e":"汇编指令为字节码(XEDParse): instr, cip(可选)"},{"interface":"AssembleAt","usage":"汇编并写入目标进程: address, instr, fillnop(可选)"},{"interface":"Enabl
eBreakpoint","usage":"启用软断点: address"},{"interface":"DisableBreakpoint","usage":"禁用软断点: address"},{"interface":"SetThreadPriority","usage":"设置线
程优先级: tid, priority(数值或名称)"},{"interface":"Memcpy","usage":"进程内内存复制: src, dst, size"},{"interface":"AllocateMemory","usage":"目标进程分配内存
: size, protect(可选)"},{"interface":"FreeMemory","usage":"释放目标进程内存: address"},{"interface":"Symbol","usage":"符号解析(模块名+偏移 或 表达式): expr"}
,{"interface":"MemoryInfo","usage":"地址内存信息(区域/保护/模块归属): address"},{"interface":"IsValidPointer","usage":"地址是否可读: address"},{"interface":"
LastException","usage":"最近一次异常信息"},{"interface":"Pause","usage":"暂停运行中的程序(DebugBreakProcess)"},{"interface":"CreateRemoteThread","usage":"目
标进程创建远程线程: start 或 hex(shellcode), param(可选)"},{"interface":"TerminateThread","usage":"结束线程: tid"},{"interface":"GetThreadLastError","usage":
"读取线程 TEB.LastErrorValue: tid"},{"interface":"WriteMemory","usage":"按 hex 字节串写内存: address, hex"},{"interface":"GetString","usage":"读取内存字符串:
address, max(可选), type(ascii/unicode)"},{"interface":"GetOpcodeSize","usage":"指令长度: address (LengthDisassembleEx)"},{"interface":"Functions","usage":"
函数标记列表"},{"interface":"AddFunction","usage":"添加函数标记: start, end(可选), name(可选)"},{"interface":"DelFunction","usage":"删除函数标记: start"},{"i
nterface":"ProcessInfo","usage":"进程详细信息: pid(可选, 默认会话进程)"},{"interface":"GetExportAddress","usage":"模块导出函数地址: module, name 或 ordinal"}
,{"interface":"Help","usage":"显示帮助"}]},"timestamp":4107265}