14 thg 10, 2010

Che dấu và làm gọn mã nguồn




(Không biết nên đặt bài này ở room nào, nếu sai mấy pác Ẹcmin đổi lại dzùm biggrin )

Tôi sẽ giới thiệu với các bạn 2 kỹ thuật rất thông dụng trong lập trình là CruncherObfuscator. Chúng để làm gì? Chúng được dùng để tối ưu mã, giúp chương trình biên dịch hoặc chương trình thông dịch phân tích mã nhanh hơn và giúp che dấu mã nguồn. Hai kỹ thuật này đã có từ lâu và được sử dụng nhiều với các ngôn ngữ kịch bản (script language) như PHP, JSP, JavaScript, ... hoặc với các ngôn ngữ cấp thấp như C chẳng hạn. Khi dùng khéo léo với PHP, JavaScript tốc độ trang web tăng lên đáng kể. Trong bài viết ngắn này tôi sẽ nói về khái niệm, nguyên lý, cách sử dụng, tool (các công cụ open-source dùng cho các kỹ thuật trên) và cuối cùng là một số kinh nghiệm khi nào bạn nên dùng và nên dùng như thế nào.

1. Khái niệm
+ Cruncher: Kỹ thuật cắt tỉa và lọai bỏ dư thừa trong mã nguồn
Rất đơn giản, khi bạn viết mã, có rất nhiều thứ dư thừa (nhưng cực kỳ hữu ích) như: các lời giải thích (comment), các khoảng trắng, các đọan mã được tinh chỉnh giống như một đọan văn được trình bày cẩn thận. Để làm gì? Để bạn dễ đọc, dễ viết mã hơn. Nhưng khi dịch mã (cả thông dịch lẫn biên dịch) chúng là những ký tự vô nghĩa đối với chương trình dịch và chương trình dịch sẽ tự động lọai bỏ sự dư thừa đó. Nếu bạn lọai bỏ chúng trước rồi cho dịch mã thì trình dịch sẽ đỡ tốn thời gian làm công việc đó và tất nhiên sẽ chạy nhanh hơn.
+ Obfuscator: Kỹ thuật làm rối mã
Kỹ thuật này giống như mã hóa source code dạng thô sơ vậy. Mục đích là để bảo vệ mã nguồn và tránh bị người khác "vô tình dùng mất mà chẳng biết làm cách nào". Kỹ thuật này thay đổi tên hàm, tên lớp, tên biến, ... hoặc chia nhỏ mã nguồn thành các đọan rất khó đọc để người khác không thể đọc được. Sẽ không có bất cứ lời giải thích nào trong mã nguồn sau khi đã thay đổi. Nhưng có một số thứ không thay đổi: các từ khóa (keyword) và cấu trúc lệnh của ngôn ngữ lập trình, vì nếu thay đổi chúng, chương trình dịch cũng ... không hiểu bạn luôn. Những thứ thay đổi đó là những thứ bạn viết ra và đặt tên riêng.

