27

Tôi phát hiện ra rằng có thể trích xuất các chuỗi được mã hóa cứng từ một nhị phân.
Ví dụ chế độ xem thuộc tính của Process Explorer hiển thị tất cả chuỗi có nhiều hơn 3 ký tự.Làm thế nào để ẩn các chuỗi trong một exe hoặc một dll?

Đây là mã của một thực thi đơn giản mà tôi đã viết chỉ đơn giản là kiểm tra nó:

#ifndef _WIN32_WINNT 
#define _WIN32_WINNT 0x0501 
#endif 
#include <stdio.h> 
#include <tchar.h> 
#include <Windows.h> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    _TCHAR* hiddenString1 =_T("4537774B-CC80-4eda-B3E4-7A9EE77991F5"); 
    _TCHAR* hiddenString2 =_T("hidden_password_or_whatever"); 
    for (int i= 0; i<argc; i++) { 
     if (0 == _tcscmp(argv[i],hiddenString1)) { 
      _tprintf (_T("The guid argument is correct.\n")); } 
     else if (0 == _tcscmp(argv[i],hiddenString2)) { 
      _tprintf (_T("Do something here.\n")); } 
    } 

    _tprintf (_T("This is a visible string.\n")); 
    //Keep Running 
    Sleep(60000); 
    return 0; 
} 

Các chuỗi rõ ràng có thể được chiết xuất từ ​​thực thi tương ứng:
alt text

Tôi nghĩ rằng đó là một chút quá dễ dàng để tìm các chuỗi.

Câu hỏi của tôi là:

  1. Làm thế nào để đơn giản ẩn hiddenString1 hoặc hiddenString2 trong thực thi?
  2. Có cách nào an toàn hơn cách để sử dụng "mã cheat" hơn với một số thông tin ẩn bị che khuất không?
+1

Câu hỏi này về GUID hoặc về chuỗi nói chung? – xtofl

+0

GUID chỉ là một ví dụ: có các URL cho các yêu cầu http mà tôi cũng muốn ẩn. – Winz

+2

Ẩn URL cho các yêu cầu http sẽ không hoạt động. Bất kỳ ai có trình thám thính sẽ có thể thấy chính xác ứng dụng của bạn đang làm gì và làm như vậy sẽ dễ dàng hơn nhiều so với việc kiểm tra bộ nhớ của quá trình của bạn. –

Trả lời

26

Chào mừng bạn đến với thế giới lập trình phòng thủ rộng lớn hơn.

Có một số tùy chọn, nhưng tôi tin rằng tất cả chúng đều phụ thuộc vào một số hình thức obfuscation; trong đó, mặc dù không hoàn hảo, ít nhất là một cái gì đó.

  1. Thay vì giá trị chuỗi thẳng, bạn có thể lưu trữ văn bản dưới dạng nhị phân khác (hex?).

  2. Bạn có thể mã hóa các chuỗi được lưu trữ trong ứng dụng của mình, sau đó giải mã chúng trong thời gian chạy.

  3. Bạn có thể chia chúng qua các điểm khác nhau trong mã của mình và hoàn nguyên sau.

Hoặc một số kết hợp của chúng.

Lưu ý rằng một số cuộc tấn công sẽ tiến xa hơn so với việc xem xét nhị phân thực tế. Đôi khi họ sẽ điều tra không gian địa chỉ bộ nhớ của chương trình trong khi nó đang chạy. MS đã đưa ra một cái gọi là SecureString in .Net 2.0. Mục đích là để giữ cho các chuỗi được mã hóa trong khi ứng dụng đang chạy.

Ý tưởng thứ tư là không lưu trữ chuỗi trong chính ứng dụng, mà là dựa vào mã xác thực được gửi tới máy chủ mà bạn kiểm soát. Trên máy chủ, bạn có thể xác minh xem đó có phải là "mã cheat" hợp pháp hay không.

+2

Tùy chọn tốt. Vì người hỏi là đặc biệt quan tâm đến việc ẩn chuỗi Windows GUID - đó chỉ là một số thập lục phân - dữ liệu đó cũng có thể được lưu trữ dưới dạng một vài int. –

