使用frida hook插件化apk
The following article is from SourceReader Author SourceReader
目录
初步分析
ps 查看
dumpsys meminfo查看
cat /proc/7906/maps
定位关键代码
字符串定位
frida枚举所有加载的类
VideoController 类分析
frida hook setVip
frida枚举classloader
frida指定classloader
最终脚本
frida hook enum
enum测试
最终脚本
整体脚本
总结
>>>>
ps 查看
ps 查看
>>>> dumpsys meminfo 查看
dumpsys meminfo 查看
>>>>
cat/proc/7906/maps
cat/proc/7906/maps
>>>> 字符串定位
>>>>
frida枚举所有加载的类
frida枚举所有加载的类
Java.perform(function () {
// 上述搜索到的多个类
var key_class = ["com.facebook.plugin.widget.dkplayer.controller.PlayerVideoController",
"com.iqiyi.plugin.widget.dkplayer.controller.PlayerVideoController",
"com.facebook.plugin.widget.dkplayer.controller.VideoController",
"com.iqiyi.plugin.widget.dkplayer.controller.VideoController"]
Java.enumerateLoadedClasses({
"onMatch": function(name, handle) {
for (var i = 0; i < key_class.length; i++) {
if (key_class[i] == name) {
console.log(name);
}
}
},
"onComplete": function() {
console.log("success");
}
});
});
com.iqiyi.plugin.widget.dkplayer.controller.VideoControllersuccess
>>>>
VideoController 类分析
VideoController 类分析
public int setProgress() {
... ...
if (this.tryWatchTv != null && position > 0) { // 如果是试看
pos = (int) (((long) this.stopPlayTime) - position);
TextView textView = this.tryWatchTv;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("剩余试看时间: "); // 此处是我们看到的字符串
if (pos > 0) {
j = (long) pos;
}
stringBuilder.append(stringForTime(j));
textView.setText(stringBuilder.toString());
}
if (!this.isVip) { // 此处是通过isVip变量执行不同逻辑
StringBuilder stringBuilder2 = new StringBuilder();
stringBuilder2.append("position = ");
stringBuilder2.append(position);
stringBuilder2.append(" showVipHintTime = ");
stringBuilder2.append(this.showVipHintTime);
LogHelper.i(stringBuilder2.toString());
if (position < ((long) this.showVipHintTime) || this.showVipHintTime <= 0) {
this.vipHintView.setVisibility(8);
} else {
this.vipHintView.setVisibility(0);
}
if (position >= ((long) this.stopPlayTime)) {
this.mMediaPlayer.pause();
}
}
... ...
}
public void setVip(boolean isVip) {
this.isVip = isVip;
this.tryWatchTv.setVisibility(this.isVip ? 8 : 0);
if (this.isVip) {
this.vipHintView.setVisibility(8);
}
}
var videoController = Java.use("com.iqiyi.plugin.widget.dkplayer.controller.VideoController");
videoController.setVip.implementation = function() {
console.log("hook setVip");
this.setVip(true);
};
{'type': 'error', 'description': 'Error: java.lang.ClassNotFoundException: Didn\'t find class "com.iqiyi.plugin.widget.dkplayer.controller.VideoController" on path: DexPathList[[dex file "InMemoryDexFile[cookie=[0, 3983850208]]", zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.iqiyi.vider-U7T4aZIQOQyXS5iLBgsNGw==/base.apk"],nativeLibraryDirectories=[/data/app/com.iqiyi.vider-U7T4aZIQOQyXS5iLBgsNGw==/lib/arm, /data/app/com.iqiyi.vider-U7T4aZIQOQyXS5iLBgsNGw==/base.apk!/lib/armeabi-v7a, /system/lib]]', 'stack': 'Error: java.lang.ClassNotFoundException: Didn\'t find class "com.iqiyi.plugin.widget.dkplayer.controller.VideoController" on path: DexPathList[[dex file "InMemoryDexFile[cookie=[0, 3983850208]]", zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.iqiyi.vider-U7T4aZIQOQyXS5iLBgsNGw==/base.apk"],nativeLibraryDirectories=[/data/app/com.iqiyi.vider-U7T4aZIQOQyXS5iLBgsNGw==/lib/arm, /data/app/com.iqiyi.vider-U7T4aZIQOQyXS5iLBgsNGw==/base.apk!/lib/armeabi-v7a, /system/lib]]\n at frida/node_modules/frida-java-bridge/lib/env.js:124\n at frida/node_modules/frida-java-bridge/lib/class-factory.js:400\n at frida/node_modules/frida-java-bridge/lib/class-factory.js:781\n at frida/node_modules/frida-java-bridge/lib/class-factory.js:90\n at frida/node_modules/frida-java-bridge/lib/class-factory.js:44\n at /script1.js:23\n at frida/node_modules/frida-java-bridge/lib/vm.js:11\n at frida/node_modules/frida-java-bridge/index.js:368\n at frida/node_modules/frida-java-bridge/index.js:318', 'fileName': 'frida/node_modules/frida-java-bridge/lib/env.js', 'lineNumber': 124, 'columnNumber': 1}
>>>>
frida 枚举 classloader
frida 枚举 classloader
Java.perform(function () {
Java.enumerateClassLoaders({
"onMatch": function(loader) {
console.log(loader);
},
"onComplete": function() {
console.log("success");
}
});
});
>>>> frida指定classloader
frida指定classloader
Java.perform(function () {
Java.enumerateClassLoaders({
"onMatch": function(loader) {
if (loader.toString().startsWith("com.tencent.shadow.core.loader.classloaders.PluginClassLoader")) {
Java.classFactory.loader = loader; // 将当前class factory中的loader指定为我们需要的
}
},
"onComplete": function() {
console.log("success");
}
});
});
>>>>
最终脚本
Java.perform(function () {
Java.enumerateClassLoaders({
"onMatch": function(loader) {
if (loader.toString().startsWith("com.tencent.shadow.core.loader.classloaders.PluginClassLoader")) {
Java.classFactory.loader = loader; // 将当前class factory中的loader指定为我们需要的
}
},
"onComplete": function() {
console.log("success");
}
});
// 此处需要使用Java.classFactory.use
var videoController = Java.classFactory.use("com.iqiyi.plugin.widget.dkplayer.controller.VideoController");
videoController.setVip.implementation = function() {
console.log("hook setVip");
this.setVip(true);
};
});
if (TextUtils.equals("1", PluginEnum.VIP.getValue())) {...}
>>>>
enum测试
enum测试
public enum TestEnum {
A("a"),
B("b"),
C("c");
private String value;
private TestEnum(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
Compiled from "TestEnum.java"
public final class TestEnum extends java.lang.Enum<TestEnum> {
public static final TestEnum A;
public static final TestEnum B;
public static final TestEnum C;
public static TestEnum[] values();
public static TestEnum valueOf(java.lang.String);
public java.lang.String getValue();
static {};
}
sget-object v3, Lcom/iqiyi/plugin/base/PluginEnum;->VIP:Lcom/iqiyi/plugin/base/PluginEnum;
invoke-virtual {v3}, Lcom/iqiyi/plugin/base/PluginEnum;->getValue()Ljava/lang/String;
>>>>
最终脚本
Java.perform(function () {
var pluginEnum = Java.classFactory.use("com.iqiyi.plugin.base.PluginEnum");
var String = Java.use("java.lang.String");
pluginEnum.getValue.implementation = function() {
var value = this.getValue();
if (this == "VIP") { // 此时this 或者 this.getString() 返回的是静态成员名
var vip = String.$new("1");
this.setValue(vip); // 调用 setValue 修改VIP值
return vip;
} else {
return value;
}
}
});
Java.perform(function () {
Java.enumerateClassLoaders({
"onMatch": function(loader) {
if (loader.toString().startsWith("com.tencent.shadow.core.loader.classloaders.PluginClassLoader")) {
Java.classFactory.loader = loader;
}
},
"onComplete": function() {
console.log("success");
}
});
var videoController = Java.classFactory.use("com.iqiyi.plugin.widget.dkplayer.controller.VideoController");
videoController.setVip.implementation = function() {
console.log("hook setVip");
this.setVip(true);
};
var pluginEnum = Java.classFactory.use("com.iqiyi.plugin.base.PluginEnum");
var String = Java.use("java.lang.String");
pluginEnum.getValue.implementation = function() {
var value = this.getValue();
if (this == "VIP") {
var vip = String.$new("1");
this.setValue(vip);
return vip;
} else {
return value;
}
}
});
1. frida枚举所有加载的类
2. frida枚举classloader
3. frida对enum类型的hook
看雪ID:liwugang
https://bbs.pediy.com/user-403246.htm
推荐文章++++
好书推荐