2. Nguyên lý
+ Cruncher
Để hiểu tại sao cần Cruncher bạn phải hiểu nguyên lý làm việc của các chương trình dịch mã. Khi dịch mã, các chương trình dịch phải phân tích các file mã nguồn (với chúng đơn giản đây là các file văn bản có cấu trúc và được sắp xếp theo một trật tự lỏng lẻo nhưng phải tuân thủ cú pháp của ngôn ngữ lập trình). Chương trình dịch phân tích các từ khóa, các cấu trúc ngữ pháp và diễn giải những gì bạn viết ra thành các mã mới mà máy có thể hiểu và chạy được. Chúng không quan tâm đến các ký tự thừa như một chuỗi khoảng trống (không phải 1 ký tự trống vì nó giúp cho trình dịch phân biệt các từ khác nhau), các đọan ghi chú, giải thích. Khi không quan tâm thì trình dịch sẽ lọai bỏ các ký tự đó trong quá trình phân tích mã. Nếu có nhiều ký tự dư thừa, kích thước file sẽ tăng lên và trình dịch cũng phải vất vả hơn để lọai bỏ chúng. Vậy để tăng tốc độc dịch mã, đơn giản nhất là lọai bỏ ký tự thừa trước khi dịch.
+ Obfuscator: Dựa trên ngữ nghĩa của từ
Bình thường con người chỉ hiểu được các từ mang tin (có ý nghĩa theo một quy ước nào đó). Nếu gặp các từ không thuộc quy ước mà bạn biết, chắc chắn bạn sẽ không hiểu nội dung. Dựa trên nguyên lý đó, để che dấu thông tin người ta nghĩ ra mật mã. Obfuscator cũng là một dạng mật mã nhưng ở mức độ thấp. Thay vì mã hóa tòan bộ source code (vì trình dịch cũng chịu, không giải mã được, trừ khi nó được support trong thư viện runtime), người ta thay đổi tên các đối tượng: biến, hàm, lớp, giao diện (interface), nghĩa là những tên bạn đặt sẽ được thay đổi theo kiểu không ai hiểu được, kể cả chính bạn. Thuật tóan áp dụng cho việc biến đổi đó nếu làm tốt sẽ không cho phép giải mã (mã hóa một chiều), và khi thay đổi, nâng cấp, bạn phải mã hóa lại và dịch lại. Ví dụ: tôi viết một lớp lấy tên là Hello, mọi người có thể đóan được tôi định viết chào mừng ai đó tới site chẳng hạn. Sau đó tôi thay tòan bộ tên lớp Hello bằng _g, khi đó không ai hiểu hoặc đóan được, kể cả tôi, cái tên _g có nghĩa là gì. Lúc này, tôi đã obfuscate mã của tôi (chính xác thì chỉ lớp Hello mà thôi). Nếu áp dụng cho toàn bộ mã nguồn, chắc chả ai muốn đọc mã của tôi, chưa nói đến có đọc cũng chả hiểu gì.
Khi viết Obfuscator cần chú ý:
-Chỉ thay đổi những tên riêng, không thay đổi từ khóa, tên lệnh, hay các API của hệ thống
-Tránh xung đột tên. Ví dụ: nếu thay tên lớp và tên biến giống nhau, chương trình có thể chạy không giống bình thường và thậm chí là không hiểu nó đang làm gì
-Nhất quán. Khi thay đổi tên phải thay đổi toàn bộ các file nguồn có chứa cùng đối tượng đó. Ví dụ: file abc.jsp chứa lớp tên ABC thì khi đổi tên lớp ABC, tất cả các file khác có dùng lớp ABC cũng phải thay đổi theo.
-Đặt tên mới càng ngắn càng tốt. Làm như thế để dịch mã nhanh hơn, đỡ tốn công sức cho trình dịch
-Lọai bỏ dư thừa (áp dụng Crucher ở trên)

3. Cách sử dụng
Bạn hòan tòan có thể viết một cái Cruncher hoặc Obfuscator để dùng riêng hoặc dùng open source. Chạy như chương trình bình thường.

4. Một số công cụ mã nguồn mở
Tốt nhất là bạn google trên Internet, đảm bảo sẽ ra khối thứ, cả comercial lẫn open source. Thông thường thì tool cho các ngôn ngữ kịch bản như PHP, JavaScript nhiều hơn. Còn như C/C++ hay Java thì ít hơn, vì bạn cứ dịch ra file .obj hoặc .jar là OK.
Một số tool:
JavaScript: JSO (viết trên Java, chỉ có 2 file rất đơn giản) http://www.shaneng.bobos.ca/ajax/obfuscator.html
PHP: pobs099: PHP Obfuscator http://pobs.mywalhalla.net
GNU C/C++: acovea-gtk-1.0.1.tar: GNU C/C++ http://directory.fsf.org/devel/compilers/acovea.html

