2010-02-23 34 views
6

Tôi muốn vô hiệu hóa ngăn xếp ngăn xếp được tạo khi một ngoại lệ được ném. Tôi đã sử dụng,Làm thế nào để tắt tính năng tạo dấu vết trong một chương trình java?

Runtime.getRuntime().traceInstructions(false); 
Runtime.getRuntime().traceMethodCalls(false); 

nhưng vẫn có thể thấy dấu vết được tạo. Làm thế nào bạn có thể làm điều đó? Ngoài ra tôi cần phải phát hiện xem một số là gỡ lỗi lớp học của tôi.

Tôi muốn tắt tất cả các dấu vết ngoại lệ. Tôi không thể sử dụng obfuscation kể từ khi sản phẩm của tôi là một SDK sẽ được sử dụng trong phát triển. Tôi đang cung cấp một Runtime cũng được sử dụng khi mọi người muốn triển khai các ứng dụng của họ được xây dựng bằng cách sử dụng SDK của tôi. Yêu cầu của tôi là bất cứ ai sử dụng các jars Runtime của tôi sẽ không thể gỡ lỗi mã được viết ... hoặc ít nhất tôi sẽ làm cho nó khó khăn để gỡ lỗi bằng cách tránh các thế hệ theo dõi ngăn xếp từ các lọ thời gian chạy của tôi.

Một cách mà tôi đã tìm thấy là tất cả các trường hợp ngoại lệ được bắt nguồn từ lọ runtime của tôi, tôi chỉ có thể bắt họ và thiết lập một mảng StackTraceElement trống trên các đối tượng ngoại lệ và tái ném nó ...

Tại sao yêu cầu đó? Giả sử bạn phát triển một ứng dụng sử dụng SDK của tôi. (SDK SDK không thể đi kèm với ứng dụng của bạn .. tôi đã hạn chế nó và cuối cùng :) !!) Bây giờ để chạy ứng dụng của bạn trên máy khách của bạn (hoặc khách hàng) cần cài đặt Thời gian chạy trên máy của khách hàng và chạy ứng dụng của bạn. Bây giờ nếu khách hàng của bạn bắt đầu phát triển các ứng dụng của riêng mình bằng cách sử dụng các jars Runtime của tôi !! Đó là một mối đe dọa cho doanh nghiệp của tôi .... Đó là lý do tại sao yêu cầu khủng khiếp.

Tại sao tắt theo dõi ngăn xếp?
Bằng cách vô hiệu hóa thế hệ theo dõi ngăn xếp hoặc tạo dấu vết cuộc gọi phương thức, tôi muốn tạo mã với các Runtime jars của tôi khó khăn và đó là lý do tại sao tôi bắt đầu câu hỏi của tôi theo cách đó ... đề xuất một số giải pháp khác để đạt được yêu cầu ...

+0

Tôi nghĩ có hai câu hỏi riêng biệt ở đây. Bạn nên giải quyết chúng một cách riêng biệt. – Joel

+2

vui lòng thêm chi tiết hơn, ví dụ: tại sao chính xác bạn muốn tắt theo dõi ngăn xếp? những gì bạn có ý nghĩa chính xác bởi "vô hiệu hóa stacktrace" (vì nó chỉ là chuỗi các trường hợp ngoại lệ) –

+2

Tôi nghĩ rằng bạn đang cung cấp cho người dùng của bạn dịch vụ kém ở đây. SDK không cung cấp ngoại lệ hữu ích? –

Trả lời

2

Có một vài phần phức tạp của JVM (ít nhất, Sun thực hiện JVM) không hoạt động nếu tạo ngăn xếp ngăn xếp bị tắt (tôi thấy điều này trong việc thực hiện một số phương pháp hỗ trợ để phản ánh). Vì vậy, tôi không nghĩ rằng thế hệ theo dõi stack có thể bị vô hiệu hóa cả. Các phương pháp Runtime.trace*() là về một cái gì đó khác (một công cụ gỡ lỗi triệt để hơn so với dấu vết ngăn xếp).

Trong tất cả các tính tổng quát, bất kỳ mã Java nào có thể được phân tích minh bạch, nếu chỉ thông qua công cụ bytecode (bytecode được sửa đổi với hướng dẫn thêm khi được tải). Việc bảo vệ duy nhất được biết đến chống lại phân tích như vậy (tôi giả định rằng bạn đang cố gắng giữ bí mật mã nội bộ của bạn) là obfuscation. Xem ví dụ ProGuard. Obfuscation sẽ làm cho ngăn xếp dấu vết vô dụng cho bất kỳ người dùng quá tò mò (và, thật đáng buồn, nó cũng làm cho gỡ lỗi rất khó khăn, vì những lý do tương tự).

+0

Tôi muốn vô hiệu hóa tất cả các dấu vết ngoại lệ. Tôi không thể sử dụng obfuscation vì sản phẩm của tôi là một SDK sẽ được sử dụng để phát triển. Tôi đang cung cấp một Runtime cũng được sử dụng khi mọi người muốn triển khai các ứng dụng của họ được xây dựng bằng cách sử dụng SDK của tôi. Yêu cầu của tôi là bất cứ ai sử dụng các jars Runtime của tôi sẽ không thể gỡ lỗi mã được viết ... hoặc ít nhất tôi sẽ làm cho nó khó khăn để gỡ lỗi bằng cách tránh các thế hệ theo dõi ngăn xếp từ các lọ thời gian chạy của tôi. –

