-
安装apk,打开应用界面,输入字符,检验到错误,程序直接退出
-
用jadx龟打开,发现几个360壳的玩意
![](https://damoxilai.github.io/post-images/1627140076803.png)
可以用PKID检验一下,确实是360 加固
![](https://damoxilai.github.io/post-images/1627140095655.png)
-
那接下来就是脱壳了,试过很多一些脱壳方法,很多都脱不了壳
用了BlackDex32脱壳
![](https://damoxilai.github.io/post-images/1627140111937.png)
到对应目录下找到dump出来的dex文件
-
用dex2jar转jar文件,输入命令
d2j-dex2jar dex文件路径
![](https://damoxilai.github.io/post-images/1627140130510.png)
-
再用jadx龟打开jar文件
-
至于从哪里入手,看最初manifest.xml文件
![](https://damoxilai.github.io/post-images/1627140159589.png)
目标就是找到com.sec.n1book1这个包
![](https://damoxilai.github.io/post-images/1627140180496.png)
oncreate方法中并没有在java层实现关键操作,那就是在so层实现
可以看到下面有个Secert类,当时我点进去看了,发现在java层声明好的check函数,程序应该是把检验在java声明好,然后再到so层实现调用
public class Secret {
static int check(String str) {
return AESUtils.encryptString2Base64(str, str.substring(0, 6), "123456").replaceAll("\r|\n", BuildConfig.FLAVOR).equals("u0uYYmh4yRpPIT/zSP7EL/MOCliVoVLt3gHcrXDymLc=") ? 0 : -1;
}
}
可以看到在进行所AESUtils.encryptString2Base64和代替操作后,与"u0uYYmh4yRpPIT/zSP7EL/MOCliVoVLt3gHcrXDymLc="进行匹配
进一步找到AES算法的实现函数
package com.sec.n1book1;
import android.util.Base64;
import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AESUtils {
//声明加密模式
private static final String CipherMode = "AES/CBC/PKCS7Padding";
//创建IV变量,必须满足16位,不足十六位补空格
private static IvParameterSpec createIV(String str) {
byte[] bArr = null;
if (str == null) {
str = BuildConfig.FLAVOR;
}
StringBuffer stringBuffer = new StringBuffer(16);
stringBuffer.append(str);
while (stringBuffer.length() < 16) {
stringBuffer.append(" ");
}
try {
bArr = stringBuffer.substring(0, 16).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new IvParameterSpec(bArr);
}
//创建密钥,必须满足32位,不足用空格填充
private static SecretKeySpec createKey(String str) {
byte[] bArr = null;
if (str == null) {
str = BuildConfig.FLAVOR;
}
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(str);
while (stringBuffer.length() < 32) {
stringBuffer.append(" ");
}
try {
bArr = stringBuffer.substring(0, 32).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new SecretKeySpec(bArr, "AES");
}
//第一参数base64解密,返回调用decryptByte2Byte
public static byte[] decryptBase642Byte(String str, String str2, String str3) {
byte[] bArr = null;
try {
bArr = Base64.decode(str, 0);
} catch (Exception e) {
e.printStackTrace();
}
return decryptByte2Byte(bArr, str2, str3);
}
public static String decryptBase642String(String str, String str2, String str3) {
return decryptByte2String(Base64.decode(str, 0), str2, str3);
}
//解密实现
public static byte[] decryptByte2Byte(byte[] bArr, String str, String str2) {
try {
SecretKeySpec createKey = createKey(str);
Cipher instance = Cipher.getInstance(CipherMode);
instance.init(2, createKey, createIV(str2));
return instance.doFinal(bArr);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String decryptByte2String(byte[] bArr, String str, String str2) {
return new String(decryptByte2Byte(bArr, str, str2));
}
//第一参数取字节,返回调用decryptByte2Byte
public static byte[] decryptString2Byte(String str, String str2, String str3) {
byte[] bArr = null;
try {
bArr = str.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return decryptByte2Byte(bArr, str2, str3);
}
public static String encryptByte2Base64(byte[] bArr, String str, String str2) {
return new String(Base64.encode(encryptByte2Byte(bArr, str, str2), 0));
}
//加密实现
public static byte[] encryptByte2Byte(byte[] bArr, String str, String str2) {
try {
SecretKeySpec createKey = createKey(str);
Cipher instance = Cipher.getInstance(CipherMode);
instance.init(1, createKey, createIV(str2));
return instance.doFinal(bArr);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String encryptByte2String(byte[] bArr, String str, String str2) {
return new String(encryptByte2Byte(bArr, str, str2));
}
public static String encryptString2Base64(String str, String str2, String str3) {
byte[] bArr = null;
try {
bArr = str.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return new String(Base64.encode(encryptByte2Byte(bArr, str2, str3), 0));
}
public static byte[] encryptString2Byte(String str, String str2, String str3) {
byte[] bArr = null;
try {
bArr = str.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return encryptByte2Byte(bArr, str2, str3);
}
public static String encryptString2String(String str, String str2, String str3) {
byte[] bArr = null;
try {
bArr = str.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return new String(encryptByte2Byte(bArr, str2, str3));
}
}
分析之后,略作修改,可以用java写出解密操作
import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.Base64.Decoder;
import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class aesdemo {
private static final String CipherMode = "AES/CBC/PKCS5Padding";
private static IvParameterSpec createIV(String str) {
byte[] bArr = null;
StringBuffer stringBuffer = new StringBuffer(16);
stringBuffer.append(str);
while (stringBuffer.length() < 16) {
stringBuffer.append(" ");
}
try {
bArr = stringBuffer.substring(0, 16).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new IvParameterSpec(bArr);
}
private static SecretKeySpec createKey(String str) {
byte[] bArr = null;
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(str);
while (stringBuffer.length() < 32) {
stringBuffer.append(" ");
}
try {
bArr = stringBuffer.substring(0, 32).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new SecretKeySpec(bArr, "AES");
}
public static byte[] decryptBase642Byte(String str, String str2, String str3) {
byte[] bArr = null;
try {
Decoder decoder = Base64.getDecoder();
bArr = decoder.decode(str);
} catch (Exception e) {
e.printStackTrace();
}
return decryptByte2Byte(bArr, str2, str3);
}
public static String decryptBase642String(String str, String str2, String str3) {
Decoder decoder = Base64.getDecoder();
return decryptByte2String(decoder.decode(str), str2, str3);
}
public static byte[] decryptByte2Byte(byte[] bArr, String str, String str2) {
try {
SecretKeySpec createKey = createKey(str);
Cipher instance = Cipher.getInstance(CipherMode);
instance.init(2, createKey, createIV(str2));
return instance.doFinal(bArr);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String decryptByte2String(byte[] bArr, String str, String str2) {
return new String(decryptByte2Byte(bArr, str, str2));
}
public static byte[] decryptString2Byte(String str, String str2, String str3) {
byte[] bArr = null;
try {
bArr = str.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return decryptByte2Byte(bArr, str2, str3);
}
public static String encryptByte2Base64(byte[] bArr, String str, String str2) {
Encoder encoder = Base64.getEncoder();
return new String( encoder.encode(encryptByte2Byte(bArr, str, str2)));
}
public static byte[] encryptByte2Byte(byte[] bArr, String str, String str2) {
try {
SecretKeySpec createKey = createKey(str);
Cipher instance = Cipher.getInstance(CipherMode);
instance.init(1, createKey, createIV(str2));
return instance.doFinal(bArr);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String encryptByte2String(byte[] bArr, String str, String str2) {
return new String(encryptByte2Byte(bArr, str, str2));
}
public static String encryptString2Base64(String str, String str2, String str3) {
byte[] bArr = null;
try {
bArr = str.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
Encoder encoder = Base64.getEncoder();
return new String(encoder.encode(encryptByte2Byte(bArr, str2, str3)));
}
public static byte[] encryptString2Byte(String str, String str2, String str3) {
byte[] bArr = null;
try {
bArr = str.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return encryptByte2Byte(bArr, str2, str3);
}
public static String encryptString2String(String str, String str2, String str3) {
byte[] bArr = null;
try {
bArr = str.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return new String(encryptByte2Byte(bArr, str2, str3));
}
public static void main(String[] args) {
String str = "u0uYYmh4yRpPIT/zSP7EL/MOCliVoVLt3gHcrXDymLc=";
System.out.print(decryptBase642String(str, "n1book", "123456"));
}
}
得到结果n1book{h3ckF0rfun}