od随便打開一個記事本,彙編幾條jmp指令,可以看到如下
位址 HEX 反彙編
010073B4 - E9 7B9E8787 JMP 88881234
010073B9 - E9 769E8787 JMP 88881234
010073BE - E9 719E8787 JMP 88881234
010073C3 - E9 6C9E8787 JMP 88881234
010073C8 - E9 679E8787 JMP 88881234
010073CD - E9 629E8787 JMP 88881234
010073D2 - E9 5D9E8787 JMP 88881234
010073D7 - E9 589E8787 JMP 88881234
010073DC - E9 539E8787 JMP 88881234
010073E1 - E9 4E9E8787 JMP 88881234
010073E6 - E9 499E8787 JMP 88881234
可以看到同樣的彙編指令,在不同的位址上的機器碼不一樣。
有啥關系呢?看第一條:88881234-010073b4=87879e80
這個值跟E9後面的那個值差了5(E9後面那個值要反過來看,因為X86是大端模式)
同樣這個規律也使用與後面幾條。
為什麼呢?
下面摘錄一個網上的
直接的jmp分3種
Short Jump(短跳轉)機器碼 EB rel8
隻能跳轉到256位元組的範圍内
Near Jump(近跳轉)機器碼 E9 rel16/32
可跳至同一個段的範圍内的位址
Far Jump(遠跳轉)機器碼EA ptr 16:16/32
可跳至任意位址,使用48位/32位全指針
要注意的是,短跳轉和近跳轉指令中包含的操作數都是相對于(E)IP的偏移,而遠跳轉指令中包含的是目标的絕對位址,是以短/近跳轉會出現跳至同一目标的指令機器碼不同,不僅會不同,而且應該不同。而遠跳轉中包含的是絕對位址,是以轉移到同一位址的指令機器碼相同
下面的指令是這樣計算偏移的.
004A2FCE ^ E9 072BFEFF jmp 00485ADA
========
485ADA-4A2FCE= FFFE2B0C 這裡隻是指向目前指令的IP處,實際計算跳轉位址要去
掉目前指令的長度,目前的跳轉指令需要5個位元組,FFFE2B0C-5=FFFE2B07
我們一般就用E9了,是以計算公式就是 要跳轉的位址-指令所在的位置-5=機器碼
當然 如果我們要在記憶體中寫的話,肯定是寫機器碼的。也就是也E9 機器碼。
結合上面的博文,可以在被HOOK的位址出寫入JMP指令跳回到原來的地方,
被HOOK的位址-原來位址-5 = 機器碼(這個就是要寫入到 被HOOK位址的地方)
為什麼不直接修改SSDT表,因為很多程式都會循環去看又沒有被改回來,又會被修改回去。
本文轉自 h2appy 51CTO部落格,原文連結:http://blog.51cto.com/h2appy/1573921,如需轉載請自行聯系原作者