+0

Liên kết không hoạt động – user956584

+1

@Userpassword: liên kết được cập nhật – NotMe

6

Ngoài các phương thức đó, Chris đề cập đến bạn cũng có thể sử dụng thuật toán băm. Nếu tất cả những gì bạn muốn làm là kiểm tra xem ID chính xác đã được chỉ định, bạn không thực sự cần lưu toàn bộ ID trong chương trình của mình hay không.

  • Tạo băm (MD5, SHA, vv) của chuỗi/mật khẩu/id bạn muốn so sánh, có thể thêm giá trị 'muối' vào nó.Lưu trữ điều này trong chương trình của bạn
  • Khi chương trình được chạy, thực hiện cùng một thuật toán trên chuỗi đầu vào/mật khẩu/id và so sánh hai băm để xem chúng có khớp không.

Bằng cách này, văn bản thực tế không bao giờ được lưu trữ trong chương trình của bạn và họ không thể đảo ngược chương trình của bạn để tìm hiểu văn bản gốc là gì bởi vì thuật toán băm chỉ là một chiều.

+0

cẩn thận, va chạm cho một số băm (ví dụ md5) có thể được tìm thấy tương đối dễ dàng những ngày này .. –

+0

Tôi không chắc đó là một vấn đề cho việc sử dụng này. –

+1

Bạn có thể tiếp tục và chỉ thực hiện giao dịch mã khóa công khai của giao dịch mã hóa khóa publc. sẽ xử lý vấn đề xung đột. Nó cũng là một trong những cách an toàn hơn để làm điều đó - an toàn như thuật toán mã hóa bạn sử dụng, ngay cả sau khi nó được đào ra thông qua trình soạn thảo hex. –

9

Cách đơn giản nhất là mã hóa chúng với thứ gì đó tầm thường như xor hoặc rot-13 và sau đó giải mã chúng khi đang sử dụng. Điều đó sẽ loại bỏ việc xem thường xuyên của họ, nhưng nó sẽ không ngăn cản bất kỳ ai có nhiều kinh nghiệm đảo ngược.

+6

Không có gì thực sự ngăn cản bất kỳ ai có nhiều kinh nghiệm đảo ngược, vì vấn đề đó;) – n3rd

+2

Vì họ phải có khóa giải mã trong bộ nhớ để chạy chương trình thì AES cũng sẽ không dừng chúng. –

2

Nếu có một chuỗi cụ thể bạn không muốn mọi người có thể xem, sau đó mã hóa và giải mã khi chạy.

Nếu bạn không muốn mọi người nhìn thấy GUID của bạn, sau đó xây dựng nó từ byte, chứ không phải là xây dựng từ một chuỗi:

const GUID SecretGuid = 
     { 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } }; 
2

tất cả các mã bí mật của bạn sẽ được GUID hoặc là chỉ là một ví dụ?

lẽ lưu trữ bí mật của bạn như một guid nhị phân:

const GUID SecretGuid = 
    { 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } }; 

Sau đó, chuyển đổi cung cấp guid từ chuỗi sang định dạng nhị phân và so sánh hai guids nhị phân của bạn.

+0

GUID chỉ là một ví dụ. Có các URL cho các yêu cầu http mà tôi cũng muốn ẩn. – Winz

+7

Mọi người có kiến ​​thức để tìm kiếm các chuỗi trong excutable của bạn sẽ có thể bắt đầu một sniffer và xem cho HTTP-Yêu cầu từ ứng dụng của bạn. Trong thực tế, tôi sẽ thử sniffer trước khi tìm kiếm các chuỗi. –

16

Có nhiều cách để che khuất dữ liệu trong tệp thực thi. Những người khác ở đây đã đăng các giải pháp tốt - một số mạnh hơn những người khác. Tôi sẽ không thêm vào danh sách đó.

Chỉ cần lưu ý: đó là tất cả một trò chơi mèo đuổi chuột: nó là không thể để đảm bảo rằng không ai sẽ tìm ra "bí mật" của bạn.

