assembly - 阅读 IA32 汇编代码 - 确定隐藏字符串?

标签 assembly x86 cpu-registers

我是一名计算机科学学生,正在学习 IA-32 汇编。对于一个项目,我们已经获得了程序的可执行文件。我们可以使用 objdump 等工具来检查二进制文件,但不允许查看原始源代码。该程序接收一个输入字符串并将其与另一个神秘字符串进行比较。如果两个字符串不相同,程序就会发出警报,我的作业就会不及格。这将是一项有趣的任务...如果助教愿意回答我的问题...呃...

所以,如果您不介意给我一些指示,我想向论坛询问我是否走在正确的道路上。当我在 CODE 可执行文件上运行 objdump -d CODE 时,我可以深入查看并在 main() 函数中看到这一点:

08048a44 <main>:
...
 8048af6:   e8 d0 08 00 00          call   80493cb <get_string>
 8048afb:   89 04 24                mov    %eax,(%esp)
 8048afe:   e8 ad 00 00 00          call   8048bb0 <test_string>

我相当确定 get_string() 从用户那里获取一个字符串 - 它可能是 fscanf() 或其他东西的包装函数 - 然后是指针该字符串被保存到寄存器%eax中。下一行将指针移动到 %esp,然后调用 test_string()。这是代码:

08048bb0 <test_string>:
 8048bb0:   83 ec 1c                sub    $0x1c,%esp
 8048bb3:   c7 44 24 04 6c a4 04    movl   $0x804a46c,0x4(%esp)
 8048bba:   08 
 8048bbb:   8b 44 24 20             mov    0x20(%esp),%eax
 8048bbf:   89 04 24                mov    %eax,(%esp)
 8048bc2:   e8 bd 04 00 00          call   8049084 <cmp_strings>
 8048bc7:   85 c0                   test   %eax,%eax
 8048bc9:   74 05                   je     8048bd0 <test_string+0x20>
 8048bcb:   e8 bc 07 00 00          call   804938c <alarm>
 8048bd0:   83 c4 1c                add    $0x1c,%esp
 8048bd3:   c3                      ret    

这就是我认为正在发生的事情......

08048bb0 <test_string>:
 8048bb0:   sub    $0x1c,%esp            // Adjusts %esp for new function
 8048bb3:   movl   $0x804a46c,0x4(%esp)  // test_string is stored at $0x804a46c; move that pointer into %esp
 8048bba:                                // ???
 8048bbb:   mov    0x20(%esp),%eax       // Moves test_string ptr to %eax
 8048bbf:   mov    %eax,(%esp)           // Moves test_string ptr to %esp - not sure why...?
 8048bc2:   call   8049084 <cmp_strings> // Calls cmp_strings(), probably with %eax and %esp as argument strings
 8048bc7:   test   %eax,%eax             // %eax is the returned value
 8048bc9:   je     8048bd0 <test_string+0x20>  // Should we jump to alarm()?
 8048bcb:   call   804938c <alarm>       // If we reach here, I flunk
 8048bd0:   add    $0x1c,%esp            // restores %esp to original value
 8048bd3:   ret                          // exits

所以...如果我是对的,那么第 2 行是这里最重要的一行。我怀疑神秘字符串存储在内存地址$0x804a46c中。但我不确定。我还注意到,当我使用字符串工具时,我看到了这个:

[linux]$ strings -t x CODE | grep 46c
   246c My dog has fleas.
[linux]$

这很有希望......但并不令人信服。内存地址 $0x804a46c 不是 246c

所以...对冗长的帖子表示歉意,但是人们可以告诉我我是否走在正确的道路上吗?任何见解或智慧都会受到热烈欢迎!

非常感谢! -RAO

最佳答案

除非存在一些反调试技巧,否则 cmp_strings() 只接受两个参数,这两个参数都在 test_string() 内给出。当然,它们都是字符串,第一个字符串是从常量位置 0x804a46c 获取的,而第二个字符串(指向它的指针,当然,不是字符串本身)是 的参数>test_string()。在调用之前,堆栈如下所示:

     |_______________|
ESP: | <your string> | <-- cmp_strings() 1st arg
+04: |   0x804a46c   | <-- cmp_strings() 2nd arg
+08: |      ...      |
+0C: |      ...      |
+10: |      ...      |
+14: |      ...      |
+18: |      ...      |
+1C: | return adress | <-- ESP at the start of test_string()
+20: | <your string> | <-- test_string() 1st arg
+24: |      ...      |

您可以使用 GDB 在运行时直接检查“secret”字符串内容(这通常是必要的,因为此处未显示的代码可能会重写它)。只需break *0x8048bc2运行,然后x/sb 0x804a46c

关于assembly - 阅读 IA32 汇编代码 - 确定隐藏字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40266882/

相关文章:

c++ - 正确实现 Timer1 以生成 PWM

ubuntu - Linux汇编编程中64位整数的关键字

windows - 连续几个int3

assembly - NASM 中的 "push BYTE 0x80"和 "warning: signed byte value exceeds bounds"

汇编、打印ascii码

assembly - POPCNT是如何在硬件中实现的?

c++ - SSE 指令在实践中优化了什么,编译器如何启用和使用它们?

c++ - 这是 sqrt 函数中的错误吗

gcc - 在 GCC 中使用内联 ARM 汇编时优化所用寄存器

serial-port - atmega32中UBRRH和UBRRL寄存器的作用是什么?