Substituting class/method names in logback log files with original names when deploying obfuscated code

Hello, What would be the best way to handle logging with logback when deploying obfuscated code? For example, with YGuard, when the obfuscator runs, it outputs a mapping file of obfuscated code (class names, method names, etc) to unobfuscated code. When a stacktrace or just any logging trace is output, the class/method names are obviously obfuscated. As it's possible to deploy this mapping with the code, say embedded in the same ".jar", all the information I would need is available. Without too much re-writing of code (default formatting with logback), what would be the best way to dynamically replace matching class/method names? Thanks, Christopher

You do realize that if you supply the mapping file to the end user, there is really no reason to obfuscale the code in the first place. They'll have everything they need to properly un-obfuscate and decompile it. (*Chris*) On Nov 28, 2011 7:32 AM, "Christopher BROWN" <brown@reflexe.fr> wrote:
Hello,
What would be the best way to handle logging with logback when deploying obfuscated code?
For example, with YGuard, when the obfuscator runs, it outputs a mapping file of obfuscated code (class names, method names, etc) to unobfuscated code. When a stacktrace or just any logging trace is output, the class/method names are obviously obfuscated. As it's possible to deploy this mapping with the code, say embedded in the same ".jar", all the information I would need is available.
Without too much re-writing of code (default formatting with logback), what would be the best way to dynamically replace matching class/method names?
Thanks, Christopher
_______________________________________________ Logback-user mailing list Logback-user@qos.ch http://mailman.qos.ch/mailman/listinfo/logback-user

Hi Chris, Keep the log stacktraces obfuscated. Then create a process that de-obfuscates the stack traces for YGuard. I'm not familiar with YGuard, so there could be something like this already. ProGuard (another obfuscation package) has this with ReTrace. http://proguard.sourceforge.net/index.html#/manual/retrace/introduction.html -- TJ On Mon, Nov 28, 2011 at 10:50 AM, Chris Pratt <thechrispratt@gmail.com>wrote:
You do realize that if you supply the mapping file to the end user, there is really no reason to obfuscale the code in the first place. They'll have everything they need to properly un-obfuscate and decompile it. (*Chris*) On Nov 28, 2011 7:32 AM, "Christopher BROWN" <brown@reflexe.fr> wrote:
Hello,
What would be the best way to handle logging with logback when deploying obfuscated code?
For example, with YGuard, when the obfuscator runs, it outputs a mapping file of obfuscated code (class names, method names, etc) to unobfuscated code. When a stacktrace or just any logging trace is output, the class/method names are obviously obfuscated. As it's possible to deploy this mapping with the code, say embedded in the same ".jar", all the information I would need is available.
Without too much re-writing of code (default formatting with logback), what would be the best way to dynamically replace matching class/method names?
Thanks, Christopher
_______________________________________________ Logback-user mailing list Logback-user@qos.ch http://mailman.qos.ch/mailman/listinfo/logback-user
_______________________________________________ Logback-user mailing list Logback-user@qos.ch http://mailman.qos.ch/mailman/listinfo/logback-user

Hi TJ, Had thought about this too. However, the most reliable way of doing this is to bundle the mapping with the code, as we can deliver lots of different versions, including hotfixes, so doing offsite de-obfuscation will be unreliable as we'll have a hell of a time ensuring that we match the right stacktraces to the right mapping versions. As I said, this is about checking out the feasibility and best approach to performing the mapping. I'm well aware that this is not in any way an absolute way to protect code, just makes it a little harder for average curious people to stick their noses in. So I'm aware of the limits and some alternatives, but I'd still be interesting in evaluating how this particular approach could be implemented. -- Christopher On 28 November 2011 17:56, TJ Rothwell <tj.rothwell@gmail.com> wrote:
Hi Chris,
Keep the log stacktraces obfuscated. Then create a process that de-obfuscates the stack traces for YGuard. I'm not familiar with YGuard, so there could be something like this already.
ProGuard (another obfuscation package) has this with ReTrace.
http://proguard.sourceforge.net/index.html#/manual/retrace/introduction.html
-- TJ
On Mon, Nov 28, 2011 at 10:50 AM, Chris Pratt <thechrispratt@gmail.com>wrote:
You do realize that if you supply the mapping file to the end user, there is really no reason to obfuscale the code in the first place. They'll have everything they need to properly un-obfuscate and decompile it. (*Chris*) On Nov 28, 2011 7:32 AM, "Christopher BROWN" <brown@reflexe.fr> wrote:
Hello,
What would be the best way to handle logging with logback when deploying obfuscated code?
For example, with YGuard, when the obfuscator runs, it outputs a mapping file of obfuscated code (class names, method names, etc) to unobfuscated code. When a stacktrace or just any logging trace is output, the class/method names are obviously obfuscated. As it's possible to deploy this mapping with the code, say embedded in the same ".jar", all the information I would need is available.
Without too much re-writing of code (default formatting with logback), what would be the best way to dynamically replace matching class/method names?
Thanks, Christopher
_______________________________________________ Logback-user mailing list Logback-user@qos.ch http://mailman.qos.ch/mailman/listinfo/logback-user
_______________________________________________ Logback-user mailing list Logback-user@qos.ch http://mailman.qos.ch/mailman/listinfo/logback-user
_______________________________________________ Logback-user mailing list Logback-user@qos.ch http://mailman.qos.ch/mailman/listinfo/logback-user

