2014-03-30 46 views
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跳轉到通話,然後從通話到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並用它來獲取內存中字符串的相對偏移量嗎?

+0

它看起來像你得到了答案,但只是爲了重申,在大會上,你只跳轉或分支到標籤。問題是,除非直接用十六進制編寫代碼,否則實際上沒有辦法知道代碼將會變得多大,這會浪費很多時間。 –

回答

1

隨着Intel語法,這應該是:

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

注意,使用相同的$ + 022H語法跳遠還是會最終跳轉到4000d2,作爲彙編將產生更小的偏移字段。這種用法很少見,最常見的例外是遺留代碼中使用的jmp short $ + 2,以在I/O設備訪問之間生成非常短的延遲。

+0

這編碼'EB 1E',這是跳轉到中斷。 'jmp short 0x20'編碼'EB 1F'。 (我用gdb檢查了程序集)。 –

+0

我對這個彙編程序不熟悉,但是由於執行跳轉時的PC = 4000b2,所以PC的偏移量應該爲0x1E,最終爲4000d0。 「$」表示當前位置(與指令執行時的PC相對),使偏移更容易計算。 – rcgldr

+0

我會高興,雖然它不是我正在尋找的東西,所以我不能接受它。你使用什麼彙編程序? –