Làm cách nào tôi có thể ẩn hoàn toàn và bảo vệ chuỗi khỏi trình phát trong Unity?


47

Tôi đã sử dụng Unity để tạo một trò chơi 2D hoàn toàn ngoại tuyến (đó là vấn đề), trò chơi cần bạn nhập một số chuỗi nhất định ở một số cấp độ nhất định và Unity biên dịch thành DLL, có thể dễ dàng đảo ngược, vì vậy Có cách nào để bảo vệ các chuỗi đó (trò chơi đang ngoại tuyến để tôi không thể truy xuất từ ​​nguồn khác)?

Trò chơi phụ thuộc rất nhiều vào các chuỗi đó, và vâng tôi biết về Obfuscation nhưng tôi muốn thứ gì đó mạnh mẽ hơn. Và tôi biết rằng lối thoát dễ dàng sẽ là làm mọi thứ trực tuyến từ nguồn dữ liệu nhưng tôi đã tự hỏi liệu điều đó có thể không.

Nó có thể được dịch ngược như thế này: nhập mô tả hình ảnh ở đây


10
Mặc dù tôi đồng ý rằng đây là một trận chiến mà bạn không bao giờ có thể thực sự chiến thắng, nhưng bạn chắc chắn có thể làm cho nó trở nên khó khăn hơn với ít nỗ lực. obfuscar.codeplex.com
Jacob Persi

46
@Gabriele Hả? Dịch ngược mã C # không bị xáo trộn là dễ dàng như nó được. Bạn nhận được khá nhiều mã hoàn toàn có thể đọc được theo cách đó, so sánh với mã IDA tạo ra cho mã C hoặc C ++ được tối ưu hóa. Điều đó nói rằng với đủ nỗ lực, mã bản địa có thể được hiểu nhiều như vậy, nhưng đó là thứ tự cường độ khó hơn. Không biết obfuscation hoạt động tốt như thế nào - nếu nó làm cho các trình dịch ngược thông thường (DotPeek, ILSpy, một cái gì khác?) Barf trên mã IL sẽ đưa ra một rào cản để giữ người bình thường tránh xa nó.
Voo

15
@GabrieleVierti, rút ​​văn bản ra khỏi DLL là chuyện nhỏ: dưới Linux hoặc Cygwin, bạn có thể làm điều đó chỉ bằng cách trỏ stringschương trình vào nó.
Đánh dấu

31
Chính xác thì bạn đang cố gắng làm gì ở đây? Điều này có vẻ như là một trường hợp khá nghiêm trọng của vấn đề XY. meta.stackexchange.com/questions/66377/what-is-the-xy-pro Hiệu Dù bạn đang cố gắng thực hiện (từ góc độ chơi trò chơi, không phải là quan điểm kỹ thuật) gần như chắc chắn không được phục vụ tốt nhất bằng cách cố gắng ẩn và mã hóa các chuỗi này .
GrandOpener

36
Tôi tự hỏi nếu ẩn chuỗi thực sự phục vụ một mục đích: Một khi một số người chơi đã giải quyết chúng, rất có thể chúng sẽ được lan truyền trong wiki hoặc tương tự, do đó bất cứ ai muốn biết chúng sẽ dễ dàng có thể tìm kiếm chúng. Có, bằng cách làm xáo trộn chúng, người chơi không thể mở dll trong trình soạn thảo văn bản và tìm chuỗi, nhưng hầu hết sẽ tham khảo google (hoặc công cụ tìm kiếm của họ) trước tiên ...
hoffmale

Câu trả lời:


159

Không lưu trữ các chuỗi đó, lưu trữ băm (mật mã) của chúng.

Hàm băm (mật mã), như mã hóa, là một cách để biến một chuỗi thành "vô nghĩa" (được gọi là hàm băm), nhưng không giống như mã hóa, bạn không thể lấy chuỗi gốc từ hàm băm này (trừ khi bạn có thể bắt buộc hoặc băm chức năng bị hỏng). Hầu hết (nếu không phải tất cả) các hàm băm lấy một chuỗi có độ dài tùy ý và trả về một chuỗi có độ dài không đổi (phụ thuộc vào hàm).

