首页 文章

短跳,相对偏移不使用我期望的偏移

提问于
浏览
1

我想了解简短的jmp指令 . 我有一个非常简单的程序,用nasm编译:

SECTION .data
bsh:    db "/bin/sh",0
arr:    dq bsh,0

        SECTION .text
        global main
main:
        jmp    short 0x20
        mov    edx, 0
        mov    rsi, arr
        mov    rdi, bsh
        mov    rax, 0x3b
        syscall

        mov    ebx, 0
        mov    eax, 0x3c
        syscall

反汇编,代码在gdb中看起来像这样(反汇编主):

0x00000000004000b0 <+0>:      jmp    0x4000d1 <main+33>
0x00000000004000b2 <+2>:      mov    $0x0,%edx
0x00000000004000b7 <+7>:      movabs $0x6000e8,%rsi
0x00000000004000c1 <+17>:     movabs $0x6000e0,%rdi
0x00000000004000cb <+27>:     mov    $0x3b,%eax
0x00000000004000d0 <+32>:     syscall
0x00000000004000d2 <+34>:     mov    $0x0,%ebx
0x00000000004000d7 <+39>:     mov    $0x3c,%eax
0x00000000004000dc <+44>:     syscall

我想跳到 0x4000d2 . 34 - 2 = 32 = 0x20 . 0x4000d2 - 0x4000b2 = 0x20 . 无论我组装什么,nasm似乎总是将跳转地址编码为跳过指令开始后一个字节的偏移量 . 为什么 jmp short 0x20 组装错误? (更不用说 jmp 0x20 有不同的结果,并且是5字节指令而不是2字节指令)

我也在阅读smashing the stack for fun and profit . Aleph1想要从jmp跳转到call,然后从call到popl . 这是他使用的代码:

jmp    0x26                 # 2 bytes
popl   %esi                 # 1 byte
movl   %esi,0x8(%esi)       # 3 bytes
movb   $0x0,0x7(%esi)       # 4 bytes
movl   $0x0,0xc(%esi)       # 7 bytes
movl   $0xb,%eax            # 5 bytes
movl   %esi,%ebx            # 2 bytes
leal   0x8(%esi),%ecx       # 3 bytes
leal   0xc(%esi),%edx       # 3 bytes
int    $0x80                # 2 bytes
movl   $0x1, %eax           # 5 bytes
movl   $0x0, %ebx           # 5 bytes
int    $0x80                # 2 bytes
call   -0x2b                # 5 bytes
.string \"/bin/sh\"         # 8 bytes

popl %esi 中的字节加到 call -0x2b 我得到42.第一条指令不应该是 jmp 0x2a 吗?并且从调用指令的末尾减去字节到 popl %esi 的开头我得到-47 . 不应该打电话 call -0x2f ?当他实际创建一个c文件并将他的程序集放在 __asm__ 块中时,他使用我计算的偏移量,但不是在此之前的代码中 . 改变了什么?

虽然我在这里,他不能只是访问eip并用它来获取内存中字符串的相对偏移量吗?

1 回答

  • 1

    使用Intel语法,这应该是:

    jmp     short $+022h    ;jump from current location ($ == 4000b0) to 4000d2
    

    请注意,使用相同的$ 022h语法的长跳转仍然会跳到4000d2,因为汇编程序会生成一个较小的偏移字段 . 这种类型的使用很少见,最常见的例外是遗留代码中使用的jmp short $ 2,以在I / O设备访问之间产生非常短的延迟 .

相关问题