Mục đích của mã opcode CIL nop là gì?


82

Tôi đang xem qua MSIL và nhận thấy có rất nhiều hướng dẫn nop trong MSIL.

Bài báo MSDN cho biết họ không thực hiện hành động nào và được sử dụng để lấp đầy không gian nếu opcode được vá. Chúng được sử dụng nhiều hơn trong các bản dựng gỡ lỗi hơn là các bản dựng phát hành.

Tôi biết rằng những loại câu lệnh này được sử dụng trong hợp ngữ để căn chỉnh các hướng dẫn sau này, nhưng tại sao MSIL lại cần các nút lệnh trong MSIL?

(Lưu ý của người biên tập: câu trả lời được chấp nhận là về các NOP mã máy, không phải MSIL / CIL NOP mà câu hỏi đã hỏi ban đầu.)


19
Có sự nhầm lẫn hàng loạt trong các câu trả lời này giữa lệnh MSIL nop do trình biên dịch ngôn ngữ phát ra vào hợp ngữ và lệnh nop x86 (trên nền tảng đó) được phát ra bởi trình biên dịch JIT khi chạy hợp ngữ. [Thực tế, câu trả lời được chấp nhận là về x86 nops, và không liên quan đến MSIL.] Tốt nhất câu hỏi này nên được chia thành 2 câu hỏi khác nhau: mục đích của MSIL :: nop? và mục đích của nop nền tảng gốc?
Steve Steiner

Câu trả lời:


107

NOP phục vụ một số mục đích:

  • Chúng cho phép trình gỡ lỗi đặt một điểm ngắt trên một dòng ngay cả khi nó được kết hợp với những điểm khác trong mã được tạo.
  • Nó cho phép trình nạp vá một bước nhảy với một khoảng chênh lệch mục tiêu có kích thước khác nhau.
  • Nó cho phép một khối mã được căn chỉnh ở một ranh giới cụ thể, điều này có thể tốt cho việc lưu vào bộ nhớ đệm.
  • Nó cho phép liên kết gia tăng để ghi đè các đoạn mã bằng lệnh gọi đến một phần mới mà không phải lo lắng về kích thước thay đổi chức năng tổng thể.

Từ Wikipedia : "NOP được sử dụng phổ biến nhất cho mục đích định thời gian, để buộc căn chỉnh bộ nhớ, ngăn chặn các mối nguy hiểm, chiếm khe trễ nhánh, làm vô hiệu một lệnh hiện có, chẳng hạn như bước nhảy, hoặc như một trình giữ chỗ cần được thay thế bằng các hướng dẫn tích cực sau này trong quá trình phát triển chương trình (hoặc để thay thế các hướng dẫn đã bị loại bỏ khi việc tái cấu trúc sẽ có vấn đề hoặc tốn thời gian). Trong một số trường hợp, NOP có thể có các tác dụng phụ nhỏ; ví dụ, trên dòng bộ xử lý Motorola 68000, NOP opcode gây ra đồng bộ hóa đường ống. "
mbomb007

10

Đây là cách MSIL / CIL nops ( không phải mã máy x86nop ) được sử dụng để gỡ lỗi:

