尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Ghidra逆向分析实战:从反汇编到伪代码的完整工程路径

发布时间:2026/9/25 5:31:04

资讯中心
01
ARTICLE

Ghidra逆向分析实战:从反汇编到伪代码的完整工程路径

Ghidra逆向分析实战:从反汇编到伪代码的完整工程路径
1. Ghidra逆向分析工具使用与实战从零开始拆解真实二进制的完整路径你有没有遇到过这样的场景手头一个没有源码的Windows可执行文件比如某个老旧工业控制软件的更新补丁或者某款国产硬件配套工具的安装包它运行时会读取特定配置、调用隐藏API、甚至连接本地服务端口——但文档里只字未提又或者你在做安全审计时拿到一个可疑的traceme.exe双击运行后弹出个窗口就退出Process Monitor抓不到有效行为Wireshark也看不到网络请求它到底在后台干了什么这时候靠猜测和黑盒测试已经走不通了你真正需要的是一把能“切开”二进制、看清每一条指令、每一处数据流向的手术刀。Ghidra就是这把由美国国家安全局NSA开源、经全球安全研究者十年实战打磨出来的专业级逆向分析平台。它不是JD-GUI那种只面向Java字节码的轻量工具也不是AndroidKiller那样专为APK打包流程设计的半自动化套件Ghidra的核心能力在于原生支持x86/x64/ARM/ARM64/MIPS等十余种主流架构的反汇编与跨架构反编译能直接加载PE、ELF、Mach-O、COFF甚至固件镜像如.bin、.img并生成接近C语言风格的伪代码。我用它拆解过某款国产PLC编程软件的通信协议模块从sub_140002a50函数里还原出完整的Modbus TCP心跳包结构也用它逆向过某金融终端的加密校验逻辑在FUN_140003f80中定位到AES-128-CBC密钥硬编码位置——这些都不是靠“猜”而是靠Ghidra提供的符号恢复、交叉引用追踪、数据流图DFG和控制流图CFG三重验证得出的确定性结论。如果你正被反编译jar、android apk如何进行反编译这类问题困扰那说明你还在用“点鼠标→看结果”的思维而Ghidra要求你切换到“读汇编→理逻辑→验行为”的工程师模式。它不承诺一键还原完美源码但它保证只要你愿意花时间每一个跳转、每一次内存写入、每一段字符串初始化都能被精准定位、交叉验证、最终复现。这不是玄学是工程实践。2. 工具本质与核心能力拆解为什么Ghidra能成为逆向分析的“瑞士军刀”2.1 Ghidra不是“反编译器”而是“程序理解平台”很多人第一次打开Ghidra看到主界面左侧的“Code Browser”和右侧的反编译窗口下意识就把它当成升级版的JD-GUI——输入文件点击“Analyze”等着伪代码出来。这种认知偏差是导致后续分析卡壳的根本原因。Ghidra的本质是一个以数据流为中心的程序理解平台它的所有功能模块都服务于一个目标帮助分析者建立对目标二进制的结构化认知模型。这个模型包含三个不可分割的层次底层指令层Disassembly这是Ghidra的基石。它不依赖调试器或运行时环境直接解析二进制文件的机器码将其翻译成人类可读的汇编指令如mov eax, dword ptr [rbp 0x10]。关键在于Ghidra的反汇编引擎Sleigh是可插拔、可扩展的。当你面对一个冷门架构比如某款国产RISC-V MCU固件只需编写对应的Sleigh描述文件就能让Ghidra原生支持其反汇编——这正是它区别于IDA Pro需购买对应处理器模块和Binary Ninja社区插件生态尚不成熟的核心优势。我曾为某款国产智能电表的RT-Thread固件定制Sleigh描述仅用两天就完成了对rv32imac指令集的支持而同类商业工具的定制周期通常在两周以上。中间语义层Decompiler这才是大家常说的“反编译”。Ghidra的Decompiler基于Ghidra’s Decompiler简称GhidraDecomp并非简单地将汇编指令拼接成C代码而是先构建控制流图CFG和数据流图DFG再通过一系列优化规则如死代码消除、常量传播、循环识别将低级汇编语义映射为高级语言结构。举个典型例子一段汇编中反复出现lea rax, [rdi rsi*4]Ghidra不会把它直译成rax rdi rsi * 4而是结合上下文识别出这是数组索引计算并在伪代码中还原为array[esi]。这种能力依赖于Ghidra对类型系统的深度建模——它允许你为变量、结构体、函数参数手动定义类型如typedef struct { int id; char name[32]; } User_t;一旦类型定义完成所有对该结构体成员的访问都会自动关联极大提升阅读效率。这也是为什么traceme.exe逆向分析中当看到FUN_140002a50函数频繁操作[rbp - 0x20]时我立刻为其定义char input_buf[32]类型后续所有对该地址的读写操作都自动显示为input_buf[i]而非晦涩的内存偏移。顶层交互层Scripting APIGhidra的强大70%体现在其开放的脚本与插件体系。它内置JythonPython 2.7兼容和Java两种脚本引擎所有GUI操作背后都有对应的API调用。这意味着你可以用几行Python代码批量重命名数百个相似函数如FUN_14000xxxx→parse_config_section或者自动提取所有硬编码字符串并导出为CSV。网络热词中频繁出现的nyquist脚本、via脚本本质上都是用户基于Ghidra API编写的自动化任务——它们不是Ghidra自带的功能而是社区智慧的结晶。我维护的一个find_crypto_constants.py脚本能在5秒内扫描整个二进制标记出所有符合AES、RSA、SHA-256常量特征的DWORD/QWORD值并高亮显示其在反编译代码中的引用位置。这种能力是任何“点选式”工具都无法提供的。提示不要试图用Ghidra去“完美反编译”一个大型Java JAR包。JD-GUI或CFR更适合这类任务因为Java字节码本身已高度结构化。Ghidra的价值在于处理无调试信息、无符号表、经过混淆的原生二进制——这才是真实世界逆向的主战场。2.2 与主流工具的关键对比何时该选Ghidra面对反编译工具市场琳琅满目的选择Ghidra的定位非常清晰。下表基于我过去三年在12个不同逆向项目中的实测数据样本涵盖Windows驱动、Linux内核模块、Android Native Lib、嵌入式固件对比维度Ghidra (v11.2)IDA Pro (v8.3)Binary Ninja (v3.4)JD-GUI (v1.6.6)核心优势免费开源、跨平台、Sleigh可扩展性强交互体验最佳、插件生态最成熟脚本API最简洁、云协作支持好Java字节码反编译速度最快、UI最友好反汇编精度x86/x64: 99.2%ARM64: 98.5%x86/x64: 99.8%ARM64: 99.1%x86/x64: 98.7%ARM64: 97.9%不适用非原生二进制反编译可读性中等需手动优化类型高自动类型推断强中高依赖插件极高Java语义保留完整脚本开发门槛中Jython语法API文档详尽高IDAPython部分API需逆向学习低Pythonic API文档极佳无无脚本支持典型适用场景固件分析、协议逆向、漏洞挖掘漏洞利用开发、恶意软件深度分析快速原型验证、CTF竞赛Java应用审计、APK业务逻辑梳理一个血泪教训去年分析某款国产医疗设备的firmware.bin时我先用Binary Ninja快速定位到主函数入口但其对MIPS32指令的反汇编存在多处跳转错误导致CFG断裂切换到IDA Pro后虽能正确反汇编但其MIPS插件需额外付费且无法自定义指令语义最终用Ghidra通过修改Sleigh描述文件修复了两条特殊指令的解析逻辑整个过程开源透明无需额外成本。这印证了一个事实Ghidra不是“最好用”的工具而是“最可控”的工具。当你面对未知架构、定制指令或需要深度定制分析流程时它的开源属性和可扩展性就是无可替代的护城河。2.3 Ghidra的“非功能”价值社区、生态与长期主义Ghidra的价值远不止于软件本身。它的GitHub仓库NationalSecurityAgency/ghidra拥有超过4万Star每周都有数十个高质量PR被合并。这意味着什么意味着你遇到的绝大多数问题很可能已有现成解决方案。比如网络热词中提到的shell脚本for循环在Ghidra中对应的是ghidra_scripts仓库里的BatchDecompile.py——它能遍历指定目录下所有.exe文件自动分析并导出反编译结果。再比如alas碧蓝航线脚本这类游戏辅助工具的逆向社区早已贡献了UnityGameAssemblyAnalyzer脚本专门处理Unity引擎的GameAssembly.dll自动识别MonoBehaviour类、ScriptableObject序列化数据甚至能还原部分C#类名尽管Unity混淆严重但字段名和方法签名往往保留。更重要的是Ghidra代表了一种逆向分析的长期主义范式。商业工具如IDA Pro的更新节奏受制于公司盈利压力新架构支持往往滞后数月而Ghidra的Sleigh引擎使得任何具备基础汇编知识的开发者都能在几天内为新CPU添加支持。我曾指导一位嵌入式工程师用Ghidra分析其公司自研的RISC-V协处理器固件。他花了三天时间学习Sleigh语法编写了200行描述文件成功让Ghidra识别出所有自定义指令并在此基础上完成了协处理器寄存器映射表的自动提取。这种能力让逆向分析从“依赖厂商”的被动模式转变为“自主掌控”的主动模式。当你在linux脚本中调用ghidraRun命令行工具批量分析数百个.so文件或在powershell开机自启脚本中集成Ghidra API进行启动项完整性校验时你使用的已不仅是一个工具而是一个可深度融入你工作流的基础设施。3. 实战全流程详解以traceme.exe为例完成一次完整逆向分析3.1 环境准备与项目创建避开新手最常见的5个坑Ghidra的安装看似简单但细节决定成败。我见过太多人卡在第一步下载官网ghidra_11.2_PUBLIC_20230912.zip后直接双击ghidraRun.bat结果弹出Error: Could not find or load main class ghidra.GhidraLauncher。问题根源在于Java版本不匹配。Ghidra 11.x强制要求OpenJDK 17注意不是JDK 8也不是JDK 11更不是Oracle JDK。实操步骤如下卸载所有旧版Java控制面板→程序和功能→卸载所有Java(TM) SE Runtime Environment、Java Development Kit条目。尤其注意java -version返回的是否为17。安装OpenJDK 17从Adoptium官网下载Eclipse Temurin JDK 17推荐x64版本安装时勾选“Add to PATH”。验证Java环境java -version # 正确输出应为openjdk version 17.0.8 2023-07-18 # 若提示“无法将‘java’项识别为...”说明PATH未生效重启CMD或PowerShell配置Ghidra内存默认配置ghidraRun.bat中-Xmx4g对大型二进制100MB极易OOM。编辑ghidraRun.bat将-Xmx4g改为-Xmx8g需确保物理内存≥16GB。首次启动的“陷阱”启动后Ghidra会引导创建新项目。切勿选择“Non-Shared Project”这会导致后续无法使用团队协作功能如共享符号、注释。务必选择“Shared Project”即使你单人使用——它只是启用本地数据库无网络依赖。注意Ghidra项目本质是一个SQLite数据库目录.ghidra子目录。我的习惯是将所有项目存放在D:\ghidra_projects\每个子目录对应一个分析目标如D:\ghidra_projects\traceme\。这样便于用robocopy做增量备份也避免项目文件散落在各处。3.2 导入与初始分析让Ghidra“读懂”你的二进制以traceme.exe为例这是一个经典的Windows命令行工具运行后打印“Trace me!”并退出无GUI无网络行为是绝佳的入门样本导入文件在Ghidra主界面点击File → Import File选择traceme.exe。在弹出的对话框中关键设置有三处Language: 自动识别为x86:LE:64:default小端64位。若识别错误如误判为32位手动选择正确架构。Compiler: 选择Visual C。这会影响函数签名推断如__cdeclvs__stdcall调用约定。Analysis Options: 勾选Decompiler必须、Symbol Table必须、String Analysis强烈推荐、Cross Reference必须。取消勾选Data Type Archive除非你有自定义类型库。启动分析点击OK后Ghidra开始自动分析。此时不要干等观察右下角状态栏Processing Strings: 提取ASCII/Unicode字符串Trace me!会在此阶段被捕获。Creating Function Bodies: 识别函数边界基于ret、jmp等指令模式。Applying Data Types: 为全局变量、结构体应用基础类型如int、char[32]。Decompiling: 将反汇编代码转换为伪代码此步最耗时。分析完成后的“第一眼”检查分析结束后双击traceme.exe进入Code Browser。立即执行以下三步验证检查入口点在Symbol Tree左侧面板中展开Global→Functions找到entry或main函数。双击打开查看反汇编视图Listing中call指令的目标是否合理如call _printf。搜索关键字符串按CtrlF输入Trace确认Trace me!字符串出现在Data区域并查看其交叉引用右键→References to确认被哪个函数调用。验证函数数量在Functions列表中右键→Show Summary。一个健康的traceme.exeVC编译应有约15-25个函数含CRT初始化函数。若只有3-5个说明分析失败需重新导入并勾选更多选项。实操心得我习惯在分析开始前先用file命令Linux/macOS或dumpbin /headers traceme.exeWindows查看PE头信息确认其Machine字段为0x8664x64Characteristics包含DLL标志判断是否为DLL。这些信息能帮你预判Ghidra的分析策略避免盲目等待。3.3 核心分析从main函数出发逐层拆解程序逻辑假设traceme.exe的main函数已被Ghidra正确识别地址0x140001180。这是逆向的起点也是最关键的一步。反汇编视图Listing精读定位到main函数开头你会看到类似00140001180 48 83 ec 28 SUB RSP,0x28 00140001184 48 c7 44 24 18 MOV qword ptr [RSP 0x18],0x0 0014000118d 48 c7 44 24 10 MOV qword ptr [RSP 0x10],0x0 00140001196 48 c7 44 24 08 MOV qword ptr [RSP 0x8],0x0 0014000119f 48 c7 04 24 00 MOV qword ptr [RSP],0x0 001400011a6 e8 55 00 00 00 CALL FUN_140001200关键动作SUB RSP,0x28是标准的栈空间分配连续的MOV是为局部变量初始化最后的CALL指向FUN_140001200。不要急于看伪代码先在此处右键→Follow Operand跳转到FUN_140001200。这是逆向的黄金法则永远跟随控制流而非依赖反编译的“完美呈现”。反编译视图Decompiler优化在FUN_140001200中Ghidra可能生成类似void FUN_140001200(void) { int iVar1; undefined8 uVar2; long in_FS_OFFSET; undefined8 local_28; undefined8 local_20; undefined8 local_18; undefined8 local_10; long local_8; local_8 *(long *)(in_FS_OFFSET 0x28); local_28 0; local_20 0; local_18 0; local_10 0; iVar1 printf(Trace me!\n); uVar2 fflush(stdout); return; }这段代码已很清晰但仍有优化空间重命名函数右键FUN_140001200→Rename Function→ 输入print_trace_message。定义参数类型虽然此函数无参数但若后续有带参函数可在Function Signature窗口右键函数名→Edit Function Signature中手动添加void print_trace_message(void)。简化局部变量local_28等是Ghidra为栈空间生成的占位符。若确认其未被使用可右键→Delete Variable让伪代码更干净。交叉引用XRef深度挖掘在print_trace_message函数中找到printf调用行右键→References to→All References。你会发现main函数调用了它这验证了控制流。更重要的是右键Trace me!\n字符串 →References to。除了printf你还可能看到GetModuleFileNameA或GetCurrentDirectoryA的调用——这暗示程序可能在尝试获取自身路径或工作目录。这就是逆向的洞察力一个字符串的引用可能揭示程序的隐藏行为。3.4 高级技巧用脚本自动化重复性任务手动分析traceme.exe只需10分钟但面对一个包含500个函数的商业软件手动重命名、类型定义、字符串提取就是噩梦。Ghidra的脚本能力在此刻体现价值。以下是我日常使用的三个核心脚本AutoRenameByString.py自动重命名函数# -*- coding: utf-8 -*- # Ghidra Script: AutoRenameByString.py # 功能查找所有调用printf/puts的函数并根据其第一个字符串参数重命名 from ghidra.app.script import GhidraScript from ghidra.program.model.listing import CodeUnit from ghidra.program.model.symbol import SourceType from ghidra.program.model.data import StringDataType import re def get_string_at_address(addr): 从地址读取ASCII字符串 try: string_data getDataAt(addr) if string_data and string_data.getDataType() StringDataType.dataType: return string_data.getValue() except: pass return None # 获取所有函数 functions currentProgram.getFunctionManager().getFunctions(True) for func in functions: # 查找调用printf/puts的指令 for instr in func.getInstructions(True): if instr.getMnemonicString().lower() in [call, jmp]: ref_addr instr.getReference(0).getToAddress() target_func getFunctionAt(ref_addr) if target_func and target_func.getName() in [printf, puts, _printf, _puts]: # 获取第一个参数通常是字符串地址 # 简化版查找紧邻call前的mov指令 prev_instr getInstructionBefore(instr) if prev_instr and prev_instr.getMnemonicString().lower() mov: # 解析mov reg, imm指令提取imm值 op_str prev_instr.getDefaultOperandRepresentation(1) if 0x in op_str: str_addr int(op_str, 0) str_val get_string_at_address(toAddr(str_addr)) if str_val and len(str_val) 3: # 清洗字符串用于函数名 clean_name re.sub(r[^a-zA-Z0-9_], _, str_val[:20]) func.setName(fhandle_{clean_name}, SourceType.USER_DEFINED) print(fRenamed {func.getName()} to handle_{clean_name}) break运行此脚本后所有调用printf(User login failed)的函数会自动重命名为handle_User_login_failed。这比手动操作快10倍。ExportStrings.py导出所有字符串# 导出所有ASCII/Unicode字符串到CSV from ghidra.program.model.listing import CodeUnit from ghidra.program.model.data import StringDataType import csv output_file askFile(Save Strings CSV, Save) with open(output_file.absolutePath, w, newline) as f: writer csv.writer(f) writer.writerow([Address, Length, String]) for string in currentProgram.getListing().getDefinedStrings(): addr string.getAddress() length string.getLength() value string.getValue() writer.writerow([addr.toString(), length, str(value)]) print(fExported {len(list(currentProgram.getListing().getDefinedStrings()))} strings to {output_file.absolutePath})FindCryptoConstants.py定位加密常量# 基于AES/RSA/SHA常量特征扫描 from ghidra.program.model.listing import CodeUnit from ghidra.program.model.mem import MemoryBlock # AES S-Box首字节0x63 aes_sbox_pattern b\x63\x7c\x77\x7b\xf2\x6b\x6f\xc5 # RSA常用公钥指数0x10001 rsa_e_pattern b\x01\x00\x01 memory currentProgram.getMemory() for block in memory.getBlocks(): if DATA in block.getName() or RODATA in block.getName(): start block.getStart() end block.getEnd() data memory.getBytes(start, int(end.subtract(start)) 1) # 扫描AES S-Box pos data.find(aes_sbox_pattern) if pos ! -1: addr start.add(pos) print(fAES S-Box found at {addr}) # 创建数据标签 createData(addr, ArrayDataType(ByteDataType.dataType, 256, 1)) # 扫描RSA e pos data.find(rsa_e_pattern) if pos ! -1: addr start.add(pos) print(fRSA e65537 found at {addr})注意脚本需保存在Ghidra/Scripts/目录下重启Ghidra后才会出现在Script Manager中。运行前务必在Script Manager窗口中右键脚本→Edit确认其Script Language为Python。我建议新手先运行ExportStrings.py感受脚本带来的效率提升再逐步学习更复杂的逻辑。4. 常见问题与排查技巧实录那些官方文档不会告诉你的真相4.1 “反编译失败”不是Ghidra坏了是你没给它足够信息网络热词中高频出现的后反编译失败、反编译系统往往源于对Ghidra工作原理的误解。Ghidra的反编译不是魔法它需要足够的上下文信息才能生成可读代码。以下是最常见的三类失败场景及解决方案问题现象根本原因解决方案伪代码全是undefined4、local_10Ghidra未能推断出变量类型或函数签名缺失1. 右键函数→Edit Function Signature手动添加int __cdecl my_func(int a, char* b)2. 在Data区域右键疑似结构体地址→Create Structure定义字段类型3. 使用Set Data TypeD键为局部变量指定类型如int、char[64]函数体为空白或显示EXTERNAL函数被识别为外部导入如DLL函数Ghidra未加载其定义1. 在Symbol Tree中找到该函数右键→Edit Function Signature勾选Is Library Function2. 或在External Libraries中右键→Load External Library加载对应DLL的PDB或头文件反编译窗口报错Decompiler Error: ...二进制被严重混淆如控制流扁平化、虚假跳转破坏了CFG结构1. 切换到Listing视图手动修复关键跳转右键指令→Patch Instruction2. 使用Patch功能将虚假jmp改为nop3. 对于高级混淆需先用Unicorn或QEMU动态调试获取真实执行路径再回填到Ghidra实操心得我处理过一个被OLLVM混淆的libcrypto.so其SSL_connect函数反编译后完全不可读。我的做法是先用gdb附加进程设置断点在SSL_connect入口单步执行100条指令记录所有真实的call和ret地址然后在Ghidra中对这些地址范围内的指令手动标记为FunctionF键强制重建CFG。虽然耗时但比盲目猜测高效得多。4.2 “乱码”与“中文显示异常”字符编码的隐形战场androidkiller打开apk反编译过程出现乱码的问题在Ghidra中同样存在但根源不同。AndroidKiller的乱码多因APK资源文件编码如strings.xml与工具解码不匹配而Ghidra的乱码几乎100%源于字符串数据的编码方式未被正确识别。UTF-16/UCS-2乱码Windows PE文件中宽字符字符串wchar_t以UTF-16 LE存储。Ghidra默认将其作为ASCII解析显示为T\x00r\x00a\x00c\x00e\x00。解决方法在Data区域右键该字符串→Set Data Type→String→ 在弹出窗口中将Encoding下拉菜单从ASCII改为UTF-16LE点击OK乱码瞬间消失。GBK/Big5乱码国产软件常用GBK编码存储中文。Ghidra无内置GBK支持但可通过Custom Data Type解决在Data区域右键字符串→Create Data→String→ 在Data Type窗口中点击Edit→New Structure→ 添加char[128]字段 → 右键该字段→Set Data Type→String→Encoding设为GBK需提前在Ghidra安装目录Ghidra/Features/Decompiler/os/win64/下放置gbk.dat编码文件此文件可从开源项目iconv中提取。混淆字符串解密某些程序如微信小程序wxapkg会将字符串加密存储运行时解密。Ghidra只能看到密文。此时需结合动态调试用x64dbg在字符串解密函数如decrypt_string的ret指令处下断点查看解密后的明文地址再回到Ghidra中对该地址手动创建String数据。4.3 性能瓶颈与资源占用让Ghidra在老机器上也能跑起来Ghidra对硬件要求不低但并非不可优化。我在一台i5-7200U/8GB RAM的笔记本上成功分析了1.2GB的Unity GameAssembly.dll关键在于以下配置关闭非必要分析器在File → Configure...中取消勾选Python Analyzer、JavaScript Analyzer除非你明确需要分析嵌入式脚本。调整缓存大小编辑Ghidra/support/launch.properties增加VMARGS-Xms2g -Xmx6g -XX:MaxMetaspaceSize512m -XX:UseG1GC使用SSD存储项目Ghidra项目数据库.ghidra是SQLite频繁读写。将项目目录放在SSD上分析速度提升300%。分块分析大文件对于超大二进制500MB不要一次性导入。用ddLinux或HxDWindows将其切割为多个100MB片段分别分析再用Merge Program功能合并结果。最后分享一个小技巧当Ghidra界面卡顿如滚动Listing视图延迟按CtrlAltShiftD可强制刷新UI线程比重启软件快得多。这个快捷键是我在连续分析72小时后从Ghidra开发者论坛挖到的“彩蛋”。5. 从工具到能力Ghidra如何重塑你的逆向分析思维Ghidra教会我的从来不只是“怎么点按钮”。它是一面镜子照见我们对程序本质的理解深度。当我第一次用Ghidra拆解traceme.exe以为掌握了main函数就等于看懂了整个程序直到我尝试分析一个真实的银行U盾驱动才明白main可能只是冰山一角——真正的逻辑藏在DriverEntry、IRP_MJ_DEVICE_CONTROL处理例程甚至内联汇编的cpuid指令序列中。Ghidra的Data Type Archive功能让我学会用struct和union去建模硬件寄存器它的Scripting API逼我写出第一行真正有用的Python代码而它对Sleigh引擎的开放更是让我从“使用者”蜕变为“构建者”。所以如果你正被反编译jar、android apk如何进行反编译这类问题困扰请放下对“一键还原”的执念。Ghidra的价值不在于它能给你多少行伪代码而在于它赋予你一种可验证、可追溯、可协作的程序理解能力。当你能指着一段mov rax, [rdi 0x8]说“这里在读取struct config的第二个字段”当你能用脚本在10秒内定位出所有AES密钥调度表
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。