+2

Một cách mà tôi đã tìm thấy là tất cả các ngoại lệ có nguồn gốc từ các lọ thời gian chạy của tôi, tôi sẽ chỉ bắt chúng và đặt một mảng StackTraceElement trống trên đối tượng ngoại lệ và ném lại ... –

+0

+1 chỉ sử dụng ProGuard . –

1

Bạn có muốn tắt tính năng này cho tất cả ngoại lệ không?

Nếu không biết bạn đang cố gắng đạt được điều gì, tôi sẽ nói đây là con đường sai để đi xuống. Nếu bạn mong đợi một ngoại lệ được ném mà bạn vui vẻ bỏ qua, bạn nên nắm bắt và xử lý nó một cách rõ ràng (nơi xử lý nó có thể đơn giản là bỏ qua nó hoặc ghi lại một tin nhắn ngắn mà không có dấu vết ngăn xếp đầy đủ).

5
  1. Tôi không nghĩ mã có thể biết rằng nó đang được gỡ lỗi, ngoại trừ gián tiếp (và không đáng tin cậy) có nghĩa là đo lường mất bao lâu để thực thi chuỗi mã.

  2. Không thể vô hiệu hóa tất cả stacktraces.Bạn có thể vô hiệu hóa các stracktraces cho các lớp ngoại lệ mà bạn tự xác định, bằng cách ghi đè Throwable.fillInStackTrace() để không làm gì cả. Nhưng điều đó sẽ không hiệu quả đối với các lớp học mà bạn không thể thay đổi.

Nhưng nếu bạn đang nghĩ đến việc làm những việc này để ngăn chặn kỹ thuật đảo ngược, bạn sẽ lãng phí thời gian của mình ngay cả khi bạn có thể làm điều đó. Sẽ rất đơn giản nếu một hacker xác định mã chống kỹ thuật ngược của ứng dụng của bạn và chỉnh sửa các tệp bytecode có liên quan để vô hiệu hóa nó.

EDIT - Tôi đã sửa đổi ý kiến ​​của mình về những gì bạn đang cố gắng làm. Cho rằng những gì bạn đang làm là phân phối một SDK mà bạn đang mong đợi khách hàng của bạn nhúng vào các ứng dụng của riêng họ, vô hiệu hóa stacktraces cho toàn bộ ứng dụng Java được tính là hành vi thù địch của khách hàng, IMO. Như một tác dụng phụ của việc bảo vệ IP "quý giá" của bạn, bạn đang làm cho nó khó khăn cho khách hàng/nhà phát triển để gỡ lỗi mã của riêng mình. Ngay cả mã không có phương pháp quý giá của bạn trên ngăn xếp cuộc gọi!

Nếu tôi là khách hàng, tôi có thể muốn bạn chuyển mã bị xáo trộn hơn làm điều này. Nhưng rất có thể, tôi muốn thử RẤT HARD để tìm một nhà cung cấp phần mềm thay thế mà không đối xử với khách hàng trả tiền của mình là kẻ trộm.

8

Tôi cũng tò mò về lý do tại sao bạn muốn làm điều này, nhưng nếu bạn thực sự có lý do của bạn, bạn có ít nhất hai lựa chọn:

Nếu bạn muốn vô hiệu hóa stack trace thế cho việc triển khai ngoại lệ của riêng bạn, bạn chỉ có thể ghi đè lên các phương pháp fillInStackTrace:

public static class MyException extends Exception { 
    @Override 
    public Throwable fillInStackTrace() { 
     return null; 
    }  
} 

Nếu bạn muốn vô hiệu hóa nó cho tất cả trường hợp ngoại lệ, bạn có thể sử dụng một byte đại lý mã số nhạc cụ để thay thế cho phương pháp fillInStackTrace trong lớp Throwable. Tuy nhiên, điều đó sẽ chỉ hoạt động đối với Java 6, vì bạn trong Java 5 không được phép thay thế một phương thức gốc (fillInStackTrace) bằng một phương thức Java bằng cách sử dụng thiết bị đo đạc.

+2

Thay thế 'fillInStackTrace' cho tất cả các trường hợp ngoại lệ có trách nhiệm phá vỡ mọi thứ; ví dụ. Bảo mật Java. –

+0

@Stephen: Bạn có quan tâm để giải thích lý do tại sao, hoặc nó nên được rõ ràng? – jarnbjo

+0

IIRC, một số kiểm tra bảo mật liên quan đến việc kiểm tra callstack để xem nếu người gọi là "đặc quyền" mã. IIRC này dựa trên fillInStackTrace. –

0

Throwable.setStackTrace (StackTraceElement [] stacktrace) sẽ chặn bất kỳ bổ sung vào stacktrace sau cuộc gọi của nó:

Throwable t = new Throwable(); 
StackTraceElement[] myStackTrace = new StackTraceElement[] { 
new StackTraceElement("MySDKClass","MySDKMethod","MySDKFile",0) 
}; 
t.setStackTrace(trace); 
Các vấn đề liên quan