2012-06-20 74 views
10

Tôi cần tìm phương thức exe/dll đã được xây dựng để xem các tiêu đề của nó hay không. [sửa] Chỉ sử dụng C++ mà không cần bất kỳ công cụ bên ngoài nào. [/ edit]Cách kiểm tra xem tệp thi hành hoặc DLL có được xây dựng trong chế độ Phát hành hoặc Gỡ lỗi (C++)

Có một cuộc thảo luận cũ về cách xác định dll được xây dựng trong chế độ Release hoặc Debug. http://forums.codeguru.com/archive/index.php/t-485996.html

Nhưng tiếc là tôi không tìm thấy câu trả lời rõ ràng nào.

+0

Điều gì chính xác bị thiếu trong cuộc thảo luận đó, hoặc bạn muốn làm gì? Không có câu trả lời rõ ràng cho điều này, bởi vì không có cách nào để biết điều này mà không phân tích các dll lên gần. – RedX

+0

Bạn xem điều gì là Chế độ phát hành hoặc Gỡ lỗi? Exe/dll của bạn có bao gồm tài nguyên phiên bản không? – harper

+0

Không có 100% đảm bảo rằng phiên bản được bao gồm. – ChatCloud

Trả lời

6

Tôi cần tìm chế độ exe/dll được xây dựng đang xem xét tiêu đề của nó.

Nếu bằng cách "tiêu đề" bạn có nghĩa là phần PE hoặc các nguồn (tiêu đề sẽ không cho bạn bất cứ điều gì, và các chương trình thường không được vận chuyển với tiêu đề phát triển họ!), Đây là loại có thể, trong giới hạn, và không chắc chắn. Nếu không, đây là một nỗ lực hoàn toàn không thể trừ khi bạn đã tự mình viết chương trình.

Nói chung, rất khó để làm một điều như vậy một cách đáng tin cậy, thậm chí nhiều hơn để "gỡ lỗi xây dựng" là một đơn giản hóa Microsoft Visual Studio không tồn tại như vậy trong hầu hết các trình biên dịch. Ví dụ, với GCC, nó hoàn toàn được phép có một cấu trúc được tối ưu hoá được tối ưu hóa mà vẫn chứa các biểu tượng gỡ lỗi. Thậm chí có thể bật và tắt tối ưu hóa với #pragma (và thay đổi mức tối ưu hóa và thậm chí cả máy mục tiêu!) Và do đó có các chức năng được tối ưu hóa (hoặc các nhóm chức năng) trong một bản dựng chưa được tối ưu hóa và ngược lại.

Sự hiện diện của các biểu tượng gỡ lỗi là dự đoán tốt nhất cho một chương trình mà bạn không viết. Nó không phải là có thể (không thực tế, trong một cách đơn giản, tự động, anyway) để nói từ một nhị phân được tạo ra cho dù nó đã được tối ưu hóa hay không.

Các phần .debug$S.debug$T chứa các biểu tượng gỡ lỗi và loại gỡ lỗi tương ứng. Có một số phần khác bắt đầu bằng .debug, nhưng chúng không còn được dùng nữa. Một chương trình đã được xây dựng trong "chế độ gỡ lỗi" và sau đó đã không bị tước sẽ chứa một số hoặc tất cả các phần này.
Sử dụng C++ không có công cụ bên ngoài, bạn sẽ muốn bỏ qua phần gốc DOS "MZ" và tiêu đề PE. Sau khi đến phần tiêu đề, bạn có thể phân tích cú pháp. Toàn bộ tài liệu của định dạng tệp có thể được tải xuống here.
Rất có thể, đọc tệp và thực hiện đối sánh chuỗi cho .debug cũng sẽ tốt.

Tương tự, bạn có thể xem VERSIONINFO hoặc tệp kê khai (chúng cũng cho phép xác định xem chương trình là một bản dựng gỡ lỗi), nhưng đây không phải là bắt buộc. Bạn có thể viết khá nhiều thứ bạn muốn vào. Insofar, chúng thậm chí còn kém tin cậy hơn là tìm kiếm các biểu tượng gỡ lỗi.

Một gợi ý khác, không đáng tin cậy một lần nữa, sẽ kiểm tra xem phiên bản của thư viện hệ thống nào được liên kết với một chương trình nào. Nếu đó là phiên bản gỡ lỗi, rất có thể đó là một bản dựng gỡ lỗi. Tuy nhiên, người ta có thể làm một bản phát hành xây dựng và vẫn liên kết với các thư viện gỡ lỗi, không có gì có thể ngăn cản bạn làm điều đó. Các dự đoán tốt nhất tiếp theo sẽ là sự vắng mặt của các cuộc gọi đến các CRT assert chức năng (mà bạn có thể làm với một trận đấu chuỗi đơn giản), kể từ khi vĩ mô assert (mà từ đó nó thường được gọi) là hoàn toàn tước ra trong một xây dựng với NDEBUG được xác định. Không sử dụng biểu tượng đó, không có chuỗi nào có trong nhị phân.
Thật không may, một chương trình mà không có bất kỳ xác nhận nào sẽ được xác định sai là "bản dựng xây dựng" bất kể bản dựng thực tế của nó là gì và hoàn toàn có thể xác định lại macro assert để làm điều gì đó hoàn toàn khác (chẳng hạn như printf a và tiếp tục). Và cuối cùng, bạn không biết wheter một số thư viện bên thứ 3 tĩnh mà bạn liên kết với (rõ ràng là đã thông qua bộ tiền xử lý) chứa các cuộc gọi đến assert mà bạn không biết.