Làm thế nào để bạn kiểm tra xem một chuỗi mà người dùng đã nhập có đúng không? Vì bạn không thể có được chuỗi hợp lệ từ hàm băm, điều duy nhất bạn có thể làm là băm đoán dự đoán của người dùng và so sánh nó với hàm băm chính xác.

Cảnh báo (bởi Eric Lippert): KHÔNG SỬ DỤNG chức năng tích hợp GetHashCodenhư một chức năng như vậy - kết quả của nó có thể khác nhau giữa các phiên bản và nền tảng .NET khác nhau, làm cho mã của bạn chỉ hoạt động trên các phiên bản và nền tảng .NET cụ thể.


81
Đây thực sự là câu trả lời tốt nhất. Nhưng hãy nhớ rằng bạn tuyệt đối tích cực không được sử dụng thuật toán băm tích hợp trên chuỗi . nó được thiết kế để làm một việc và một điều duy nhất và đó là để cân bằng một bảng băm. Bạn không thể lưu trữ băm của chuỗi và sử dụng chúng làm xác thực của một bí mật được chia sẻ vì các tác giả thời gian chạy .NET có quyền thay đổi thuật toán băm chuỗi bất cứ lúc nào vì bất kỳ lý do gì và thực tế họ đã làm như vậy trong quá khứ . Sử dụng hàm băm tiêu chuẩn về sức mạnh hoặc thực hiện hàm băm đơn giản của riêng bạn.
Eric Lippert

4
Điều này. Chính xác. Nếu bạn sử dụng một thuật toán như sha256 (có nhiều thư viện thực hiện điều này để bạn không phải tự viết) thì bạn sẽ có thứ gì đó không thể bị phá vỡ dễ dàng và rất đáng tin cậy.
Micheal Johnson

12
@Michael Johnson sử dụng muối sẽ khiến việc sử dụng bảng cầu vồng trở nên khó khăn hơn nhiều và việc sử dụng hàm băm mật khẩu như bcrypt sẽ khiến việc này chậm hơn và do đó khó phá vỡ hơn. Nhưng cuối cùng vào cuối ngày, điều này có vẻ như quá nhiều nỗ lực để đi đến; Người dùng đã mua trò chơi nếu họ muốn gian lận đó là lựa chọn của riêng họ
Melkor

2
@MichealJohnson: Kéo dài khóa có thể làm cho các cuộc tấn công vũ phu như vậy khó hơn một chút (giả sử, theo hệ số một tỷ hoặc hơn). Nhưng vấn đề thực sự với câu trả lời này là, có lẽ, đến một lúc nào đó, trò chơi cần có khả năng cho người chơi biết chuỗi nào họ cần nhập. Trừ khi những chuỗi đó thực sự là giải pháp cho một loại câu đố mà người chơi cần giải, tôi đoán vậy. Hoặc trừ khi các chuỗi được cung cấp trực tuyến, mặc dù trò chơi đang ngoại tuyến, giống như các khóa cấp phép kiểu cũ.
Ilmari Karonen

5
@Sentinel Điều đó có nghĩa là lối chơi có thể khác nhau đối với những người chơi khác nhau. Chúng tôi thực sự cần biết chúng ta đang nói về loại chuỗi nào, nếu chúng được chứa trong sách / bảng hiệu / hộp thoại trong trò chơi, nếu chúng là giải pháp cho các câu đố trong đó câu trả lời thực tế không được đưa ra cho người chơi trực tiếp, hoặc nếu chúng được tạo ngẫu nhiên. Và nếu chúng là từ, câu hoặc ký tự ngẫu nhiên.
Micheal Johnson

106

Những gì bạn đang cố gắng làm là vô ích và vô nghĩa.

Điều đó là vô ích vì không có cách nào để ẩn thông tin chính xác trên máy của người dùng. Bất cứ ai đủ tận tâm sẽ tìm thấy nó. Bạn có thể làm cho nó khó hơn, nhưng bạn không bao giờ có thể ngăn chặn nó. Nếu bạn mã hóa nó, thì bạn cần lưu trữ khóa mã hóa và thuật toán ở đâu đó. Cho dù bạn thêm bao nhiêu lớp mã hóa, lớp ngoài cùng sẽ luôn cần phải được mã hóa để trò chơi của bạn chạy.

