Trợ giúp

Deobfuscate JavaScript online: biến mã bị làm rối thành mã dễ đọc

Một JavaScript deobfuscator đảo ngược những mánh khiến mã khó đọc. Công cụ này giải nén các mảng chuỗi đơn giản, tính các biểu thức hằng, giải mã chuỗi thoát hex và Unicode, đổi tên các tên kiểu _0x, rồi in kết quả với thụt lề 2 dấu cách. Tất cả đều dựa trên việc đọc mã, không chạy mã: JavaScript của bạn không bao giờ được chạy và không bao giờ được tải lên, còn một số kiểu làm rối, nêu bên dưới, được giữ nguyên.


Deobfuscate JS online: cách dùng từng bước

  1. Dán mã vào ô JavaScript bị làm rối. Cho đến khi bạn dán, ô hiển thị “Dán JavaScript bị làm rối vào đây…”. Giới hạn là 5.000.000 ký tự.
  2. Chọn Tùy chọn gỡ làm rối để mở bốn hộp kiểm, tất cả đều bật sẵn: Giải nén mảng chuỗi, Tính các hằng số, Giải mã chuỗi thoát hex và Unicode và Đổi tên biến hex. Bỏ chọn bước nào bạn không muốn.
  3. Nhấn Gỡ làm rối. Màn hình Mã đã gỡ làm rối hiển thị kết quả dưới dạng mã được tô màu, chỉ để đọc.
  4. Đọc các nhãn phía trên mã. Chúng cho biết điều gì đã thay đổi, chẳng hạn “Đã thay 3 lượt truy cập mảng”, “Đã đơn giản hóa 5 biểu thức”, “Đã giải mã 2 giá trị” hoặc “Đã đổi tên 4 biến”. Nếu không có gì được áp dụng, nhãn ghi “Không có gì cần giải nén hay đơn giản hóa, nên mã chỉ được định dạng lại.”
  5. Nhấn Sao chép (nút chuyển thành Đã sao chép) hoặc Tải .js xuống để lưu mã thành da-go-lam-roi.js.
  6. Chọn Sửa mã để quay lại văn bản của bạn và chạy lại với các tùy chọn khác.

Nếu văn bản không phải JavaScript hợp lệ, bạn sẽ thấy “Đây không phải JavaScript hợp lệ: lỗi cú pháp ở dòng N, cột M.” kèm dòng và cột thật, và không có gì bị thay đổi.

Mỗi tùy chọn làm gì

Các bước chạy theo thứ tự đó, nên một lượt truy cập mảng có thể được giải nén trước rồi được ghép với phần bên cạnh khi tính hằng số. Tên thuộc tính, nhãn và tên import, export không bao giờ bị đổi, và dòng shebang ở đầu tập lệnh được giữ lại.

Một ví dụ cụ thể

Đầu vào này có một mảng chuỗi, một tên kiểu hex, một thuộc tính trong ngoặc kép và một phép cộng:

var _0x1a2b = ['hello', 'world', '\x68\x69']; function _0x3c(_0x4d) { console['log'](_0x1a2b[0] + ' ' + _0x1a2b[1], _0x4d, _0x1a2b[2]); } _0x3c(1 + 2 * 3);

Và đây là kết quả:

function func1(arg1) { console.log("hello world", arg1, "hi"); } func1(7);

Các nhãn ghi “Đã thay 3 lượt truy cập mảng”, “Đã đơn giản hóa 5 biểu thức”, “Đã giải mã 1 giá trị” và “Đã đổi tên 2 biến”. Kết quả thật được chia thành nhiều dòng với thụt lề 2 dấu cách.

Công cụ hoàn tác được gì và không hoàn tác được gì

Công cụ không bao giờ chạy mã của bạn, nên chỉ hoàn tác được những gì thấy trong văn bản. Mọi thứ cần chạy chương trình trước đều được giữ nguyên thay vì đoán.

Đây là công cụ hỗ trợ đọc, không phải trình quét bảo mật. Nó không kiểm tra mã có độc hại hay không và không thể biến mã lạ thành an toàn. Nếu một tập lệnh đến từ nguồn bạn không tin, đừng chạy nó chỉ vì kết quả trông gọn gàng.

Vì sao mảng chuỗi bị xoay vòng vẫn được giữ nguyên

Nhiều trình làm rối dịch chuyển các phần tử của mảng chuỗi bằng một vòng lặp ngắn trước lần đọc đầu tiên, nên list[0] không phải phần tử đầu tiên bạn thấy trong mã nguồn. Thay bằng các phần tử nhìn thấy sẽ đặt sai văn bản vào mã của bạn.

Vì vậy công cụ chỉ giải nén một mảng khi mọi lần dùng đều là list[3] với số nằm trong phạm vi, hoặc list.length. Nếu mảng được truyền vào một hàm, được thêm phần tử bằng push, bị gán lại, hoặc được đọc bằng chỉ mục mà công cụ không tính ra được, mảng đó giữ nguyên đúng như đã viết.

Unminify JavaScript online và tệp lớn

