日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

__declspec(naked)详解

發布時間:2024/4/11 编程问答 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 __declspec(naked)详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

__declspec(naked)是用來告訴編譯器函數代碼的匯編語言為自己的所寫,不需要編譯器添加任何匯編代碼

注意點:

[cpp]?view plaincopy
  • void?__declspec(naked)?funname()??
  • ??
  • {??
  • _asm??
  • {??
  • ...??
  • [cpp]?view plaincopy
  • ret??
  • }??
  • }??
  • 注意,__declspec(naked)是編譯器直接拿來用的匯編函數代碼,所以一定要記得在開始的時候保存上下文標志位(壓棧),在結束的時候要記得恢復上下文(出棧)。并且在結尾要加上ret命令

    比較下面兩段代碼:(都是調用strcmp函數)

    [cpp]?view plaincopy
  • VOID?__declspec(naked)?MyNakedFunction()??
  • {??
  • strcmp(...);??
  • //?__cdecl?函數是調用者清除參數堆棧,對于非內聯匯編調用這類函數,編譯器將自動平衡堆棧,加入?ADD?ESP,?8??
  • }??
  • ??
  • VOID?__declspec(naked)?MyNakedFunction()??
  • {??
  • //...??
  • __asm?CALL?strcmp;??
  • __asm?ADD?ESP,?8;?//?內聯匯編需要自己平衡堆棧??
  • }??

  • 對于jmp類型的hook, 如果自己的過程沒有使用_declspec(naked),那么系統會自動給添加一些額外的代碼,控制堆棧平衡,但是這些額外的代碼會破壞被hook函數的堆棧。對于call類型的hook,如果使用_declspec(naked)修飾的話,要注意自己恢復堆棧平衡。使用__declspec(naked)關鍵字定義函數:

    1,使用 naked 關鍵字必須自己構建 EBP 指針 (如果用到了的話,如果最后是JMP到原函數,要自己在開始構建push ebp mov ebp, esp pushad pushfd在最后加popfd popad mov esp, ebp, pop ebp jmp xxxx);

    2,必須自己使用 RET 或 RET n 指令返回?(除非你不返回,比如JMP到原函數); 對于一般的匯編內嵌代碼(沒有使用_declspec(naked)),不必保存上下文了,保存也不會有事,但是不能再加ret命令,因為編譯器也會為其加一個,ret命令不能同時執行兩次。會導致越界錯誤

    ?

    ?剛發現,在naked函數中不能出現如int i=0;這樣的賦值

    在標明naked的函數中是不可以使用任何賦值都是不允許的。如果非要想用可以另寫一個函數進行處理,處理完成后將結果返回既可。如果使用VS會提示以下錯誤。

    ?initialized auto or register variable not allowed at function scope in 'naked' function

    其實原因也很好解釋,因為naked和父函數共用一個ebp, 所以要子局部變量,就用esp,

    naked函數就不要帶參數了,帶參數的沒必要寫成naked函數

    總結

    以上是生活随笔為你收集整理的__declspec(naked)详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。