可选中1个或多个下面的关键词,搜索相关资料。也可直接点“搜索资料”搜索整个问题。
电脑安装安卓虚拟机(直接上网)_计算机软件及应用_it...下载并安装 java jdk 6。可以去网上搜索下载,可以...下载软件安装之外,还可以用专门的 apk 安装器,进行.........
电脑安装安卓虚拟机的方法_it计算机_专业资料。设置...下载并安装 java jdk 6。可以去网上搜索下载,可以...在点击上面【选择 apk 文件】按钮,选择你下载的 .........
暂无评价|0人阅读|0次下载 | 举报文档 apk 破解之dexdump反编译android程序_it...的字节码,所有的 java 文件 托管代码既然虚拟机可以识别,那么我们就可以很轻松.........
可选中1个或多个下面的关键词,搜索相关资料。也可直接点“搜索资料”搜索整个问题。
安卓应用即使没有跨平台需求,但Java是跨平台语言,凡是使用Java语言开发的应用,在编译时都只编译成中间码,在具体的终端执行时,由Java虚拟机转译成最终的机器码,所以需要Java虚拟机。 这一机制也使得JAVA开发的应用可以一次编写,随处运行。
刚刚看了一些关于Detect Android Emulator的开源项目/文章/论文, 我看的这些其实都是13年14年提出的方法, 方法里大多是检测一些环境属性, 检查一些文件这样, 但实际上检测的思路并不局限于此. 有的是很直接了当去检测qemu, 而其它的方法则是旁敲侧击比如检测adb, 检测ptrace之类的. 思路也很灵活. 最后看到有提出通过利用QEMU这样的模拟CPU与物理CPU之间的实际差异(任务调度差异), 模拟传感器和物理传感器的差异, 缓存的差异等方法来检测. 相比检测环境属性, 检测效果会提升很多.
下面我就列出各个资料中所提出的一些方法/思路/代码供大家交流学习.
以下是对应的c++代码
这里我的描述可能并不准确, 因为并没有找到相关的资料. 我只能以自己的理解来解释一下:
SIGTRAP
是调试器设置断点时发生的信号, 在nexus5或一加手机等大多数手机都可以触发. SIGBUS
则是在一个总线错误, 指针也许访问了一个有效地址, 但总线会因为数据未对齐等原因无法使用, 在nexus4手机上可以触发. 而bkpt
则是arm的断点指令,
这是曾经qemu被提出来的一个issue, qemu会因为SIGSEGV
信号而崩溃, 作者想利用这个崩溃来检测qemu. 如果程序没有正常退出或被冻结, 那么就可以认定很可能是在模拟器里.
这个其实是用于检测当前操作到底是用户还是脚本在要求应用执行.
|
这个方法是用来检测调试, 判断是否有调试器连接.
|
这个方法是通过检查/proc/self/status
的TracerPid
项, 这个项在没有跟踪的时候默认为0, 当有程序在跟踪时会修改为对应的pid. 因此如果TracerPid
不等于0, 那么就可以认为是在模拟器环境.
因为adb通常是反射到0.0.0.0
这个ip上, 虽然端口有可能改变, 但确实是可行的.
这个比较单纯了. 就是通过检测包名, 检测Taint
类来判断是否安装有TaintDroid
这个污点分析工具. 另外也还可以检测TaintDroid
的一些成员变量.
检测是否存在eth0
网卡.
手机上配备了各式各样的传感器, 但它们实质上都是基于从环境收集的信息输出值, 因此想要模拟传感器是非常具有挑战性的. 这些传感器为识别手机和模拟器提供了新的机会.
显然对于现实世界的传感器, 这是不可能的.
于是我们可以先注册一个传感器监听器, 如果注册失败, 就可能是在模拟器中(排除实际设备不支持传感器的可能性). 如果注册成功, 那么检查onSensorChanged
回调方法, 如果在连续调用这个方法的过程所观察到的传感器值或时间间隔相同, 那么就可以认定是在模拟器环境中.
出于性能优化的原因, QEMU在每次执行指令时都不会主动更新程序计数器(PC), 由于翻译指令在本地执行, 而增加PC需要额外的指令带来开销. 所以QEMU只在执行那些从线性执行过程里中断的指令(例如分支指令)时才会更新程序计数器. 这也就导致在执行一些基本块的期间如果发生了调度事件, 那么也没有办法恢复调度前的PC, 也是出于这个原因, QEMU仅在执行基本块后才发生调度事件, 绝不会执行的过程中发生.
如上图, 因为调度可能在任意时间发生, 所以在非模拟器环境下, 会观察到大量的调度点. 而在模拟器环境中, 只能看到特定的调度点.
因为QEMU会跟踪代码页的改动, 于是存在一种新颖的方法来检测QEMU--使用自修改代码(Self-Modifying Code, SMC)引起模拟器和实际设备之间的执行流变化.
ARM处理器包含有两个不同的缓冲Cache, 一个用于指令访问(I-Cache), 而另一个用于数据访问(D-Cache). 但如ARM这样的哈佛架构并不能保证I-Cache和D-Cache之间的一致性. 因此CPU有可能在新代码片已经写入主存后执行旧的代码片(也许是无效的).
这个问题可以通过强迫两个缓存一致得到解决, 这有两步:
在原生Android代码中, 可以使用cacheflush
函数, 该函数通过系统调用完成上述操作.
识别代码, 使用一个具有读写权限的内存, 其中包含两个不同函数f1和f2的代码, 这两个函数其实很简单, 只是单纯在一个全局字符串变量的末尾附加各自的函数名称, 这两个函数会在循环里交错执行, 这样就可以通过结果的字符串推断出函数调用序列.
如前所述, 我们调用cacheflush
来同步缓存. 在实际设备和模拟器上运行代码得到的结果是相同的--每次执行都会产生一致的函数调用序列.
接下来我们移除调用cacheflush
, 执行相同的操作. 那么在实际设备中, 我们每次运行都会观察到一个随机的函数调用序列, 这也如前所述的那样, 因为I-Cache可能包含一些旧指令, 每次调用的时候缓存都不同步所导致的.
而模拟器环境却不会发生这样的情况, 而且函数调用序列会跟之前没有移除cacheflush
时完全相同, 也就是每次函数调用前缓存都是一致的. 这是因为QEMU会跟踪代码页上的修改, 并确保生成的代码始终与内存中的目标指令匹配, 因此QEMU会放弃之前版本的代码翻译并重新生成新代码.
看到这里会不会已经觉得检测方法够多了. 可是我还只是看了13年14年的资料. 有关近几年的资料还未涉及.
最后我就把这些检测方法整合在一张思维导图(见附件)里供大家一览, 欢迎大家和我交流带带我