__declspec(naked)详解
__declspec(naked)是用來(lái)告訴編譯器函數(shù)代碼的匯編語(yǔ)言為自己的所寫,不需要編譯器添加任何匯編代碼
注意點(diǎn):
[cpp]?view plaincopy注意,__declspec(naked)是編譯器直接拿來(lái)用的匯編函數(shù)代碼,所以一定要記得在開(kāi)始的時(shí)候保存上下文標(biāo)志位(壓棧),在結(jié)束的時(shí)候要記得恢復(fù)上下文(出棧)。并且在結(jié)尾要加上ret命令
比較下面兩段代碼:(都是調(diào)用strcmp函數(shù))
[cpp]?view plaincopy
對(duì)于jmp類型的hook, 如果自己的過(guò)程沒(méi)有使用_declspec(naked),那么系統(tǒng)會(huì)自動(dòng)給添加一些額外的代碼,控制堆棧平衡,但是這些額外的代碼會(huì)破壞被hook函數(shù)的堆棧。對(duì)于call類型的hook,如果使用_declspec(naked)修飾的話,要注意自己恢復(fù)堆棧平衡。使用__declspec(naked)關(guān)鍵字定義函數(shù):
1,使用 naked 關(guān)鍵字必須自己構(gòu)建 EBP 指針 (如果用到了的話,如果最后是JMP到原函數(shù),要自己在開(kāi)始構(gòu)建push ebp mov ebp, esp pushad pushfd在最后加popfd popad mov esp, ebp, pop ebp jmp xxxx);
2,必須自己使用 RET 或 RET n 指令返回?(除非你不返回,比如JMP到原函數(shù)); 對(duì)于一般的匯編內(nèi)嵌代碼(沒(méi)有使用_declspec(naked)),不必保存上下文了,保存也不會(huì)有事,但是不能再加ret命令,因?yàn)榫幾g器也會(huì)為其加一個(gè),ret命令不能同時(shí)執(zhí)行兩次。會(huì)導(dǎo)致越界錯(cuò)誤
?
?剛發(fā)現(xiàn),在naked函數(shù)中不能出現(xiàn)如int i=0;這樣的賦值
在標(biāo)明naked的函數(shù)中是不可以使用任何賦值都是不允許的。如果非要想用可以另寫一個(gè)函數(shù)進(jìn)行處理,處理完成后將結(jié)果返回既可。如果使用VS會(huì)提示以下錯(cuò)誤。
?initialized auto or register variable not allowed at function scope in 'naked' function
其實(shí)原因也很好解釋,因?yàn)閚aked和父函數(shù)共用一個(gè)ebp, 所以要子局部變量,就用esp,
naked函數(shù)就不要帶參數(shù)了,帶參數(shù)的沒(méi)必要寫成naked函數(shù)
總結(jié)
以上是生活随笔為你收集整理的__declspec(naked)详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 反汇编RETN 0x0c的理解
- 下一篇: windows终止处理程序( __try