2.分析Android程序
来源:互联网 发布:原油投资网络骗局 编辑:程序博客网 时间:2024/06/05 08:13
分析Android程序四要素: Android程序开发流程、程序结构、语句分支、解密原理。
一、编写Crackme
1.新建一个Android工程,需要有MainActivity
2.res\values\strings.xml 增加 info、username、hint_username、sn、hini_sn、register、registered、unsuccessed、successed 这几个字段
<?xml version="1.0" encoding="utf-8"?><resources> <string name="app_name">Crackme0201</string> <string name="hello_world">Hello world!</string> <string name="action_settings">Settings</string><string name="info">Android程序破解演示程序</string><string name="username">用户名:</string><string name="hint_username">请输入用户名</string><string name="sn">注册码:</string><string name="hint_sn">请输入注册码</string><string name="register">注册</string><string name="registered">程序已注册</string><string name="unsuccessed">无效用户名或注册码</string><string name="successed">恭喜您!注册成功</string></resources>3.res\layout\activity_main.xml 如下
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/info" android:textSize="20dp"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/username"/> <EditText android:id="@+id/edit_username" android:hint="@string/hint_username" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_weight="1" android:ems="10"/>" </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/sn"/> <EditText android:id="@+id/edit_sn" android:hint="@string/hint_sn" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_weight="1" android:ems="10"/>" </LinearLayout> <Button android:id="@+id/button_register" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:layout_gravity="right" android:text="@string/register"/></LinearLayout>
布局效果如图:
4.MainActivity 编码 (在OnCreate中为按钮 "注册" 绑定OnClick事件,取出EditText中的用户名和注册码,调用checkSN传入用户名计算出16位的注册码与输入的注册码比较
一致(忽略大小写)则提示注册成功,否则失败! ):
package com.droider.crackme0201;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends ActionBarActivity {private EditText edit_userName;private EditText edit_sn;private Button btn_register; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setTitle(R.string.unsuccessed); edit_userName=(EditText)findViewById(R.id.edit_username); edit_sn=(EditText)findViewById(R.id.edit_sn); btn_register=(Button)findViewById(R.id.button_register); btn_register.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubif(!checkSN(edit_userName.getText().toString().trim(),edit_sn.getText().toString().trim())){Toast.makeText(MainActivity.this,R.string.unsuccessed,Toast.LENGTH_SHORT).show();}else{Toast.makeText(MainActivity.this,R.string.successed,Toast.LENGTH_SHORT);btn_register.setEnabled(false);setTitle(R.string.registered);}} }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Incflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } private boolean checkSN(String userName,String sn){ try{ if((userName==null) || (userName.length()==0)) return false; if((sn==null) || (sn.length()==0)) return false; MessageDigest digest=MessageDigest.getInstance("MD5"); digest.reset(); digest.update(userName.getBytes()); byte[] bytes=digest.digest(); String hexstr=toHexString(bytes,""); StringBuilder sb=new StringBuilder(); for(int i=0;i<hexstr.length();i+=2){ sb.append(hexstr.charAt(i)); } String userSN=sb.toString(); if(!userSN.equalsIgnoreCase(sn)) return false; }catch(NoSuchAlgorithmException e) { e.printStackTrace(); return false; } return true; } private static String toHexString(byte[] bytes, String separator) { StringBuilder hexString = new StringBuilder(); for (byte b : bytes) { String hex = Integer.toHexString(0xFF & b); if(hex.length() == 1){ hexString.append('0'); } hexString.append(hex).append(separator); } return hexString.toString(); }}
5.编译运行,用户名输入1,输入错误的注册码r,点击注册 提示 无效的用户名或注册码。
二、反编译Android程序
1. 利用ShakaApktool_2.0.0.jar 反编译 crackme02.apk
命令行: java -jar ShakaApktool_2.0.0.jar d crackme02.apk
执行命令成功后,apk同目录中会出现一个同名文件夹 crackme02 ,反编译完成。
crackme02文件夹:
2.利用错误提示"无效用户或注册码"找到引用这个字符串的name
字符串位于crackme02\res\values\strings.xml 中,即它的name为unsuccessed。
<?xml version="1.0" encoding="utf-8"?><resources>
<string name="unsuccessed">无效用户名或注册码</string>
</resources>
3.查找字符串的ID
但是代码中引用的为字符串的ID,在编码过程中通过 R.java 来标识字符串的ID,而在反编译得到的代码中 ,ID是在crackme02\res\values\public.xml 中。
从public.xml中找到 ,即字符串 unsuccessed的ID为 0x7f0a0017。
<?xml version="1.0" encoding="utf-8"?><resources> <public type="string" name="unsuccessed" id="0x7f0a0017" /></resources>
4.查找引用这个ID的smali代码
然后再在 crackme02\smali\com\droider\crackme0201 文件夹中的smali文件中查找引用 0x7f0a0017 的代码。
找到 MainActivity$1.smali 中有一处引用了 0x7f0a0017 ,可以看出在 .line36 调用 checkSN 计算并比较注册码,返回值存在v0寄存器中,
.line37 如果返回值不为0则跳转到 cond_0 (注册成功) 继续执行,否则将顺序执行 .line 38 .line 39 的代码。
在 .line 39 引用了 unsuccessed 的字符串。
.line 36 # invokes: Lcom/droider/crackme0201/MainActivity;->checkSN(Ljava/lang/String;Ljava/lang/String;)Z invoke-static {v0, v1, v2}, Lcom/droider/crackme0201/MainActivity;->access$2(Lcom/droider/crackme0201/MainActivity;Ljava/lang/String;Ljava/lang/String;)Z move-result v0 .line 37 if-nez v0, :cond_0 .line 38 iget-object v0, p0, Lcom/droider/crackme0201/MainActivity$1;->this$0:Lcom/droider/crackme0201/MainActivity; .line 39 const v1, 0x7f0a0017 .line 38 invoke-static {v0, v1, v3}, Landroid/widget/Toast;->makeText(Landroid/content/Context;II)Landroid/widget/Toast; move-result-object v0 .line 39 invoke-virtual {v0}, Landroid/widget/Toast;->show()V .line 46 :goto_0 return-void
三、修改smali代码,实现破解crackme。
1.修改smali代码,将 .line 37 的 if-nez 改为 if-eqz ,即不为0跳转改为为0时跳转。
.line 36 # invokes: Lcom/droider/crackme0201/MainActivity;->checkSN(Ljava/lang/String;Ljava/lang/String;)Z invoke-static {v0, v1, v2}, Lcom/droider/crackme0201/MainActivity;->access$2(Lcom/droider/crackme0201/MainActivity;Ljava/lang/String;Ljava/lang/String;)Z move-result v0 .line 37 if-eqz v0, :cond_0 .line 38 iget-object v0, p0, Lcom/droider/crackme0201/MainActivity$1;->this$0:Lcom/droider/crackme0201/MainActivity; .line 39 const v1, 0x7f0a0017 .line 38 invoke-static {v0, v1, v3}, Landroid/widget/Toast;->makeText(Landroid/content/Context;II)Landroid/widget/Toast; move-result-object v0 .line 39 invoke-virtual {v0}, Landroid/widget/Toast;->show()V .line 46 :goto_0 return-void
2.重新编译修改后的代码,在原来执行命令的apk文件的目录执行命令
命令行: java -jar apktool.jar b crackme02 -o crackme02_repack.apk
成功执行后将会得到一个新的apk文件 crackme02_repack.apk。
这里用的是 apktool.jar,也可以使用ShakaApktool。
3.给新的apk签名
命令行:java -jar signapk.jar platform.x509.pem platform.pk8 crackme02_repack.apk crackme02_repack_signed.apk
成功执行后将会得到一个新的apk文件 crackme02_repack_signed.apk
4.安装测试,注册成功了。
- 2.分析Android程序
- android su程序分析
- Android 程序静态分析
- android 程序内存分析
- 逆向分析 Android 程序
- android 程序架构分析
- Android程序简单分析
- 逆向分析 Android 程序
- Android init初始化程序分析
- Android 程序的结构分析
- 分析android程序项目结构
- Android安全:如何逆向分析Android程序
- Android逆向分析基础-静态分析Android程序
- 利用 traceview和 dmtracedump 分析 android 程序
- Android程序的执行流程分析
- iphone, Android程序接口分析软件
- Android程序分析工具Traceview的使用方法
- android app(3)-Hello world程序分析
- 事务的一阶段提交协议和二阶段提交协议
- thinkphp3.2.3加载公共函数
- I2C时序剖析
- Git笔记(持续更新)
- 二叉树迭代器遍历
- 2.分析Android程序
- 解决Android SDK下载和更新失败"Connection to https://dl-ssl.google.com refused"的问题
- HDU1251-统计难题
- 矩形的面积
- 多列布局(column)
- HDU 2855(由递推式构造矩阵+矩阵快速幂)
- LeetCode376. Wiggle Subsequence
- Fraction(长春重现赛)
- ResultSet用法集锦