保护Android代码(防止反编译)

保护Android代码(防止反编译)

2023年6月28日发(作者:)

保护Android代码(防⽌反编译)保护Android代码(防⽌反编译)原⽂地址:逆向Android软件的步骤: ⾸先使⽤反编译的⼯具对反编译,然后阅读反汇编代码,如果有必要还会对其进⾏动态调试,找到突破⼝后注⼊或直接修改反汇编代码,最后重新编译软件进⾏测试。整个过程可分为反编译、静态分析、动态调试、重编译等4个环节。结论:反破解技术也是从这四个⽅⾯进⾏的。⼀、对抗反编译⼯具(如ApkTool、BackSmali、dex2jar),使其⽆法进⾏反编译,或者反编译后⽆法得到软件正确的反汇编代码。思路是:寻找反编译⼯具在处理apk或dex⽂件时的缺陷,然后在⾃⼰的软件中加以利⽤。主要⽅法有:1、阅读反编译⼯具源码,找出漏洞。2、压⼒测试。测试⼤量apk⽂件,找到反编译⼯具反编译不了的,分析其特征。此⽅法难度较⼤,⽽且反编译⼯具不断升级,⽅法容易过时,因此不太建议。(不⾏)⼆、对抗静态分析。1、代码混淆技术:Android2.3的SDK中正式加⼊了ProGuard代码混淆⼯具,开发⼈员可以使⽤该⼯具对⾃⼰的代码进⾏混淆。Android2.3以前的项⽬同样可以使⽤此⼯具。2、NDK保护。NDK简介:“android原⽣开发套件”。他是⼀款功能强⼤的⼯具,可以将原⽣C,C++代码的强⼤功能和android应⽤的图形化界⾯结合到⼀起,解决软件的跨平台问题。通过使⽤该⼯具,⼀些应⽤程序直接通过JNI调⽤(ps:java native interface,允许Java代码和其他语⾔编写的代码进⾏交互)与CPU打交道使性能得到提升。同时能够将程序的核⼼功能封装进基于“原⽣开发套件”的模块中,从⽽⼤⼤提⾼性能!(PS:C/C++的抗攻击能⼒⽐Java强)优势:逆向NDK程序是很困难和繁琐的,安全性很⾼。缺点:程序员开发成本提⾼。3、外壳保护。java由于其语⾔⾃⾝特殊性,没有外壳保护这个概念,只能通过混淆⽅式对其进⾏保护。外壳保护重点针对使⽤NDK编写的Native代码,逆向Native本⾝就已经够困难了,如果添加了外壳保护则更是难上加难,⽬前已知可⽤于ARM Linux内核程序的加壳⼯具只有upx。三、对抗动态调试。1、检测调试器:动态调试使⽤调试器来挂钩软件,获取软件运⾏时的数据,我们可以在软件中加⼊检测调试器的代码,当检测到软件被调试器连接时,中⽌软件的运⾏。⾸先,在⽂件的Application标签中加⼊android:debuggable="false",让程序不可调试,这样,如果别⼈想调试该程序,就必然会修改它的值,我们在代码中检查它的值来判断程序是否被修改过。代码如下:[java]

01.

02.

03.

04.

if (0!=(getApplicationInfo().flags&=_DEBUGGABLE)) {

Log.e("DEBUG", "程序被修改为可调试状态");

ocess(());

}

另外,Android SDK中提供了⼀个⽅法⽅便程序员来检测调试器是否已经连接,代码如下:[java]

01. ggerConnected() 如果⽅法返回真,说明了调试器已经连接。我们可以随机地在软件中插⼊这⾏代码来检测调试器,碰到有调试器连接就果断地结束程序运⾏。(PS:感觉这是个好的办法!但是不知道是否有破解的⽅法如果有必要留待以后查资料)对抗检测调试器的⽅法:⽅法1:IsDebuggerPersent()/查找PEB中BeingDebugged内容⽅法2:检查是否有异常处理器⽅法3:利⽤调试器约定特殊指令检测⽅法4:查找当前硬件断点⽅法5:在执⾏特殊函数后检查GetLastError()值⽅法6:DebugPort: CheckRemoteDebuggerPresent()/NtQueryInformationProcess()⽅法7:检测SetUnhandledExceptionFilter()⽅法8:ThreadHideFromDebugger⽅法9:进程遍历⽅法10:⽗进程检查⽅法11:SeDebugPrivilege()⽅法12:FindWindow⽅法13:STARTUPINFO⽅法14:⽅法N:利⽤调试器漏洞(未扩展 但是不知道能不能在android上实现这些对抗)2、检测模拟器。(ps:只是增加了逆向的成本,必须有⼀台android机器)软件发布后会安装到⽤户的⼿机中运⾏,如果有发现软件运⾏在模拟器中,很显然不合常理,可能是有⼈试图破解或分析它,这种情况我们必须予以阻⽌。模拟器与真实的Android⼿机有许多差异,我们可以在命令提⽰符下执⾏"adb shell getprop"查看并对⽐它们的属性值,经过对⽐发现如下⼏个属性值可以⽤来判断软件是否运⾏在模拟器中:、、。编写检测代码如下:[java]