Các nút được sử dụng bởi trình biên dịch ngôn ngữ (C #, VB, v.v.) để xác định các điểm trình tự ngầm định. Những điều này cho trình biên dịch JIT biết nơi đảm bảo các lệnh máy có thể được ánh xạ trở lại các lệnh IL.

Mục nhập blog của Rick Byer trên DebuggingModes.IgnoreSymbolStoreSequencePoints , giải thích một số chi tiết.

C # cũng đặt Nops sau lệnh gọi để vị trí trang web trả về trong nguồn là lệnh gọi ra chứ không phải dòng sau lệnh gọi.


C # cũng đặt Nops sau lệnh gọi để vị trí trang web trả về trong nguồn là lệnh gọi ra chứ không phải dòng sau lệnh gọi. Không chắc liệu tôi có nhận được điều này hay không. Bạn có bất kỳ tài liệu tham khảo có sẵn?
user492238

8

Nó tạo cơ hội cho các điểm đánh dấu dựa trên dòng (ví dụ: điểm ngắt) trong mã mà một bản phát hành sẽ không phát ra.


Các điểm ngắt có cần phải ở trên không? Tại sao không chỉ đặt một điểm ngắt trên opcode thông thường?
Dan Goldstein

4
rất nhiều opcode thông thường được tối ưu hóa trong các phiên bản phát hành. Đó sẽ lộn xộn lên breakpoint của bạn trừ khi có một nop giữ chỗ có các breakpoint sẽ vẫn điểm đến
Jimmy

1
Trong các bản dựng gỡ lỗi, chúng cũng được sử dụng để cung cấp hướng dẫn để phá vỡ nơi mã không có hướng dẫn. Ví dụ như mở ngoặc nhọn.
Greg D

1
Bạn có thể muốn thêm tham chiếu tới blog.msdn.com/oldnewthing/archive/2007/08/17/4422794.aspx làm nguồn.
Greg D

1
Vâng, cảm ơn Greg và Jimmy đã biến điều này thành một câu trả lời thực tế.
harpo

6

Nó cũng có thể làm cho mã chạy nhanh hơn, khi tối ưu hóa cho các bộ xử lý hoặc kiến ​​trúc cụ thể:

Các bộ vi xử lý trong một thời gian dài sử dụng nhiều đường ống hoạt động gần như song song, vì vậy có thể xuất hiện hai lệnh độc lập cùng một lúc. Trên một bộ xử lý đơn giản với hai đường ống, đường ống thứ nhất có thể hỗ trợ tất cả các lệnh, trong khi đường ống thứ hai chỉ hỗ trợ một tập hợp con. Ngoài ra, có một số gian hàng giữa các đường ống khi người ta phải đợi kết quả của một hướng dẫn trước đó chưa hoàn thành.

Trong những trường hợp này, một nop chuyên dụng có thể buộc hướng dẫn tiếp theo vào một đường dẫn cụ thể (đầu tiên hoặc không phải đầu tiên) và cải thiện việc kết hợp các hướng dẫn sau để chi phí của nop nhiều hơn được khấu hao.


5

Anh bạn! No-op thật tuyệt vời! Đó là một chỉ dẫn không làm gì khác ngoài việc tiêu tốn thời gian. Trong thời kỳ tăm tối mờ mịt, bạn sẽ sử dụng nó để thực hiện các vi điều chỉnh về thời gian trong các vòng quan trọng hoặc quan trọng hơn như một bộ đệm trong mã tự sửa đổi.


Tôi hiểu cách sử dụng của nó khi nó được chạy trực tiếp trên phần cứng, nhưng MSIL đã được JITed.
Dan Goldstein

MSIL chỉ được JITed trên các hệ thống có JIT - MSIL không yêu cầu JIT.
plinth

5

Trong một bộ xử lý mà tôi đã làm việc gần đây (trong bốn năm) NOP được sử dụng để đảm bảo rằng hoạt động trước đó đã hoàn thành trước khi hoạt động tiếp theo được bắt đầu. Ví dụ:

tải giá trị để đăng ký (mất 8 chu kỳ) số 8 thêm 1 để đăng ký

Điều này đảm bảo thanh ghi có giá trị chính xác trước khi thực hiện thêm.

Một cách sử dụng khác là điền vào các đơn vị thực thi, chẳng hạn như các vectơ ngắt phải có kích thước nhất định (32 byte) vì địa chỉ cho vectơ0, chẳng hạn như 0, cho vectơ 1 0x20, v.v., vì vậy trình biên dịch đặt NOP vào đó nếu cần thiết.


4

Họ có thể sử dụng chúng để hỗ trợ chỉnh sửa và tiếp tục trong khi gỡ lỗi. Nó cung cấp cho trình gỡ lỗi không gian để làm việc để thay thế mã cũ bằng mã mới mà không thay đổi hiệu số, v.v.


4
Tôi đã triển khai hỗ trợ trình gỡ lỗi trong VS cho Chỉnh sửa và tiếp tục (tôi không triển khai CLR hoặc các phần trình biên dịch). Nops là một phần của câu chuyện để đảm bảo ánh xạ chính xác từ phiên bản cũ sang phiên bản mới của một phương thức (cụ thể là trong các trường hợp nhảy ra khỏi mã xử lý exeception). Tuy nhiên, việc thay thế MSIL được thực hiện trên cơ sở toàn bộ chức năng. Đối với mã được quản lý CLR, không cần thiết phải 'chừa chỗ' trong thư để hoàn thành phần đó. Những gì bạn nói ở đây là chính xác đối với bản gốc Chỉnh sửa và tiếp tục.
Steve Steiner

4

Một cách sử dụng hơi không chính thống là NOP-Slides , được sử dụng trong khai thác tràn bộ đệm.


đang tìm kiếm :) này
Suraj Jain

Hãy sửa lại Liên kết của bạn, nó không hoạt động, hãy luôn đảm bảo rằng, bạn đã gửi liên kết lưu trữ web, bởi vì họ sẽ không cung cấp 404 không tìm thấy.
Suraj Jain

Hiện đang làm việc trên shellcode và muốn có thêm ngữ cảnh trên NOP. Đã phải quay trở lại một chút nhưng đây là một kho lưu trữ: web.archive.org/web/20110124015428/http://www.phreedom.org:80/...
saniboy

4

50 năm quá muộn nhưng hey.

Nop rất hữu ích nếu bạn đang gõ mã lắp ráp bằng tay. Nếu bạn phải loại bỏ mã, bạn có thể chốt các mã opc cũ.

