How to print logs safely in Android

Preface @ h_ 404_ 5@

During Android development, whether writing demos or actual projects, some logs will be printed to record data. For debugging, the log tool class in Android is log, which provides some methods to print logs. The five levels, V, D, I, W, e, have different overloads@ H_ 404_ 5@

When it comes to how to print logs? Many people will think that this is not very simple. Just use the android.util.log class directly? However, logs are very sensitive information; When reverse engineers reverse your program, they need to capture all kinds of output of your program, then speculate, follow the steps, and then get the required information; Once your log is leaked, it is tantamount to opening the portal and cracking your program is like entering nobody's land@ H_ 404_ 5@

The concept of security is relative. If the cost of cracking your program is far greater than the value obtained by cracking, you can think that the program is "safe"; Here is an analysis of what should be paid attention to when printing logs in order to improve the security of the program@ H_ 404_ 5@

First look at the practices of most companies and developers: @ h_ 404_ 5@

Log switch + log class @ h_ 404_ 5@

In order to avoid log output in the release version, the simplest idea is to put all log printing statements in an if (debug) statement; During daily development, the debug switch is turned on and turned off when the official version is released. The general idea is as follows: @ h_ 404_ 5@

Next, let's take a real example. A foreign APK is called powerclean; Package name: com.lionmobi.powerclean; We install this package; It is found that it is normal and there is no log output; Then we reverse the APK; Browse through several classes and find similar log output in many places: @ h_ 404_ 5@

@H_ 404_ 5 @ log output picture @ h_ 404_ 5@

We open this class called X. although it has been confused, the meaning is very clear. It is the same as our idea above: @ h_ 404_ 5@

This is a real example, and there are many users of this app; Next, let's see what's wrong with this approach@ H_ 404_ 5@

Statically decompile and turn on the log switch @ H_ 404_ 5@

There is a problem with the above method: Although there is no log output in the release version; However, the code for outputting logs still exists, but it has not been executed! (if condition doesn't hold) so, is there any way to make this code execute? Simply put, can you make this debug variable true in the release version? Certainly. And it's very simple@ H_ 404_ 5@

We use apktool to decompile the SmalI code of the APK; Then, the decompilation above tells us that the location of the log class is com. Lionmobi. Util. X. we open the x.smali file with the following contents: @ h_ 404_ 5@

It is clear that the static variable called a is our switch, and its initialization is in which static code block; Create a new local variable 0x0 and assign it to a; Therefore, we change the 0x0 to 0x1 to turn on the switch. It's very simple. Next, we package the modified SmalI and sign it to get a new running APK; Run it and see the results. Sure enough, a lot of logs are output. You tell others what your program is doing every step, and you don't need to guess; I'll just cut a picture and feel it: @ h_ 404_ 5@

@H_ 404_ 5 @ leaked log information @ h_ 404_ 5@

Let the release version not contain the log code @ H_ 404_ 5@

From the above analysis, we can draw a conclusion: if the program is required to be "log safe", there should be no code to output logs in the release version@ H_ 404_ 5@

How to do this? We can make a tool to print logs normally during development; Once the version needs to be released, delete all the statement codes that print the log. The code is very simple. You can do it with some regular expressions@ H_ 404_ 5@

In fact, we can also use some other tools to realize this similar function; That's Proguard; When it comes to this tool, many people just think it is a tool for code confusion. In fact, it can also help you eliminate useless code! What kind of code is useless@ H_ 404_ 5@

Similarly, when statically compiling, it is considered as "code that will never be executed", which is considered as useless code and will be directly optimized by this tool. There is no if statement in the generated class file. This function perfectly meets our needs; We only need to enclose the code outputting the log with such an IF statement, and then we will definitely use this tool when releasing; Then, in the release version, all the code for outputting logs is gone! Not like before, leaving a shadow, just do nothing@ H_ 404_ 5@

Correct practice @ h_ 404_ 5@

Finally, all our statements for printing logs should be as follows: @ h_ 404_ 5@

Then, use Proguard to optimize the code@ H_ 404_ 5@

It looks simple. It seems that it is no different from the original "log switch". Analyze it carefully: @ h_ 404_ 5@

The log switch must be a static constant @ H_ 404_ 5@

Compare the correct method with the initial log switch. One is a static variable and the other is a static constant; If it is a constant, it will never change. When the debug variable is false, Proguard can take it for granted that this part of the code will never be executed. In this way, the statements for printing logs will be optimized (deleted); If it is a variable, it is possible to change its value during operation (private is only a change for the programmer, and nothing can be changed for the compiler and runtime). In this way, Proguard will ignore it, so that your log code will be exposed and lost by a thousand words@ H_ 404_ 5@

Discard log class @ h_ 404_ 5@

Suppose we use static constant code blocks and Proguard optimization technology; But what happens if the above log class technology is still used@ H_ 404_ 5@

I wrote a demo, packaged it myself and decompiled it. The log class is as follows (for convenience, there is no confusion): @ h_ 404_ 5@

We can see that the if code block is gone, and no log will be output; But let's look at where this class is called@ H_ 404_ 5@

@H_ 404_ 5 @ log @ h_ 404_ 5@

The call of logutil. D is tantamount to stealing a bell; Although the cracker can't make android.util.log output any logs, your call here still tells others what you're doing; Therefore, to mask the output of the log, you must use the if code block to directly contain the log to be eliminated. The log class above should be optimized, that is: @ h_ 404_ 5@

Here, it's unnecessary. Writing a log class is whether you want to write if (debug) repeatedly. Here, in order to hide this sentence, you can't escape; But I'm sorry, monks can't escape the temple. This method can't completely hide information; You must abandon the practice of wrapping log code with log class@ H_ 404_ 5@

Free hands replenishment @ h_ 404_ 5@

Some people may say that for the so-called log security, it is not troublesome to write an IF statement every time you output the log; It's anti human. I'm lazy! In fact, to write fewer lines of code, we can choose to reuse (code level, such as the above log class) or generate (directly generate code); In languages that support metaprogramming, generating code is very common, such as C + + template metaprogramming and Ruby's boasted DSL capability; It's not so big here. We use code to generate code. We directly use the editor to help us write a few lines of code@ H_ 404_ 5@

IDEA/Android Studio@H_ 404_ 5@

You can use the function of live template; For example, my method is to write an IFD template. Every time I enter IFD, it will automatically expand into an IF statement, and the cursor will stop in the middle: @ H_ 404_ 5@

@H_ 404_ 5 @ use live template to simplify input @ h_ 404_ 5@

vim/ emacs@H_ 404_ 5@

You can use the macro recording function to implement the above live template@ H_ 404_ 5@

Summary @ h_ 404_ 5@

The above is the whole content of this article. I hope the content of this article has a certain reference value for your study or work. If you have any questions, you can leave a message. Thank you for your support for programming tips@ H_ 404_ 5@

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>