函式開始處的MOV EDI, EDI的作用

2021-06-19 21:41:40 字數 1662 閱讀 8616

除錯程式除錯到系統庫函式的**時,總會發現系統函式都是從一條mov edi, edi指令開始的,緊接著這條指令下面才是標準的建立函式區域性棧的**。對系統dll比如ntdll.dll進行反彙編,可以發現它的每個匯出函式都是如此,並且每個匯出函式開始處的mov edi, edi上面緊接著5條nop指令。比如在windbg中檢視textouta周圍的**: 

0:000> u textouta-0x0a l 10 

gdi32!ntgditransparentblt+0xa: 

77efc43f ff12            call    dword ptr [edx] 

77efc441 c22c00          ret     2ch 

77efc444 90              nop 

77efc445 90              nop 

77efc446 90              nop 

77efc447 90              nop 

77efc448 90              nop 

gdi32!textouta: 

77efc449 8bff            mov     edi,edi 

77efc44b 55              push    ebp 

77efc44c 8bec            mov     ebp,esp 

很明顯,兩個位元組的mov edi,edi指令什麼事情也不做,那麼,就有兩個問題:第一,為什麼不直接從函式體開始而要從這條什麼都不做的指令開始呢?第二,即使需要在函式一開始空出兩個位元組,為什麼不直接使用兩條nop指令,而要使用這條mov指令呢?在網上查閱一些資料後,得到了答案: 

對於第乙個問題,答案是為了實現hot-patching技術,即執行時修改乙個函式的行為。修改過程如下:把mov edi, edi修改為一條短跳轉指令(一條短跳轉指令恰好兩個位元組),把mov edi, edi上面的五個nop修改為一條長跳轉指令(一條長跳轉指令恰好五個位元組),短跳轉指令跳到長跳轉指令上,長跳轉指令跳到修改後的函式體上。 

對於第二個問題,答案是為了提高效率。執行一條mov指令比執行兩條nop指令花費更少的時間。 

下面是在網上搜尋到的相關資料: 

在這篇日誌中作者指出這是一種實現hot-patching和hot-fix的技術,而且解釋了為什麼不使用detours技術來實現hot-patching。此外,作者提到了具體是如何使用這種技術來實現hot-patching的,但是只是一句話帶過。 

這篇文章中作者從效率和其它方面詳細解釋了為什麼選擇用這種技術來實現hot-patching以及為什麼要這樣實現(短跳轉加長跳轉而不是一次性長跳轉)。 

這裡給出了具體的memcpy的c語言源**。如果在安裝vc6的時候選擇了安裝crt源**,則在vc安裝目錄的src/intel/目錄中有memcmp.asm等檔案,它們就是對應的crt函式的源**,這些源**中也都有詳細的注釋。 

另外,在自己的日誌

裡面,曾經對strcmp函式中的mov edi, edi指令感到困惑,其實只要看看strcmp.asm中的源**就可以明白,那條mov edi, edi完全是為了記憶體四位元組對齊的。源**中寫的是align 4,在執行時,如果需要乙個填充位元組,則會填充一條nop指令,如果需要兩個位元組來填充,則會填充一條mov edi, edi指令,之所以不用兩條nop,是出於效率的考慮。

Linux檔案中開始處的feff,行末的 M

windows中的換行符為 m,若直接把windows中的檔案複製到linux中,則在linux中的檔案開始處有乙個 feff 代表著檔案的開始,包含三個位元組 0xef,0xbb,0xbf 每一行的末尾會有乙個 m 在linux中 m的轉義字元為 r,所以去除 m可以使用python中的strip...

js setTimeout 呼叫帶參函式的處理方式

settimeout callback,times js 計時器 法用於在指定的毫秒數後呼叫函式或計算表示式 此函式只執行callback一次,如果多次呼叫使用setinterval 或者callback中呼叫自己 方式1 引數中使用字串或者數字等引數的可以使用 settimeout callbac...

開始的開始

剛學習ios開發的時候,在網上看前輩們總結經驗,其中一條建議就是建立乙個自己的部落格,把自己學習過程中遇到的問題 解決方法和重要的知識點記錄下來,既可以增加印象也便於以後回顧複習。算算時間,自辭職開始自學ios也有三個月了,慚愧的是一直沒有建立自己的部落格,只是把知識點零零碎碎地記錄在印象筆記裡了。...