Nó cũng là vô nghĩa, bởi vì chúng ta đang sống trong thời đại internet. Khi trò chơi của bạn trở nên phổ biến từ xa, thì những mật mã đó sẽ được đăng trên web.

Tất cả những gì bạn có thể làm là tin tưởng người chơi không phá hỏng trải nghiệm trò chơi của riêng họ bằng cách tra cứu thông tin mà trò chơi chưa được cho là đã nói với họ. Đại đa số người chơi sẽ không bắt đầu thiết kế ngược trò chơi của bạn. Và nếu một vài người có các kỹ năng cần thiết làm điều này, thì đó là lỗi của chính họ.


38
Kỹ thuật đảo ngược là một trò chơi của riêng mình! Đây là câu trả lời đúng duy nhất - hiện tại không nên ẩn thông tin trong các trò chơi một người chơi, người chơi sẽ truy cập nó nếu họ muốn.
Mephy

27
@TheBinaryGuy An toàn từ cái gì? Người dùng của bạn đang chơi một trò chơi ngoại tuyến . Những mối đe dọa nào làm lộ mã hiện tại? Người chơi cuối cùng được cho là khám phá nó bằng mọi cách để có thể chơi trò chơi! Một quy tắc bảo mật quan trọng là bạn phải xác định điều trị mà bạn đang bảo vệ; đây được gọi là "mô hình mối đe dọa."
jpmc26

7
@TheBinaryGuy Ngoài các điểm khác, tôi đặt câu hỏi về tính nhạy cảm của việc sử dụng mật mã "cố định" - ngay cả khi không tra cứu mã trực tuyến / thông qua kỹ thuật đảo ngược, chỉ cần chơi trò chơi lần thứ hai sẽ cho phép người chơi chỉ cần lướt qua các phần của trò chơi (vì họ đã biết mã). Nếu bạn thực sự muốn "buộc" người chơi kiếm được các mã này, bạn cần làm cho họ thay đổi theo từng lần phát (ví dụ: có một số hình thức ngẫu nhiên)
UnholySheep

6
Câu trả lời này có một số điểm tốt nhưng đoạn thứ hai không chính xác. Bạn không phải mã hóa chuỗi. Bạn có thể băm nó. Nếu một người chơi có thể phá vỡ hàm băm, thì thay vào đó anh ta sẽ cướp tài khoản ngân hàng, sẽ được FBI thuê, hoặc đại loại như thế. Các điểm khác là hợp lệ mặc dù.
Pedro A

5
@Rouletterific Tôi đoán câu trả lời giả định rằng bạn cần lưu trữ các chuỗi thực tế, ví dụ: để hiển thị chúng cho người chơi tại một số điểm, điều đó có nghĩa là băm sẽ không làm.
Frank Hopkins

4

Nếu một điều như vậy thực sự mong muốn, thì thay vì băm, bạn có thể xem xét việc xây dựng các chuỗi từ một giá trị đầu vào số khi chạy.

Ưu điểm là như được chỉ ra bởi @Philipp, việc thử và ẩn mã trong tệp thực thi là điều vô nghĩa nếu bạn có thể mong đợi chúng được đăng trên internet bằng mọi cách. Băm hay không, cùng một từ được tìm thấy trên internet và được đưa vào trò chơi sẽ cho cùng một hàm băm và sẽ hoạt động theo cách nào đó.

Ngoại trừ ... ngoại trừ nếu mã của người khác không phù hợp với bạn. Điều mà bạn có thể làm một cách tầm thường - không phải là giả mạo 100% nhưng khá khó để làm việc cho người dùng trung bình. Bất cứ điều gì đơn giản như "Trình tạo tên Elven trực tuyến" sẽ làm (có thể đơn giản tùy ý, thực sự không cần nhiều công cụ gen văn bản markov, kéo 4-5 âm tiết từ danh sách ngẫu nhiên là đủ tốt).

