【问题标题】:Disassembling C, replace operation code反汇编C,替换操作码
【发布时间】:2012-03-10 01:57:21
【问题描述】:

我试图学习逆向的基础知识,并试图反汇编一个小型 C 程序。我在 MacOS 10.7.2(64 位 - Intel)下工作并使用 gcc 4.2.1。

#include <stdio.h>

int main() {

    char word[20];

    scanf("%s",word);
    if (strcmp(word,"password")==0) 
        printf("Correct\n");
    else
        printf("Fail\n");
}

我用gcc -o test test.c 编译,然后用gdb 工作了一段时间,我在strcmp 调用(100000e8e) 之后放置了一个断点并获取(我认为是)相关的汇编代码:

0x0000000100000e40 <main+0>:    push   %rbp
0x0000000100000e41 <main+1>:    mov    %rsp,%rbp
0x0000000100000e44 <main+4>:    sub    $0x30,%rsp
0x0000000100000e48 <main+8>:    mov    0x1e9(%rip),%rax        # 0x100001038
0x0000000100000e4f <main+15>:   mov    (%rax),%rax
0x0000000100000e52 <main+18>:   mov    %rax,-0x8(%rbp)
0x0000000100000e56 <main+22>:   lea    -0x20(%rbp),%rax
0x0000000100000e5a <main+26>:   mov    %rax,%rcx
0x0000000100000e5d <main+29>:   xor    %dl,%dl
0x0000000100000e5f <main+31>:   lea    0xda(%rip),%rsi        # 0x100000f40
0x0000000100000e66 <main+38>:   mov    %rsi,%rdi
0x0000000100000e69 <main+41>:   mov    %rcx,%rsi
0x0000000100000e6c <main+44>:   mov    %rax,-0x28(%rbp)
0x0000000100000e70 <main+48>:   mov    %dl,%al
0x0000000100000e72 <main+50>:   callq  0x100000eee <dyld_stub_scanf>
0x0000000100000e77 <main+55>:   mov    -0x28(%rbp),%rcx
0x0000000100000e7b <main+59>:   xor    %dl,%dl
0x0000000100000e7d <main+61>:   lea    0xbf(%rip),%rsi        # 0x100000f43
0x0000000100000e84 <main+68>:   mov    %rcx,%rdi
0x0000000100000e87 <main+71>:   mov    %dl,%al
0x0000000100000e89 <main+73>:   callq  0x100000ef4 <dyld_stub_strcmp>
0x0000000100000e8e <main+78>:   mov    %eax,%ecx
0x0000000100000e90 <main+80>:   cmp    $0x0,%ecx
0x0000000100000e93 <main+83>:   jne    0x100000ea6 <main+102>
0x0000000100000e95 <main+85>:   lea    0xb0(%rip),%rax        # 0x100000f4c
0x0000000100000e9c <main+92>:   mov    %rax,%rdi
0x0000000100000e9f <main+95>:   callq  0x100000ee8 <dyld_stub_puts>
0x0000000100000ea4 <main+100>:  jmp    0x100000eb5 <main+117>
0x0000000100000ea6 <main+102>:  lea    0xa7(%rip),%rax        # 0x100000f54
0x0000000100000ead <main+109>:  mov    %rax,%rdi
0x0000000100000eb0 <main+112>:  callq  0x100000ee8 <dyld_stub_puts>
0x0000000100000eb5 <main+117>:  mov    -0xc(%rbp),%eax
0x0000000100000eb8 <main+120>:  mov    0x179(%rip),%rcx        # 0x100001038
0x0000000100000ebf <main+127>:  mov    (%rcx),%rcx
0x0000000100000ec2 <main+130>:  mov    -0x8(%rbp),%rdx
0x0000000100000ec6 <main+134>:  cmp    %rdx,%rcx
0x0000000100000ec9 <main+137>:  mov    %eax,-0x2c(%rbp)
0x0000000100000ecc <main+140>:  jne    0x100000ed7 <main+151>
0x0000000100000ece <main+142>:  mov    -0x2c(%rbp),%eax
0x0000000100000ed1 <main+145>:  add    $0x30,%rsp
0x0000000100000ed5 <main+149>:  pop    %rbp
0x0000000100000ed6 <main+150>:  retq   
0x0000000100000ed7 <main+151>:  callq  0x100000edc <dyld_stub___stack_chk_fail>

现在,根据我对汇编程序的理解,事情应该很简单:在strcmp 调用 100000e89 之后,%ecx 的值被保存,然后与 0 进行比较。

如果它们不相等 (jne),则跳转 (else),否则应继续 (if)。

很好,我认为将jne 修改为je 即使输入错误,我也应该得到“正确”。

其实我没有。试图了解问题可能是什么,我试图检查操作代码,我得到一个奇怪的(对我来说)输出:

(gdb) x/8x 0x100000e93
0x100000e93 <main+83>:  0x8d481175  0x0000b005  0xc7894800  0x000044e8
0x100000ea3 <main+99>:  0x480feb00  0x00a7058d  0x89480000  0x0033e8c7

没有0f85 的符号应该是jne 的代码。

那我有点糊涂了……我不应该得到跳转的操作码吗?有人可以解释一下我的错误吗?

【问题讨论】:

    标签: c gcc gdb disassembly opcode


    【解决方案1】:

    在此处查看 JNE 的操作码: http://ref.x86asm.net/coder64.html

    所以,这是预期的: 0x8d481175 因为它是双字印刷的,而且建筑是小端的, 您有以下从该地址开始的字节序列: 75 11 48 8天

    而 75 是 64 位模式下 JNE 的操作码,具有 8 位相对偏移量。

    验证:跳转地址由下一条指令地址+偏移量计算得出。 所以, 0x0000000100000e95 + 0x11 = 0x0000000100000eA6 这正是 gdb 所显示的

    【讨论】:

    • 谢谢,它成功了。我实际上正在查看您链接的同一页面,并且我从该页面中获取了 0f85...您能否解释一下“8 位 rel 偏移”以及为什么 0f85 是错误的?
    • 8 位相对偏移量表示相对偏移量,以单字节编码,因此您的偏移量值在 -128 .. 127 之间。 64 位模式下的 0f85 操作码用于 16 位和 32 位 rel 偏移(取决于操作数大小的指令前缀)。
    • 使用各种偏移长度显然是为了节省代码大小,即如果您的跳转目标位于 8 位或 16 位范围内,则无需浪费空间将偏移量编码为 32 位整数整数范围。
    猜你喜欢
    • 1970-01-01
    • 2021-07-08
    • 2011-08-06
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 2017-01-08
    • 2014-09-17
    相关资源
    最近更新 更多