機器碼call和jmp地址的計算


call和jmp都是跳轉指令,但是call的同時會把pc地址壓入堆棧,並且這兩種方式都有遠和近跳轉。下面的分析不全,因為沒有在網上找到足夠的資料,個人創造這個情景還是有些困難。

1.例子中的call的機器碼為0xe8。

  0x400204ba <+30>:     e8 41 b6 05 00 call   0x4007bb00 <__printf>

  0x400204bf <+35>:     c9     leave  

問題:0x4007bb00是如何計算得來的?

pc = 0x400204bf(取完當前指令之后,pc指向下一條語句)

另一個因為是是在x86機器上,所以是小端,那么下一個32位操作數就是0005b641,

pc + 操作數 =0x400204bf + 0x0005b641 = 0x4007bb00 

2.jmp有多種跳轉:

2.1.如果是遠跳轉,操作數是一個32位數,機器碼e9

0x40011728 <+392>: e9 46 ff ff ff jmp 0x40011673 <_dl_open+211>
0x4001172d <+397>: 8b bb ec 04 00 00 mov 0x4ec(%ebx),%edi

計算方式和call(e8)一樣,0x4001172d + 0x ffffff46 = 0x40011673 

2.2.如果是短跳轉,操作數8位數,機器碼eb

0x0804850d <+9>: c7 04 24 0a 00 00 00 movl $0xa,(%esp)
0x08048514 <+16>: e8 1f ff ff ff call 0x8048438 <sleep@plt>
0x08048519 <+21>: e8 0a ff ff ff call 0x8048428 <myprint@plt>
0x0804851e <+26>: eb ed jmp 0x804850d <main+9>

解:pc = 0x8048520

  操作數 = 0xed  

  0x8048520 + 0xed - 0x100 = 0x804850d

情況2:0x4013b30d <+93>:     eb ee  jmp    0x4013b2fd <*__GI___libc_dlsym+77>

  pc = 0x4013b30f

  操作數 = 0xee

  0x4013b30f + 0xee = 0x4013b3fd

  0x4013b3fd - 0x100 = 0x4013b2fd 

  操作數-0x100就是操作數的補碼,最高位是符號位,若為1,則代表負數,若為0 代表正數。需要擴展符號位

  0x4013b30f +0xffffffee = 0x4013b2fd 

情況3: 0x4013b2d6 <+38>:     75 2b  jne    0x4013b303 <*__GI___libc_dlsym+83>

  0x4013b2d8 + 2b  = 0x4013b303 

2.3.如果是近跳轉,操作數是16位數

  由於沒有找到合適的例子,個人覺得和短跳轉的計算方式是一樣的

2.4.以上都是相對跳轉,還有一種絕對跳轉,機器碼ff25

0x08048428 <+0>: ff 25 08 a0 04 08 jmp *0x804a008
0x0804842e <+6>: 68 10 00 00 00 push $0x10
0x08048433 <+11>: e9 c0 ff ff ff jmp 0x80483f

跳轉到0x0804a08中保存的地址。還是屬於間接跳轉。

其他的跳轉方式,等遇到了再補。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM