"
之前看到过这个帖子,原出处:https://bbs.binmt.cc/thread-68293-1-2.html,那么多人水他的帖子估计是挺有趣的,不过我没看,虽然不知道是怎么弄的,但无非是改跳转或者改签名值,应该不是修改汇编
使用工具
1、Android studio
2、IDA
方法应该不会雷同,这种改法一般没人用
到应用市场下载好软件以后,重新签名安装,发现闪退。按照常规流程先搜索dex里面的>signatures,不过并没有发现什么。然后so再搜索signatures,有结果了,从字符串来看so有获取签名的行为,接下来就祭出ida看看做了什么。
ida打开
libnative-interface.so
,打开输出表,双击Java_com_imzhiqiang_period_security_NativeInterface_getSHA1Signature,部分代码如下:
if ( _system_property_get("ro.build.version.sdk") GetObjectClass(a1, v19);
v21 = ((*a1)->GetFieldID)(a1, v20, "signatures", "[Landroid/content/pm/Signature;", 64);
v18 = (*a1)->GetObjectField(a1, v19, v21);
}
else
{
v12 = _JNIEnv::CallObjectMethod(a1, v7, v10);
v13 = (*a1)->GetObjectClass(a1, v12);
v14 = ((*a1)->GetFieldID)(a1, v13, "signingInfo", "Landroid/content/pm/SigningInfo;", 0x8000000);
v15 = (*a1)->GetObjectField(a1, v12, v14);
v16 = (*a1)->GetObjectClass(a1, v15);
v17 = (*a1)->GetMethodID(a1, v16, "getApkContentsSigners", "()[Landroid/content/pm/Signature;");
v18 = _JNIEnv::CallObjectMethod(a1, v15, v17);
}
v22 = (*a1)->GetObjectArrayElement(a1, v18, 0);
v23 = (*a1)->GetObjectClass(a1, v22);
v24 = (*a1)->GetMethodID(a1, v23, "toByteArray", "()[B");
_JNIEnv::CallObjectMethod(a1, v22, v24);
v25 = (*a1)->FindClass(a1, "java/security/MessageDigest");
v26 = (*a1)->GetStaticMethodID(a1, v25, "getInstance", "(Ljava/lang/String;)Ljava/security/MessageDigest;");
v27 = (*a1)->NewStringUTF(a1, "SHA-256");
v28 = _JNIEnv::CallStaticObjectMethod(a1, v25, v26, v27);
v29 = (*a1)->GetMethodID(a1, v25, "digest", "([B)[B");
return _JNIEnv::CallObjectMethod(a1, v28, v29);
从代码中可以看出他获取了签名SHA-256,然后返回的是一个byte类型。但是Java方法名写SHA1我感觉是混淆视听的,so里面并没有保存这个签名值,所以应该放在了Java里面。现在修改思路有2个,要么把签名值改成自己的,要么写死正确的签名值。如果软件需要联网的话,改成自己的签名值可能会出现问题,所以推荐第二种,写死正确的签名值。
因为他把签名sha256转换成了byte,所以我们在Java层模仿so的功能即可。
举例1:
import android.content.Context;
public class check {
public final byte[] getSHA1Signature(Context context) {
String SHA256 ="599b0ad91afaa0bac640a273694d7581733bfe76fc8d1023276d920f65c413c7"; //原apk签名值,用mt管理器可以查看
String s = "0123456789abcdef";
int length = SHA256.length() / 2;
char[] hex = SHA256.toCharArray();
byte[] sign = new byte[length];
for (int i = 0; i
举例2:
import android.content.Context;
import java.util.concurrent.atomic.AtomicInteger;
public class check {
public final byte[] getSHA1Signature(Context context) {
final String SHA256;
SHA256 = "599b0ad91afaa0bac640a273694d7581733bfe76fc8d1023276d920f65c413c7".toLowerCase();
final byte[] sign = new byte[SHA256.length() / 2];
final AtomicInteger s = new AtomicInteger();
for (int i = 0; i
可以得到smali代码:
.method public final getSHA1Signature(Landroid/content/Context;)[B
.registers 12
.line 8
const-string v0, "599b0ad91afaa0bac640a273694d7581733bfe76fc8d1023276d920f65c413c7"
.line 9
const-string v7, "0123456789abcdef"
.line 10
invoke-virtual {v0}, Ljava/lang/String;->length()I
move-result v9
div-int/lit8 v5, v9, 0x2
.line 11
invoke-virtual {v0}, Ljava/lang/String;->toCharArray()[C
move-result-object v2
.line 12
new-array v8, v5, [B
.line 13
const/4 v3, 0x0
:goto_11
if-ge v3, v5, :cond_2d
.line 14
mul-int/lit8 v6, v3, 0x2
.line 15
aget-char v9, v2, v6
invoke-virtual {v7, v9}, Ljava/lang/String;->indexOf(I)I
move-result v9
shl-int/lit8 v1, v9, 0x4
.line 16
add-int/lit8 v9, v6, 0x1
aget-char v9, v2, v9
invoke-virtual {v7, v9}, Ljava/lang/String;->indexOf(I)I
move-result v4
.line 17
or-int v9, v1, v4
int-to-byte v9, v9
aput-byte v9, v8, v3
.line 13
add-int/lit8 v3, v3, 0x1
goto :goto_11
.line 19
:cond_2d
return-object v8
.end method
填入软件的native方法以后就可以正常启动了