我想了解短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並用它來獲取內存中字符串的相對偏移量嗎?
它看起來像你得到了答案,但只是爲了重申,在大會上,你只跳轉或分支到標籤。問題是,除非直接用十六進制編寫代碼,否則實際上沒有辦法知道代碼將會變得多大,這會浪費很多時間。 –