01.

02.

03.

04.

05.

06.

07.

08.

09.

10.

11.

12.

13.

14.

15.

16.

17.

18.

19.

20.

21.

22.

23.

24.

25.

26.

27.

28.

29.

30.

31.

32.

33.

34.

35.

36.

37.

38.

39.

40.

41.

42.

boolean isRunningInEmualtor() {

boolean qemuKernel = false;

Process process = null;

DataOutputStream os = null;

try{

process = time().exec("getprop ");

os = new DataOutputStream(putStream());

BufferedReader in = new BufferedReader(new InputStreamReader(utStream(),"GBK"));

ytes("exitn");

();

r();

qemuKernel = (f(ne()) == 1);

Log.d("emu", "检测到模拟器:" + qemuKernel);

} catch (Exception e){

qemuKernel = false;

Log.d("emu", "run failed" + sage());

} finally {

try{

if (os != null) {

();

}

y();

} catch (Exception e) {

}

Log.d("emu", "run finally");

}

return qemuKernel;

}

public static String getProp(Context context, String property) {

try {

ClassLoader cl = ssLoader();

Class SystemProperties = ass("Properties");

Method method = hod("get", );

Object[] params = new Object[1];

params[0] = new String(property);

return (String)(SystemProperties, params);

} catch (Exception e) {

return null;

}

}

四、防⽌重编译。1、检查签名。每⼀个软件在发布时都需要开发⼈员对其进⾏签名,⽽签名使⽤的密钥⽂件是开发⼈员所独有的,破解者通常不可能拥有相同的密钥⽂件,因此,签名成了Andriod软件⼀种有效的⾝份标识,如果软件运⾏时的签名与⾃⼰发布时的不同,说明软件被篡改过,这个时候我们就可以让软件中⽌运⾏。获取签名hash值的代码如下:[java]

01.

02.

03.

04.

05.

06.

07.

08.

09.

10.

11.

12.

13.

14.

public int getSignature(String packageName) {

PackageManager pm = kageManager();

PackageInfo pi = null;

int sig = 0;

try {

pi = kageInfo(packageName, _SIGNATURES);

Signature[] s = ures;

sig = s[0].hashCode();

} catch (Exception e1) {

sig = 0;

tackTrace();

}

return sig;

}

可使⽤Eclipse⾃带的调试版密钥⽂件⽣成的apk⽂件的hash值,与上⾯的函数获取的hash⽐较,可以判断签名是否⼀致。2、校验保护。(PS:通过联⽹的⽅式检验)重编译Andriod软件的实质是重新编译⽂件,代码经过重新编译后,⽣成的⽂件的hash值已经改变,我们可以检查程序安装后⽂件的Hash值,来判断软件是否被重打包过。[java]

01.

02.

03.

04.

05.

06.

07.

08.

09.

10.

11.

12.

13.

14.

15.

16.

17.

private boolean checkCRC() {

boolean beModified = false;

long crc = ong(getString());

ZipFile zf;

try {

zf = new ZipFile(getApplicationContext().getPackageCodePath());

ZipEntry ze = ry("");

Log.d("rc", f(()));

if (() == crc) {

beModified = true;

}

} catch (IOException e) {

tackTrace();

beModified = false;

}

return beModified;

}

五:动态修改dalvik字节码 增加逆向分析的难度,这个技术⽐较新 搜不到相应的⽐较详细的技术介绍六:将核⼼代码隐藏,增加分析的难度,这个技术有待查询

参考:

发布者:admin,转转请注明出处:http://www.yc00.com/news/1687954017a60476.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信