登录走else if 逻辑,hook a 方法
function hook_java() {
Java.perform(function () {
console.log('进入hook。。。')
var LoginActivity = Java.use("com.example.androiddemo.Activity.LoginActivity");
console.log(LoginActivity);
LoginActivity.a.overload('java.lang.String', 'java.lang.String').implementation = function (str, str2) {
// LoginActivity.a.implementation = function(str, str2) {
var result = this.a(str, str2); //调用原来的函数
console.log("LoginActivity.a:", str, str2, result);
return result;
};
console.log("hook_java");
});
}
frida
发现a方法的两个入参都是用户名,后面那个就是加密后的密码
可以复制一下这个密码登录,还用111做用户名:
成功进入第一关。
点击第一关显示 Check Failed! 还进不了下一关,
跳到FridaActivity1声明:
我们还需要hook这里面的a方法的返回值让它恒等于那串字符串就ok了,接着往下写
function hook_java() {
Java.perform(function () {
console.log('进入hook。。。')
var LoginActivity = Java.use("com.example.androiddemo.Activity.LoginActivity");
console.log(LoginActivity);
LoginActivity.a.overload('java.lang.String', 'java.lang.String').implementation = function (str, str2) {
// LoginActivity.a.implementation = function(str, str2) {
var result = this.a(str, str2); //调用原来的函数
console.log("LoginActivity.a:", str, str2, result);
return result;
};
console.log('aaaaaaaa66666')
var FridaActivity1 = Java.use("com.example.androiddemo.Activity.FridaActivity1");
console.log(FridaActivity1);
//hook函数,没有调用原来的函数,直接返回值
FridaActivity1.a.implementation = function (barr) {
console.log("FridaActivity1.a");
return "R4jSLLLLLLLLLLOrLE7/5B+Z6fsl65yj6BgC6YWz66gO6g2t65Pk6a+P65NK44NNROl0wNOLLLL=";
};
console.log("hook_java");
});
}
运行后再点击成功进入第2关,
进入第三关同理,需要我们跳到FridaActivity2的声明里看代码逻辑:
静态函数直接use class然后调用方法,非静态函数需要先choose实例然后调用。
hook代码:
function call_FridaActivity2() {
//主动调用函数
Java.perform(function () {
console.log('进入hook FridaActivity2。。。')
var FridaActivity2 = Java.use("com.example.androiddemo.Activity.FridaActivity2");
FridaActivity2.setStatic_bool_var(); //调用静态函数
// 调用非静态函数
Java.choose("com.example.androiddemo.Activity.FridaActivity2", {
onMatch: function (instance) {
instance.setBool_var();
},
onComplete: function () {
}
});
console.log('hook FridaActivity2结束')
});
}
运行frida:
手机端点击一下就可以进入下一关了:
这里可以看出我们需要hook的是: static_bool_var 、bool_var和same_name_bool_var 三个成员变量。
注意:
设置成员变量的值,写法是xx.value = yy,其他方面和函数一样。
如果有一个成员变量和成员函数的名字相同,则在其前面加一个下划线
function call_FridaActivity3() {
Java.perform(function () {
console.log('进入hook call_FridaActivity3 ...')
var FridaActivity3 = Java.use("com.example.androiddemo.Activity.FridaActivity3");
FridaActivity3.static_bool_var.value = true; //设置静态成员变量
console.log('当前FridaActivity3.static_bool_var的值:',FridaActivity3.static_bool_var.value);
Java.choose("com.example.androiddemo.Activity.FridaActivity3", {
onMatch: function (instance) {
//设置非静态成员变量的值
instance.bool_var.value = true;
//设置有相同函数名的成员变量的值 (成员变量和成员函数的名字相同,则在其前面加一个下划线)
instance._same_name_bool_var.value = true;
console.log('当前same_name_bool_var的值:', instance._same_name_bool_var.value);
console.log('当前bool_var的值:',instance.bool_var.value);
},
onComplete: function () {
}
});
console.log('hook call_FridaActivity3完成')
});
}
运行frida:
手机再点击就可以进入第四关了:
跳转到第四关的声明:
这里需要hook内部类的check1() - check6()
hook代码:
function hook_InnerClasses() {
Java.perform(function () {
console.log('hook进入 hook_InnerClasses')
//hook内部类
var InnerClasses = Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses");
console.log('innerClasses',InnerClasses);
InnerClasses.check1.implementation = function () {
return true;
};
InnerClasses.check2.implementation = function () {
return true;
};
InnerClasses.check3.implementation = function () {
return true;
};
InnerClasses.check4.implementation = function () {
return true;
};
InnerClasses.check5.implementation = function () {
return true;
};
InnerClasses.check6.implementation = function () {
return true;
};
console.log('hook_InnerClasses完成')
});
}
或者枚举
function hook_mul_function() {
Java.perform(function () {
//hook 类的多个函数
var class_name = "com.example.androiddemo.Activity.FridaActivity4$InnerClasses";
var InnerClasses = Java.use(class_name);
var all_methods = InnerClasses.class.getDeclaredMethods();
for (var i = 0; i < all_methods.length; i++) {
var method = (all_methods[i]);
var methodStr = method.toString();
var substring = methodStr.substr(methodStr.indexOf(class_name) + class_name.length + 1);
var methodname = substring.substr(0, substring.indexOf("("));
console.log(methodname);
InnerClasses[methodname].implementation = function () {
console.log("hook_mul_function:", this);
return true;
}
}
});
}
运行后成功hook,手机就可点击进入下一关:
跳转到第5关的声明:
想通过就走else if 逻辑,getDynamicDexCheck().check() 这个是动态加载dex ,调用check()方法,返回参数满足条件语句则通关成功。
可以通过enumerateClassLoaders来枚举加载进内存的classloader,再loader.findClass(xxx)寻找是否包括我们想要的interface的实现类,最后通过Java.classFactory.loader = loader来切换classloader,从而加载该实现类。
hook代码:
function hook_dyn_dex() {
Java.perform(function () {
console.log('hook进入 FridaActivity5...')
var FridaActivity5 = Java.use("com.example.androiddemo.Activity.FridaActivity5");
Java.choose("com.example.androiddemo.Activity.FridaActivity5", {
onMatch: function (instance) {
console.log('instance.getDynamicDexCheck().$className-->',instance.getDynamicDexCheck().$className);
}, onComplete: function () {
}
});
//hook 动态加载的dex
Java.enumerateClassLoaders({
onMatch: function (loader) {
try {
if (loader.findClass("com.example.androiddemo.Dynamic.DynamicCheck")) {
console.log('loader-->',loader);
Java.classFactory.loader = loader; //切换classloader
}
} catch (error) {
}
}, onComplete: function () {
}
});
var DynamicCheck = Java.use("com.example.androiddemo.Dynamic.DynamicCheck");
console.log('DynamicCheck--->',DynamicCheck);
DynamicCheck.check.implementation = function () {
console.log("进入DynamicCheck.check");
return true;
}
console.log("hook dex完成");
});
}
接着点击就可以进入下一关了:
跳转到第6关的声明:
Frida6Class0、Frida6Class1、Frida6Class2都是下面这种形式
可以挨个hook静态函数
function hook_FridaActivity6() {
Java.perform(function () {
console.log('进入hook_FridaActivity6')
var Frida6Class0 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class0");
Frida6Class0.check.implementation = function () {
return true;
};
var Frida6Class1 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class1");
Frida6Class1.check.implementation = function () {
return true;
};
var Frida6Class2 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class2");
Frida6Class2.check.implementation = function () {
return true;
};
console.log('hook_FridaActivity6 完成!')
});
}
或者枚举class
function hook_mul_class() {
Java.perform(function () {
console.log('hook 进入枚举类')
Java.enumerateLoadedClasses({
onMatch: function (name, handle) {
if (name.indexOf("com.example.androiddemo.Activity.Frida6") >= 0) {
console.log(name);
var fridaclass6 = Java.use(name);
fridaclass6.check.implementation = function () {
console.log("frida 6 check:", this);
return true;
};
}
}, onComplete: function () {
}
})
console.log('hook6 完成!')
});
}
之后再点击就可以进入下一关了:
到第7关结束。