我正在通过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