经过反射了截取屏android
public class EncoderFeeder {
public static Bitmap screenshot() {
String surfaceClassName;
if (VERSION.SDK_INT <= 17) {
surfaceClassName = "android.view.Surface";
} else {
surfaceClassName = "android.view.SurfaceControl";
}
Class<?> classname;
Bitmap bm = null;
try {
classname = Class.forName(surfaceClassName);
Method method = classname.getDeclaredMethod("screenshot",
new Class[] { int.class, int.class });
bm = (Bitmap) method.invoke(
null,
new Object[] { Integer.valueOf(Device.x),//分辨率
Integer.valueOf(Device.y) });
} catch (Exception e) {
e.printStackTrace();
}
return bm;
}
}
复制代码
这是咱们反射调用SurfaceControl.screenshot()和Surface.screenshot(),他们都是系统提供的截屏方法,但是这个方法被@hide的了,没法调用,咱们但是使用反射的方式调用,但是咱们普通用户经过代码反射调用,方法会返回null,缘由是SurfaceControl这个类也被Google隐藏了, 咱们知道通adb shell 命令能够调用screencap或者screenshot来截屏adb shell具备截屏截屏的权限也就是说adb shell可以调用到Surface和SurfaceControl这个两个类。 怎么经过adb shell来调用到这两个类呢,这里的主角是app_process,app_process能够直接运行一个普通的Java类。 小结一下:shell
1.经过adb shell 命令来启动一个app_process程序bash
export CLASSPATH=/data/app/com.test.syscreen-1.apk", "exec app_process /system/bin com.test.syscreen.Main '@@'
复制代码
2.使用app_process程序来启动一个Java程序,在Java程序中可访问到Surface和SurfaceControl这两个类,就能够绕过Root,反射截屏。 更进一步的分析,为何app_precess程序会有普通用户访问不到的东西呢,查了一下(app_process其实就是Zygote进程,Zygote是由app_process“更名”而来),android中应用程序的进程都是由Zygote进程孵化而来的,Zygote进程启动时会建立一个Dalvik虚机实例,每当有新的应用用进程产生,Zygote会将虚拟机实例复制到它里面,而且Zygote启动时会将Java运行库加载进来,因此一个新的应用有Zygote建立出来,不只拥有从Zygote拷贝来的虚拟机,还会和Zygote共享Java运行库。app