You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从CheckUserPermissionAccess函数汇编代码中提取用户名和密码?

分析CheckUserPermissionAccess汇编代码以获取用户名和密码

问题描述

如何通过分析CheckUserPermissionAccess函数的汇编代码获取用户名和密码?以下是用objdump -drwC生成的汇编代码(含重定位信息):

0000000000000120 <CheckUserPermissionAccess()>:
120:   55                      push   %rbp
121:   48 89 e5                mov    %rsp,%rbp
124:   53                      push   %rbx
125:   48 83 ec 48             sub    $0x48,%rsp
129:   64 48 8b 04 25 28 00 00 00      mov    %fs:0x28,%rax
132:   48 89 45 e8             mov    %rax,-0x18(%rbp)
136:   31 c0                   xor    %eax,%eax
138:   48 8d 45 bb             lea    -0x45(%rbp),%rax
13c:   48 89 c7                mov    %rax,%rdi
13f:   e8 00 00 00 00          callq  144   <CheckUserPermissionAccess()+0x24>   140: R_X86_64_PLT32     std::allocator<char>::allocator()-0x4
144:   48 8d 55 bb             lea    -0x45(%rbp),%rdx
148:   48 8d 45 c0             lea    -0x40(%rbp),%rax
14c:   48 8d 35 00 00 00 00    lea    0x0(%rip),%rsi        # 153 <CheckUserPermissionAccess()+0x33>   14f: R_X86_64_PC32       .rodata+0xe9
153:   48 89 c7                mov    %rax,%rdi
156:   e8 00 00 00 00          callq  15b  <CheckUserPermissionAccess()+0x3b>   157: R_X86_64_PLT32      std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char>  const&)-0x4
15b:   48 8d 45 bb             lea    -0x45(%rbp),%rax
15f:   48 89 c7                mov    %rax,%rdi
162:   e8 00 00 00 00          callq  167  <CheckUserPermissionAccess()+0x47>   163: R_X86_64_PLT32      std::allocator<char>::~allocator()-0x4
167:   c7 45 bc 00 00 00 00    movl   $0x0,-0x44(%rbp)
16e:   48 8d 35 00 00 00 00    lea    0x0(%rip),%rsi        # 175 <CheckUserPermissionAccess()+0x55>   171: R_X86_64_PC32       .rodata+0xea
175:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # 17c <CheckUserPermissionAccess()+0x5c>   178: R_X86_64_PC32       std::cout-0x4
17c:   e8 00 00 00 00          callq  181 <CheckUserPermissionAccess()+0x61>   17d: R_X86_64_PLT32       std::basic_ostream<char, std::char_traits<char> >& std::operator<<  <std::char_traits<char> >(std::basic_ostream<char,  std::char_traits<char> >&, char const*)-0x4
181:   48 8d 35 00 00 00 00    lea    0x0(%rip),%rsi        # 188  <CheckUserPermissionAccess()+0x68>   184: R_X86_64_PC32        username-0x4
188:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # 18f  <CheckUserPermissionAccess()+0x6f>   18b: R_X86_64_PC32      std::cin-0x4
18f:   e8 00 00 00 00          callq  194 <CheckUserPermissionAccess()+0x74>   190: R_X86_64_PLT32     std::basic_istream<char, std::char_traits<char> >& std::operator>> <char, std::char_traits<char> >(std::basic_istream<char, std::char_traits<char>  >&, char*)-0x4
194:   48 8d 35 00 00 00 00    lea    0x0(%rip),%rsi        # 19b  <CheckUserPermissionAccess()+0x7b>   197: R_X86_64_PC32       .rodata+0x101
19b:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # 1a2 <CheckUserPermissionAccess()+0x82>   19e: R_X86_64_PC32      std::cout-0x4
1a2:   e8 00 00 00 00          callq  1a7 <CheckUserPermissionAccess()+0x87>   1a3: R_X86_64_PLT32     std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)-0x4
1a7:   48 8d 45 c0             lea    -0x40(%rbp),%rax
1ab:   48 89 c6                mov    %rax,%rsi
1ae:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # 1b5 <CheckUserPermissionAccess()+0x95>   1b1: R_X86_64_PC32      std::cin-0x4
1b5:   e8 00 00 00 00          callq  1ba <CheckUserPermissionAccess()+0x9a>   1b6: R_X86_64_PLT32     std::basic_istream<char, std::char_traits<char> >& std::operator>> <char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)-0x4
1ba:   48 8d 45 c0             lea    -0x40(%rbp),%rax
1be:   48 8d 35 00 00 00 00    lea    0x0(%rip),%rsi        # 1c5 <CheckUserPermissionAccess()+0xa5>   1c1: R_X86_64_PC32      .rodata+0x118
1c5:   48 89 c7                mov    %rax,%rdi
1c8:   e8 00 00 00 00          callq  1cd <CheckUserPermissionAccess()+0xad>   1c9: R_X86_64_PLT32     std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare(char const*) const-0x4
1cd:   89 45 bc                mov    %eax,-0x44(%rbp)
1d0:   83 7d bc 00             cmpl   $0x0,-0x44(%rbp)
1d4:   75 07                   jne    1dd <CheckUserPermissionAccess()+0xbd>
1d6:   bb 01 00 00 00          mov    $0x1,%ebx
1db:   eb 05                   jmp    1e2 <CheckUserPermissionAccess()+0xc2>
1dd:   bb 02 00 00 00          mov    $0x2,%ebx
1e2:   48 8d 45 c0             lea    -0x40(%rbp),%rax
1e6:   48 89 c7                mov    %rax,%rdi
1e9:   e8 00 00 00 00          callq  1ee <CheckUserPermissionAccess()+0xce>   1ea: R_X86_64_PLT32     std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()-0x4
1ee:   89 d8                   mov    %ebx,%eax
1f0:   48 8b 4d e8             mov    -0x18(%rbp),%rcx
1f4:   64 48 33 0c 25 28 00 00 00      xor    %fs:0x28,%rcx
1fd:   74 3b                   je     23a <CheckUserPermissionAccess()+0x11a>
1ff:   eb 34                   jmp    235 <CheckUserPermissionAccess()+0x115>
201:   48 89 c3                mov    %rax,%rbx
204:   48 8d 45 bb             lea    -0x45(%rbp),%rax
208:   48 89 c7                mov    %rax,%rdi
20b:   e8 00 00 00 00          callq  210 <CheckUserPermissionAccess()+0xf0>   20c: R_X86_64_PLT32     std::allocator<char>::~allocator()-0x4
210:   48 89 d8                mov    %rbx,%rax
213:   48 89 c7                mov    %rax,%rdi
216:   e8 00 00 00 00          callq  21b  <CheckUserPermissionAccess()+0xfb>   217: R_X86_64_PLT32     _Unwind_Resume-0x4
21b:   48 89 c3                mov    %rax,%rbx
21e:   48 8d 45 c0             lea    -0x40(%rbp),%rax
222:   48 89 c7                mov    %rax,%rdi
225:   e8 00 00 00 00          callq  22a <CheckUserPermissionAccess()+0x10a>  226: R_X86_64_PLT32     std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()-0x4
22a:   48 89 d8                mov    %rbx,%rax
22d:   48 89 c7                mov    %rax,%rdi
230:   e8 00 00 00 00          callq  235 <CheckUserPermissionAccess()+0x115>  231: R_X86_64_PLT32     _Unwind_Resume-0x4
235:   e8 00 00 00 00          callq  23a <CheckUserPermissionAccess()+0x11a>  236: R_X86_64_PLT32     __stack_chk_fail-0x4
23a:   48 83 c4 48             add    $0x48,%rsp
23e:   5b                      pop    %rbx
23f:   5d                      pop    %rbp
240:   c3                      retq   