Hello Chris, I do indeed realise this. The primary reason for obfuscation here is to shorten the names of symbols to make file sizes smaller (and additionally, some people claim better performance due to faster lookup but I don't think that makes much difference). However some customers have asked for the obfuscation for security reasons: we have pointed out as you did that it's a bit pointless, but the argument is that they'd like it anyway as a means of making it more difficult (even if not impossible). And in any case, all obfuscation is always about making it difficult without ever achieving total security, because at some point the CPU has to do something intelligent :-) We'd probably end up doing some encryption of the mapping file, but again, it's like licence keys: difficult but not impossible. Thanks, Christopher On 28 November 2011 17:50, Chris Pratt <thechrispratt@gmail.com> wrote:
You do realize that if you supply the mapping file to the end user, there is really no reason to obfuscale the code in the first place. They'll have everything they need to properly un-obfuscate and decompile it. (*Chris*) On Nov 28, 2011 7:32 AM, "Christopher BROWN" <brown@reflexe.fr> wrote:
Hello,
What would be the best way to handle logging with logback when deploying obfuscated code?
For example, with YGuard, when the obfuscator runs, it outputs a mapping file of obfuscated code (class names, method names, etc) to unobfuscated code. When a stacktrace or just any logging trace is output, the class/method names are obviously obfuscated. As it's possible to deploy this mapping with the code, say embedded in the same ".jar", all the information I would need is available.
Without too much re-writing of code (default formatting with logback), what would be the best way to dynamically replace matching class/method names?
Thanks, Christopher
_______________________________________________ Logback-user mailing list Logback-user@qos.ch http://mailman.qos.ch/mailman/listinfo/logback-user
_______________________________________________ Logback-user mailing list Logback-user@qos.ch http://mailman.qos.ch/mailman/listinfo/logback-user

Hello, I've not yet found an answer to my question (I did get some suggestions back but no solution), so if anyone can help... So far, by investigating myself, it appears that I could either replace PatternLayout (but that means basically forking code with all the associated drawbacks) or use something like ClassicConverter (but I didn't see how do override just the parts of the layout I need, the ANSI colour example wraps the whole line... maybe I missed something). The conversion word "replace" doesn't seem to be a scalable solution (and furthermore, it's static whereas the application is OSGi-based therefore JARs can be reloaded at runtime with modified contents). I'm stuck! One suggestion I did get back was to keep the obfuscated code mapping outside of the runtime environment, and decode "in house" stacktraces when a customer sends us log files containing stacktraces with obfuscated class/method names. This suggestion does not provide the solution, as we can't be sure that we match versions (version reported by customer and version of class/method name mappings), so the "package the mapping file in the JAR" is still the most reliable from that point of view. Also, another reply pointed out that if the mapping is in the JAR, then it effectively renders useless the obfuscation: regarding that remark, yes, it makes it easier to restore the original source code, however the aim isn't a naive "total security" approach, it's primarily to discourage casual use and most of all, to encourage our customers not to link to obfuscated code, as we deliver a public non-obfuscated API, and it's a way of discouraging people taking shortcuts (because they unfortunately do and they can end up making their own code more prone to breakage by fiddling with internals and by having things change during upgrades). So a solution remains relevant. Thanks, Christopher On 28 November 2011 16:31, Christopher BROWN <brown@reflexe.fr> wrote:
Hello,
What would be the best way to handle logging with logback when deploying obfuscated code?
For example, with YGuard, when the obfuscator runs, it outputs a mapping file of obfuscated code (class names, method names, etc) to unobfuscated code. When a stacktrace or just any logging trace is output, the class/method names are obviously obfuscated. As it's possible to deploy this mapping with the code, say embedded in the same ".jar", all the information I would need is available.
Without too much re-writing of code (default formatting with logback), what would be the best way to dynamically replace matching class/method names?
Thanks, Christopher

