The first attempt to decompile bypasses APK’s simple JNI signature verification


The first attempt to reverse the operation bypasses APK’s simple JNI signature verification

1. Phenomenon

After modifying the content of the application, the search for SmalI did not find any signature verification for the application, but after repackaging, the application opened and flashed back directly. Check the log and confirm that the JNI method has performed signature verification.


Caused by: java.lang.UnsatisfiedLinkError: JNI_ERR returned from JNI_OnLoad in "/data/app/pkgpath/lib/arm64/"

The error occurred atJniUtilsGo loadlibencryption.soDuring the process of, I checked the Java code and found that this library is used for AES encryption. This method is used for every network request, and the signature verification is put hereJNI_OnloadYou can prevent it from being removed directly from the Java layerLoadLibrary

Open (download and install) IDA to see the code.

2. Positioning

Because IDA was downloaded for the first time, IDA free at the beginning did not support arm, and started IDA Pro again.

For the first time, I used ida64 to load armeabi-v7a files until I needed to distinguish 64 bits and use different exe.

Finally successfully loaded, search directlySignature, found onecheckSignatureMethod, and then you see a familiar string in the interface you can’t understand on the right. This should be the local signature cache used for comparison.


Because it is a simple signature verification, just change this value to the MD5 value after our re signature. The simplest and crudest way is to change the data directly…


Find the string in hex view and press F2 to edit it. You can see the value directly changed to hexadecimal, and it will take effect. After replacing this paragraph, save it and repackage it, and it can run normally.

But this change is too low, and I haven’t learned any knowledge. You still need to find the source of the error and try to bypass the verification instead of simply modifying the signature

Use IDA for the first time, check the tutorial and operate at the same time. First useCtrl+F5Let IDA decompile a C pseudo code. IDA view is full of instructions and can’t understand it at all.

200KB lib directly exports a C file with more than 30000 lines, which makes people look big. But at last we can manage the logic. Let’s see what’s wrong firstJNI_OnLoadmethod. You can see that when judging that the signature is not empty andcheckSignatureWhere the results are,return -1Or version number.


Locate the problem and then solve how to change it.

3. Modification

As a vegetable chicken that can only understand a little SmalI, there is nothing that can understand the content displayed in IDA.


The corresponding method location is found. If the SmalI code is really changed casually. This is the first time, I can’t start at all.

I’m still addicted to food and won’t change itif(!checkSignature()), it will not be changed directlyreturn 65542, the final decision is fromcheckSignatureThe return value of the method, so that he can do it anywayreturn trueJust fine. rely onCopy to assembly, put the decompiled code into the heavenly book, at least let me see where it is.


You can see the call herestrcmpMethod, compare S1 and S2. Just change this to S1 and compare S1.


The idea is beautiful. It took a long time to change this parameter. Finally, it was usedkey-patchImplemented, directly change the call here


After modification, look at the decompiled code again to realize the function of bypassing signature verification.


4. Test

After the 64 – and 32-bit libraries are modified, they are repackaged and signed, and the operation is normal.

5. Summary

It is more stupid to directly change the stored signature information. Later, it is more to try to modify the code of the Lib library.

Manage the code logic. Modifying the content is much more interesting than bypassing the signature verification itself. We still need to learn more later.

6. PS

As like as two peas, I wrote the first JNI code, which is the signature verification from the Internet, which is almost identical with this.Application:onCreateThe JNI method is called, then the method is compared with the signed dead signature.killProcess。 In terms of security, it’s not as good as putting it in the encryption library that must be called. I wrote at that time that it can be bypassed without calling.

When doing this attempt, I couldn’t understand it for several times and wanted to give up. It’s OK to think that the demand can be realized directly in a stupid way.

But I always want to see how I can completely kill the junk code I’ve written before, just check and change it a little bit.

Later, you can learn better signature verification practices of other applications through this. I have encountered an interesting design before. After the signature verification is successful, initialize a static singleton, and then call the singleton method directly elsewhere. If the signature verification fails, the call here will only throw a null pointer error and cause an application crash. At first, it will not be associated with the application error caused by re signature…

Of course, I found the problem when I looked at traces. Maybe it was just that I didn’t consider that null pointers would be caused here during the design. After all, no one would be bored to have nothing to do to re sign someone else’s APK.

Recommended Today

SQL statement of three-level linkage of provinces, cities and counties

The first is the table creation statement Copy codeThe code is as follows: CREATE TABLE `t_address_province` ( `id` INT AUTO_ Increment primary key comment ‘primary key’,`Code ` char (6) not null comment ‘province code’,`Name ` varchar (40) not null comment ‘province name’)Engine = InnoDB default charset = utf8 comment = ‘province information table’; CREATE TABLE […]