x86-64汇编参数传递:寻找函数参数中的密码
定位x86-64汇编函数参数密码的可行思路
嘿,我来给你梳理几个靠谱的方向,结合你手里的objdump输出和可执行文件,一步步定位这个作为参数的密码:
先把参数入栈的汇编段拆透
你提到的4006aa到4006be这段参数入栈操作,大概率是函数内部把寄存器里的参数备份到栈帧里(x86-64前6个参数存在寄存器,但函数内部可能需要临时保存)。你得逐行分析这段代码:- 比如如果是
push rdi、push rsi、push rdx...这样的序列,那每个push对应一个参数(rdi是第一个参数,rsi第二个,直到r9第六个)。 - 接着追踪这些栈上的参数副本在后续代码里的用途:有没有和某个硬编码值做
cmp比较?有没有被传递给strcmp这类字符串验证函数?这些都是密码所在参数的关键线索。
- 比如如果是
动态调试要抓准时机,别拿错参数值
你之前用GDB拿寄存器值没成功,可能是断点位置不对?试试这两个技巧:- 在调用foo的指令前下断点:先通过
objdump -d ParamsRegs | grep "call.*foo"找到调用foo的地址,比如假设是0x400700,就用b *0x400700,运行到这里时,寄存器rdi/rsi/rdx/rcx/r8/r9里的就是原始未修改的参数值,把这些值都记下来逐个试——如果参数是指针类型,记得用x/s rdi(字符串)或x/d rdi(整数)查看指向的内容,而不是直接用寄存器的地址值。 - 如果在foo入口下断点,要确保在函数修改寄存器前保存参数:比如foo刚进入时的第一条指令如果是
push rbp,那此时寄存器还没被修改,赶紧用info registers rdi rsi rdx rcx r8 r9导出所有参数。
- 在调用foo的指令前下断点:先通过
找密码验证的核心逻辑分支
密码肯定会有验证环节,你可以在objdump里搜索foo函数里的这些关键指令:- 比较指令:
cmp、test,尤其是和立即数(比如cmp rdi, 0xdeadbeef)或者内存值的比较。 - 字符串验证函数调用:比如
call strcmp、call strncmp,查看这些函数的参数(调用前rdi和rsi会是两个字符串指针),其中一个可能是用户输入,另一个就是来自foo参数的密码。 - 条件跳转指令:
jne、je、jmp,这些分支通常对应“密码正确/错误”的逻辑,顺着跳转的目标往前找,就能找到之前的验证判断。
- 比较指令:
提取可执行文件里的硬编码线索
用简单的命令就能挖出不少线索:- 提取所有字符串:
strings ParamsRegs,看看有没有可疑的字符串(比如“Wrong password”这类提示,或者看起来像密码的短字符串)。 - 搜索大的十六进制数值:
objdump -d ParamsRegs | grep "0x[0-9a-f]\{4,\}",这些可能是硬编码的密码或哈希值,和你拿到的参数值对比试试。
- 提取所有字符串:
用逆向工具简化分析(可选)
如果能用上免费的Ghidra或者IDA Pro,导入可执行文件后它们会自动生成伪代码,把寄存器参数标记为param_1到param_6,你一眼就能看出哪个参数参与了密码验证逻辑,比纯看汇编轻松太多。
内容的提问来源于stack exchange,提问作者Tribunal Homeland
相关产品推荐
相关产品推荐