Hi Christopher, It think writing a custom conversion specifier [1] is really the way to go here. Let's assume the converter is called ObfuscatedClassConverter. You would place the mapping in ObfuscatedClassConverter or in some other resource that ObfuscatedClassConverter looks up at run time. Once ObfuscatedClassConverter has the class mapping it would output caller class name similar to what ClassOfCallerConverter [2] does. As discussed in [1], you can register a conversion specifier in a configuration file. You can also register a specifier programmatically by populating the pattern rule registry. See ConversionRuleAction [3] for details. Alternatively, you could also access PatternLayout's defaultConverterMap directly. HTH, [1] http://logback.qos.ch/manual/layouts.html#customConversionSpecifier [2] http://logback.qos.ch/xref/ch/qos/logback/classic/pattern/ClassOfCallerConve... [3] http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/ConversionRuleAc... -- Ceki http://twitter.com/#!/ceki On 05.12.2011 12:26, Christopher BROWN wrote:
Hello,
I've not yet found an answer to my question (I did get some suggestions back but no solution), so if anyone can help...
So far, by investigating myself, it appears that I could either replace PatternLayout (but that means basically forking code with all the associated drawbacks) or use something like ClassicConverter (but I didn't see how do override just the parts of the layout I need, the ANSI colour example wraps the whole line... maybe I missed something). The conversion word "replace" doesn't seem to be a scalable solution (and furthermore, it's static whereas the application is OSGi-based therefore JARs can be reloaded at runtime with modified contents).
I'm stuck!
One suggestion I did get back was to keep the obfuscated code mapping outside of the runtime environment, and decode "in house" stacktraces when a customer sends us log files containing stacktraces with obfuscated class/method names. This suggestion does not provide the solution, as we can't be sure that we match versions (version reported by customer and version of class/method name mappings), so the "package the mapping file in the JAR" is still the most reliable from that point of view.
Also, another reply pointed out that if the mapping is in the JAR, then it effectively renders useless the obfuscation: regarding that remark, yes, it makes it easier to restore the original source code, however the aim isn't a naive "total security" approach, it's primarily to discourage casual use and most of all, to encourage our customers not to link to obfuscated code, as we deliver a public non-obfuscated API, and it's a way of discouraging people taking shortcuts (because they unfortunately do and they can end up making their own code more prone to breakage by fiddling with internals and by having things change during upgrades).
So a solution remains relevant.
Thanks, Christopher
On 28 November 2011 16:31, Christopher BROWN <brown@reflexe.fr <mailto:brown@reflexe.fr>> wrote:
Hello,
What would be the best way to handle logging with logback when deploying obfuscated code?
For example, with YGuard, when the obfuscator runs, it outputs a mapping file of obfuscated code (class names, method names, etc) to unobfuscated code. When a stacktrace or just any logging trace is output, the class/method names are obviously obfuscated. As it's possible to deploy this mapping with the code, say embedded in the same ".jar", all the information I would need is available.
Without too much re-writing of code (default formatting with logback), what would be the best way to dynamically replace matching class/method names?
Thanks, Christopher

Hello Ceki, Thanks for that information. After looking into your suggestions, it seems the most straightforward way to intercept this is by accessing * PatternLayout.defaultConverterMap* at application startup to install either an overriding or alternative converter in the *Map<String,String>*, most likely by basing the implementation on *ClassOfCallerConverter*. However, this led me onto the conversion "*%ex*" which seems to be implemented by *ThrowableProxyConverter*, and I'm guessing I need to do some work here too: I'm guessing I need to provide an implementation of * IThrowableProxy*, such as a subclass of *ThrowableProxy* that overrides * getStackTraceElementProxyArray()*? Here, I'm guessing I'd need to call * super.getStackTraceElementProxyArray()* and build an equivalent array of proxies whenever the underlying stack trace elements refer to a package I know to be obfuscated. Would that be correct? If so, where and how can I install my implementation of *IThrowableProxy*? As for the example you cited with ConversionRuleAction, I'm guessing it's the "cleanest" approach to the API (no assumptions about layout or encoder) but requiring the use of Joran/XML configuration? Thanks again, Christopher On 5 December 2011 13:49, ceki <ceki@qos.ch> wrote:
Hi Christopher,
It think writing a custom conversion specifier [1] is really the way to go here. Let's assume the converter is called ObfuscatedClassConverter. You would place the mapping in ObfuscatedClassConverter or in some other resource that ObfuscatedClassConverter looks up at run time. Once ObfuscatedClassConverter has the class mapping it would output caller class name similar to what ClassOfCallerConverter [2] does.
As discussed in [1], you can register a conversion specifier in a configuration file. You can also register a specifier programmatically by populating the pattern rule registry. See ConversionRuleAction [3] for details. Alternatively, you could also access PatternLayout's defaultConverterMap directly.
HTH,
[1] http://logback.qos.ch/manual/**layouts.html#** customConversionSpecifier<http://logback.qos.ch/manual/layouts.html#customConversionSpecifier> [2] http://logback.qos.ch/xref/ch/**qos/logback/classic/pattern/** ClassOfCallerConverter.html<http://logback.qos.ch/xref/ch/qos/logback/classic/pattern/ClassOfCallerConverter.html> [3] http://logback.qos.ch/xref/ch/**qos/logback/core/joran/action/** ConversionRuleAction.html<http://logback.qos.ch/xref/ch/qos/logback/core/joran/action/ConversionRuleAction.html>
-- Ceki http://twitter.com/#!/ceki
On 05.12.2011 12:26, Christopher BROWN wrote:
Hello,
I've not yet found an answer to my question (I did get some suggestions back but no solution), so if anyone can help...
So far, by investigating myself, it appears that I could either replace PatternLayout (but that means basically forking code with all the associated drawbacks) or use something like ClassicConverter (but I didn't see how do override just the parts of the layout I need, the ANSI colour example wraps the whole line... maybe I missed something). The conversion word "replace" doesn't seem to be a scalable solution (and furthermore, it's static whereas the application is OSGi-based therefore JARs can be reloaded at runtime with modified contents).
I'm stuck!
One suggestion I did get back was to keep the obfuscated code mapping outside of the runtime environment, and decode "in house" stacktraces when a customer sends us log files containing stacktraces with obfuscated class/method names. This suggestion does not provide the solution, as we can't be sure that we match versions (version reported by customer and version of class/method name mappings), so the "package the mapping file in the JAR" is still the most reliable from that point of view.
Also, another reply pointed out that if the mapping is in the JAR, then it effectively renders useless the obfuscation: regarding that remark, yes, it makes it easier to restore the original source code, however the aim isn't a naive "total security" approach, it's primarily to discourage casual use and most of all, to encourage our customers not to link to obfuscated code, as we deliver a public non-obfuscated API, and it's a way of discouraging people taking shortcuts (because they unfortunately do and they can end up making their own code more prone to breakage by fiddling with internals and by having things change during upgrades).
So a solution remains relevant.
Thanks, Christopher
On 28 November 2011 16:31, Christopher BROWN <brown@reflexe.fr <mailto:brown@reflexe.fr>> wrote:
Hello,
What would be the best way to handle logging with logback when deploying obfuscated code?
For example, with YGuard, when the obfuscator runs, it outputs a mapping file of obfuscated code (class names, method names, etc) to unobfuscated code. When a stacktrace or just any logging trace is output, the class/method names are obviously obfuscated. As it's possible to deploy this mapping with the code, say embedded in the same ".jar", all the information I would need is available.
Without too much re-writing of code (default formatting with logback), what would be the best way to dynamically replace matching class/method names?
Thanks, Christopher
______________________________**_________________ Logback-user mailing list Logback-user@qos.ch http://mailman.qos.ch/mailman/**listinfo/logback-user<http://mailman.qos.ch/mailman/listinfo/logback-user>
participants (4)
-
ceki
-
Chris Pratt
-
Christopher BROWN
-
TJ Rothwell