Cho dù bạn sử dụng bao nhiêu mã hóa hoặc các thủ thuật khác; không có vấn đề bao nhiêu nỗ lực hoặc tiền bạc bạn đưa vào nó. Không có vấn đề bao nhiêu "NASA/MIT/CIA/NSA" loại có liên quan đến ẩn nó.

Tất cả đều đi xuống đến vật lý đơn giản:
Nếu nó là không thể đối với bất kỳ người sử dụng để kéo ra bí mật của bạn khỏi sự thực thi và "thôi ẩn" nó, sau đó máy tính sẽ không thể thôi ẩn nó cả, và chương trình của bạn sẽ không thể sử dụng nó. Bất kỳ nhà phát triển có kỹ năng vừa phải nào có đủ động lực sẽ tìm cách để ẩn bí mật.

Thời điểm bạn đã trao cho người dùng thực thi của mình, họ có mọi thứ họ cần để tìm ra bí mật.

Điều tốt nhất bạn có thể hy vọng là làm cho nó khó khăn như vậy để khám phá bí mật mà bất kỳ lợi ích nào bạn có thể nhận được từ việc biết bí mật trở nên không đáng lo ngại.

Vì vậy, bạn nên cố che khuất dữ liệu nếu nó chỉ là "không đẹp" để được công khai hoặc nếu hậu quả của việc trở thành công khai sẽ chỉ là "bất tiện". Nhưng thậm chí không nghĩ đến việc ẩn trong chương trình của bạn "mật khẩu cho cơ sở dữ liệu khách hàng chủ của bạn", một khóa riêng, hoặc một số bí mật quan trọng khác. Bạn không thể.

Nếu bạn có thông tin cực kỳ bí mật mà chương trình của bạn bằng cách nào đó cần nhưng KHÔNG BAO GIỜ trở thành thông tin công cộng (như khóa riêng), thì bạn sẽ cần phải có chương trình nói chuyện với máy chủ từ xa dưới sự kiểm soát của bạn, áp dụng xác thực phù hợp và các điều khiển ủy quyền (nghĩa là, hãy đảm bảo chỉ những người hoặc máy tính được phê duyệt mới có thể thực hiện yêu cầu tới máy chủ) và yêu cầu máy chủ giữ bí mật và sử dụng nó.

+1

Cũng nói. Và bánh quy thật là khá ghê gớm, bạn sẽ không thể ngăn chúng bằng một mẹo nhỏ. Họ sẽ nhận thấy các điểm nóng nơi bạn chơi với dây và kiên nhẫn cho các ứng dụng để giải mã nó để xem điều thực sự. – toto

2

Điều tốt nhất bạn có thể làm là viết mã mật khẩu hoặc chuỗi khác mà bạn muốn ẩn làm mảng char. Ví dụ:

std::string s1 = "Hello"; // This will show up in exe in hex editor 
char* s2 = "World"; // this will show up in exe in hex editor 
char s3[] = {'G', 'O', 'D'}; // this will not show up in exe in hex editor. 
+1

Trong chương trình đơn giản này trong C 'char s3 [] = {'G', 'O', 'D'}; int n = sizeof (s3)/sizeof (s3 [0]); printf ("% d \ n", n); ', tôi tìm thấy văn bản có trình chỉnh sửa hex ->' .D $ .G.D $ .O.D $ .D.D $ .' trong tệp thi hành xây dựng. – Tuksn

5

Có URL cho các yêu cầu http mà tôi muốn để ẩn quá.

Nếu ứng dụng của bạn đang đưa ra yêu cầu, không có điểm nào che giấu điều này. Chạy một ứng dụng như fiddler, phân tích http hoặc một trong hàng tá phương pháp miễn phí và có sẵn khác sẽ hiển thị tất cả lưu lượng truy cập mà ứng dụng của bạn đang tạo.

+0

Điều đó thực sự tồi tệ. : ( –

+0

@ZeeshanMahmood phần nào? – CaffGeek

+0

Có nghĩa là, chúng tôi không thể ẩn các URL trong mã như một số phương tiện khác mà chúng sẽ được tiết lộ. –

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