逆向Android软件的步骤
2019獨角獸企業重金招聘Python工程師標準>>>
逆向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。
PS:關于upx:http://upx.sourceforge.net/? ??支持的平臺
三、對抗動態調試。
1、檢測調試器:
動態調試使用調試器來掛鉤軟件,獲取軟件運行時的數據,我們可以在軟件中加入檢測調試器的代碼,當檢測到軟件被調試器連接時,中止軟件的運行。
首先,在AndroidManifest.xml文件的Application標簽中加入android:debuggable="false",讓程序不可調試,這樣,如果別人想調試該程序,就必然會修改它的值,我們在代碼中檢查它的值來判斷程序是否被修改過。代碼如下:
if?(0!=(getApplicationInfo().flags&=ApplicationInfo.FLAG_DEBUGGABLE))?{??Log.e("DEBUG",?"程序被修改為可調試狀態!!!");??android.os.Process.killProcess(android.os.Process.myPid());??}另外,Android SDK中提供了一個方法方便程序員來檢測調試器是否已經連接,代碼如下:
android.os.Debug.isDebuggerConnected()
如果方法返回真,說明了調試器已經連接。我們可以隨機地在軟件中插入這行代碼來檢測調試器,碰到有調試器連接就果斷地結束程序運行。
(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:timecheck
...
方法N:利用調試器漏洞
(未擴展 ??但是不知道能不能在android上實現這些對抗)
2、檢測模擬器。(ps:只是增加了逆向的成本,必須有一臺android機器)
軟件發布后會安裝到用戶的手機中運行,如果有發現軟件運行在模擬器中,很顯然不合常理,可能是有人試圖破解或分析它,這種情況我們必須予以阻止。
模擬器與真實的Android手機有許多差異,我們可以在命令提示符下執行"adb shell getprop"查看并對比它們的屬性值,經過對比發現如下幾個屬性值可以用來判斷軟件是否運行在模擬器中:
ro.product.model、ro.build.tag、ro.kernel.qemu。
編寫檢測代碼如下:
boolean?isRunningInEmualtor()?{??boolean?qemuKernel?=?false;??Process?process?=?null;??DataOutputStream?os?=?null;??try{????process?=?Runtime.getRuntime().exec("getprop?ro.kernel.qemu");????os?=?new?DataOutputStream(process.getOutputStream());??BufferedReader?in?=?new?BufferedReader(new?InputStreamReader(process.getInputStream(),"GBK"));??os.writeBytes("exit\n");????os.flush();??process.waitFor();??qemuKernel?=?(Integer.valueOf(in.readLine())?==?1);??Log.d("com.droider.checkqemu",?"檢測到模擬器:"?+?qemuKernel);???????????????}?catch?(Exception?e){????qemuKernel?=?false;??Log.d("com.droider.checkqemu",?"run?failed"?+?e.getMessage());???}?finally?{??try{????if?(os?!=?null)?{????os.close();????}????process.destroy();????}?catch?(Exception?e)?{??}????Log.d("com.droider.checkqemu",?"run?finally");???}??return?qemuKernel;??}??public?static?String?getProp(Context?context,?String?property)?{??try?{??ClassLoader?cl?=?context.getClassLoader();??Class?SystemProperties?=?cl.loadClass("android.os.SystemProperties");??Method?method?=?SystemProperties.getMethod("get",?String.class);??Object[]?params?=?new?Object[1];??params[0]?=?new?String(property);??return?(String)method.invoke(SystemProperties,?params);??}?catch?(Exception?e)?{??return?null;??}??}四、防止重編譯。
1、檢查簽名。
每一個軟件在發布時都需要開發人員對其進行簽名,而簽名使用的密鑰文件是開發人員所獨有的,破解者通常不可能擁有相同的密鑰文件,因此,簽名成了Andriod軟件一種有效的身份標識,如果軟件運行時的簽名與自己發布時的不同,說明軟件被篡改過,這個時候我們就可以讓軟件中止運行。
獲取簽名hash值的代碼如下:
public?int?getSignature(String?packageName)?{????????PackageManager?pm?=?this.getPackageManager();??PackageInfo?pi?=?null;??int?sig?=?0;??try?{??pi?=?pm.getPackageInfo(packageName,?PackageManager.GET_SIGNATURES);??Signature[]?s?=?pi.signatures;??sig?=?s[0].hashCode();????}?catch?(Exception?e1)?{??sig?=?0;??e1.printStackTrace();??}??return?sig;??}可使用Eclipse自帶的調試版密鑰文件生成的apk文件的hash值,與上面的函數獲取的hash比較,可以判斷簽名是否一致。
2、校驗保護。(PS:通過聯網的方式檢驗)
重編譯Andriod軟件的實質是重新編譯classes.dex文件,代碼經過重新編譯后,生成的classes.dex文件的hash值已經改變,我們可以檢查程序安裝后classes.dex文件的Hash值,來判斷軟件是否被重打包過。
private?boolean?checkCRC()?{??boolean?beModified?=?false;??long?crc?=?Long.parseLong(getString(R.string.crc));??ZipFile?zf;?? try?{??zf?=?new?ZipFile(getApplicationContext().getPackageCodePath());??ZipEntry?ze?=?zf.getEntry("classes.dex");??Log.d("com.droider.checkcrc",?String.valueOf(ze.getCrc()));??if?(ze.getCrc()?==?crc)?{??beModified?=?true;??}??? }?catch?(IOException?e)?{??e.printStackTrace();??beModified?=?false;?? }?? return?beModified;??}五:動態修改dalvik字節碼 增加逆向分析的難度,這個技術比較新 搜不到相應的比較詳細的技術介紹
六:將核心代碼隱藏,增加分析的難度,這個技術有待查詢
轉載自夢想天涯的博客:http://blog.csdn.net/viviwen123/article/details/9117589
轉載于:https://my.oschina.net/kutengshe/blog/482744
總結
以上是生活随笔為你收集整理的逆向Android软件的步骤的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到蛇是什么仙家
- 下一篇: Android View滚动、拉伸到顶/