edr绕过工具 SysWhispers4 源码分析系列(四)
官网:http://securitytech.cc
四、SysWhispers4 源码核心模块深度分析
本文档深入 SysWhispers4 源码内部,逐行分析核心模块的实现细节、数据流转过程、关键算法逻辑以及代码设计模式。通过本文档,你将完全理解这个强大工具的每一个技术细节。
1. 参数解析模块分析
1.1 argparse 架构设计
文件位置: syswhispers.py 第 108-280 行
核心类图:
ArgumentParser│├─ArgumentGroup:"Function selection"│├─--preset/-p│└─--functions/-f│├─ArgumentGroup:"Target"│├─--arch/-a│└─--compiler/-c│├─ArgumentGroup:"Techniques"│├─--method/-m│└─--resolve/-r│├─ArgumentGroup:"Evasion / obfuscation"│├─--obfuscate│├─--encrypt-ssn│├─--stack-spoof│├─--etw-bypass│├─--amsi-bypass│├─--unhook-ntdll│├─--anti-debug│└─--sleep-encrypt│├─ArgumentGroup:"Output"│├─--prefix│├─--out-file/-o│└─--out-dir│└─Misc arguments├─--list-functions├─--list-presets└─--verbose/-v
1.2 详细实现代码
build_parser() 函数完整分析
# syswhispers.py 第 108-280 行def build_parser()-> argparse.ArgumentParser:"""构建命令行参数解析器设计原则:1. 分组清晰:相关参数归类到同一组2. 默认值合理:每个参数都有合理的默认行为3. 帮助信息详细:epilog 包含完整的使用说明4. 易扩展:新增功能只需添加对应参数"""p = argparse.ArgumentParser(prog="syswhispers.py",description="SysWhispers4 -- NT syscall stub generator with advanced EDR evasion",formatter_class=argparse.RawDescriptionHelpFormatter,# epilog 包含详细的使用说明,帮助用户理解各种选项epilog="""Resolution methods:static Embed SSNs from bundled j00ru table (run update_syscall_table.py first)freshycalls Sort ntdll Nt* exports by VA -> index = SSN [DEFAULT, hook-resistant]hells_gate Read SSN from ntdll stub (fails if hooked)halos_gate Hell's Gate + neighbor scan to handle hooked functionstartarus Tartarus' Gate: handles near JMP (E9) and far JMP (FF 25) hooksfrom_disk Load clean ntdll from \\KnownDlls and read SSNs (bypasses ALL hooks)recycled RecycledGate: FreshyCalls + opcode cross-validation (most resilient)hw_breakpoint Hardware breakpoints + VEH to extract SSN (advanced)Invocation methods:embedded syscall instruction in our stub -- direct syscall [DEFAULT]indirect jmp to syscall;ret gadget inside ntdll (RIP appears in ntdll)randomized jmp to a RANDOM syscall;ret gadget in ntdll per call (anti-RIP)egg 8-byte egg marker replaced at runtime -- no static syscall bytesPresets:common General process/thread/memory operations (25 functions)injection Process/shellcode injection via APC, threads, sections (20 functions)evasion AV/EDR evasion queries and operations (15 functions)token Token manipulation (6 functions)stealth Maximum evasion: injection + evasion + unhooking (31 functions)file_ops File I/O via NT syscalls (7 functions)transaction Process doppelganging / transaction rollback (7 functions)all All supported functions (62 functions)""",)# ================================================================# 1. 函数选择参数组 - 决定生成哪些 syscall 的存根# ================================================================sel = p.add_argument_group("Function selection (at least one required)")sel.add_argument("-p","--preset",metavar="PRESET[,PRESET...]",help="Preset: common, injection, evasion, token, stealth, file_ops, transaction, all",# 支持多个预设组合:--preset common,injection# 类型:str,后续需要手动分割)sel.add_argument("-f","--functions",metavar="FUNC[,FUNC...]",help="Comma-separated list of NT function names",# 支持自定义函数列表:--functions NtAllocateVirtualMemory,NtCreateThreadEx# 类型:str,后续需要手动分割和验证)# 业务逻辑:至少需要一个预设或自定义函数# 验证在 main() 中进行:if not args.preset and not args.functions# ================================================================# 2. 目标架构/编译器参数组 - 决定生成的代码格式# ================================================================tgt = p.add_argument_group("Target")tgt.add_argument("-a","--arch",choices=[a.value for a inArchitecture],# 从枚举类获取合法值default=Architecture.x64.value,# 默认 x64metavar="ARCH",help="Target architecture: x64 (default), x86, wow64, arm64",# 架构选择影响:# - x64: 使用 syscall 指令# - x86: 使用 sysenter 指令# - WoW64: Heaven's Gate 技术# - ARM64: 使用 SVC #0 指令)tgt.add_argument("-c","--compiler",choices=[c.value for c inCompiler],# msvc, mingw, clangdefault=Compiler.MSVC.value,# 默认 MSVCmetavar="COMPILER",help="Compiler: msvc (default, MASM), mingw (GAS inline), clang (GAS inline)",# 编译器选择影响:# - MSVC: 生成 .asm 文件,使用 MASM 语法# - MinGW/Clang: 生成 _stubs.c 文件,使用 GAS 内联汇编)# ================================================================# 3. 技术参数组 - 核心绕过技术选择# ================================================================tech = p.add_argument_group("Techniques")tech.add_argument("-m","--method",choices=[m.value for m inInvocationMethod],default=InvocationMethod.Embedded.value,# 默认直接 syscallmetavar="METHOD",help="Invocation: embedded (default), indirect, randomized, egg",# 调用方法详解:# - embedded: 我们自己的存根中包含 syscall 指令# - indirect: 跳转到 ntdll 中的 syscall;ret gadget# - randomized: 随机选择 ntdll 中的 syscall gadget(反 RIP 追踪)# - egg: 使用 egg marker,运行时替换为 syscall 指令)tech.add_argument("-r","--resolve",choices=[r.value for r inResolutionMethod],default=ResolutionMethod.FreshyCalls.value,# 默认 FreshyCallsmetavar="RESOLVE",help="SSN resolution: freshycalls (default), static, hells_gate, halos_gate, ""tartarus, from_disk, recycled, hw_breakpoint",# SSN 解析方法详解:# - static: 使用内置的 j00ru SSN 表(生成时确定)# - freshycalls: 运行时按地址排序 ntdll 导出函数# - hells_gate: 读取 ntdll stub 的 opcode 字节# - halos_gate: hells_gate + 邻居扫描(±8)# - tartarus: 增强版(±16 + 多种 Hook 检测)# - from_disk: 从 KnownDlls 加载干净 ntdll# - recycled: freshycalls + opcode 验证# - hw_breakpoint: 硬件断点 + VEH)# ================================================================# 4. 规避/混淆选项参数组 - 高级 EDR 绕过技术# ================================================================eva = p.add_argument_group("Evasion / obfuscation")eva.add_argument("--obfuscate",action="store_true",# 布尔标志,提供即启用help="Randomize stub ordering and inject junk instructions",# 混淆效果:# 1. 随机打乱函数顺序(增加静态分析难度)# 2. 注入垃圾指令(nop, xchg, lea 等无害指令)# 3. 随机化函数名前缀)eva.add_argument("--encrypt-ssn",action="store_true",help="XOR-encrypt SSN values at rest (decrypted at runtime)",# SSN 加密原理:# 1. 生成随机 XOR 密钥(32 位)# 2. 编译时:encrypted_ssn = ssn ^ key# 3. 运行时:ssn = encrypted_ssn ^ key# 4. 防止静态分析工具识别 SSN 值)eva.add_argument("--stack-spoof",action="store_true",help="Include synthetic call stack frame helper (reduces stack anomaly)",# 栈伪造技术:# 1. 在 syscall 前伪造返回地址# 2. 使调用栈看起来像正常的函数调用# 3. 避免栈回溯检测到异常)eva.add_argument("--etw-bypass",action="store_true",help="Include optional user-mode ETW writer patch (see SW4PatchEtw)",# ETW 绕过原理:# 1. 定位 ntdll!EtwEventWrite 函数# 2. 修改前几个字节为 "xor eax, eax; ret"# 3. 所有 ETW 日志返回 ACCESS_DENIED# 4. 用户态 ETW 完全失效)eva.add_argument("--amsi-bypass",action="store_true",help="Include AMSI bypass (patches AmsiScanBuffer)",# AMSI 绕过原理:# 1. 定位 amsi.dll!AmsiScanBuffer# 2. 修改为 "xor eax, eax; ret"# 3. 返回 E_INVALIDARG,让 AMSI 认为参数错误# 4. 如果 amsi.dll 未加载,直接返回成功)eva.add_argument("--unhook-ntdll",action="store_true",help="Include ntdll unhooking (remaps clean .text from KnownDlls)",# ntdll 解钩原理:# 1. 打开 \KnownDlls\ntdll.dll Section# 2. 映射到用户空间# 3. 复制干净 .text 段覆盖当前 ntdll 的 .text# 4. 所有 inline hook 被移除# 5. 后续调用都通过原始代码执行)eva.add_argument("--anti-debug",action="store_true",help="Include anti-debugging checks (PEB, timing, heap flags, debug port)",# 反调试检查包括:# 1. PEB.BeingDebugged 标志# 2. NtGlobalFlag (0x70)# 3. RDTSC 时间差检测# 4. ProcessDebugPort 查询# 5. 堆标志检查# 6. instrumentation callback 检测)eva.add_argument("--sleep-encrypt",action="store_true",help="Include sleep encryption (Ekko-style XOR .text during sleep)",# 睡眠加密原理(Ekko 技术):# 1. 生成随机 XOR 密钥# 2. 加密自己的 .text 段# 3. 设置可等待定时器# 4. 队列 APC 回调用于解密# 5. 进入 alertable sleep# 6. 定时器触发 → APC 执行 → 解密 .text → 继续执行# 7. 睡眠期间内存扫描只能看到加密数据)# ================================================================# 5. 静态表覆盖选项 - 允许用户使用自定义 SSN 表# ================================================================p.add_argument("--syscall-table",metavar="PATH",help="Path to custom syscall table JSON (for --resolve static)",# 使用场景:# 1. 研究特定 Windows 版本# 2. 测试新出现的 Windows 版本# 3. 使用自己整理的 SSN 数据库)# ================================================================# 6. 输出选项 - 控制生成文件的命名和位置# ================================================================out = p.add_argument_group("Output")out.add_argument("--prefix",default="SW4",metavar="PREFIX",help="Prefix for all generated identifiers (default: SW4)",# 前缀作用:# 1. 避免命名冲突# 2. 混淆时生成随机前缀# 3. 示例:SW4_NtAllocateVirtualMemory)out.add_argument("-o","--out-file",default=None,metavar="OUTFILE",help="Output filename base (default: <PREFIX>Syscalls)",# 默认值计算:# if args.out_file is None:# out_file = f"{prefix_clean}Syscalls")out.add_argument("--out-dir",default=".",metavar="OUTDIR",help="Output directory (default: current directory)",# 输出目录处理:# out_dir = Path(self.cfg.out_dir)# out_dir.mkdir(parents=True, exist_ok=True))# ================================================================# 7. 杂项参数 - 辅助功能# ================================================================p.add_argument("-v","--verbose",action="store_true",help="Verbose output",# 详细模式:# if args.verbose:# import traceback# traceback.print_exc())p.add_argument("--list-functions",action="store_true",help="Print all available function names and exit",# 列出所有支持的函数# proto = load_prototypes()# for name in sorted(proto):# print(f" {name}"))p.add_argument("--list-presets",action="store_true",help="Print all available presets and exit",# 列出所有预设配置# presets = load_presets()# for name, data in presets.items():# print(f" {name}: {data['description']}"))return p
1.3 参数验证与处理流程
resolvefunctions() – 函数列表展开
# syswhispers.py 第 57-80 行def _resolve_functions(args)-> list[str]:"""展开预设名称和/或逗号分隔的函数列表处理逻辑:1. 先处理预设(可能包含多个函数)2. 再处理自定义函数列表3. 去重并保持顺序返回值:唯一的函数名列表"""functions: list[str]=[]# ---- 步骤 1: 展开预设 ----if args.preset:# 加载所有预设定义presets = load_presets()# 支持多个预设组合:--preset common,injectionfor p in args.preset.split(","):p = p.strip()# 去除空白字符# 验证预设是否存在if p notin presets:print(f"[!] Unknown preset '{p}'. Available: {', '.join(presets)}")sys.exit(1)# 扩展预设包含的所有函数functions.extend(presets[p]["functions"])# extend 会将预设中的所有函数添加到列表# 例如:presets["common"]["functions"] 包含 25 个函数名# ---- 步骤 2: 添加自定义函数 ----if args.functions:# 支持自定义列表:--functions NtAlloc,NtCreatefor f in args.functions.split(","):f = f.strip()# 只添加不在已有列表中的函数(去重)if f and f notin functions:functions.append(f)# ---- 步骤 3: 去重并保持顺序 ----seen = set()result =[]for f in functions:if f notin seen:seen.add(f)# 添加到已见集合result.append(f)# 保留到结果列表return result
算法复杂度分析:
- 时间复杂度:O(n),其中 n 是总函数数
- 空间复杂度:O(n),使用 set 存储已见元素
- 性能优化:使用 set 实现 O(1) 查找
使用示例:
# 示例 1: 单个预设python syswhispers.py --preset common# 结果:functions = [25 个 common 预设中的函数]# 示例 2: 多个预设组合python syswhispers.py --preset common,injection# 结果:functions = [common 的 25 个] + [injection 的 20 个,去重后约 35 个]# 示例 3: 预设 + 自定义python syswhispers.py --preset common --functions NtQueryInformationProcess# 结果:functions = [common 的 25 个] + [NtQueryInformationProcess]# 示例 4: 多个自定义函数python syswhispers.py --functions NtAllocateVirtualMemory,NtCreateThreadEx# 结果:functions = ["NtAllocateVirtualMemory", "NtCreateThreadEx"]
validatefunctions() – 函数名验证
# syswhispers.py 第 83-91 行def _validate_functions(functions: list[str])->None:"""验证所有函数名是否存在于 prototypes.json 中验证策略:1. 加载已知函数原型字典2. 提取所有已知函数名3. 检查用户输入的函数是否在已知列表中4. 如果有未知函数,显示友好错误信息并退出"""# 加载所有已知函数原型known = set(load_prototypes().keys())# known = {"NtAllocateVirtualMemory", "NtCreateThreadEx", ...} 共 64 个# 找出未知的函数名unknown =[f for f in functions if f notin known]# 列表推导式高效过滤# 如果有未知函数,显示错误信息if unknown:print(f"[!] Unknown function(s): {', '.join(unknown)}")print(f" Available: {', '.join(sorted(known))}")# 显示所有可用函数名,帮助用户纠正输入sys.exit(1)# 立即终止程序,避免后续处理
错误处理示例:
# 输入错误函数名python syswhispers.py --functions NtAllocFake,NtCreateThreadEx# 输出错误信息[!]Unknownfunction(s):NtAllocFakeAvailable:NtAdjustPrivilegesToken,NtAllocateVirtualMemory,NtAllocateVirtualMemoryEx,NtAlertResumeThread,...(按字母顺序显示所有64个可用函数)
1.4 配置对象构建
# syswhispers.py 第 320-350 行def main()->None:# ... 前面的处理 ...# ---- 清理前缀并确定输出文件名 ----prefix_clean = args.prefix.rstrip("_")# 移除末尾的下划线# 示例:"SW4_" → "SW4"out_file = args.out_file if args.out_file isnotNoneelse f"{prefix_clean}Syscalls"# 如果未指定 --out-file,使用默认值:SW4Syscalls# ---- 构建 GeneratorConfig 对象 ----cfg =GeneratorConfig(# 1. syscall 选择functions = functions,# 经过展开和验证的函数列表# 2. 目标选项arch =Architecture(args.arch),# 枚举转换compiler =Compiler(args.compiler),# 枚举转换method =InvocationMethod(args.method),#枚举转换resolve =ResolutionMethod(args.resolve),#枚举转换# 3. 输出选项prefix = prefix_clean +"_",# 添加下划线:SW4_out_file = out_file,# SW4Syscallsout_dir = args.out_dir,# 默认 "."# 4. 规避选项obfuscate = args.obfuscate,# boolencrypt_ssn = args.encrypt_ssn,# boolstack_spoof = args.stack_spoof,# booletw_bypass = args.etw_bypass,# boolamsi_bypass = args.amsi_bypass,# boolunhook_ntdll = args.unhook_ntdll,# boolanti_debug = args.anti_debug,# boolsleep_encrypt = args.sleep_encrypt,# bool# 5. 其他选项syscall_table = args.syscall_table,# str or None)# ---- 打印配置摘要 ----print(f" Functions : {len(functions)}")print(f" Arch : {cfg.arch}")print(f" Compiler : {cfg.compiler}")print(f" Resolution : {cfg.resolve}")print(f" Method : {cfg.method}")print(f" Prefix : {cfg.prefix}")# 动态显示启用的选项if cfg.obfuscate:print(" Obfuscate : yes (stub reordering + junk instructions)")if cfg.encrypt_ssn:print(" Encrypt SSN: yes (XOR key embedded at compile time)")if cfg.stack_spoof:print(" Stack spoof: yes (synthetic call stack helper)")if cfg.etw_bypass:print(" ETW bypass : yes (user-mode EtwEventWrite patch)")if cfg.amsi_bypass:print(" AMSI bypass: yes (AmsiScanBuffer patch)")if cfg.unhook_ntdll:print(" Unhook : yes (remap clean ntdll from KnownDlls)")if cfg.anti_debug:print(" Anti-debug : yes (PEB, timing, heap, debug port)")if cfg.sleep_encrypt:print(" Sleep crypt: yes (Ekko-style XOR .text during sleep)")
配置对象优点:
- 类型安全:所有字段有明确类型定义
- 集中管理:所有配置在一个对象中传递
- 默认值:合理的默认配置
- 易扩展:新增选项只需添加字段
- 自文档化:配置对象本身就是文档
2. syscall 数据解析流程
2.1 数据加载入口 – loaddata()
# generator.py 第 92-125 行classSysWhispers4:def __init__(self, config:GeneratorConfig):self.cfg = configself.obf =Obfuscator(seed=random.randint(0,0xFFFFFFFF))self._prototypes:List[SyscallPrototype]=[]self._ssn_x64: dict ={}self._ssn_x86: dict ={}def _load_data(self)->None:"""加载并处理所有必需的数据数据流:JSON 文件 → Python dict → 转换为数据类对象 → 缓存到实例变量处理步骤:1. 加载函数原型(prototypes.json)2. 加载 SSN 表(syscalls_nt_x64.json)3. 可选:加载自定义 SSN 表4. 过滤并转换为用户选择的函数5. 可选:随机打乱顺序(混淆模式)"""# ---- 步骤 1: 加载函数原型 ----raw_proto = load_prototypes()# raw_proto 结构:# {# "NtAllocateVirtualMemory": {# "return_type": "NTSTATUS",# "params": [# {"name": "ProcessHandle", "type": "HANDLE", "annotation": "IN"},# {"name": "BaseAddress", "type": "PVOID*", "annotation": "IN OUT"},# ...# ]# },# "NtCreateThreadEx": {...},# ... 共 64 个函数# }# ---- 步骤 2: 加载 SSN 表 ----self._ssn_x64 = load_ssn_table_x64()self._ssn_x86 = load_ssn_table_x86()# SSN 表结构:# {# "NtAllocateVirtualMemory": {# "xp_sp1": 70,# "7_sp0": 70,# "8.0": 71,# "8.1": 23,# "10240": 24,# "22000": 24, # Windows 11# ...# },# "NtCreateThreadEx": {...},# ... 共 400+ 个函数# }# ---- 步骤 3: 可选 - 覆盖自定义 SSN 表 ----if self.cfg.syscall_table andPath(self.cfg.syscall_table).exists():from.utils import load_jsonself._ssn_x64 = load_json(self.cfg.syscall_table)# 使用用户提供的 SSN 表替换内置表# 使用场景:研究特定版本、测试新版本# ---- 步骤 4: 构建原型对象列表 ----for fname in self.cfg.functions:# 遍历用户选择的所有函数# 4.1 验证函数是否存在于原型表中if fname notin raw_proto:print(f" [!] Warning: '{fname}' not found in prototypes.json, skipping.")continue# 跳过未知函数,继续处理下一个# 4.2 获取函数的原始数据entry = raw_proto[fname]# entry 结构:# {# "return_type": "NTSTATUS",# "params": [# {"name": "...", "type": "...", "annotation": "..."},# ...# ]# }# 4.3 解析参数列表params =[SyscallParam(name=p["name"],# 参数名:如 "ProcessHandle"type=p["type"],# 参数类型:如 "HANDLE"annotation=p.get("annotation",""),# 方向注解:IN/OUT/OPTIONAL)for p in entry.get("params",[])# 如果 entry 中没有 params 字段,使用空列表 []]# 列表推导式将 dict 转换为 SyscallParam 对象# 4.4 创建 SyscallPrototype 对象self._prototypes.append(SyscallPrototype(name=fname,# 函数名:如 "NtAllocateVirtualMemory"return_type=entry.get("return_type","NTSTATUS"),# 返回类型params=params,# 参数对象列表))# SyscallPrototype 是 dataclass,提供以下属性:# - name: str# - return_type: str# - params: List[SyscallParam]# - param_count: int (property)# - c_signature(): str (method)# - c_prototype(): str (method)# ---- 步骤 5: 可选 - 混淆函数顺序 ----if self.cfg.obfuscate:# 如果启用了混淆,随机打乱函数顺序self._prototypes =[self._prototypes[i]for i in self.obf.shuffle_functions(list(range(len(self._prototypes))))]# shuffle_functions() 返回打乱后的索引列表# 例如:[0, 1, 2, 3] → [2, 0, 3, 1]# 效果:生成的代码中函数顺序是随机的
2.2 数据类定义 – models.py
SyscallParam 数据类
# models.py 第 54-63 行@dataclassclassSyscallParam:"""syscall 参数数据类属性:- name: 参数名称(如 "ProcessHandle")- type: 参数类型(如 "HANDLE", "PVOID*")- annotation: 方向注解("IN", "OUT", "IN OUT", "OPTIONAL")方法:- c_declaration(): 返回 C 语言参数声明字符串"""name: str # 参数名type: str # 参数类型annotation: str =""# 方向注解,默认为空def c_declaration(self)-> str:"""生成 C 语言参数声明示例:SyscallParam(name="ProcessHandle", type="HANDLE")→ "HANDLE ProcessHandle"SyscallParam(name="BaseAddress", type="PVOID*", annotation="IN OUT")→ "PVOID* BaseAddress" (annotation 不包含在声明中)"""return f"{self.type} {self.name}"
使用示例:
# 创建参数对象param1 =SyscallParam(name="ProcessHandle",type="HANDLE",annotation="IN")param2 =SyscallParam(name="BaseAddress",type="PVOID*",annotation="IN OUT")# 生成 C 声明print(param1.c_declaration())# 输出:HANDLE ProcessHandleprint(param2.c_declaration())# 输出:PVOID* BaseAddress# 用于生成函数签名params =[param1, param2]param_str =", ".join(p.c_declaration()for p in params)# 结果:"HANDLE ProcessHandle, PVOID* BaseAddress"
SyscallPrototype 数据类
# models.py 第 66-82 行@dataclassclassSyscallPrototype:"""syscall 函数原型数据类属性:- name: 函数名称(如 "NtAllocateVirtualMemory")- return_type: 返回类型(通常是 "NTSTATUS")- params: 参数对象列表属性(计算得出):- param_count: 参数数量方法:- c_signature(prefix=""): 生成 C 函数签名(无分号)- c_prototype(prefix=""): 生成 C 函数原型(带分号)"""name: str # 函数名return_type: str # 返回类型params:List[SyscallParam]= field(default_factory=list)# 参数列表@propertydef param_count(self)-> int:"""返回参数数量"""return len(self.params)def c_signature(self, prefix: str ="")-> str:"""生成 C 函数签名(不带分号)参数:- prefix: 函数名前缀(如 "SW4_")示例:proto = SyscallPrototype(name="NtAllocateVirtualMemory",return_type="NTSTATUS",params=[SyscallParam(name="ProcessHandle", type="HANDLE"),SyscallParam(name="BaseAddress", type="PVOID*"),# ... 更多参数])proto.c_signature()→ "NTSTATUS NTAPI NtAllocateVirtualMemory(HANDLE ProcessHandle, PVOID* BaseAddress, ...)"proto.c_signature(prefix="SW4_")→ "NTSTATUS NTAPI SW4_NtAllocateVirtualMemory(HANDLE ProcessHandle, PVOID* BaseAddress, ...)""""func_name = f"{prefix}{self.name}"if prefix else self.name# 如果有 prefix,添加前缀: "SW4_" + "NtAllocateVirtualMemory"param_str =", ".join(p.c_declaration()for p in self.params)# 将所有参数的 C 声明用逗号和空格连接return f"{self.return_type} NTAPI {func_name}({param_str})"# 组合完整签名:返回类型 + 调用约定 + 函数名 + (参数列表)def c_prototype(self, prefix: str ="")-> str:"""生成 C 函数原型(带分号)示例:proto.c_prototype("SW4_")→ "NTSTATUS NTAPI SW4_NtAllocateVirtualMemory(HANDLE ProcessHandle, ...);""""return self.c_signature(prefix)+";"# 在签名后添加分号,形成完整的 C 原型声明
完整示例:
from core.models importSyscallParam,SyscallPrototype# 创建 NtAllocateVirtualMemory 的原型proto =SyscallPrototype(name="NtAllocateVirtualMemory",return_type="NTSTATUS",params=[SyscallParam(name="ProcessHandle", type="HANDLE", annotation="IN"),SyscallParam(name="BaseAddress", type="PVOID*", annotation="IN OUT"),SyscallParam(name="ZeroBits", type="ULONG_PTR", annotation="IN"),SyscallParam(name="RegionSize", type="PSIZE_T", annotation="IN OUT"),SyscallParam(name="AllocationType", type="ULONG", annotation="IN"),SyscallParam(name="Protect", type="ULONG", annotation="IN"),])# 访问属性print(proto.name)# 输出:NtAllocateVirtualMemoryprint(proto.return_type)# 输出:NTSTATUSprint(proto.param_count)# 输出:6# 生成 C 原型print(proto.c_prototype("SW4_"))# 输出:# NTSTATUS NTAPI SW4_NtAllocateVirtualMemory(# HANDLE ProcessHandle,# PVOID* BaseAddress,# ULONG_PTR ZeroBits,# PSIZE_T RegionSize,# ULONG AllocationType,# ULONG Protect# );
2.3 数据加载工具函数 – utils.py
# utils.py 第 1-35 行"""SysWhispers4 - Utility Functions通用工具函数模块,提供:1. JSON 文件加载2. 哈希函数(DJB2, ROR-13, CRC32, FNV-1a)3. SSN 表查询辅助函数"""import jsonimport osimport structfrom pathlib importPathfrom typing importAny# 数据目录路径DATA_DIR =Path(__file__).parent.parent /"data"# 解析路径:# __file__ = ".../core/utils.py"# __file__.parent = ".../core/"# __file__.parent.parent = ".../SysWhispers4-main/"# DATA_DIR = ".../SysWhispers4-main/data/"def load_json(path:Path| str)->Any:"""通用 JSON 加载器参数:- path: Path 对象或字符串路径返回:- 解析后的 JSON 数据(dict、list 等)异常:- FileNotFoundError: 文件不存在- json.JSONDecodeError: JSON 格式错误"""with open(path,"r", encoding="utf-8")as f:return json.load(f)# 使用 with 语句自动管理文件关闭# encoding="utf-8" 确保跨平台兼容性def load_prototypes()-> dict:"""加载函数原型定义返回:- dict[func_name: {return_type, params}]文件路径:- data/prototypes.json"""return load_json(DATA_DIR /"prototypes.json")def load_presets()-> dict:"""加载预设配置返回:- dict[preset_name: {description, functions}]文件路径:- data/presets.json"""return load_json(DATA_DIR /"presets.json")def load_ssn_table_x64()-> dict:"""加载 x64 架构 SSN 表返回:- dict[func_name: {build_key: ssn}]文件路径:- data/syscalls_nt_x64.json"""return load_json(DATA_DIR /"syscalls_nt_x64.json")def load_ssn_table_x86()-> dict:"""加载 x86 架构 SSN 表返回:- dict[func_name: {build_key: ssn}]文件路径:- data/syscalls_nt_x86.json注意:- x86 SSN 表是可选的,如果不存在返回空字典"""path = DATA_DIR /"syscalls_nt_x86.json"if path.exists():return load_json(path)return{}# 优雅降级:如果没有 x86 表,返回空字典
哈希工具函数:
# utils.py 第 37-73 行def djb2_hash(name: str)-> int:"""DJB2 哈希算法(32 位)用途:- 运行时函数名哈希查找- 与编译时哈希对比验证算法:h = 5381 (0x1505)for each char c in name:h = ((h << 5) + h) ^ c示例:djb2_hash("NtAllocateVirtualMemory") → 0x8A3B2C1D (示例值)"""h =0x1505# 初始值 5381for ch in name.encode("ascii"):h =(((h <<5)+ h)^ ch)&0xFFFFFFFF# h << 5 = h * 32# (h << 5) + h = h * 33# & 0xFFFFFFFF 保持 32 位return hdef ror13_hash(name: str)-> int:"""ROR-13 哈希算法(32 位)用途:- Metasploit/PEB Walker 惯例- 兼容某些 shellcode 加载器算法:h = 0for each char c in name:h = (h >> 13) | (h << 19) # 循环右移 13 位h = h + c示例:ror13_hash("NtAllocateVirtualMemory") → 0x5E7F8A2B (示例值)"""h =0for ch in name.encode("ascii"):h =(((h >>13)|(h <<19))&0xFFFFFFFF)+ ch# (h >> 13) | (h << 19) = 循环右移 13 位# & 0xFFFFFFFF 保持 32 位return h &0xFFFFFFFFdef crc32_hash(name: str)-> int:"""CRC32 校验和哈希(32 位)用途:- 标准校验和算法- 某些恶意软件使用算法:标准 CRC32 多项式:0xEDB88320示例:crc32_hash("NtAllocateVirtualMemory") → 0x9A4B7C2D (示例值)"""crc =0xFFFFFFFF# 初始值for ch in name.encode("ascii"):crc ^= ch # 与字节异或for _ in range(8):if crc &1:crc =(crc >>1)^0xEDB88320else:crc >>=1return crc ^0xFFFFFFFF# 最终异或def fnv1a_hash(name: str)-> int:"""FNV-1a 哈希算法(32 位)用途:- 快速非加密哈希- 另一种常见选择算法:h = 2166136261 (0x811C9DC5)for each char c in name:h = (h ^ c) * 16777619 (0x01000193)示例:fnv1a_hash("NtAllocateVirtualMemory") → 0x3C5D8E9F (示例值)"""h =0x811C9DC5# FNV offset basisfor ch in name.encode("ascii"):h =((h ^ ch)*0x01000193)&0xFFFFFFFF# 先异或再乘法return h
哈希算法对比:
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3. syscall 选择与过滤机制
3.1 预设系统详解
presets.json 结构分析
{"common":{"description":"Common functions for process/thread/memory operations","functions":["NtAllocateVirtualMemory","NtFreeVirtualMemory","NtWriteVirtualMemory","NtReadVirtualMemory","NtProtectVirtualMemory","NtQueryVirtualMemory","NtCreateThreadEx","NtOpenProcess","NtOpenThread","NtSuspendThread","NtResumeThread","NtGetContextThread","NtSetContextThread","NtTerminateProcess","NtTerminateThread","NtClose","NtDuplicateObject","NtWaitForSingleObject","NtUnmapViewOfSection","NtMapViewOfSection","NtCreateSection","NtQueryInformationProcess","NtSetInformationProcess","NtQuerySystemInformation","NtDelayExecution"]},"injection":{"description":"Functions for process/shellcode injection (APC, thread, section)","functions":["NtAllocateVirtualMemory","NtFreeVirtualMemory","NtWriteVirtualMemory","NtReadVirtualMemory","NtProtectVirtualMemory","NtCreateThreadEx","NtOpenProcess","NtOpenThread","NtSuspendThread","NtResumeThread","NtGetContextThread","NtSetContextThread","NtUnmapViewOfSection","NtMapViewOfSection","NtCreateSection","NtQueueApcThread","NtQueueApcThreadEx","NtAlertResumeThread","NtTestAlert","NtClose"]},//...共7个预设}
预设设计理念:
- 场景化:每个预设对应一个具体使用场景
- 最小化:只包含必要的函数,减少代码体积
- 可组合:多个预设可以组合使用
- 可扩展:易于添加新的预设
3.2 函数分类统计
基于 prototypes.json 的完整分析:
# 分析脚本import jsonfrom collections importCounterwith open('data/prototypes.json')as f:prototypes = json.load(f)# 按参数量分类param_distribution =Counter()for func_name, func_data in prototypes.items():param_count = len(func_data.get('params',[]))param_distribution[param_count]+=1print("参数分布统计:")for params, count in sorted(param_distribution.items()):percentage =(count / len(prototypes))*100print(f" {params:2d} 个参数:{count:2d} 个函数 ({percentage:.1f}%)")# 按功能分类(手动标注)functional_categories ={"内存操作":["NtAllocateVirtualMemory","NtFreeVirtualMemory","NtWriteVirtualMemory","NtReadVirtualMemory","NtProtectVirtualMemory","NtQueryVirtualMemory",],"进程/线程":["NtCreateThreadEx","NtOpenProcess","NtOpenThread","NtTerminateProcess","NtTerminateThread","NtSuspendThread","NtResumeThread",],"同步/通信":["NtWaitForSingleObject","NtDelayExecution","NtCreateSection","NtMapViewOfSection","NtUnmapViewOfSection",],"信息查询":["NtQueryInformationProcess","NtQuerySystemInformation","NtQueryInformationThread",],"句柄操作":["NtClose","NtDuplicateObject",],//...更多分类}print("\n功能分类统计:")for category, functions in functional_categories.items():print(f" {category}: {len(functions)} 个函数")
输出结果:
参数分布统计:2个参数:3个函数(4.7%)3个参数:5个函数(7.8%)4个参数:12个函数(18.8%)5个参数:15个函数(23.4%)6个参数:18个函数(28.1%)7个参数:7个函数(10.9%)8个参数:2个函数(3.1%)10个参数:1个函数(1.6%)11个参数:1个函数(1.6%)功能分类统计:内存操作:6个函数进程/线程:7个函数同步/通信:5个函数信息查询:3个函数句柄操作:2个函数...
3.3 函数过滤逻辑
完整过滤流程图
用户输入(--preset /--functions)↓_resolve_functions()├─展开预设│└─从 presets.json 加载│└─ common →25个函数│└─ injection →20个函数│├─添加自定义函数│└─解析逗号分隔列表│└─去重并保持顺序└─使用set跟踪已见元素↓_validate_functions()├─加载 prototypes.json├─检查每个函数是否存在└─错误时显示可用函数列表↓GeneratorConfig.functions↓_load_data()├─遍历 functions 列表├─从 raw_proto 获取原型数据├─创建SyscallPrototype对象└─添加到self._prototypes↓可选混淆└─ shuffle_functions()打乱顺序
实际案例分析
案例 1:纯预设模式
python syswhispers.py --preset common
处理过程:
# 1. 加载 presets.jsonpresets ={"common":{"description":"...","functions":["NtAllocateVirtualMemory",...]# 25 个},//...}# 2. 展开预设args.preset ="common"functions =[]for p in["common"]:# split(",")functions.extend(presets["common"]["functions"])# functions = [25 个函数名]# 3. 去重(这里没有重复)seen = set()result =[]for f in functions:if f notin seen:seen.add(f)result.append(f)# result = [25 个唯一函数]# 4. 验证_validate_functions(result)# 检查所有 25 个函数都在 prototypes.json 中# ✓ 全部通过# 5. 构建原型对象for fname in result:entry = raw_proto[fname]params =[SyscallParam(...)for p in entry['params']]proto =SyscallPrototype(name=fname, return_type="...", params=params)self._prototypes.append(proto)# 最终:self._prototypes 包含 25 个 SyscallPrototype 对象
案例 2:预设组合模式
python syswhispers.py --preset common,injection
处理过程:
# 1. 展开多个预设args.preset ="common,injection"functions =[]for p in["common","injection"]:functions.extend(presets[p]["functions"])# functions 现在包含:# - common 的 25 个函数# - injection 的 20 个函数# 总计 45 个,但有重复# 2. 去重seen = set()result =[]for f in functions:if f notin seen:seen.add(f)result.append(f)# 假设 common 和 injection 有 10 个公共函数# result = 25 + (20 - 10) = 35 个唯一函数# 3. 验证和构建原型对象# ... 同上 ...
案例 3:混合模式
python syswhispers.py --preset common --functions NtQueryInformationThread
处理过程:
# 1. 展开预设functions =[]functions.extend(presets["common"]["functions"])# 25 个# 2. 添加自定义函数args.functions ="NtQueryInformationThread"for f in["NtQueryInformationThread"]:if f and f notin functions:functions.append(f)# functions = [25 个 common 函数] + ["NtQueryInformationThread"]# 总计 26 个函数# 3. 去重、验证、构建# ... 同上 ...
4. 模板渲染生成逻辑
4.1 代码生成器架构
# generator.py 核心结构classSysWhispers4:"""主代码生成引擎设计模式:1. 模板方法模式:定义生成流程,子类重写具体步骤2. 策略模式:不同的解析方法/调用方法作为策略3. 构建者模式:逐步构建复杂的输出文件"""def __init__(self, config:GeneratorConfig):self.cfg = config # 生成配置self.obf =Obfuscator(seed=...)# 混淆器self._prototypes:List[...]=[]# 函数原型列表self._ssn_x64: dict ={}# x64 SSN 缓存self._ssn_x86: dict ={}# x86 SSN 缓存def generate(self)->Dict[str, str]:"""生成所有输出文件返回:{"SW4Syscalls_Types.h": "<内容>","SW4Syscalls.h": "<内容>","SW4Syscalls.c": "<内容>","SW4Syscalls.asm": "<内容>"}"""self._load_data()# 加载数据cfg = self.cfgoutputs:Dict[str, str]={}# 1. 生成类型头文件types_fname = f"{cfg.out_file}_Types.h"outputs[types_fname]= self._gen_types_header()# 2. 生成声明头文件hdr_fname = f"{cfg.out_file}.h"outputs[hdr_fname]= self._gen_syscalls_header(types_fname)# 3. 生成 C 源文件c_fname = f"{cfg.out_file}.c"outputs[c_fname]= self._gen_syscalls_c(hdr_fname)# 4. 生成汇编存根if cfg.compiler ==Compiler.MSVC:asm_fname = f"{cfg.out_file}.asm"outputs[asm_fname]= self._gen_asm_msvc()else:asm_fname = f"{cfg.out_file}_stubs.c"outputs[asm_fname]= self._gen_asm_gas_inline()return outputsdef write_outputs(self, outputs:Dict[str, str])->None:"""写入所有生成的文件到磁盘"""out_dir =Path(self.cfg.out_dir)out_dir.mkdir(parents=True, exist_ok=True)for fname, content in outputs.items():fpath = out_dir / fnamefpath.write_text(content, encoding="utf-8")print(f" [+] Generated {fpath}")
4.2 类型头文件生成
# generator.py 第 199-300 行def _gen_types_header(self)-> str:"""生成 SW4Syscalls_Types.h内容包括:1. 保护宏(#pragma once)2. 必需的系统头文件3. NT 宏定义4. 信息类枚举5. 结构体定义6. 内部使用的辅助类型"""p = self.cfg.prefix # 如 "SW4_"guard = f"{p}SYSCALLS_TYPES_H"# 如 "SW4_SYSCALLS_TYPES_H"return f"""\/** {self.cfg.out_file}_Types.h -- generated by SysWhispers4* DO NOT EDIT -- regenerate with syswhispers.py** Resolution : {self.cfg.resolve}* Method : {self.cfg.method}* Arch : {self.cfg.arch}* Compiler : {self.cfg.compiler}*/#pragma once#ifndef {guard}#define {guard}#include <windows.h>#include <winternl.h>/* =========================================================================* NT 宏定义(如果未定义)* ========================================================================= */#ifndef NT_SUCCESS# define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)#endif#ifndef STATUS_SUCCESS# define STATUS_SUCCESS ((NTSTATUS)0x00000000L)#endif#ifndef STATUS_ACCESS_DENIED# define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)#endif#ifndef STATUS_INFO_LENGTH_MISMATCH# define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)#endif/* =========================================================================* 信息类枚举(PROCESSINFOCLASS, THREADINFOCLASS, etc.)* ========================================================================= */#ifndef _PROCESSINFOCLASStypedef enum _PROCESSINFOCLASS {{ProcessBasicInformation = 0,ProcessDebugPort = 7,ProcessWow64Information = 26,ProcessImageFileName = 27,ProcessBreakOnTermination = 29,ProcessSubsystemInformation = 75,ProcessInstrumentationCallback = 40,}} PROCESSINFOCLASS;#endif#ifndef _THREADINFOCLASStypedef enum _THREADINFOCLASS {{ThreadBasicInformation = 0,ThreadTimes = 1,ThreadPriority = 2,ThreadBasePriority = 3,ThreadAffinityMask = 4,ThreadImpersonationToken = 5,ThreadDescriptorTableEntry = 6,ThreadEnableAlignmentFaultFixup = 7,ThreadEventPair = 8,ThreadQuerySetWin32StartAddress = 9,ThreadZeroTlsCell = 10,ThreadPerformanceCount = 11,ThreadAmILastThread = 12,ThreadIdealProcessor = 13,ThreadPriorityBoost = 14,ThreadSetTlsArrayAddress = 15,ThreadIsIoPending = 16,ThreadHideFromDebugger = 17,}} THREADINFOCLASS;#endif/* =========================================================================* 结构体定义(PS_ATTRIBUTE_LIST, CLIENT_ID, etc.)* ========================================================================= */#ifndef _PS_ATTRIBUTE_LISTtypedef struct _PS_ATTRIBUTE {{ULONG_PTR Attribute;SIZE_T Size;union {{ULONG_PTR Value;PVOID ValuePtr;}};PSIZE_T ReturnLength;}} PS_ATTRIBUTE, *PPS_ATTRIBUTE;typedef struct _PS_ATTRIBUTE_LIST {{SIZE_T TotalLength;PS_ATTRIBUTE Attributes[1];}} PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST;#endif#ifndef _CLIENT_IDtypedef struct _CLIENT_ID {{PVOID UniqueProcess;PVOID UniqueThread;}} CLIENT_ID, *PCLIENT_ID;#endif#ifndef _IO_STATUS_BLOCKtypedef struct _IO_STATUS_BLOCK {{union {{NTSTATUS Status;PVOID Pointer;}};ULONG_PTR Information;}} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;#endif/* =========================================================================* 内部使用的辅助类型* ========================================================================= *//* SSN 表项(用于静态解析) */typedef struct _{p}SSN_ENTRY {{DWORD Count;struct {{DWORD Build;DWORD Ssn;}} Entries[64];}} {p}SSN_ENTRY;/* 导出表项(用于 FreshyCalls/Hell's Gate 扫描) */typedef struct _{p}EXPORT {{PVOID Address;DWORD Hash;DWORD Ordinal;}} {p}EXPORT, *P{p}EXPORT;#endif /* {guard} */"""
生成的头文件示例:
/** SW4Syscalls_Types.h -- generated by SysWhispers4* DO NOT EDIT*/#pragma once#ifndef SW4_SYSCALLS_TYPES_H#define SW4_SYSCALLS_TYPES_H#include<windows.h>#include<winternl.h>// NT 宏定义#ifndef NT_SUCCESS# define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)#endif// 信息类枚举typedefenum _PROCESSINFOCLASS {ProcessBasicInformation=0,ProcessDebugPort=7,// ...} PROCESSINFOCLASS;// 结构体定义typedefstruct _CLIENT_ID {PVOID UniqueProcess;PVOID UniqueThread;} CLIENT_ID,*PCLIENT_ID;// 辅助类型typedefstruct _SW4_SSN_ENTRY {DWORD Count;struct{DWORD Build;DWORD Ssn;}Entries[64];} SW4_SSN_ENTRY;#endif/* SW4_SYSCALLS_TYPES_H */
4.3 声明头文件生成
# generator.py 第 302-400 行def _gen_syscalls_header(self, types_header: str)-> str:"""生成 SW4Syscalls.h内容包括:1. 包含类型头文件2. 初始化函数声明3. 可选功能函数声明(ETW/AMSI/Unhook 等)4. 所有 syscall 函数原型"""p = self.cfg.prefixguard = f"{p}SYSCALLS_H"# 生成所有函数的原型声明protos ="\n".join(f"EXTERN_C {proto.c_prototype(prefix=p)}"for proto in self._prototypes)# EXTERN_C 确保 C++ 兼容# proto.c_prototype("SW4_") → "NTSTATUS NTAPI SW4_NtAllocateVirtualMemory(...);"# 根据启用的功能添加初始化函数声明init_comment ={ResolutionMethod.Static:"static table -- no init required",ResolutionMethod.FreshyCalls:"FreshyCalls -- sorts ntdll Nt* exports by VA",ResolutionMethod.HellsGate:"Hell's Gate -- reads SSN from ntdll stub",ResolutionMethod.HalosGate:"Halo's Gate -- Hell's Gate + neighbor scan",ResolutionMethod.TartarusGate:"Tartarus' Gate -- handles near/far JMP hooks",ResolutionMethod.SyscallsFromDisk:"SyscallsFromDisk -- loads clean ntdll",ResolutionMethod.RecycledGate:"RecycledGate -- FreshyCalls + opcode validation",ResolutionMethod.HWBreakpoint:"HW Breakpoint -- DR registers + VEH",}[self.cfg.resolve]# 可选功能声明egg_init =""if self.cfg.method ==InvocationMethod.Egg:egg_init = f"\nEXTERN_C BOOL {p}HatchEggs(VOID); /* Patch egg markers */"etw_init =""if self.cfg.etw_bypass:etw_init = f"\nEXTERN_C BOOL {p}PatchEtw(VOID); /* Patch ETW writer */"amsi_init =""if self.cfg.amsi_bypass:amsi_init = f"\nEXTERN_C BOOL {p}PatchAmsi(VOID); /* Patch AMSI */"unhook_init =""if self.cfg.unhook_ntdll:unhook_init = f"\nEXTERN_C BOOL {p}UnhookNtdll(VOID); /* Remap ntdll */"antidebug_init =""if self.cfg.anti_debug:antidebug_init = f"\nEXTERN_C BOOL {p}AntiDebugCheck(VOID); /* Check debugger */"sleep_init =""if self.cfg.sleep_encrypt:sleep_init = f"\nEXTERN_C VOID {p}SleepEncrypt(DWORD ms); /* Encrypted sleep */"return f"""\/** {self.cfg.out_file}.h -- generated by SysWhispers4* DO NOT EDIT*/#pragma once#ifndef {guard}#define {guard}#include "{types_header}"#ifdef __cplusplusextern "C" {{#endif/* =========================================================================* 运行时初始化* {init_comment}* ========================================================================= */EXTERN_C BOOL {p}Initialize(VOID);{egg_init}{etw_init}{amsi_init}{unhook_init}{antidebug_init}{sleep_init}/* =========================================================================* syscall 函数原型* ========================================================================= */{protos}#ifdef __cplusplus}}#endif#endif /* {guard} */"""
生成的头文件示例:
/** SW4Syscalls.h -- generated by SysWhispers4*/#pragma once#ifndef SW4_SYSCALLS_H#define SW4_SYSCALLS_H#include"SW4Syscalls_Types.h"#ifdef __cplusplusextern"C"{#endif/* 运行时初始化 */EXTERN_C BOOL SW4_Initialize(VOID);/* 可选功能 */EXTERN_C BOOL SW4_PatchEtw(VOID);EXTERN_C BOOL SW4_UnhookNtdll(VOID);/* syscall 函数原型 */EXTERN_C NTSTATUS NTAPI SW4_NtAllocateVirtualMemory(HANDLE ProcessHandle,PVOID*BaseAddress,ULONG_PTR ZeroBits,PSIZE_T RegionSize,ULONG AllocationType,ULONG Protect);EXTERN_C NTSTATUS NTAPI SW4_NtCreateThreadEx(PHANDLE ThreadHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,HANDLE ProcessHandle,PVOID StartRoutine,PVOID Argument,ULONG CreateFlags,SIZE_T ZeroBits,SIZE_T StackSize,SIZE_T MaximumStackSize,PPS_ATTRIBUTE_LIST AttributeList);// ... 更多函数#ifdef __cplusplus}#endif#endif/* SW4_SYSCALLS_H */
总结
通过对 SysWhispers4 核心模块的深度源码分析,我们理解了:
参数解析模块
- argparse 的分组设计哲学
- 函数列表展开和验证算法
- 配置对象的构建流程
数据解析流程
- JSON 数据的加载和转换
- 数据类的设计和使用
- 哈希函数的选择和实现
syscall 选择机制
- 预设系统的设计理念
- 函数过滤和去重算法
- 原型对象的构建过程
模板生成逻辑
- 代码生成器的架构设计
- 各类文件的生成策略
- 条件编译和可选功能
这些知识不仅帮助我们理解 SysWhispers4 的工作原理,也为开发类似工具提供了宝贵的参考。
-
公众号:安全狗的自我修养
-
vx:2207344074
-
http://gitee.com/haidragon
-
http://github.com/haidragon
-
bilibili:haidragonx
-


夜雨聆风
