1. jmp 和 jmpq
通常我們會(huì)看到很多類似的:
mov 對(duì)應(yīng)的有 movl咱士、movq;
call 對(duì)應(yīng)的有 callq序厉;
jum 對(duì)應(yīng)的有 jmpq;
這里多出來的一個(gè)字符表示是什么弛房?匯編代碼指令有一個(gè)字符的后綴,表明指令后面操作數(shù)的大小荷逞,如圖:
2. call和jmp
call 一般用于調(diào)用子程序粹排,ret 返回到 call 的下一行种远;
jmp 一般用于程序控制恨搓,jmp 之后的指令如果跟了 ret,那就直接退出到上一個(gè) call 對(duì)應(yīng)指令的下一行斧抱;
3. 舉例
main 函數(shù)下調(diào)用。
情況一:
// foo
mov edi,1000
call myfunction
add eax,7
ret
myfunction:
mov eax,edi ; copy our first parameter into eax (to be returned)
ret ; go back to foo
情況二:
mov edi,1000
jmp myfunction
add eax,7 ; <- never executed!
ret
myfunction:
mov eax,edi ; copy our first parameter into eax (to be returned)
ret ; go back to main
總結(jié):
- call 應(yīng)該是有個(gè)寄存器之類的地方保留了上次之前命令的位置弄抬,而 jmp 沒有宪郊。
- call 影響代碼執(zhí)行流程,而 jmp 不影響弛槐,即 jmp 本身就是流程中的一部分。所以上訴例子乎串,jmp未影響代碼執(zhí)行流程,ret 才會(huì)直接從 foo 退出到 main 函數(shù)鸯两;
4. 樁函數(shù)的例子
樁函數(shù)的調(diào)用:
打個(gè)斷點(diǎn):
(lldb) breakpoint set -a 0x7fff201932ac
Breakpoint 7: where = libobjc.A.dylib`symbol stub for: issetugid, address = 0x00007fff201932ac
進(jìn)入到樁函數(shù):
這里調(diào)用樁函數(shù)使用的是 call长豁,而樁函數(shù)內(nèi)部,取出了 __la_symbol_ptr / __got 中指針存儲(chǔ)的值之后匠襟,使用的是 jmp 進(jìn)行跳轉(zhuǎn)该园。因此机错,再遇到下一個(gè) ret 時(shí),會(huì)直接返回到 call 的下一行弱匪;
如果 call 換成 jmp 就亂了~~~
即:
- call 用來調(diào)用子程序璧亮,如函數(shù)。jmp 用來執(zhí)行指令的跳轉(zhuǎn)枝嘶;