tương tự, bạn có thể chèn mã mới bằng cách ghi đè một số opcode và chuyển sang một nơi khác. Ở đó bạn đặt các mã opcodes đã ghi đè và chèn mã mới của bạn. Khi đã sẵn sàng, bạn quay trở lại.

Đôi khi bạn phải sử dụng các công cụ có sẵn. Trong một số trường hợp, đây chỉ là một trình soạn thảo mã máy rất cơ bản.

Ngày nay với các trình biên dịch, các kỹ thuật không còn ý nghĩa gì nữa.


3

Một cách sử dụng cổ điển cho chúng là để trình gỡ lỗi của bạn luôn có thể kết hợp một dòng mã nguồn với một lệnh IL.


Vì msil là JIT được biên dịch nên khi chạy có thể mất ánh xạ đó (ví dụ: lệnh gốc không có lệnh MSIL duy nhất). Các NOP được sử dụng như một cơ chế giao tiếp từ trình biên dịch ngôn ngữ đến trình biên dịch JIT để duy trì một ánh xạ như vậy.
Steve Steiner

3

Trong bối cảnh bẻ khóa phần mềm, một phương pháp cổ điển để mở khóa một ứng dụng sẽ là vá bằng một dòng NOP kiểm tra khóa hoặc đăng ký hoặc khoảng thời gian hoặc những thứ khác để nó sẽ không làm gì cả và chỉ cần tiếp tục khởi động ứng dụng như thể nó đã được đăng ký .


5
Tôi khá chắc chắn hướng dẫn không-op không được phát minh ra để giúp đỡ phần mềm người cướp biển :-)
Simon Howard

3

Tôi cũng đã thấy các NOP trong mã tự sửa đổi để làm xáo trộn những gì nó hoạt động như một trình giữ chỗ (bảo vệ bản sao cũ).


3

Như ddaa đã nói, nops cho phép bạn tính toán phương sai trong ngăn xếp, do đó khi bạn ghi đè địa chỉ trả về, nó sẽ chuyển đến nop sled (rất nhiều nops liên tiếp) và sau đó truy cập chính xác mã thực thi, thay vì nhảy đến một số byte trong lệnh không phải là đầu.


1

Chúng cho phép trình liên kết thay thế một lệnh dài hơn (thường là bước nhảy dài) bằng một lệnh ngắn hơn (bước nhảy ngắn). NOP chiếm thêm không gian - mã không thể được di chuyển xung quanh vì nó sẽ ngăn các bước nhảy khác hoạt động. Điều này xảy ra tại thời điểm liên kết, vì vậy trình biên dịch không thể biết liệu một bước nhảy dài hay ngắn sẽ phù hợp.

Ít nhất, đó là một trong những cách sử dụng truyền thống của họ.


1

Đây không phải là câu trả lời cho câu hỏi cụ thể của bạn, nhưng ngày xưa, bạn có thể sử dụng NOP để lấp đầy khoảng thời gian trễ chi nhánh , nếu bạn không thể điền vào nó bằng một hướng dẫn hữu ích khác.


1

Các trình biên dịch .NET có căn chỉnh đầu ra MSIL không? Tôi nghĩ rằng nó có thể hữu ích để tăng tốc độ truy cập vào IL ... Ngoài ra, tôi hiểu rằng nó được thiết kế để di động và các quyền truy cập được căn chỉnh là bắt buộc trên một số nền tảng phần cứng khác.


1

Hợp ngữ đầu tiên tôi học là SPARC vì vậy tôi quen thuộc với khe trễ rẽ nhánh, nếu bạn không thể điền nó bằng một lệnh khác, thường là lệnh bạn sẽ đặt phía trên lệnh rẽ nhánh hoặc tăng một bộ đếm trong vòng lặp, bạn sử dụng một NOP.

Tôi không quen với việc bẻ khóa, nhưng tôi nghĩ rằng việc ghi đè ngăn xếp bằng NOP là điều phổ biến, vì vậy bạn không phải tính toán chính xác vị trí bắt đầu chức năng độc hại của mình.


1

Tôi đã sử dụng NOP để tự động điều chỉnh độ trễ tích lũy sau khi nhập ISR. Rất tiện lợi để định thời gian chết trên móng tay.


-1

nopsẽ hữu ích trong tải trọng khai thác tham nhũng bộ nhớ. Tất nhiên noplà tương tự vớixchg eax, eax


Một câu trả lời khác đã được đề cập đến các slide NOP cho các khai thác chèn mã. Vì vậy, đã có một câu trả lời khác cho cùng một câu hỏi này. Câu trả lời này không đề cập đến cách chúng hữu ích và sẽ không rõ ràng nếu bạn chưa biết.
Peter Cordes
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.