Chỉ cần tạo một số cụ thể theo người dùng hoặc máy cụ thể, nó thậm chí không phải là hoàn toàn độc đáo hoặc chống giả mạo. Một cái gì đó có khả năng khác nhau đối với hầu hết mọi người và không thể thay đổi thường xuyên, ví dụ như tên mạng của máy tính, địa chỉ MAC hoặc GUID của ổ đĩa hệ thống, bất cứ điều gì (số sê-ri GPU có thể rất tệý tưởng vì người dùng có khả năng nâng cấp GPU). Thêm vào đó là mã số mà mã mở khóa đề cập đến và đưa mã đó vào trình tạo từ của bạn. Nhưng hãy chuẩn bị để trả lời các truy vấn hỗ trợ khi người chơi sử dụng hai máy tính hoặc thay đổi card mạng của họ (điều này là bất thường, nhưng không phải là không thể). Đây có thể là một kế hoạch tốt để chỉ tạo ID ngẫu nhiên một lần và lưu trữ nó với các cài đặt của trò chơi. Bằng cách đó, ít nhất nó không phá vỡ các cài đặt hiện có trên cùng một máy nếu có gì đó thay đổi.

Hoặc, bạn chỉ có thể sử dụng số sê-ri duy nhất của trò chơi và sẽ hoạt động nếu người dùng thay đổi phần cứng (tuy nhiên, điều này có thể thúc đẩy vi phạm bản quyền vì mã mở khóa được chia sẻ hoạt động cho sê-ri lậu nhưng không dành cho khách hàng hợp pháp!).

Lưu ý rằng ngăn người dùng gian lận không nhất thiết là một điều tốt. Trong một trò chơi ngoại tuyến (tức là trò chơi không có tính cạnh tranh) thường không có vấn đề gì nếu người dùng gian lận và nhận được mã từ một nơi nào đó thay vì chơi. Anh ta chỉ đang lừa dối chính mình. Ai quan tâm.
Mặt khác, nhận được quá nhiều theo cách của họ nếu họ thực sự muốn gian lận là một cơ hội tuyệt vời để hoàn toàn chọc giận khách hàng.

Vì vậy, ... trước khi bạn làm điều gì đó theo cách đó, hãy suy nghĩ thật kỹ xem bạn có thực sự muốn điều đó không, và bạn muốn gì. Rất có thể, có các chuỗi có thể đọc được của con người (hoặc được tạo ra một cách tầm thường "không thể đọc được" bằng xor) là đủ tốt và thực sự thích hợp hơn.


Quá trình nào bạn hình dung? Nếu chương trình tạo giá trị băm sau khi được tải xuống, thì nó phải có chuỗi chưa được xóa khi tải xuống. Vì vậy, máy chủ sẽ truy vấn máy khách để xác định thông tin và sau đó tạo ra phía máy chủ băm?
Tích lũy

@Acccumulation: Máy chủ gì? Q nói "hoàn toàn ngoại tuyến". Điều này có thể có nghĩa là một chương trình trên DVD (hoặc có thể tải xuống) cộng với số sê-ri. Vì vậy, bạn có các sự kiện 1,2,3,4 mà mật mã phải tồn tại. Bạn tính toán ví dụ hash(serial + 1)để lấy một số tương ứng với mã đầu tiên. Sau đó đưa dữ liệu đó vào trình tạo từ của bạn, kéo theo một âm tiết từ danh sách 16 cho mỗi 4 bit đầu vào. Ở đó bạn đi, "từ" cá nhân cho mỗi người dùng.
Damon

Nếu đó là tải xuống, thì nó đang được tải xuống từ máy chủ. Nếu chương trình tính toán hash(serial+1) sau khi được tải xuống, điều gì sẽ ngăn người dùng tính toán hash(serial+1)? Sau khi chương trình được tải xuống, người dùng có quyền truy cập vào mọi thứ mà chương trình thực hiện.
Tích lũy

@Acccumulation: Không có gì ngăn người dùng trước tiên dịch ngược chương trình và sau đó tính toán hash(serial + 1). Vậy thì sao? Đây không phải là vấn đề. Hãy nhìn xem, nếu ai đó đầu tư một đến hai giờ (có thể là 6-8 giờ cho một "người dùng" thông thường không có nền tảng của nhà phát triển phần mềm) chỉ để lừa dối chính mình, thì ... hãy để anh ta. Vấn đề là, điều này hiệu quả với một người, nhưng không phải cho tất cả mọi người, và nó không cạnh tranh ... vì vậy, không có vấn đề gì.
Damon