Nếu bạn muốn kiểm tra chương trình bạn tự viết, bạn có thể khai thác thực tế là trình tối ưu hóa sẽ xóa hoàn toàn những thứ không thể truy cập được hoặc không được sử dụng. Nó có thể mất 2-3 lần để làm cho nó vừa phải, nhưng về cơ bản nó phải đơn giản như xác định một biến (hoặc một hàm xuất khẩu nếu trình biên dịch/liên kết của bạn không xuất các ký hiệu không được sử dụng) và viết hai hoặc ba giá trị ma thuật cho nó từ một vị trí chương trình mà không thể truy cập được. Một trình biên dịch tối ưu hóa sẽ ít nhất sụp đổ một số di chuyển dư thừa vào một, hoặc nhiều khả năng hoàn toàn loại bỏ tất cả chúng.
Sau đó bạn có thể thực hiện tìm kiếm chuỗi nhị phân cho các giá trị ma thuật. Nếu họ không có mặt, đó là một bản dựng được tối ưu hóa.

+0

hầu hết các ứng dụng biên dịch gỡ lỗi của tôi (win32, vs2010) của tôi không chứa chuỗi '.debug'. Một lựa chọn khác là kiểm tra phiên bản thời gian chạy C++ được ứng dụng sử dụng. ví dụ. tìm kiếm 'MSVCR80D.dll'' MSVCR90D.dll' 'MSVCR100D.dll' ... – smerlin

+0

@smerlin: Vâng, đó là một điều khác (mặc dù không đáng tin cậy) mà người ta có thể tìm kiếm (như đã nói ở trên, tham khảo đoạn số 6) . Thing là, bạn thực sự không thể nói chắc chắn. – Damon

0

Khi bạn tạo dự án C++ trong Visual Studio, nó tạo hai cấu hình cho bạn. Tên của các cấu hình này là Gỡ lỗiPhát hành. Cấu hình gỡ lỗi bao gồm việc tạo thông tin gỡ lỗi, tối ưu hóa ít hơn và hỗ trợ Chỉnh sửa & Tiếp tục.

Nhưng đây chỉ là điểm khởi đầu. Bạn có thể tạo các cấu hình tùy ý và thậm chí thêm tất cả thông tin gỡ lỗi vào cấu hình Phát hành. Vì vậy, không có bản dựng Debug hoặc Release rõ ràng.

Bạn có thể thử xác định xem ký hiệu tiền xử lý _DEBUG đã được xác định chưa. Điều này hiếm khi được thay đổi và nó được sử dụng trong tài nguyên phiên bản. Bit 0 của trường FILEFLAGES thường chỉ ra rằng các ký hiệu _DEBUG được định nghĩa khi biên dịch tài nguyên.

1

Câu hỏi này rất hay và như đã nêu, không có chỉ báo rõ ràng (độc đáo) nào gắn cờ cho dù hình ảnh có được gỡ lỗi hay không.

explained tại đây và here, sự hiện diện của Thư mục gỡ lỗi KHÔNG phải là chỉ báo về việc một hình ảnh có được xây dựng trong Chế độ phát hành hay không. Nó là rất phổ biến mà phát hành hình ảnh được xây dựng với sự hỗ trợ gỡ lỗi. Trên thực tế, hầu hết các tệp hình ảnh của Windows OS đều được xây dựng với sự hỗ trợ gỡ lỗi (nếu không, sẽ KHÔNG có khả năng liên kết các hình ảnh được phát hành này với các tệp biểu tượng từ Máy chủ biểu tượng của Microsoft). Mặc dù những hình ảnh này là hình ảnh Phát hành!

Ngay cả sự hiện diện của phần .debug (thực tế, các tên mục KHÔNG đóng một vai trò trong đặc tả PE, tên của một phần có thể được thay đổi và đặt như bạn muốn - Trình tải không quan tâm đến nó!) KHÔNG phải là chỉ báo của hình ảnh Phát hành và Gỡ lỗi.

1

Có một công cụ đảo ngược cũ có tên là LordPE. Nó sẽ cho phép bạn mở hai tệp và phân biệt các tiêu đề. Tôi đã biên soạn một chương trình "hello world" trong VS2008 ở chế độ Release và Debug và so sánh chúng. Như trong các áp phích khác, tôi không thấy bất cứ thứ gì có thể làm chỉ báo.

Nhưng những gì tôi đã tìm thấy làm chỉ báo là phần đệm trong phần .text của tệp nhị phân. Có hơn một trăm byte với giá trị 0xCC sau byte cuối cùng của mã trong phần .text trong phiên bản Gỡ lỗi. Trong phiên bản Release, không có 0xCC byte. 0xCC byte sẽ hiển thị dưới dạng int3 hoặc breakpoint trong trình gỡ lỗi.