我正在通過MSIL,並注意到有很多nop說明。 MSDN文章說,他們不採取任何行動,如果操作碼被修補,則用於填充空間。它們在調試構建中比發佈構建中用得更多。我知道在彙編語言中使用這些類型的語句來確保操作碼符合字邊界,但爲什麼它在MSIL中需要?nop操作碼的用途是什麼?
回答
的NOP一舉數得:
- 他們允許調試器放置一個斷點,即使與他人在生成的代碼相結合的線。
- 它允許加載程序用不同大小的目標偏移量來跳轉跳轉。
- 它允許一段代碼在特定的邊界對齊,這對緩存很有好處。
- 它允許增量鏈接以調用新的部分來覆蓋代碼塊,而不必擔心整體功能會改變大小。
它爲代碼中的基於行的標記(例如斷點)提供了一個機會,在該代碼中,發佈版本不會發出任何消息。
斷點是否需要一個nop?爲什麼不在普通操作碼上放一個斷點? – 2008-10-24 19:23:43
許多常規操作碼在發佈版本中得到了優化。這會弄亂你的斷點,除非有一個佔位符,否則斷點仍然指向 – Jimmy 2008-10-24 19:28:49
在調試版本中,它們也被用來提供一個指令來打破代碼沒有指令的地方。例如,打開大括號。 – 2008-10-24 19:31:29
它們的一個經典用法是讓調試器始終可以將源代碼行與IL指令相關聯。
難道這不可能發生嗎? – 2008-10-24 19:24:17
由於msil在運行時編譯爲JIT,因此可能會丟失該映射(例如,本機指令沒有唯一的MSIL指令)。 NOP被用作從語言編譯器到JIT編譯器的通信機制來保存這種映射。 – 2008-12-28 18:18:50
老兄! No-op太棒了!這是一種無用之事,但消耗時間的指令。在昏暗的黑暗時代,您可以用它在關鍵循環中進行微調,或者更重要的是作爲自我修改代碼中的填充。
它們允許鏈接器用較短的指令(短跳轉)替換較長的指令(通常是跳轉)。 NOP需要額外的空間 - 代碼不能移動,因爲它會阻止其他跳轉工作。這發生在鏈接時間,所以編譯器無法知道長短跳是否合適。
至少,這是他們的傳統用途之一。
他們可能會在調試時使用它們來支持編輯和繼續。它爲調試器提供了工作空間,可以在不更改偏移量的情況下替換舊代碼。
這不是您的具體問題的答案,但回到過去,您可以使用NOP填充branch delay slot ,如果你不能用其他有用的指令填寫它。
.NET編譯器對齊MSIL輸出嗎?我想這對於加速訪問IL可能是有用的......另外,我的理解是,它的設計是可移植的,並且在一些其他硬件平臺上需要對齊訪問。
在軟件破解的場景中,解鎖應用程序的一個經典方法是使用NOP補丁來檢查密鑰或註冊或時間段,或者不會做任何事情的行,並簡單地繼續啓動應用程序如果它被註冊。
我也看到了代碼中的NOP,它修改自身以混淆它作爲佔位符(veeery舊版本保護)的功能。
的第一組裝我的教訓是SPARC所以我很熟悉的分支延遲槽,如果你不能與其他指令填充它,通常是指示你打算把分支指令高於或遞增計數器循環,你使用NOP。
我不熟悉的開裂,但我認爲這是常見的覆蓋使用NOP所以你沒有精確地計算你的惡意功能開始在堆棧。
它也可能使代碼運行速度更快,在爲特定處理器或體系結構優化時:
處理器很長一段時間採用的是並行粗略工作的多個管道,讓兩個獨立的指令能夠在同一時間exceuted。在具有兩個管道的簡單處理器上,第一個可以支持所有指令,而第二個僅支持一個子集。另外,當需要等待前一條尚未完成的指令的結果時,管道之間會有一些停頓。
在這種情況下,專用NOP可能迫使下一個指令到特定的管道(第一,或不是第一次),並提高了以下說明配對,以便NOP的費用比較比攤銷。
Nop在緩衝區溢出攻擊的有效負載中非常重要。
正如ddaa所說,nops讓你在堆棧中考慮了方差,這樣當你覆蓋返回地址時,它會跳轉到nop sled(連續很多nops),然後正確地命中可執行代碼,而不是跳轉到不是開始的指令中的某個字節。
下面是空指令是如何被用於調試:
瑞爾是由語言編譯器使用(C#,VB等)來定義隱序列點。這些告訴JIT編譯器在哪裏確保機器指令可以映射回IL指令。
上DebuggingModes.IgnoreSymbolStoreSequencePoints裏克·拜爾的博客文章,解釋了一些細節。
C#還會在呼叫指令後放置Nops,以便源中的返回站點位置是呼出而不是呼叫後的線路。
我使用NOP來自動調整進入ISR後累積的延遲。非常方便指定時間死亡。
一種略爲非正統的用途是NOP-Slides,在緩衝區溢出攻擊使用。
50年太晚了,但嘿。
如果您手動輸入彙編代碼,則Nop's非常有用。 如果您必須刪除代碼,則可以禁用舊操作碼。
similary,你可以通過覆蓋一些操作碼並在其他地方跳轉來插入新的代碼。在那裏你把覆蓋的操作碼,並插入你的新代碼。準備好後,你跳回來。有時你不得不使用可用的工具。在某些情況下,這只是一個非常基本的機器碼編輯器。
現在使用編譯器,這些技術再也沒有意義了。
在我最近工作的一個處理器(四年)中,NOP被用來確保在下一個操作開始之前先前的操作完成。例如:
負載值寄存器(需要8個週期) NOP 8 加1寄存器
這確信寄存器有該加載操作之前的正確的值。
另一個用途是填充執行單元,例如中斷向量必須是一定的大小(32字節),因爲vector0的地址是0,對於向量1 0x20等等,所以編譯器把NOP在那裏如果需要的話。
- 1. ||的用途是什麼? []操作
- 2. 什麼Java代碼將強制javac 1.6使用'swap'和'nop'操作碼?
- 3. JavaScript函數聲明中$操作符的用途是什麼?
- 4. FLATTEN操作符在PIG拉丁語中的用途是什麼?
- 5. EnableEventValidation的用途是什麼?它的工作原理是什麼?
- 6. 爲什麼ILGenerator.Emit()在動態程序集中插入nop操作碼?
- 7. `$ .support.ownLast`的用途是什麼?
- 8. TPopupActionBar的用途是什麼?
- 9. _GLOBAL__I_的用途是什麼?
- 10. $ _POST的用途是什麼?
- 11. 「$ this」的用途是什麼?
- 12. CreateSilverlight.js的用途是什麼?
- 13. vertexAttribPointer的用途是什麼?
- 14. RecognizerIntent.DETAILS_META_DATA的用途是什麼?
- 15. Rake的用途是什麼?
- 16. javax.security.auth.callback。*的用途是什麼?
- 17. config.assets.precompile的用途是什麼?
- 18. is_uploaded_file()的用途是什麼?
- 19. archetypeArtifactId的用途是什麼?
- 20. System.Data.SqlClient.SqlParameter.IsNullable的用途是什麼?
- 21. com.sun.org.apache.xpath.internal.operations.String的用途是什麼?
- 22. FXCollections.unmodifiableObservableList的用途是什麼?
- 23. __init__的用途是什麼?
- 24. __cxa_pure_virtual的用途是什麼?
- 25. cURL的用途是什麼?
- 26. RhoMobile的用途是什麼?
- 27. curdoc()的用途是什麼?
- 28. configSections的用途是什麼?
- 29. RegisterGlobalFilters的用途是什麼?
- 30. PhoneGap的用途是什麼?
這些答案在語言編譯程序發出的MSIL nop指令與程序集運行時JIT編譯器發出的x86 nop指令(在該平臺上)之間存在質量混淆。 [事實上,接受的答案是關於x86的nops,並且與MSIL沒有任何關係。] 理想情況下,這個問題應該分成兩個不同的問題:MSIL :: nop的目的是什麼?和本地平臺nop的目的? – 2009-11-29 19:57:38