3

Nếu bạn không cần hiển thị các chuỗi, thì ý tưởng băm có lẽ là cách để đi. Mặt khác, nếu bạn cần hiển thị chúng cho người dùng, có một số cách khác bạn có thể tránh để chúng hiển thị trực tiếp trong DLL của bạn.

Một cách để đối phó với điều này bên cạnh việc mã hóa hoặc làm xáo trộn các chuỗi là phá vỡ chúng. Có lẽ chỉ cần có một từ điển được sắp xếp theo thứ tự abc của tất cả các từ có thể từ tất cả các chuỗi trong trò chơi. Sau đó, có một mảng ở đâu đó cho phép bạn ghép các từ thành chuỗi bạn cần bằng cách lập chỉ mục vào mảng từ. Bằng cách này, bạn không có chuỗi hoàn chỉnh ở bất cứ đâu trong trò chơi. Không có khóa chủ cần thiết để giải mã chuỗi. Và dữ liệu cho biết thứ tự của chúng có thể ở khắp nguồn của bạn, ví dụ, nếu mỗi hàm sử dụng một chuỗi chỉ có một mảng các chỉ mục cục bộ cho hàm. Tôi không chắc nó thực tế đến mức nào trong trường hợp cụ thể của bạn, nhưng đó là một cách để làm điều đó.

Bạn thậm chí có thể có chuỗi gồm một vài từ, nhưng cuối cùng chúng lại được đặt theo các thứ tự khác nhau. Ví dụ: bạn có thể cần 2 chuỗi sau:

  1. Một con gấu đi qua nhà tôi
  2. Nhà tôi bảo vệ tôi khỏi một con gấu

Danh sách các cụm từ của bạn sẽ chứa cả "một con gấu" và "nhà của tôi", nhưng bạn có một danh sách lớn các cụm từ khác có thể được đặt ở giữa chúng, vì vậy hãy tìm ra cái nào sẽ khó như tìm ra câu đố trong trò chơi (hoặc bất cứ điều gì). Ví dụ: các cụm từ hành động có thể là "đi qua", "đốt cháy", "đẩy qua", "bảo vệ tôi khỏi", "tách tôi khỏi", "sản xuất kỳ diệu", v.v.

Bạn có thể làm việc này trong trò chơi của mình bằng cách làm cho các chỉ mục được dựa trên thứ mà người chơi đã thu thập hoặc thực hiện. Vì vậy, sẽ không có danh sách tổng thể các chỉ mục ở bất cứ đâu trong trò chơi. Chúng sẽ được tạo ra bởi người chơi đang chơi trò chơi.


4
Vì vậy, thay vì tìm hàm tham chiếu một chuỗi cụ thể, bạn tìm hàm tham chiếu một mảng bằng các chỉ mục và sau đó tạo lại chuỗi. Điều đó dường như không hơn 30 giây bảo vệ. Những gì nó bảo vệ chống lại là một người chỉ sử dụng stringschống lại thực thi mặc dù.
Voo

Như tôi đã nói, nếu các mảng tham chiếu các chuỗi được phân phối cho tất cả các hàm cần chúng, thì sẽ khó hơn một chút so với việc chỉ tìm một mảng trong một hàm duy nhất. Không phải là không thể, nhưng bao gồm một khu vực lớn hơn mà không có nhiều công việc làm thêm.
dùng1118321

Đây không phải là một hình thức mã hóa ít hơn sao?
Arturo Torres Sánchez

2
Chờ đã, thậm chí không mã hóa. Chỉ cần mã hóa.
Arturo Torres Sánchez

2
Tôi đã cập nhật câu trả lời để rõ ràng hơn. Về cơ bản, nếu các chỉ mục dựa trên thứ mà người chơi đã thực hiện, thì chúng không thực sự được lưu trữ trong trò chơi. Một lần nữa, nó có thể không phải là bằng chứng ngu ngốc, hoặc hoàn hảo, nhưng tôi đặt nó ở đây như một lựa chọn mà mọi người có thể muốn khám phá.
dùng1118321
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.