5. Một số kinh nghiệm
Điều hay ở 2 kỹ thuật trên là trong nhiều trường hợp, chúng làm tăng tốc độ chương trình, đặc biệt là khi dùng cho các ngôn ngữ kịch bản như PHP hay JavaScript. Mỗi lần dịch, file có kích thước nhỏ và tên biến, tên hàm, tên lớp ngắn bao giờ cũng chạy nhanh hơn. Nếu dùng nhiều file .js thì nên dùng để tăng tốc độ dịch cho JavaScript. Khi dùng với Ajax mà kích thước file .js lớn, thì giảm size của các file đó đi để truyền nhanh hơn. Ví dụ tiêu biểu cho Obfuscator là Google khi dùng cho GoogleMaps (nếu không tin thì bạn cứ down load về xem thử), họ chỉ để các API cho mọi người dùng thôi (shared not open).
Với PHP thì rõ ràng là tốt khi bạn đi trình diễn source-code cho khách hàng (nhiều người mất công làm hàng tháng trời rồi bị khách hàng cướp mất mà đành bó tay, chả biết kêu ai). Nếu có tiền sài đồ xịn hẳn là ZendStudio (mã hóa 100%, không phải mã dạng thô như Obfuscator). Tùy khả năng mà lựa chọn phương án. Nhưng lưu ý là trước khi chọn tool phải xem kỹ, nếu tool đó có thuật tóan tồi thì mã hóa cũng như không.
Chỉ khi nào cần thiết bạn mới nên dùng, còn nếu đã open source thì không dùng là rõ rồi. Khi dùng của người khác thì phải có sự đồng ý của họ bạn mới nên crunche hoặc obfuscate (JavaScript chẳng hạn).

Kết thúc
Bài này ít liên quan đến Java, nhưng 2 kỹ thuật trên là hay. Tôi post lên để cả nhà cùng coi!

3 nhận xét:

  1. Chào anh, em hiện là sinh viên và đang có project viết riêng 1 chương trình obfuscation ngăn quá trình reverse engineering, nhưng chưa biết bắt đầu từ đâu.
    Mong anh có thể giúp em hướng đi với 1 ít tài liệu liên quan được không ạ.Em cám ơn anh trước nha

    Trả lờiXóa
    Trả lời
    1. chào bạn mình cũng đang nghiên cứu về làm rối mã, bảo vệ mã nguồn.
      Bạn có tài liệu gì về vấn đề này có thể chia sẻ với mình được không ạ

      Xóa
    2. CẢM ƠN CÁC BẠN ĐÃ ỦNG HỘ NHÓM HỖ TRỢ LÀM ĐỒ ÁN CNTT TRONG THỜI GIAN QUA NHÓM SẼ CÓ NHIỀU DỊCH VỤ VÀ GIÁ CẢ PHẢI CHĂNG ĐỂ HỖ TRỢ TỐT HƠN NỮA :
      ĐT : 01629732025
      -NHỮNG NGƯỜI Ở XA THÌ XEM QUA TEAMVIEW NÓI CHUYỆN QUA SKYPE HOẶC MOBILE VÀ THANH TOÁN QUA NGÂN HÀNG .
      - Ở GẦN BỌN MÌNH CÓ THỂ HỖ TRỢ ĐƯỢC TRƯỢC TIẾP
      VÀ :
      Tất cả sẽ giúp bạn có được một đồ án công nghệ thông tin, một phần mềm, một website hoàn chỉnh theo đúng thời gian yêu cầu (chúng tôi sẽ có phác thảo cho những bạn chưa có yêu cầu của giáo viên). Chúng tôi sẽ hướng dẫn miễn phí về đồ án của bạn tới khi bảo vệ xong lưu trữ bài của các bạn khi các bạn cần lấy lại. Bạn sẽ tự tin khi nắm được bài toán và phần mềm, có thể sẵn sàng trả lời các câu hỏi vấn đáp của hội đồng.
      Các loại ngôn ngữ có kinh nghiệm:
      * C, C++
      * CSDL: Sql Sever, Mysql, Acess, Excel, XML....
      * Lập trình ứng dụng: Visual Basic 6.0, Lập trình ứng dụng trên access, C#, VB, Java.
      * Lập trình Web: HTML - CSS - Javacript , Asp, PHP - MySQL, JSP - servlet
      * Xây dựng web trên nguồn mở: Joomla, Wordpress, Joomla, Drupal, Vbulletin, Magento......
      * Xây dựng tất cả các báo cáo đồ án, luận văn trên word, powerpoint.
      Điều mong muốn nhất của nhóm là hướng dẫn cho khách hàng hiểu được bài cũng như cách thuyết trình để có kết quả bảo vệ tốt nhất.
      Các bạn có thể liên hệ với nhóm chúng tôi bằng cách gửi tin nhắn đến page hoặc
      Liên hệ: inbox hoặc call: +841629732025
      Email: codethuexyz@gmail.com
      Facebook: www.facebook.com/codethuedoancntt/

      Xóa