Android anti-hook技术

原文出处:http://d3adend.org/blog/?p=589


Stab 1: 检查是否安装hook框架,例如xposed或Substrate

PackageManager packageManager = context.getPackageManager();
List applicationInfoList  = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
		
for(ApplicationInfo applicationInfo : applicationInfoList) {
	if(applicationInfo.packageName.equals("de.robv.android.xposed.installer")) {
		Log.wtf("HookDetection", "Xposed found on the system.");
	}
	if(applicationInfo.packageName.equals("com.saurik.substrate")) {
		Log.wtf("HookDetection", "Substrate found on the system.");
	}
} 

Stab 2: 检查调用栈

在方法中打印调用栈,看看有没插入可疑方法,


例如原来的调用栈为:

com.example.hookdetection.DoStuff->getSecret
com.example.hookdetection.MainActivity->onCreate
android.app.Activity->performCreate
android.app.Instrumentation->callActivityOnCreate
android.app.ActivityThread->performLaunchActivity
android.app.ActivityThread->handleLaunchActivity
android.app.ActivityThread->access$800
android.app.ActivityThread$H->handleMessage
android.os.Handler->dispatchMessage
android.os.Looper->loop
android.app.ActivityThread->main
java.lang.reflect.Method->invokeNative
java.lang.reflect.Method->invoke
com.android.internal.os.ZygoteInit$MethodAndArgsCaller->run
com.android.internal.os.ZygoteInit->main
dalvik.system.NativeStart->main
xposed hook后:

com.example.hookdetection.DoStuff->getSecret
de.robv.android.xposed.XposedBridge->invokeOriginalMethodNative
de.robv.android.xposed.XposedBridge->handleHookedMethod
com.example.hookdetection.DoStuff->getSecret
com.example.hookdetection.MainActivity->onCreate
android.app.Activity->performCreate
android.app.Instrumentation->callActivityOnCreate
android.app.ActivityThread->performLaunchActivity
android.app.ActivityThread->handleLaunchActivity
android.app.ActivityThread->access$800
android.app.ActivityThread$H->handleMessage
android.os.Handler->dispatchMessage
android.os.Looper->loop
android.app.ActivityThread->main
java.lang.reflect.Method->invokeNative
java.lang.reflect.Method->invoke
com.android.internal.os.ZygoteInit$MethodAndArgsCaller->run
com.android.internal.os.ZygoteInit->main
de.robv.android.xposed.XposedBridge->main
dalvik.system.NativeStart->main
Substratehook后:

com.example.hookdetection.DoStuff->getSecret
com.saurik.substrate._MS$MethodPointer->invoke
com.saurik.substrate.MS$MethodPointer->invoke
com.cigital.freak.Freak$1$1->invoked
com.saurik.substrate.MS$2->invoked
com.example.hookdetection.DoStuff->getSecret
com.example.hookdetection.MainActivity->onCreate
android.app.Activity->performCreate
android.app.Instrumentation->callActivityOnCreate
android.app.ActivityThread->performLaunchActivity
android.app.ActivityThread->handleLaunchActivity
android.app.ActivityThread->access$800
android.app.ActivityThread$H->handleMessage
android.os.Handler->dispatchMessage
android.os.Looper->loop
android.app.ActivityThread->main
java.lang.reflect.Method->invokeNative
java.lang.reflect.Method->invoke
com.android.internal.os.ZygoteInit$MethodAndArgsCaller->run
com.android.internal.os.ZygoteInit->main
com.android.internal.os.ZygoteInit->main
dalvik.system.NativeStart->main
检测代码:

try {
	throw new Exception("blah");
}
catch(Exception e) {
	int zygoteInitCallCount = 0;
	for(StackTraceElement stackTraceElement : e.getStackTrace()) {
		if(stackTraceElement.getClassName().equals("com.android.internal.os.ZygoteInit")) {
			zygoteInitCallCount++;
			if(zygoteInitCallCount == 2) {
				Log.wtf("HookDetection", "Substrate is active on the device.");
			}
		}
		if(stackTraceElement.getClassName().equals("com.saurik.substrate.MS$2") && 
				stackTraceElement.getMethodName().equals("invoked")) {
			Log.wtf("HookDetection", "A method on the stack trace has been hooked using Substrate.");
		}
		if(stackTraceElement.getClassName().equals("de.robv.android.xposed.XposedBridge") && 
				stackTraceElement.getMethodName().equals("main")) {
			Log.wtf("HookDetection", "Xposed is active on the device.");
		}
		if(stackTraceElement.getClassName().equals("de.robv.android.xposed.XposedBridge") && 
				stackTraceElement.getMethodName().equals("handleHookedMethod")) {
			Log.wtf("HookDetection", "A method on the stack trace has been hooked using Xposed.");
		}

	}
}



Stab 3:检查你的方法是否变成native

xposed会将要hook的方法本地化,再添加hook的方法,具体实现见 XposedBridge_hookMethodNativeSubstrate的原理和它差不多。

for (ApplicationInfo applicationInfo : applicationInfoList) {
	if (applicationInfo.processName.equals("com.example.hookdetection")) {		
		Set classes = new HashSet();
		DexFile dex;
		try {
			dex = new DexFile(applicationInfo.sourceDir);
			Enumeration entries = dex.entries();
			while(entries.hasMoreElements()) {
				String entry = entries.nextElement();
				classes.add(entry);
			}
			dex.close();
		} 
		catch (IOException e) {
			Log.e("HookDetection", e.toString());
		}
		for(String className : classes) {
			if(className.startsWith("com.example.hookdetection")) {
				try {
					Class clazz = HookDetection.class.forName(className);
					for(Method method : clazz.getDeclaredMethods()) {
						if(Modifier.isNative(method.getModifiers())){
							Log.wtf("HookDetection", "Native function found (could be hooked by Substrate or Xposed): " + clazz.getCanonicalName() + "->" + method.getName());
						}
					}
				}
				catch(ClassNotFoundException e) {
					Log.wtf("HookDetection", e.toString());
				}
			}
		}
	}
}


Stab 4:根据 /proc/[pid]/maps 来检查内存中已加载的共享库或jar包

try {
	Set libraries = new HashSet();
	String mapsFilename = "/proc/" + android.os.Process.myPid() + "/maps";
	BufferedReader reader = new BufferedReader(new FileReader(mapsFilename));
	String line;
	while((line = reader.readLine()) != null) {
		if (line.endsWith(".so") || line.endsWith(".jar")) {
			int n = line.lastIndexOf(" ");
			libraries.add(line.substring(n + 1));
		}
	}
	for (String library : libraries) {
		if(library.contains("com.saurik.substrate")) {
			Log.wtf("HookDetection", "Substrate shared object found: " + library);
		}
		if(library.contains("XposedBridge.jar")) {
			Log.wtf("HookDetection", "Xposed JAR found: " + library);
		}
	}
	reader.close();
}
catch (Exception e) {
	Log.wtf("HookDetection", e.toString());
}

以下是对应的anti-anti-hook:

1.hookPackageManager的检测方法,去掉可疑的包名

2.hook getStackTrace去掉调用栈里的可疑函数

3.hook getModifiers 去掉native

4.hook jave.io相应的方法



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值