分析结果 :定制手机、魔改magisk、魔改su、软件白名单
1:定制面具-并隐藏magisk
2:定制root的su被改名,存储对应的名称后面进一步分析
3:隐藏魔改后的edxposed等相关app,让你以为是一部普通手机
4: 定制手机,只有白名单的软件才可以安装进去。(你的软件它不然你安装进去哦)
5:exposed对应的jar包也进行了魔改(类型de.robv.android.xposed:api:82)
主apk下载
adb 查看apk
adb shell pm list packages |findstr com.lkb.mainview
#查看apk路径
C:\Users\Lenovo>adb shell pm path com.lkb.mainview
package:/data/app/com.lkb.mainview-YIr9V6k8TSlEWhK1dEDXnA==/base.apk
#apk 下载到本地
C:\Users\Lenovo>adb pull /data/app/com.lkb.mainview-YIr9V6k8TSlEWhK1dEDXnA==/base.apk C:\Users\Lenovo\base.apk
/data/app/com.lkb.mainview-YIr9V6k8TSlEWhK1dEDXnA==/base.a...le pulled, 0 skipped. 34.1 MB/s (24341494 bytes in 0.681s)
apk内证书cert.pfx
分析相关代码,,不同的客户使用不同的cert.pft证书
public static String getCompanyName() {
try {
String name = X509Certificate.getInstance(InstallUtils.getAssetsFileStream(ApplicationWrapper.getAppContext(), "cert.pfx")).getSubjectDN().getName();
int i = name.indexOf(",OU=");
String corpName = name.substring(i + 4, name.indexOf(",O=", i));
DataManager.putString("corpName", corpName);
return corpName;
} catch (Exception e) {
HLog.e(TAG, "cert checkValidity Exception: ", e);
return null;
}
}
不同的公司也使用证书里指定的服务器(可能存在部分公用的情况)
public static String getDeviceServerHost() {
try {
if (DEVICE_SERVER_HOST == null) {
X509Certificate certificate = X509Certificate.getInstance(InstallUtils.getAssetsFileStream(ApplicationWrapper.getAppContext(), "cert.pfx"));
if (certificate == null) {
return null;
}
String name = certificate.getSubjectDN().getName();
int start = name.indexOf("CN=");
int end = name.indexOf(",", start);
if (end == -1) {
end = name.length();
}
DEVICE_SERVER_HOST = "http://" + name.substring(start + 3, end) + "/app";
}
return DEVICE_SERVER_HOST;
} catch (CertificateException e) {
SLog.e(TAG, "getDeviceServerHost Exception: ", e);
return null;
}
}
证书指纹
public static String getThumbprint() {
try {
X509Certificate certificate = X509Certificate.getInstance(InstallUtils.getAssetsFileStream(ApplicationWrapper.getAppContext(), "cert.pfx"));
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(certificate.getEncoded());
return HexString.toHexString(md.digest()).toLowerCase().replace(" ", "");
} catch (Throwable th) {
return null;
}
}
使用的rsa算法
public static byte[] encrypt_rsa(byte[] data) {
try {
X509Certificate certificate = X509Certificate.getInstance(InstallUtils.getAssetsFileStream(ApplicationWrapper.getAppContext(), "cert.pfx"));
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(1, certificate.getPublicKey());
byte[] bytes = cipher.doFinal(data);
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(certificate.getEncoded());
byte[] digest = md.digest();
ByteBuffer buffer = ByteBuffer.allocate(digest.length + bytes.length).put(digest).put(bytes);
buffer.flip();
return buffer.array();
} catch (Exception e) {
HLog.E(TAG, "cert checkValidity Exception", e);
return null;
}
}
新建apk简单调用观察
binding.btnGetCompany.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("main","公司名称"+AppInfo.getCompanyName());//公司名称
Log.i("main","公司名称"+AppInfo.getDeviceServerHost());//http://你公司的指定host.app.*****.com/app
Log.i("main","指纹"+AppInfo.getThumbprint());//dfdfdd12****0e27fd564a63
}
});
assets下的so(elf)
第三方的库 curl(不同cpu版本)、ffmpeg、wcvCodec
1.用于音视频解析、视频裁剪
2.图片解码
3.网络传输等
assets相关文件.png (30.69 KB, 下载次数: 0)
下载附件
2023-3-24 15:59 上传
# 网络命令、及su超级管理员
shell-chmod等.png (79.75 KB, 下载次数: 0)
下载附件
2023-3-24 16:02 上传
# 加载模块,消息、加好友、标签等功能分开在不同的模块中
子模块通过主app下载,并动态加载
~~~
[ModuleEnv][yyyy-mm-dd#18-41-41] ### Mission Module V46
[ModuleEnv][yyyy-mm-dd#18-41-41] init mission module finish
[LoginUser][yyyy-mm-dd#18-41-42] reportLoginUser:junit.framework.AssertionFailedError: mCoreStorage not initialized!
[base/Module][yyyy-mm-dd#18-41-42] ModuleInfo:
[{"moduleName":"finder","moduleId":8,"version":8,"package":"com.lkb.scrm.finder"},
{"moduleName":"friend","moduleId":5,"version":140,"package":"com.lkb.scrm.friend"},
{"moduleName":"msg","moduleId":3,"version":188,"package":"com.lkb.scrm.msg"},
{"moduleName":"sns","moduleId":4,"version":163,"package":"com.lkb.scrm.sns"},
{"moduleName":"risk","moduleId":10,"version":16,"package":"com.lkb.scrm.risk"},
{"moduleName":"group","moduleId":7,"version":121,"package":"com.lkb.scrm.group"},
{"moduleName":"label","moduleId":6,"version":120,"package":"com.lkb.scrm.label"},
{"moduleName":"mission","moduleId":9,"version":46,"package":"com.lkb.scrm.mission"}]
~~~
#设计到面具脚本、即模块脚本的代码
~~~
String flashBinary = null;
if (ShellUtils.execCommand("/sbin/magisk --help 2>&1", true).successMsg.contains("--install-module")) {
flashBinary = "install-module";
}
~~~
LoadModuleActivity.java
~~~
LoadModuleActivity.java
public /* synthetic */ void lambda$installModule$0$LoadModuleActivity(String[] modules, String path) {
String[] strArr = modules;
try {
HLog.e(TAG, "installModule:" + Arrays.toString(modules));
String flashBinary = null;
if (ShellUtils.execCommand("/sbin/magisk --help 2>&1", true).successMsg.contains("--install-module")) {
flashBinary = "install-module";
}
char c = 3;
if (strArr != null) {
int length = strArr.length;
int i = 0;
while (i
pluginModule.png (62.5 KB, 下载次数: 0)
下载附件
2023-3-24 16:05 上传
base-Module.png (150.61 KB, 下载次数: 0)
下载附件
2023-3-24 16:06 上传
加载子模块
mainWrapper.png (237.13 KB, 下载次数: 0)
下载附件
2023-3-24 16:14 上传
~~~
private void mainWrapper() {
l.a(i.a("com.tencent.tinker.loader.app.TinkerApplication", Module.loadPackageParam.y), "onCreate", new com.lkb.b.i() {
protected void b(i$a arg9) {
Object v1_2;
JSONArray v3;
Object v0_1;
try {
v0_1 = m.a(arg9.bN, "getBaseContext", new Object[0]);
String v1 = ((Context)v0_1).getPackageManager().getPackageInfo(Module.loadPackageParam.packageName, 0).versionName;
Module.loadPackageParam.y = ((Context)v0_1).getClassLoader();
Module.mContext = ((Context)v0_1);
e.g("base/Module", v1 + "微信启动: " + Module.loadPackageParam.bZ.dataDir + ", " + Module.loadPackageParam.y);
if(!com.lkb.scrm.base.c.j.b(v1, a.ag)) {
e.j("base/Module", "当前微信版本未适配, " + v1);
return;
}
com.lkb.scrm.base.c.c.e(Module.getSerialNumber());
g.a();
com.lkb.scrm.base.a.a(Module.loadPackageParam);
a.p(v1);
com.lkb.scrm.base.e.a();
b.a();
com.lkb.scrm.base.j.a();
Set v1_1 = com.lkb.agency.module.c.q();
v3 = new JSONArray();
Iterator v4 = v1_1.iterator();
while(true) {
label_57:
if(!v4.hasNext()) {
goto label_111;
}
v1_2 = v4.next();
if(((String)v1_2).equals("account")) {
continue;
}
break;
}
}
catch(Throwable v0) {
goto label_82;
}
try {
com.lkb.agency.module.c v5 = com.lkb.agency.module.c.f(((String)v1_2));
if(v5 == null) {
throw new NullPointerException("no such module");
}
v5.getClassLoader().loadClass(v5.getPackageName().concat(".LoadEntry")).newInstance().a(Module.loadPackageParam, ((Context)v0_1));
v3.put(new f().a("moduleName", v1_2).a("moduleId", Integer.valueOf(v5.p())).a("version", Integer.valueOf(v5.getVersionCode())).a("package", v5.getPackageName()).P());
goto label_57;
}
catch(Throwable v2) {
try {
e.b("base/Module", "加载子模块出错: " + (((String)v1_2)), v2);
goto label_57;
label_111:
d.a(0);
e.g("base/Module", "ModuleInfo: " + v3.toString());
return;
}
catch(Throwable v0) {
label_82:
e.b("base/Module", "attach", v0);
return;
}
}
}
});
}
~~~
loadSubModule.png (66.56 KB, 下载次数: 0)
下载附件
2023-3-24 16:15 上传
# su魔改名称
~~~
private static final String COMMAND_SU = SystemProperties.get("lkb.shfile", SystemProperties.get("lkb.sufile", "su"));
~~~
结束语
就这些了。其实就是魔改hook框架。