2010-07-06 33 views
7

Tôi đã phát triển kỹ năng lập trình của mình đến mức tôi có thể làm mọi thứ hàng ngày khá tốt và dễ dàng, và tôi nghĩ một ngày nào đó, việc tạo ra một động cơ đa hình sẽ thực sự kiểm tra kỹ năng của tôi, và tôi đã tự hỏi tạo ra một công cụ đa hình cho một chương trình, bắt đầu từ đâu, có thể là một số ví dụ về mã? thực sự bất cứ điều gì sẽ là hữu ích vào thời điểm này :)Động cơ đa hình, bằng ngôn ngữ được quản lý?

đây là một số resorces tôi:

+1

Động cơ đa hình là gì? – OscarRyz

+2

Đoán của tôi là động cơ đa hình có liên quan đến câu lệnh chạy trên? :) –

+1

Bạn có dự định mã hóa các vi-rút được quản lý không? :) –

Trả lời

5

Như tôi đã đề cập trong nhận xét, điều này có thể bằng .NET bằng cách sử dụng không gian tên huyền diệu System.Reflection.Emit. Bạn chỉ cần tạo một DynamicMethod mới và phát ra bất kỳ [hợp lệ] opcodes vào nó, và sau đó gọi Invoke.

Tôi đã dành vài giờ cuối cùng để xây dựng một bản trình diễn đơn giản cho chương trình "sạch" sẽ tạo bản sao mới của chính nó bằng mã il đã mã hóa. Cách tiếp cận tôi đã đi là có một phương pháp Exec, lấy các il-byte (sử dụng MethodBase.GetMethodBody), mã hóa chúng và phát ra một hội đồng mới có khóa iv + và các byte được mã hóa. Phương pháp chính sau đó sẽ giải mã, tạo một DynamicMethod mới, gọi DynamicILInfo.SetCode và hy vọng làm việc. Nó không.

Máy mã hóa/giải mã hoạt động và mã được phát của tôi là chính xác. Tuy nhiên, có vẻ như bạn không thể lấy các byte thô từ một assembly và chỉ thực hiện chúng trong một assembly khác.

Dữ liệu (từ BitConverter.ToString) từ chạy A và chạy B.
A: 28-01-00-00-0A ...
B: 28-11-00-00-0A ...

Trừ khi bạn biết giá trị byte cho mọi mã vạch, hãy mở ILDAsm, chọn Xem> Hiển thị byte. Ngoài ra còn có giá trị Xem> Hiển thị mã thông báo cũng giúp gỡ lỗi. Nhấn ctrl-m cho Chế độ xem> Siêu dữ liệu> Hiển thị! để giải quyết các thẻ và các sinh vật huyền bí khác.

"28 01 00 00 0A" -> CALL 0A000001 -> [Theo ctrl-m] MethodBase.GetCurrentMethod

Những giá trị thẻ khác nhau được tạo ra liên tục bởi trình biên dịch. Điều này có nghĩa là không thể đảm bảo rằng mọi thứ sẽ hoạt động bằng cách sử dụng byte thô. Chỉ cần nghĩ về trường hợp phổ biến mà trình biên dịch chỉ tạo ra các thẻ cho mỗi cuộc gọi phương thức yêu cầu giải mã mảng byte của bạn, và bạn gọi Console.WriteLine trong mã được mã hóa của bạn. Không có mã thông báo như vậy được viết và bạn sẽ kết thúc bằng "Chữ ký nhị phân BadImageFormatException: Bad" khi gọi phương thức động của bạn.

Tôi để nó làm nhiệm vụ đọc (hoặc cho đến khi tôi lại chán) để chuyển mảng byte, trong quá trình phát, sang định dạng mà bộ giải mã có thể đọc và phát ra thành il byte thực. Quá trình phát sẽ tạo ra tất cả các thẻ cần thiết, vì vậy nó sẽ hoạt động.

Nếu bạn muốn gà ra khỏi tất cả các awesomeness phát ra opcodes, làm một số biên dịch năng động từ mã được lưu trữ như chuỗi (mà tất nhiên có thể được mã hóa). Điều này, tuy nhiên, mất cả thông minh, mát mẻ và mọi thứ khác có thể được sử dụng để đo lường sự khiếp sợ tinh khiết của nhà phát triển (BẠN!). Kiểm tra this tutorial để hiển thị nhanh việc biên dịch động và thực thi C# trong chuỗi.

+0

Bạn có bao giờ cảm thấy buồn chán nữa không? ;) – caesay

0

Vâng, theo như tôi biết một công cụ đa hình chỉ là mã bạn muốn chạy mã hóa, sau đó ghép nối với một mô-đun giải mã. Vì vậy, tất cả những gì bạn cần làm là mã hóa mã của bạn thành một chuỗi. Sau đó, bạn viết một decypter. Tôi sẽ sử dụng một lớp mã hóa đối xứng cơ bản như hxxp: //www.obviex.com/samples/Code.aspx? Source = EncryptionCS & Tiêu đề = Symmetric% 20Key% 20Encryption & Lang = C% 23 Sau đó, hãy chạy mã trong bộ nhớ, một cái gì đó như hxxp: //support.microsoft.com/kb/304655

EDIT: Nếu bạn muốn nhận được nhiều hơn nữa, bạn luôn có thể viết mã hóa/giải mã của riêng mình, làm cho nó giống như base_64 (không có khóa), thay vì AES (với một chìa khóa)

Hy vọng rằng sẽ giúp, Max

+0

Đa hình là mã không chỉ được mã hóa/giải mã, mà còn bị THAY ĐỔI mỗi lần. Mỗi khi nó được chạy, mã phải khác nhau, trong khi vẫn giữ nguyên thuật toán ban đầu. – caesay

+0

Ồ, điều đó thật thú vị. Tôi đoán bạn có thể viết ngôn ngữ cơ bản của riêng bạn, mỗi lệnh của nó sau đó sẽ có thể được dịch sang nhiều lệnh C#. Điều này sẽ cho phép bạn tạo mã của bạn, sau đó phân tích nó? Một ví dụ có thể là các vòng lặp khác nhau mà bạn có thể sử dụng bất kỳ vòng lặp nào trong số chúng để lặp qua một mảng và bạn có thể thay đổi tên biến trên đầu trang của nó. Điều đó sẽ khá đa hình đối với tôi;) – Ben

0

loại mã khác nhau là không thể trong C# hoặc người đàn ông ngôn ngữ tuổi. Nó đòi hỏi bạn phải tạo mã lắp ráp cho một nền tảng cụ thể (.NET không phải là nền tảng cụ thể) vào vùng đệm hoặc vùng dữ liệu, sau đó nhảy vào vùng đệm hoặc vùng dữ liệu đó. Có rất nhiều lớp phần mềm và phần cứng tại chỗ để ngăn chặn điều đó xảy ra - xem bit NX trên Wikipedia chẳng hạn.

Bạn không thể làm điều đó trong mã được quản lý. Bạn sẽ phải viết nó trong mã không được quản lý và gọi vào đó.

Hy vọng điều đó sẽ hữu ích.


Vui lòng xem nhận xét hữu ích về câu trả lời này, vì bạn có thể tự động tạo mã được quản lý từ mã được quản lý; Tôi đã xem xét mã không được quản lý, như được sử dụng trên toàn bộ.

+3

Nhưng bạn không thể phát ra mã IL thành một DynamicMethod và Invoke()? – sisve

+1

Có, đề nghị bạn viết câu trả lời về điều đó! –

+0

@ simon bạn thực sự nên, mà âm thanh như một giải pháp rất tốt. – Ben

Các vấn đề liên quan