android 无须root截图方案的实现
通过反射了截取屏
publicclassEncoderFeeder{ publicstaticBitmapscreenshot(){ StringsurfaceClassName; if(VERSION.SDK_INT<=17){ surfaceClassName="android.view.Surface"; }else{ surfaceClassName="android.view.SurfaceControl"; } Class>classname; Bitmapbm=null; try{ classname=Class.forName(surfaceClassName); Methodmethod=classname.getDeclaredMethod("screenshot", newClass[]{int.class,int.class}); bm=(Bitmap)method.invoke( null, newObject[]{Integer.valueOf(Device.x),//分辨率 Integer.valueOf(Device.y)}); }catch(Exceptione){ e.printStackTrace(); } returnbm; } }
这是我们反射调用SurfaceControl.screenshot()和Surface.screenshot(),他们都是系统提供的截屏方法,可是这个方法被@hide的了,无法调用,我们可是使用反射的方式调用,可是我们普通用户通过代码反射调用,方法会返回null,原因是SurfaceControl这个类也被Google隐藏了,我们知道通adbshell命令可以调用screencap或者screenshot来截屏adbshell具有截屏截屏的权限也就是说adbshell能够调用到Surface和SurfaceControl这个两个类。怎么通过adbshell来调用到这两个类呢,这里的主角是app_process,app_process可以直接运行一个普通的Java类。小结一下:
1.通过adbshell命令来启动一个app_process程序
exportCLASSPATH=/data/app/com.test.syscreen-1.apk", "execapp_process/system/bincom.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运行库。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。