android 反编译调试反调试技术有哪些

未开启cookie无法登录使用i春秋的完整服务,请设置开启浏览器cookie
新人专享,注册送VIP
Android源码定制添加反反调试机制
Android源码定制添加反反调试机制
试看结束,请登录后观看完整视频
本节课程为收费课程,您登录后才能观看
零基础入门Android(安卓)逆向 收起>
第一章:Android Java 逆向基础
第二章:Android Hook 插件开发
第三章:阶段考核
第四章:Android 系统编译
第五章:Android arm native 逆向
第六章:Android 应用初步编程保护
第七章:Android 应用脱壳
第八章:Android 应用保护
关注(1598)
通过对本课程的学习,学者能够快速脱掉一些比较热门的壳,熟悉Android程序的逆向与分析,调试与破解。
Android逆向爱好者
课程评论()
课程评分(5.0)
现价:1500泉
第一章:Android Java 逆向基础
现价:280泉
第二章:Android Hook 插件开发
现价:108泉
第三章:阶段考核
第四章:Android 系统编译
现价:144泉
第五章:Android arm native 逆向
现价:175泉
第六章:Android 应用初步编程保护
现价:144泉
第七章:Android 应用脱壳
现价:504泉
第八章:Android 应用保护
现价:145泉
快获得免费弹幕、提问、点赞、吐槽权限,已有账号直接
课程与描述相符:非常满意
课程内容的价值:非常满意
老师讲解与表达:非常满意
我在i春秋学习《零基础入门Android(安卓)逆向
》课程,很不错哦~更多网络安全学习内容,尽在i春秋
课时2013分钟
课时252分钟
课时155分钟
更新到第24
应该支付金额为45泉(已优惠10泉)×
购课优惠(*仅按门购买时优惠)
9折优惠:优惠10泉
余额支付 当前余额44泉
还需支付:1&泉
1泉等于1元人民币
请到个人中心进行充值
支付提醒×
请在新弹出的支付宝页面进行支付,完成后本页面自动跳转
微信扫码支付×
请用手机打开微信,扫描上方二维码进行支付
北京五一嘉峪科技有限公司
海淀区中关村软件广场C座
京ICP证150695号
京公网安备37号
实验环境构建:0%
为了提供倍速播放、断点续看、学习时长记录等功能,推荐您使用Chrome、Firefox浏览器,点击下载浅谈android反调试之 转发端口
时间: 12:43:41
&&&& 阅读:166
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&反调试方案:
我们最通常使用的动态工具是IDA, IDA的动态调试端口默认为23946,我们可以通过/pro/net/tcp 查看android 系统所有TCP Socket
启动android_server之后,/proc/net/tcp ,端口号是0x5D8A,十进制为23946
我们可以利用默认的调试端口23946 来实现反调试。实现代码如下, 实现原理: Android操作系统不允许一个IP可能同时存在多个相同的端口的套接字
解决方案:
最常见的解决的解决方案, 我们不使用默认转发端口23946。 android_server 提供命令指定转发端口
命令: ./android_server -p12345 ,注意端口号和参数之间没有空格
端口号变为0x3039,即12345
虽然这种做法很简单,但是对于一个崇尚简约的程序员而言,每次都要都要指定端口,烦不烦。我们能不能和之前的通过逆向android_server, 通过修改android_server的默认端口来永久改变端口号。不同IDA版本的android_server 使用指令集不太一样,比如IDA6.6 使用是ARM指令集, IDA6.8 使用的是Thumb指令集。不过修改方案是一致的, 笔者以使用Thumb指令集的IDA6.8的android_server.
1. IDA打开android_server, 找到main函数,如下:
对应的二进制指令代码
2.这里需要知道一点关于ARM指令的知识,这里的LDR R5, =5D8A, 一条伪指令, =5D8A指的指令和变量(存储值为5D8A)的相对偏移地址,这句为什么同一条ARM汇编对应16进制不一样了,因为指令地址不一样,导致偏移地址不一样。 按照惯例,这个存储5D8A的地址就在所在函数结束的后面.如下:
右侧有个DATA_XREF可知,这里有两处被应用,即两个伪指令LDR, R5, =0x5D8A的地址, 双击可以验证。
3.接下来我们用二进制编辑工具010 Editor 编辑文件偏移B8D8
将这个值改成我们指定端口号:19),保存,测试
&标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:http://www.cnblogs.com/jiaoxiake/p/6801093.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!拒绝访问 | www.4hou.com | 百度云加速
请打开cookies.
此网站 (www.4hou.com) 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(3ffae06af34443ad-ua98).
重新安装浏览器,或使用别的浏览器安卓常见的反调试与对抗方案 - 『移动安全区』
- 吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn
后使用快捷导航没有帐号?
只需一步,快速开始
请完成以下验证码
请完成以下验证码
查看: 580|回复: 9
安卓常见的反调试与对抗方案
阅读权限20
本帖最后由 fxb960704 于
16:48 编辑
以下反调试技术均为本人分析安卓各大加固厂商以及游戏厂商程序中遇到的,并班门弄斧做出了一些对应的对抗方案。总结有疏漏错误之处在所难免,望诸位大佬指正。
既然我们要反反调试,那么何谓反调试呢?众所周知,当我们完全静态分析某个程序进入“山重水复疑无路”的境地时,动态调试往往能让我们觉得“柳暗花明又一村”。那么对应的保护程序必不可少的方案就是反调试检测,将攻击者扼杀在调试前。以下总结了常见的反调试方案以及对抗措施,没有相应的反反调试技能你甚至都无法附加到目标程序,寸步难行。
1. 安卓调试检测函数& && & 本人最早调试百度加固中遇到,最近在某ctf题目中再次遇到,位于android.os.Debug.isDebuggerConnected()
1.png (12.64 KB, 下载次数: 1)
16:19 上传
原理:如图所示常用在java层,比如检测到调试状态不加载对应so导致应用运行出错。通过分析该函数在native的实现,是可以移植到so层使用该函数的(暂时没有遇到过),如:dalvik模式下在libdvm.so可以找到,art模式下结果存放在libart.so中的全局变量gDebuggerActive中。 对抗:在Java层属于非常容易绕过的反调试检测,只需要修改对应smali即可。不可小觑,下文会讲到修改安卓内核的方式绕过常见反调试,但修改该函数貌似会影响正常调试,如果被放在so层调用并加以字符串混淆将很难发现并绕过。2. IDA调试端口检测& && & 最早在调试360加固中遇到,做ctf也遇到了,当我们使用IDA提供的android_server默认端口启动,并没有正式开始调试就发现软件已经崩溃,再次打开软件依然崩溃。那么很可能就是端口检测和下面即将讲到的调试器进程名检测。原理:读取/proc/net/tcp,查找IDA远程调试的默认23946端口(或者执行命令netstat -apn)
2.1.png (15.23 KB, 下载次数: 1)
16:22 上传
2.2.png (1.92 KB, 下载次数: 1)
16:22 上传
对抗:很简单,只需要自定义调试器启动端口即可,使用&&-p&&可自定义端口。3.调试器进程名检测& && & 通常和2中提到的一起出现原理:遍历进程,查找类似android_server,gdbserver,gdb等调试器进程对抗:很简单,重命名android_server为其他字符即可4.ptrace自身检测& && & 属于占着茅坑不XX的反调试,当你用IDA附加目标程序出现如下情况,首先要怀疑遇到了这种反调试。
4.png (22.98 KB, 下载次数: 1)
16:25 上传
原理:每个进程同一时刻只能被一个调试进程ptrace,不能再被其他进程附加对抗:& && & 抢占先机,以调试模式启动目标程序(adb shell am start –D –n 包名/入口类),这时用IDA附加就抢在应用启动前,使用jdb恢复执行(调试加固软件的基本操作)。或者可以尝试hook ptrace,如果该检测是用在下文讲到的多进程反调试中,可以参考对应的对抗思路。 5.检测系统关键文件& && & 是现在市面上各类安卓软件反调试中最最常用的,当你附加到某个应用,单步了几下IDA就莫名其妙的挂掉了首先应该怀疑遇到了这种反调试。原理:在调试状态下,Linux内核会向一些文件写入进程状态信息,比如/proc/[pid]/status ,/proc/[pid]/task/[pid]/status文件的TracerPid字段写入调试器进程pid,state字段写入t(tracing stop)
5.1.jpg (15.67 KB, 下载次数: 1)
16:28 上传
/proc/[pid]/stat ,/proc/[pid]/task/[pid]/stat文件中第二个字段填入T来表示调试状态
5.2.jpg (11.96 KB, 下载次数: 1)
16:29 上传
/proc/[pid]/wchan , /proc/[pid]/task/[pid]/wchan文件写入ptrace_stop这些文件的特征能有效的反映有没有调试器附加进程,实现起来简单,正打调试器痛处,是市面上最为热门的反调试方案之一。
对抗:最容易想到的当然是在IDA中在open, fopen, strcmp, strstr等函数下断点来试图拦截这些文件的内容读取,然后伪造成没有调试器的样子。但往往一个程序会在不同时机做多次这种检测,甚至会创建线程或者进程死循环检测,想要每次都利用IDA修改只是我们一厢情愿。但道高一尺魔高一丈,修改安卓内核从根源上处理这些文件,比如将/proc/[pid]/status的TracerPid字段写死为0等,能过掉市面上绝大部分软件的反调试,让我们的调试顺畅很多(篇幅有限,如何修改,以及如何编译安卓源码不再赘述)。
6.检测安卓内核修改& && & 上文说到了修改安卓内核过反调试这么嗨皮,是不是万事大吉了?原理:创建一个子进程,让子进程主动ptrace附加自身,正常情况下,上文提到的/proc/[pid]/status的TracerPid字段应该为子进程pid,但我们修改内核源码后在任何情况下该字段都是0,以此判断出用户的安卓内核是不是改造的。对抗:其实本人并没有遇到过这种反调试,但不得不承认理论上确实存在。如果真的出现的话,本菜鸟觉得可以再次修改内核,控制fork函数,让程序子进程无法创建,诸位有更好的方案欢迎探讨。7.多进程反调试最早在调试全民枪战和穿越火线枪战王者中发现,目标程序创建了多个进程,互相ptrace,不同进程分工明确,守护或者反调试。只要有一个进程出现异常,集体挂掉,颇有一番兄弟有难同当的感觉。原理:通常是融合了多种反调试方案在子进程中,进程间可以通过管道、信号、共享内存、套接字等通信,保证反调试功能运行正常。子进程ptrace自身同时也达到了防止IDA附加的目的,这种也算是目前最流行,保护效果最好的方案之一。对抗:一种思路是,首先通过ps找出子孙进程的pid,查看/proc/&pid3&/task找出子孙进程所有的thread,并记录下他们的tid。最后使用kill -19&tid& 将这些子孙线程挂起,调试器就能正常附加主进程了。还有一种思路是修改安卓源码/bionic/libc/bionic/fork.c里面的fork函数来使得目标进程fork失败。8.代码执行时间检测最早分析360加固时遇到,当你附加并可以单步调试目标程序后,发现单步很容易在不同的地方莫名其妙的跑飞了,那么很可能是这种检测。原理:通过五个能获得时间的api,如:time()函数与time_t结构体,clock()函数与clock_t结构体,gettimeofday()函数与timeval timezone结构体,clock_gettime()函数与timespec结构体,getrusage()函数与rusage结构体获取到某处代码的执行时间,在另一处代码出再次获取时间比较时间差,正常情况下程序运行很快时间差非常小。对抗:Hook以上api,返回同一个值9. rtld_db_dlactivity函数& & 也是在360加固中遇到的,非调试状态该函数是空函数,调试状态该函数的内容改写为相应指令集的breakpoint指令
9.1.png (15.8 KB, 下载次数: 1)
16:30 上传
原理:& & 如图是Thumb breakpoint机器码& &0x01, 0xde对抗:& & IDA中可尝试对该函数下断点来到相应检测点或者修改内存中的机器码进行绕过
9.2.png (17.35 KB, 下载次数: 1)
16:31 上传
位于如图link模块下。
由于本人能力有限,暂时总结出以上反调试及对抗方案,其他的诸如检测软件断点、函数指令、Inotify事件监控等极少遇到,篇幅有限也只能侧重于理论层次,不足之处敬请谅解!
——BinCrack
吾爱币 +20
感谢发布原创作品,吾爱破解论坛因你更精彩!
谢谢@Thanks!
我很赞同!
谢谢@Thanks!
我很赞同!
我很赞同!
欢迎分析讨论交流,吾爱破解论坛有你更精彩!
感谢发布原创作品,吾爱破解论坛因你更精彩!
谢谢@Thanks!
我很赞同!
好文章,有技术含量,学习一下……
我很赞同!
热心回复!
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限25
不错文章,支持一下,请继续努力,谢谢分享。
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
感谢分享,360加固实在很难
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
Inotify事件监控极少遇到
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
感谢分享,总结不错
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
感谢分享,
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
厉害厉害!学习了
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
感谢分享,学习一波
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
免责声明:吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。
( 京ICP备号 | 京公网安备 87号 )
Powered by Discuz!
Comsenz Inc.&nbsp>&nbsp
&nbsp>&nbsp
&nbsp>&nbsp
Android反调试浅析
摘要::)侵删本文的主要内容验证apk是否被重新打包验证apk是否开启了调试,以及是否有debugger已经连接检测进程的TracerPid验证签名破解apk的时候一般都会将apk反编译,然后修改一些东西,再编译成apk(这个时候的签名和发布版本的签名是不一样的)验证签名是否和发布版本一致最好是放到服务器验证(本地传一个签名信息到服务器,服务器只需返回是否正确就行)java层验证(这里仅仅是获取了签名信息的hascode)publicstaticintgetSignature(Co
本文的主要内容
验证apk是否被重新打包
验证apk是否开启了调试,以及是否有debugger已经连接
检测进程的TracerPid
破解apk的时候一般都会将apk反编译,然后修改一些东西,再编译成apk(这个时候的签名和发布版本的签名是不一样的)
验证签名是否和发布版本一致最好是放到服务器验证(本地传一个签名信息到服务器,服务器只需返回是否正确就行)
java层验证 (这里仅仅是获取了签名信息的 hascode)
public static int getSignature(Context context){
PackageManager pm = context.getPackageManager();
StringBuilder sb = new StringBuilder();
pi = pm.getPackageInfo(context.getPackageName(),PackageManager.GET_SIGNATURES);
Signature[] signatures = pi.
for(Signature signature : signatures){
sb.append(signature.toCharsString());
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
Log.i(LOG_TAG,&获取到的签名信息 : &+sb.toString());
return sb.toString().hashCode();
native层验证(将获取签名信息方法放到native层,这里顺带讲讲jni开发)
现在的Android studio 2.2 之后就已经可以使用cmake进行ndk开发了(cmake相比以前的传统方法来说更加方便)
首先是配置app的build.gradle
主要是配置需要生成的平台和CMakeLists.txt的路径
defaultConfig {
externalNativeBuild {
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a'
externalNativeBuild {
path &src/main/cpp/CMakeLists.txt&
创建保存源文件的目录(传统的目录名字是jni,cmake的方式是cpp)
创建一个c源文件,这里已经不需要先生成头文件了(源文件里面直接按照jni的写法写函数就行了)
#include &string.h&
#include &jni.h&
Java_com_suse_yuxin_opengldemo_OpenGL20DemoActivity_helloJni( JNIEnv* env,
jobject thiz ){
return (*env)-&NewStringUTF(env,&hello Jni.&);
public native String helloJni();
System.loadLibrary(&native-lib&);
配置cmake文件(CMakeLists.txt里面的配置也比较简单 百度百度就知道了)
#指定 cmake的版本
cmake_minimum_required(VERSION 3.4.1)
add_library( native-lib
native-lib.c )
target_link_libraries(native-lib log android)
然后就可以运行了,回到正题就是jni获取签名信息
#include &string.h&
#include &jni.h&
const char HexCode[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
jobject getApplication(JNIEnv *env) {
jclass localClass = (*env)-&FindClass(env,&android/app/ActivityThread&);
if (localClass!=NULL)
// LOGI(&class have find&);
jmethodID getapplication = (*env)-&GetStaticMethodID(env,localClass, &currentApplication&, &()Landroid/app/A&);
if (getapplication!=NULL)
jobject application = (*env)-&CallStaticObjectMethod(env,localClass, getapplication);
return NULL;
return NULL;
Java_com_suse_yuxin_opengldemo_OpenGL20DemoActivity_stringFromJNI( JNIEnv* env,
jobject thiz )
//获取到Context
jobject context= getApplication(env);
if(context == NULL){
return NULL;
jclass activity = (*env)-&GetObjectClass(env,context);
// 得到 getPackageManager 方法的 ID
jmethodID methodID_func = (*env)-&GetMethodID(env,activity, &getPackageManager&, &()Landroid/content/pm/PackageM&);
// 获得PackageManager对象
jobject packageManager = (*env)-&CallObjectMethod(env,context,methodID_func);
jclass packageManagerclass = (*env)-&GetObjectClass(env,packageManager);
//得到 getPackageName 方法的 ID
jmethodID methodID_pack = (*env)-&GetMethodID(env,activity,&getPackageName&, &()Ljava/lang/S&);
//获取包名
jstring name_str = (jstring)((*env)-&CallObjectMethod(env,context, methodID_pack));
// 得到 getPackageInfo 方法的 ID
jmethodID methodID_pm = (*env)-&GetMethodID(env,packageManagerclass,&getPackageInfo&, &(Ljava/lang/SI)Landroid/content/pm/PackageI&);
// 获得应用包的信息
jobject package_info = (*env)-&CallObjectMethod(env,packageManager, methodID_pm, name_str, 64);
// 获得 PackageInfo 类
jclass package_infoclass = (*env)-&GetObjectClass(env,package_info);
// 获得签名数组属性的 ID
jfieldID fieldID_signatures = (*env)-&GetFieldID(env,package_infoclass,&signatures&, &[Landroid/content/pm/S&);
// 得到签名数组,待修改
jobject signatur = (*env)-&GetObjectField(env,package_info, fieldID_signatures);
jobjectArray signatures = (jobjectArray)(signatur);
// 得到签名
jobject signature = (*env)-&GetObjectArrayElement(env,signatures, 0);
// 获得 Signature 类,待修改
jclass signature_clazz = (*env)-&GetObjectClass(env,signature);
//---获得签名byte数组
jmethodID tobyte_methodId = (*env)-&GetMethodID(env,signature_clazz, &toByteArray&, &()[B&);
jbyteArray signature_byte = (jbyteArray) (*env)-&CallObjectMethod(env,signature, tobyte_methodId);
//把byte数组转成流
jclass byte_array_input_class=(*env)-&FindClass(env,&java/io/ByteArrayInputStream&);
jmethodID init_methodId=(*env)-&GetMethodID(env,byte_array_input_class,&&init&&,&([B)V&);
jobject byte_array_input=(*env)-&NewObject(env,byte_array_input_class,init_methodId,signature_byte);
//实例化X.509
jclass certificate_factory_class=(*env)-&FindClass(env,&java/security/cert/CertificateFactory&);
jmethodID certificate_methodId=(*env)-&GetStaticMethodID(env,certificate_factory_class,&getInstance&,&(Ljava/lang/S)Ljava/security/cert/CertificateF&);
jstring x_509_jstring=(*env)-&NewStringUTF(env,&X.509&);
jobject cert_factory=(*env)-&CallStaticObjectMethod(env,certificate_factory_class,certificate_methodId,x_509_jstring);
//certFactory.generateCertificate(byteIn);
jmethodID certificate_factory_methodId=(*env)-&GetMethodID(env,certificate_factory_class,&generateCertificate&,(&(Ljava/io/InputS)Ljava/security/cert/C&));
jobject x509_cert=(*env)-&CallObjectMethod(env,cert_factory,certificate_factory_methodId,byte_array_input);
jclass x509_cert_class=(*env)-&GetObjectClass(env,x509_cert);
jmethodID x509_cert_methodId=(*env)-&GetMethodID(env,x509_cert_class,&getEncoded&,&()[B&);
jbyteArray cert_byte=(jbyteArray)(*env)-&CallObjectMethod(env,x509_cert,x509_cert_methodId);
//MessageDigest.getInstance(&SHA1&)
jclass message_digest_class=(*env)-&FindClass(env,&java/security/MessageDigest&);
jmethodID methodId=(*env)-&GetStaticMethodID(env,message_digest_class,&getInstance&,&(Ljava/lang/S)Ljava/security/MessageD&);
//如果取SHA1则输入SHA1
//jstring sha1_jstring=(*env)-&NewStringUTF(env,&SHA1&);
jstring sha1_jstring=(*env)-&NewStringUTF(env,&MD5&);
jobject sha1_digest=(*env)-&CallStaticObjectMethod(env,message_digest_class,methodId,sha1_jstring);
//sha1.digest (certByte)
methodId=(*env)-&GetMethodID(env,message_digest_class,&digest&,&([B)[B&);
jbyteArray sha1_byte=(jbyteArray)(*env)-&CallObjectMethod(env,sha1_digest,methodId,cert_byte);
//toHexString
jsize array_size=(*env)-&GetArrayLength(env,sha1_byte);
jbyte* sha1 =(*env)-&GetByteArrayElements(env,sha1_byte,NULL);
char hex_sha[array_size*2+1];
for (i = 0;i&array_++i) {
hex_sha[2*i]=HexCode[((unsigned char)sha1[i])/16];
hex_sha[2*i+1]=HexCode[((unsigned char)sha1[i])%16];
hex_sha[array_size*2]='/0';
return (*env)-&NewStringUTF(env, hex_sha);
可调式状态校验
一个是AndroidManifest的调试flag是否打开
* 验证是否可以调试
* i != 0 已经打开可调式
int i = getApplicationInfo().flags &; ApplicationInfo.FLAG_DEBUGGABLE;
debugger是否已经连接
boolean debuggerConnected = Debug.isDebuggerConnected();
Log.i(LOG_TAG,&是否连接调试 : &+debuggerConnected);
获取获取TracerPid来判断(TracerPid正常情况是0,如果被调试这个是不为0的)
* 获取TracerPid来判断
int pid = android.os.Process.myPid();
String info =
File file = new File(&/proc/& + pid + &/status&);
FileInputStream fileInputStream = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(reader);
while((info = bufferedReader.readLine()) != null){
Log.i(LOG_TAG,&proecc info : &+info);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
上面这个是获取到了进程的各种状态下面给一个log日志信息
Nothing is certain in this life. The only thing i know for sure is that. I love you and my life. That is the only thing i know. have a good day
以上是的内容,更多
的内容,请您使用右上方搜索功能获取相关信息。
若你要投稿、删除文章请联系邮箱:zixun-group@service.aliyun.com,工作人员会在五个工作日内给你回复。
云服务器 ECS
可弹性伸缩、安全稳定、简单易用
&40.8元/月起
预测未发生的攻击
&24元/月起
为您提供0门槛上云实践机会
你可能还喜欢
你可能感兴趣
阿里云教程中心为您免费提供
Android反调试浅析相关信息,包括
的信息,所有Android反调试浅析相关内容均不代表阿里云的意见!投稿删除文章请联系邮箱:zixun-group@service.aliyun.com,工作人员会在五个工作日内答复
售前咨询热线
服务与支持
资源和社区
关注阿里云
International

我要回帖

更多关于 android unity 反调试 的文章

 

随机推荐