我曾尝试查看cmp指令以确定比对的字符,但发现仅存在一条cmp指令,这似乎意味着密码仅为单个字符,显然不合理。请问该如何从此汇编代码中获取用户名和密码?


分析与解决方法

1. 关于密码的误解

你看到的唯一cmp指令(1d0: cmpl $0x0,-0x44(%rbp))并不是直接比对单个字符,而是判断std::string::compare方法的返回值:

  • 1c8处调用的std::__cxx11::basic_string::compare会逐字符比对输入密码和硬编码的正确密码,返回0表示完全匹配;
  • 1d0的cmp只是检查返回值是否为0,以此判断密码是否正确,所以密码并不是单个字符,完整的比对逻辑在C++标准库的compare函数内部,不会出现在当前函数的汇编中。

2. 获取正确密码

正确密码硬编码在程序的只读数据段(.rodata)中,对应汇编里1be行的重定位.rodata+0x118。你可以用以下方法获取:

  • 执行objdump -s -j .rodata <二进制文件名>查看只读数据段内容,找到偏移0x118处的字符串;
  • 或者用十六进制编辑器打开二进制文件,定位到.rodata段的对应偏移位置,读取字符串。

3. 获取用户名

汇编中181行的重定位是username-0x4,说明程序存在一个全局字符数组username,用于接收输入的用户名:

  • 如果用户名是硬编码的正确值,查看.data段中username符号对应的初始内容即可;
  • 如果用户名的验证逻辑不在当前函数中,可能需要结合其他代码段分析,但从当前函数看,它仅负责接收用户名输入,没有做验证。

内容的提问来源于stack exchange,提问作者FireMonkey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 23:15:41