Câu hỏi này sẽ mất một chút giới thiệu.Hành vi ủy nhiệm của CIL với xung đột "tĩnh" của phương pháp đích
Tôi đang làm việc trên một dự án bảo mật sẽ phân tích các cụm CIL và từ chối những người thực hiện những điều "xấu" nhất định đồng thời cho phép ứng dụng lưu trữ cung cấp "cổng" cho một số phương pháp. (Đây là một tập con nhỏ của chức năng của dự án, nhưng đó là phần tôi sẽ hỏi về đây.)
Dự án quét tất cả các hướng dẫn trong mọi phương pháp trong hội đồng, và tìm kiếm cuộc gọi, callvirt, ldftn, ldvirtftn, và newobj opcodes, vì đây là những opcodes duy nhất mà cuối cùng có thể dẫn đến một cuộc gọi phương thức. Opcodes ldftn được sử dụng khi xây dựng các đại biểu, như vậy:
ldarg.1
ldftn instance bool string::EndsWith(string)
newobj instance void class [System.Core]System.Func`2<string, bool>::'.ctor'(object, native int)
Vào cuối của dãy này, một Func<string, bool>
là trên đỉnh của ngăn xếp.
Giả sử tôi muốn chặn tất cả các cuộc gọi đến String.EndsWith(String)
. Đối với cuộc gọi và callvirt, tôi chỉ có thể thay thế cuộc gọi cá thể bằng một cuộc gọi tĩnh của chữ ký Boolean(String,String)
- đối số đầu tiên sẽ là cá thể chuỗi mà phương thức ban đầu được gọi. Ở mức CIL, hành vi sẽ rõ ràng và được xác định rõ ràng, vì đây là cách các phương thức tĩnh được gọi.
Nhưng đối với ldftn? Tôi đã cố gắng chỉ cần thay thế các toán hạng của lệnh ldftn với phương pháp tĩnh cùng sử dụng để thay thế toán hạng cuộc gọi/callvirt của:
ldarg.1
ldftn bool class Prototype.Program::EndsWithGate(string, string)
newobj instance void class [System.Core]System.Func`2<string, bool>::'.ctor'(object, native int)
Tôi đã hoàn toàn mong đợi này thất bại, vì các đại biểu được đưa ra một đối tượng mục tiêu (không null) trong khi đưa một con trỏ phương thức tĩnh. Trước sự ngạc nhiên của tôi, điều này thực sự hoạt động trên cả Microsoft .NET runtime và Mono. Tôi hiểu rằng tham số đích/tham số này chỉ là tham số đầu tiên của phương thức và được ẩn cho các phương thức ví dụ. (Dự án dựa trên kiến thức này.) Nhưng thực tế là các đại biểu thực sự làm việc trong những trường hợp này là một chút khó hiểu với tôi.
Vì vậy, câu hỏi của tôi: là hành vi được xác định và được ghi lại? Sẽ đại biểu, khi được gọi, luôn luôn đẩy mục tiêu của họ vào ngăn xếp nếu nó không null? Nó sẽ được tốt hơn để xây dựng một lớp đóng cửa mà sẽ nắm bắt các mục tiêu và "đúng" gọi phương pháp tĩnh, mặc dù điều này sẽ phức tạp hơn nhiều và gây phiền nhiễu?
Nếu không có hành vi này, bạn không thể tạo đại biểu từ một phương thức tiện ích mở rộng giống như từ một phương pháp thể hiện. – CodesInChaos