asp.net 4.0网站开发实例教程,网线制作的步骤,17173游戏排行榜,网站图片在手机上做多大最清晰分析
要在未修复dex并打包情况下对其app内在类进行hook#xff0c;单纯的hook会由于加固的问题而导致加载不到内在想hook的类。因此需要进行加载加固的classloader。 在此之前需要先了解Context
在Android中#xff0c;只有Application、Activity以及Service有自己的Contex…分析
要在未修复dex并打包情况下对其app内在类进行hook单纯的hook会由于加固的问题而导致加载不到内在想hook的类。因此需要进行加载加固的classloader。 在此之前需要先了解Context
在Android中只有Application、Activity以及Service有自己的Context。
Application的Context
我们知道Application的Context是伴随着Application的创建而创建的AMS在需要启动应用进程的时候通过本地socket通知Zygote来fork应用进程应用进程在启动完成之后会通过Binder机制向AMS报告“我已经启动好了”AMS在接收到该Binder调用之后会立即通过Binder调用通知应用进程创建Application。
应用在创建Application的时候首先通过ClassLoader加载对应的class文件并通过newInstance创建一个应用的Application对象这样就经过了Application的构造函数同时应用进程还会实例化一个Context对象通过Application对象的attachBaseContext方法赋值给Application这些都做完之后应用进程才会调用Application对象的onCreate方法。这里需要注意Application中的context其实只是一个空壳真正起作用的是应用进程通过attachBaseContext赋值的mBaseApplication的context其实是mBase的静态代理。
Application的总结
● 继承关系Application - ContextWrap - Context
● 调用顺序构造函数 - attachBaseContext - onCreate
ContextWrap中包含了一个ContextmBase变量是应用进程通过attachBaseContext赋值的Application中关于Context的调用都是委托给它
在android的android.app.Application的源码中可以发现 Application继承ContextWrapper attachBaseContext方法被attach调用而大部分的壳都是在attachBaseContext这个方法里面去完成代码的解密使用加固之后的应用的classloader会被换成其加固应用本身的。 编写 因此可以利用java.use编写脚本加载样本app的classloader
if(Java.available) {Java.perform(function(){var application Java.use(android.app.Application);application.attach.overload(android.content.Context).implementation function(context) {var result this.attach(context); // 先执行原来的attach方法var classloader context.getClassLoader();return result;}});
}
利用加载到的classloader再次对样本app的类进行hook
//框架为
if(Java.available) {Java.perform(function(){var application Java.use(android.app.Application);application.attach.overload(android.content.Context).implementation function(context) {var result this.attach(context); // 先执行原来的attach方法var classloader context.getClassLoader(); // 获取classloaderJava.classFactory.loader classloader;var Hook_class Java.classFactory.use(com.xxx.xxx); // app的类console.log(Hook_class: Hook_class);// 下面代码和写正常的hook一样Hook_class.函数.implementation function() // 有参数填参数{}return result;}});
}
有一处root检测只需要将其返回的值为false就可以了。
public class RootCheckUtil {private static final String TAG RootCheckUtil.class.getSimpleName();public static boolean isRooted() {if (Build.MODEL.equals(Redmi Note 4)) {return false;}if (isExecuted(/system/xbin/su)) {return true;}if (isExecuted(/system/bin/su)) {return true;}if (isExecuted(/su/bin/su)) {return true;}if (isExecuted(/system/sbin/su)) {return true;}if (isExecuted(/sbin/su)) {return true;}if (isExecuted(/vendor/bin/su)) {return true;}return checkRootMethod2();}private static boolean isExecuted(String path) {boolean ret false;try {if (new File(path).exists()) {Process exec Runtime.getRuntime().exec(ls -l path \n);BufferedReader br new BufferedReader(new InputStreamReader(exec.getInputStream()));while (true) {String str br.readLine();if (str null) {break;} else if (str.length() 10) {String key (String) str.subSequence(9, 10);if (key.equals(x) || key.equals(d.ap)) {ret true;}}}exec.waitFor();br.close();}} catch (Exception e) {LoggerFactory.getTraceLogger().debug(TAG, Exception rootcheck e);}return ret;}private static boolean checkRootMethod2() {try {return new File(/system/app/Superuser.apk).exists();} catch (Exception e) {LoggerFactory.getTraceLogger().debug(TAG, Exception checkRootMethod e);return false;}}
}
在hook signature的过程中发现存在Context字段内存在一个Request-Data对其产生了兴趣代码如下
private RpcSignUtil.SignData a(String operationType, byte[] body, String ts, InnerRpcInvokeContext invokeContext, int[] signCostPtr) {StringBuffer signPlain new StringBuffer();signPlain.append(Operation-Type).append(operationType).append();signPlain.append(Request-Data).append(Base64.encodeToString(body, 2)).append();signPlain.append(Ts).append(ts);String content signPlain.toString();if (MiscUtils.isDebugger(getRpcFactory().getContext())) {LogCatUtil.debug(RpcInvoker, [getSignData] sign content: content);}boolean useSignAtlas MiscUtils.isAlipayGW(invokeContext.gwUrl);long startTime SystemClock.elapsedRealtime();MonitorInfoUtil.startLinkRecordPhase(operationType, WbCloudFaceContant.SIGN, null);try {return RpcSignUtil.signature(this.d.getContext(), invokeContext.appKey, isReq2Online(invokeContext), content, useSignAtlas);} finally {long signCost SystemClock.elapsedRealtime() - startTime;signCostPtr[0] (int) signCost;LogCatUtil.debug(RpcInvoker, [getSignData] sign time signCost ms. );MonitorInfoUtil.endLinkRecordPhase(operationType, WbCloudFaceContant.SIGN, null);}}
在写hook的过程发现其加密的发现是调用了android的原生包中的类android.util.Base64。而真正想要hook的类为
public static SignData signature(Context context, String externalAppKey, boolean isReq2Online, String content, boolean pUseSignAtlas) {try {SignRequest signRequest new SignRequest();signRequest.appkey MpaasPropertiesUtil.getAppkey(externalAppKey, isReq2Online, context);signRequest.content content;if (a(context, pUseSignAtlas)) {signRequest.signType SignRequest.SIGN_TYPE_ATLAS;}return SignData.createSignDataBySignResult(SecurityUtil.signature(signRequest));} catch (Throwable e) {LoggerFactory.getTraceLogger().warn(RpcSignUtil, e);return SignData.newEmptySignData();}}
综合上述最终的hook脚本为
if(Java.available) {Java.perform(function(){var application Java.use(android.app.Application);var dedata1 Java.use(android.util.Base64);application.attach.overload(android.content.Context).implementation function(context) {var result this.attach(context);var classloader context.getClassLoader();Java.classFactory.loader classloader;var Hook_class Java.classFactory.use(com.alipay.mobile.common.transport.utils.RpcSignUtil);var passroot Java.classFactory.use(com.1111.common.api.util.RootCheckUtil);var requestdata Java.classFactory.use(com.alipay.mobile.common.rpc.RpcInvoker);console.log(Hook_class: Hook_class);Hook_class.signature.implementation function(context,externalAppKey,isReq2Online,dcontent,pUseSignAtlas){console.log(context context);console.log(externalAppKey: externalAppKey);console.log(isReq2Online: isReq2Online);console.log(content: dcontent);console.log(pUseSignAtlas: pUseSignAtlas);}requestdata.a.overload(java.lang.String, [B, java.lang.String, com.alipay.mobile.common.rpc.transport.InnerRpcInvokeContext, [I).implementation function (operationType,body,ts,invokeContext,signCostPtr) {console.log(-------------------);console.log(-------------------);var ret dedata1.encodeToString(body, 10);console.log(Request-Dataret);console.log(decode);console.log(base64decode(ret));}passroot.isRooted.implementation function (){return false;}passroot.isExecuted.implementation function (path){return false;}passroot.checkRootMethod2.implementation function (){return false;}return result;}function base64decode(str){var base64DecodeChars new Array(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);var c1, c2, c3, c4;var i, len, out;len str.length;i 0;out ;while(i len) {do {c1 base64DecodeChars[str.charCodeAt(i) 0xff];} while(i len c1 -1);if(c1 -1)break;do {c2 base64DecodeChars[str.charCodeAt(i) 0xff];} while(i len c2 -1);if(c2 -1)break;out String.fromCharCode((c1 2) | ((c2 0x30) 4));do {c3 str.charCodeAt(i) 0xff;if(c3 61)return out;c3 base64DecodeChars[c3];} while(i len c3 -1);if(c3 -1)break;out String.fromCharCode(((c2 0XF) 4) | ((c3 0x3C) 2));do {c4 str.charCodeAt(i) 0xff;if(c4 61)return out;c4 base64DecodeChars[c4];} while(i len c4 -1);if(c4 -1)break;out String.fromCharCode(((c3 0x03) 6) | c4);}return out;}});}
最后进行hook的效果