Mã đã nén nhưng chưa bị làm rối sẽ trở lại với định dạng mới và thụt lề 2 dấu cách, và nhãn cho biết chỉ bố cục thay đổi. Đó là cách unminify JavaScript ở đây: tên ngắn như a và b không bị đổi, vì chúng không phải kiểu hex và tên gốc đã mất. Nếu bạn chỉ muốn làm đẹp code JavaScript đã dễ đọc, hoặc cả JSON, HTML và CSS, hãy dùng Định dạng mã nguồn. Để thu nhỏ lại stylesheet có Nén CSS, và để giải mã một chuỗi Base64 tìm thấy trong tập lệnh có Bộ chuyển đổi Base64.

Mọi thứ chạy trong một Web Worker, nên trang vẫn phản hồi tốt với tệp lớn. Biểu thức rất dài hoặc lồng rất sâu có thể quá sức với trang, và khi đó trang báo rằng mã quá lớn hoặc lồng nhau quá sâu nên không thể xử lý ở đây.


Câu hỏi thường gặp

Làm thế nào để deobfuscate JavaScript code?

Dán mã vào “JavaScript bị làm rối” rồi nhấn “Gỡ làm rối”. Mã được chuyển thành cây cú pháp, các mảng chuỗi được giải nén, hằng số được tính, chuỗi thoát được giải mã, tên _0x được đổi, rồi cây được in lại thành mã có thụt lề. Hãy sao chép hoặc nhấn “Tải .js xuống” để lưu da-go-lam-roi.js.

Có JavaScript deobfuscator online nào dùng được ngay không?

Có, trang này là một công cụ như vậy. Nó chạy trong thẻ trình duyệt của bạn: mã được phân tích trong một Web Worker và không bao giờ được tải lên hay chạy. Nó xử lý mảng chuỗi đơn giản, biểu thức hằng, chuỗi thoát hex và Unicode, và các tên kiểu _0x. Nó không hoàn tác mọi kiểu làm rối, và danh sách những gì được giữ nguyên nằm trên trang này.

Có xử lý được mã từ obfuscator.io không?

Chỉ những phần không cần chạy mã. Chuỗi thoát hex và Unicode được giải mã, hằng số được tính và tên _0x được đổi thành var1, func1 và arg1. Mảng chuỗi mà obfuscator.io xoay vòng lúc khởi động bằng push(shift()), cùng các chuỗi lấy qua một hàm giải mã, được giữ nguyên, vì hoàn tác chúng nghĩa là phải chạy mã.

Làm sao để giải mã chuỗi hex trong mã bị làm rối?

Hãy để nguyên dấu chọn ở “Giải mã chuỗi thoát hex và Unicode” trong “Tùy chọn gỡ làm rối”. Một chuỗi như \x68\u0069 trở thành hi, và một số hex như 0x1f trở thành 31. Chỉ những chuỗi thoát nằm ngay trong mã được giải mã; chuỗi hex mà chương trình tự ghép khi chạy thì không.

Công cụ có thể unminify JavaScript code không?

Có, kết quả luôn được in lại với thụt lề 2 dấu cách, nên mã đã nén trở nên dễ đọc ngay cả khi không có gì cần giải nén. Khi đó kết quả hiện “Không có gì cần giải nén hay đơn giản hóa, nên mã chỉ được định dạng lại.” Chú thích trong đầu vào bị xóa. Tên biến đã bị rút gọn như a và b không thể khôi phục.

Công cụ có chạy JavaScript của tôi không?

Không. Mã chỉ được đọc và viết lại như văn bản. Không có eval, không gọi Function và không chạy trong trang hay trong Web Worker, vì vậy mảng bị xoay vòng và hàm giải mã được giữ nguyên. Đây cũng không phải kiểm tra bảo mật: kết quả dễ đọc hơn, nhưng trình quét hay kết luận về mã độc là việc khác.

Vì sao một mảng chuỗi vẫn còn trong kết quả?

Mảng chỉ được giải nén khi mọi lần dùng đều là chỉ mục hằng như list[3] hoặc list.length. Nếu mã còn xoay vòng nó, truyền nó vào hàm, thêm phần tử bằng push hoặc đọc bằng chỉ mục tính toán, mảng được để nguyên hoàn toàn, vì thay các lần đọc ở đó có thể cho ra chuỗi sai.

“Đổi tên biến hex” làm gì?

Nó đặt tên dễ đọc cho các tên như _0x1a2b: var1 cho biến, func1 cho hàm và arg1 cho tham số. Mọi chỗ dùng được đổi cùng lúc, không tên nào đã có trong chương trình bị dùng lại, và tên thuộc tính cùng nhãn không bao giờ bị đụng đến. Nó không khôi phục được tên gốc vì tên gốc không có trong tệp.

Mã có thể lớn đến mức nào, và nếu có lỗi thì sao?

Tối đa 5.000.000 ký tự. Nếu mã không phải JavaScript hợp lệ, bạn sẽ thấy “Đây không phải JavaScript hợp lệ: lỗi cú pháp ở dòng N, cột M.” kèm số thật, và không có gì bị thay đổi; văn bản của bạn vẫn nằm trong ô để bạn sửa đúng chỗ.

Mã của tôi có bị tải lên đâu không?

Không. Việc phân tích, viết lại và in ra đều diễn ra trong trình duyệt của bạn, trong một Web Worker, và không có gì được gửi đến máy chủ. Mã cũng không bao giờ được chạy.