first, the Knowledge review
About the signature check in Android is a very common security strategy, many applications have done this part of the work, before I also introduced a few about how to use the application of the signature verification issue of the article, do not know the students can go to see: Android Blasting Application signature Verification function, At that time after the introduction of this article, in fact, summed up the current burst signature verification of several ways, one of the most convenient and fast is: Global search string content: "Signature", because as long as there is a signature verification function, will call the system a method, And this method contains the string content.
The same is true of the signature verification process described earlier in this article, when a specific signature verification function is found, the correct signature information can be replaced directly, or the If judgment can be manually changed to TRUE. But when it comes to a problem, is now applied in order to strengthen the protection, almost in the important part of the content of the signature verification function, so if you want to manually change, you need to change each signature check, it will appear very laborious, some people said, there is a good way, is to hook the application with the Xposed method of obtaining the system signature, and then replace the return value of the method . This way is possible, but not the best, because if you solve the signature verification, two times packaging for others to use, it is not possible to call someone else root cell phone, and then in the installation of xposed frame work, is unreasonable. So we need to solve this problem fundamentally, which is also a focus of this article. A versatile and efficient approach is described later.
As we can see in the previous article, most of the signature checks are in the Java layer and are locally verified. So the blasting difficulty is not very big, but today we want to introduce an application sample his signature check is placed in so, and combined with the service side to verify, more difficult. But original aim, signature verification is always required to obtain the signature information of the application itself, to perform a comparison operation.
second, the blasting signature check
The following starts to enter the topic of this article, look at the application of sample signature verification problem, after getting samples, the direct anti-compilation, two times packaging, installation appears the following error message prompt:
This direct pop-up dialog information, click OK to exit the program, this is relatively simple, after the anti-compilation, through the prompt content, find the signature check entry, in the values/string.xml to find this string information:
Then open the app with JADX and search for the name value globally:
Click to enter the code location:
Seeing that there is a show method in the I method should be the logic that the dialog box shows. Look at the place where the I method calls:
See, before there is a judgement, if false, is to go to the I method, Show dialog box, so this checkhashkey method is definitely the method of signature verification, go to view:
is a native method, where the global search for Socketjni class calls:
See here to load a so file, which is the libmzd.so file, we open this file with Ida (the file is in the Libs directory after the decompile):
Find the corresponding native function to see the specific logic code:
In order to better read the code, using F5, to view the corresponding C language code, the logic here is very simple, that is, the Java layer passed the signature string content, do a MD5 value, and then the specified string "8f2a24 ...". Then the value of the Checkhashkey method above is passed through the COM.XIAOENAI.APP.UTILS.AJ.M method:
What we see here is the standard way to get application signature information.
Here we see a Java Layer signature verification method, there are many ways to solve this problem, you can modify the corresponding Smali method, the If judgment is forced to change to true. You can also directly modify the return value of the M method to the correct signature string content. Here we choose the second, because we need to refer to the signature string content, which will continue to be used later. This acquisition method is also very simple, directly write a demo case, through the application package name to build the corresponding context variable, and then start to obtain the signature information:
Run this demo program if you want to install an official version of the app on your device to get the correct signature string content:
See, where the signature string: "An+vcd8ns0yqsotx2wukyscq/za=" is the correct official version of the value. Here is a way to directly return the string, and then compile to get the corresponding Smali code:
Then replace the code copy of this method with the AJ.M method Code of the sample application:
Save, two times package, Remember: There is no need to manually write Smali code to return the specified signature string, unless you are very familiar with the Smali syntax, but I will not do so. Because I am not familiar with Smali, the most effective way is the most stupid to manually write a Java method, and then decompile the corresponding Smali code can be.
Two times after the package is successful, install the application, run the discovery unexpectedly error, Login failed:
At this time, it is thought that the sample application may have done a service-side data validation, the following to see how to solve this problem, the breach of the problem is relatively simple, do not use the hint string information to find, because this error message may be returned by the service, this time need to grab a packet, each request, Just grab a service pack and use the Fiddler tool here:
See here, the parameters of the request is very simple, an encrypted data and version number ver, the data returned to suggest that the encryption signature error, so we can jadx in the global Search "login2" string information, to find the breach:
Once found, double-click into the code:
See finally called, a method, click into the A method:
Here, a JSON parameter format is constructed using a process that continues to look down:
With these information parameter values, in order to better see this JSON data format, we can take advantage of the xposed next hook function:
Then run this xposed module and click on the sample login function to view the log information:
See, result is the final concatenation of the JSON parameter format content. The last string in the sig is to encrypt the entire parameter of the signature, in order to verify the integrity of the parameters on the server. After this JSON format is obtained, the Com.xiaoenai.app.utils.b.a.a method is called:
Continue to view this method implementation:
Continue tracking code:
Again to the native method, to here in fact, the last Java will be stitching good parameter information in JSON format passed to the native layer for cryptographic operations, continue to see native layer code implementation, still in the previous libmzd.so:
Find the corresponding core function function and follow the view implementation:
Continue tracking:
See here, there is the data string content, that is, the beginning of the JSON data passed above the encryption, and then splicing into data, in the native layer in the stitching set of json:{"data": "The value after Encryption", "ver": "1.1"}, And here is a search for encryption key function, unfortunately here I do not analyze, because I look at the headache, his encryption algorithm is still more complex. So I gave up the analysis.
So what are some of the ways we can get a cryptographic algorithm here? Some students may think of dynamic debugging, this method is the best, but this app has done a lot of anti-debugging strategy, dynamic debugging is not good, and the algorithm is a bit complex, timely dynamic debugging, but also to read the arm instructions in detail, to guess the encryption algorithm function. So the road is not good to go.
So there's another way? Of course, it is the beginning of the article to address the Basic Law of the signature check: Global Search string "signature"; in Ida, use shirt+f12 to Open the string window in so Then search for signature:
Sure enough, double-click into:
See here may be in the native layer called the system to get the signature method, check the contents of the red box, and then press the x key to show the local index is called :
Double-click to enter, this is the Init method of the Socketjni that we analyzed earlier:
Here, in order to better read the code, you need to change the function address to be readable, that is, jnienv*, check the red box, press the y key :
Modify to jnienv*, OK:
This is quite clear, and this part of the code is very simple, is to call the system to get the signature method, and then assign a value to a variable, but here is not the string content, but the hashcode value of the int type:
When you return to the ARM code, you see the assignment, which is to get the R0 register value into the R9.
Here, we must be clear-minded, that is, no matter how the native layer encryption, will eventually use the application's signature value to do encryption key information. So we just have to get rid of it. To obtain the value of the signature information, that is, the R9 register value here, we also need to get the original signature information Hashcode value can be:
Then run, view values: 2081383250
Then we can modify the above arm instruction: MOV r9,r0; But it's not good here, because this hashcode value int type four bytes, and here to see a command only 2 bytes, certainly not enough. An LDR pseudo-directive is required to operate. But there is no such laborious modification here. Because if other places also have such code, then still have to modify, is back to our article began to talk about the problem, to solve all the signature verification function, is the purpose of this article.
But here we can try to test our blasting results first, by using the xposed framework, hook this application to get the signature Hashcode method, and replace the return value with the correct -2081383250 value:
After modification, run:
Sure enough, and for the previous removal of the dialog box that logic can not be so troublesome, so that the entire app all the signature check place is bursting. But this is the way to use xposed, so it's not the final solution. The following is to introduce a high-tech to solve this problem.
Three, efficient hook blasting method
I don't know if you remember me. I introduced a series of system articles that describe how to hook the various services of the system, such as AMS,PMS, and then intercept activity-initiated functions within the application. Do not know the students can read this article: The Android Hook system service function, the principle is very simple is the use of reflection mechanism + dynamic Proxy technology, replace the system service Binder object can be. This technical benefit is root-free, and the disadvantage is that it can only be used inside the app. That some people are curious, since the application itself can only be effective, what is the use of it? In fact, there are some development scenarios need this technology, timely now useless to, in the future is not necessarily, this is not used here. Here we use this technology to hook the system's PMS service, intercept the application to obtain the signature information method. As long as the operation in this application, so just meet the requirements.
The procedure is very simple, we at the start of the sample application at the entrance, plus our interception code can be, then we first write the interception of the PMS Service code, this code is given at the end of the article.
is to use reflection to hook the class of the system, and then use the dynamic agent to construct a own PMS binder to replace it:
Here we can intercept the signature information by the method name, we construct a new signature object with the genuine signature information, and then set it to the existing object. Because we finally need to put the code at the entrance to the sample case, so here we put these two classes under the sample entry class package, the specific package name can be constructed manually:
The demo is then recompiled to get the corresponding Smali code, copied to the sample case corresponding to the package, and then at the entrance of the sample case Add method call:Servicemanagerwraper.hookpms (this); The corresponding Smali code is as follows:
invoke-static {p0}, Lcom/xiaoenai/app/servicemanagerwraper;->hookpms (Landroid/content/context;) V
The sample entry can be found from the application in Androidmanifest.xml :
Add the OnCreate method entry in application, add it, two packs, and then use JADX to open the modified APK package:
The entry code has been added. Then the installation runs and it can be done. It is correct to apply all the signature information after this operation. Includes the signature check logic for the native layer. So this is the most reliable way. Do not change the logic of the signature check more.
Iv. Summary of Signature Verification blasting method
Here we have successfully exploded a service-side +native double signature check sample case, and this operation signature blasting, the following will not introduce more signature verification, the reason is very simple, because after this operation, we invented a general blasting method, can solve the signature verification problem, Here is a summary of the current Android signature Check logic processing mode:
first , the Basic Law should not forget: Global search string "signature", java layer can be searched with JADX, so can be used in Ida search.
second , in the reverse domain, the string information is always the first choice of the blasting breakthrough, in the previous article I have said many times, whether it is Ida, or JADX tools, as long as the global search for key string information, we can find the entrance we want.
Third , the focus of this article: The invention of a new high-efficiency blasting application signature Verification logic, is a manual hook sample application of the PMS function, and then at the entrance of the application to add hook code. Finally, intercept the desired method in the hook's Invoke method.
With the idea of this article, the following will develop a tool, one-click to solve the signature problem, the principle is to use the Icodetools tool I introduced earlier and the hook systems described in this article, the System PMS service, tamper with the application signature information. For details and tool development please look forward to. If this tool is developed, it is definitely a new challenge for the application of signature verification. The security is endless, reverse not only!
Serious statement: The purpose of this article is only one, through a case analysis of the current application of the reverse analysis skills, if someone uses this content for any commercial purposes and illegal profit, any legal liability will be borne by the operator himself, and the author of this article has no relationship, So still sincerely hope that everyone holds the purpose of technical learning to read this article, thank you very much!
Hook code: Https://github.com/fourbrother/HookPmsSignature
v. Summary
This article introduces a little bit more, so we may look a bit tired, in fact, there is a part of the content is not introduced, is how to access the existing so file function, variable value, this is my sample in this case used in a method, limited to the length of the reason is not much introduction. However, it is important to remember the method of the final verification of the blasting signature in this paper. Such absolute advanced positive energy. Hope can be a precept. Finally read the article, if you feel that there is a harvest, a lot of praise spread sharing, if there is a reward that the best!!
Click here for more information:
Focus on the public, the latest technology dry real-time push
Coding Beautiful Technology Circle
sweep into my "tech circle" World
Sweep and make a small series
please specify when adding: "Code Beautiful" Thank you very much!
Android Reverse Journey---a new and efficient way to sign a blast application (native+ server Authentication)