前言 停更了一周,其实前些天倒是也学了点,但是五一假期太诱人了,都想把事情放在假期来做,然而前两天基本上就睡过去了,所以拖到了今天。Android这部分,2月份疫情期间学了不少,不过之后开始更新Windows内核的内容了,也就没续上,之前又做了一遍实验,发现很多坑都没有再踩。所以这篇可能会漏掉部分我以前遇到的坑。
之前有计划在3月下旬就开始更新Android,后来发现,由于先前日更的缘故,周末其实也是比较赶进度的,所以拖了很久,现在不日更了,Windows内核的基础部分,也就差个多核同步以及APC了,所以就可以偶尔穿插的更新些Android相关的了,把这部分的内容再巩固下。(题外话,瀚哥真是个狠人,感觉他醒着的时间都在学习新的内容,认识这个世界,太佩服了)
回到本篇的内容,我计划是在博客里演示一遍虫神书上的第一个逆向实验,但是需要一些准备工作,比如CrackMe程序代码的编写,部分Android逆向用到的工具下载及配置等等,所以这篇叫做准备工作,具体程序逆向分析,会在下一篇进行。
编写Android程序 首先我们需要编写一个简单的Android程序,实现一个低级的注册功能(仅有前端部分),然后再逆向分析,破解这个程序。一个Android程序主要编写的是布局文件 和功能实现 的部分,这两部分,分别使用xml和Java/Kotlin语言编写(本篇采用Java)下面来看代码
activity_main.xml 布局文件,本次实验采用的约束布局(ConstaintLayout),相关内容可参考此处 
1 2 3 4 5 6 7 8 9 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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 <androidx.constraintlayout.widget.ConstraintLayout  xmlns:android ="http://schemas.android.com/apk/res/android"      xmlns:app ="http://schemas.android.com/apk/res-auto"      xmlns:tools ="http://schemas.android.com/tools"      android:layout_width ="match_parent"      android:layout_height ="match_parent"      tools:context =".MainActivity" >     <TextView           android:id ="@+id/tv_name"          android:layout_width ="99dp"          android:layout_height ="51dp"          android:text ="Username"          app:layout_constraintBottom_toBottomOf ="parent"          app:layout_constraintEnd_toEndOf ="parent"          app:layout_constraintHorizontal_bias ="0.179"          app:layout_constraintStart_toStartOf ="parent"          app:layout_constraintTop_toTopOf ="parent"          app:layout_constraintVertical_bias ="0.242"  />     <TextView           android:id ="@+id/tv_code"          android:layout_width ="99dp"          android:layout_height ="51dp"          android:text ="Code"          app:layout_constraintBottom_toBottomOf ="parent"          app:layout_constraintEnd_toEndOf ="parent"          app:layout_constraintHorizontal_bias ="0.179"          app:layout_constraintStart_toStartOf ="parent"          app:layout_constraintTop_toTopOf ="parent"          app:layout_constraintVertical_bias ="0.317"  />     <EditText           android:id ="@+id/ed_name"          android:layout_width ="188dp"          android:layout_height ="51dp"          app:layout_constraintBottom_toBottomOf ="parent"          app:layout_constraintEnd_toEndOf ="parent"          app:layout_constraintHorizontal_bias ="0.695"          app:layout_constraintStart_toStartOf ="parent"          app:layout_constraintTop_toTopOf ="parent"          app:layout_constraintVertical_bias ="0.219"  />     <EditText           android:id ="@+id/ed_code"          android:layout_width ="188dp"          android:layout_height ="51dp"          app:layout_constraintBottom_toBottomOf ="parent"          app:layout_constraintEnd_toEndOf ="parent"          app:layout_constraintHorizontal_bias ="0.695"          app:layout_constraintStart_toStartOf ="parent"          app:layout_constraintTop_toTopOf ="parent"          app:layout_constraintVertical_bias ="0.294"  />     <Button           android:id ="@+id/btn_reg"          android:text ="Register"          android:layout_width ="88dp"          android:layout_height ="51dp"          app:layout_constraintBottom_toBottomOf ="parent"          app:layout_constraintEnd_toEndOf ="parent"          app:layout_constraintHorizontal_bias ="0.695"          app:layout_constraintStart_toStartOf ="parent"          app:layout_constraintTop_toTopOf ="parent"  /> androidx.constraintlayout.widget.ConstraintLayout >
MainActivity.java 这里采用MD5算法 ,根据输入的用户名计算出一个哈希值 ,作为用来校验的注册码。具体实现部分,用到了Java提供的MessageDigest类,使用方法可以参考此篇文章 
1 2 3 4 5 6 7 8 9 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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 package  com.droider.crackme_0x1;import  androidx.appcompat.app.AppCompatActivity;import  android.os.Bundle;import  android.os.Message;import  android.view.View;import  android.widget.Button;import  android.widget.EditText;import  android.widget.Toast;import  java.security.MessageDigest;import  java.security.NoSuchAlgorithmException;public  class  MainActivity  extends  AppCompatActivity      private  Button btn_reg;     private  EditText ed_name, ed_code;     private  void  initialView ()          btn_reg = (Button)findViewById(R.id.btn_reg);         ed_name = (EditText)findViewById(R.id.ed_name);         ed_code = (EditText)findViewById(R.id.ed_code);         btn_reg.setOnClickListener(new  MyListener());     }     @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         initialView();     }     class  MyListener  implements  View .OnClickListener           @Override          public  void  onClick (View v)              String inputName = ed_name.getText().toString();             String inputCode = ed_code.getText().toString();             MessageDigest md = null ;             try  {                 md = MessageDigest.getInstance("MD5" );                 md.update(inputName.getBytes());                 byte [] result = md.digest();                 StringBuffer sb = new  StringBuffer();                 for (int  i = 0 ; i < result.length/2 ; i++) {                     int  val = result[i] & 0xff ;                     sb.append(val);                 }                 if (sb.toString() == inputCode){                     Toast.makeText(MainActivity.this , R.string.success, Toast.LENGTH_SHORT).show();                 } else  {                     Toast.makeText(MainActivity.this , R.string.unsuccess, Toast.LENGTH_SHORT).show();                 }             } catch  (NoSuchAlgorithmException e) {                 e.printStackTrace();             }             Toast.makeText(MainActivity.this , "Failed" , Toast.LENGTH_SHORT).show();         }     } } 
程序运行 下面在Android虚拟机上运行app:
可以看到,当我们输入用户名以及校验码的时候,会显示Register Failed,原因是我们输入的校验码是错的;当输入正确的校验码时会显示Register Succeed。下一篇会学习如何通过逆向暴破这个程序。本篇是准备工作,所以此时程序已经满足了我们的要求,下面介绍一下本次实验用到的工具及其相关内容。
右键命令行 右键命令行设置主要是为了方便,因为后期逆向的程序越来越多,分布在不同的文件夹,有些命令需要在命令行中执行(Basn on Windows执行不了时),进入命令行如果从切换盘开始一点点找,固然是麻烦的一件事,但有了右键命令行就可以较为方便的定位到当前目录下。比如我在写博客时用的Git Bash就设置了右键快捷键,可以在切换到博客目录后再进入Git Bash,不用打开后不停的用cd命令切换那么麻烦。
下面来看一下如何在右键快捷键中设置命令行:
首先Win+r ,输入Regedit,进入注册表  
接着,我们查找路径 
1 计算机\HKEY_CLASSES_ROOT\Directory\Background\shell 
找到shell后,右键新建一个项 ,并命名为OpenCmdHere,这时,里面会有一个默认值,我们修改默认值 的数值数据 为“在此处打开命令行窗口 ”,这一步是设置右键看到的描述。然后再新建一个字符串值 ,名称 设置为“Icon ”,数值数据 设置为cmd.exe ,这一步是设置右键看到的图标。具体操作完了的情况如下图:
接下来,我们选择OpenCmdHere并新建一个项 ,命名为command ,并修改默认值的数值数据 为“cmd.exe /s /k pushd “%V” ”,具体如下图:
以上全部设置完后,退出注册表,随便进入一个文件夹,单机右键,就可以看到已经成功在右键快捷键中设置命令行。 
 
在Android逆向分析中,会用到很多工具,例如Apktool,AndroidKiller,dex2jar,jd-gui等等,本篇中只介绍本次实验中会用到的工具,其余等到后期进一步作逆向分析时再讨论。
进入ApkTool官网 ,这里面有详细的安装教程,针对不同操作系统的都有,这里简单概述一下:
去这里 下载最新版的apktool.jar,例如我下载的是当前最新版本的apktool_2.4.1.jar(最好一定要下载最新版本的,不然反汇编Apk文件时会发生错误 )下载后,将apktool_2.4.1.jar重命名为 apktool.jar
下载批处理文件,由于官网好像挂掉了,我就直接复制我这份的:
1 2 3 4 5 6 7 8 9 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 @echo  off setlocal set  BASENAME=apktool_chcp  65001  2 >nul  >nul setlocal  EnableDelayedExpansionpushd  "%~dp0"if  exist  apktool.jar (    set  BASENAME=apktool     goto  skipversioned ) set  max=0 for  /f "tokens=1 * delims=-_.0 " %%A  in  ('dir  /b /a-d %BASENAME% *.jar') do  if  %%~ B gtr  !max!  set  max=%%~ nB:skipversioned popd setlocal  DisableDelayedExpansionif  "%~1 "=="" goto  loadif  not  "%~2 "=="" goto  loadset  ATTR=%~a1if  "%ATTR:~0,1% "=="d" (    set  fastCommand=b ) if  "%ATTR:~0,1% "=="-" if  "%~x1"==".apk" (    set  fastCommand=d ) :load java -jar -Duser.language=en -Dfile.encoding=UTF8 "%~dp0% BASENAME%%m ax%.jar" %fastCommand%  %* for  /f "tokens=2 " %%#  in  ("%cmdcmdline% ") do  if  /i "%%# " equ  "/c" pause 
新建一个批处理(.bat)文件 ,命名为apktool ,将上述内容copy进去然后保存
将apktool.bat和apktool.jar复制到C:\Windows目录下,如下图所示:
完成上述操作后,进入命令行,输入apktool,若结果如下图所示,说明apktool安装成功
 
AndroidKiller Apktool是对apk文件反汇编用的,AndroidKiller则可以用来分析,修改,签名等操作,当然,它也可以设置Apktool插件从而增加反汇编功能。默认也是有的。
AndroidKiller可以直接去52pojie的爱盘 下载,下载压缩包后解压,有个AndroidKiller.exe,点击即可食用。
本次实验是采用apktool在命令行中对apk文件进行反编译的,想在AndroidKiller中完成也行,但是需要更新一下插件,用 前文中下载的最新版的apktool.jar替换目录AndroidKiller_v1.3.1\bin\apktool\apktool下的ShakaApktool.jar ,即可。
到这,准备工作也就完成了,过几天会再更新一篇,正式对我们编写的android程序进行逆向分析,有关AndroidKiller更多的使用方法可以参考吾爱破解上的一篇文章 。这里不再赘述。
参考链接 参考书籍:《Android软件安全权威指南》—— 丰生强
参考文章:
https://www.jianshu.com/p/17ec9bd6ca8a https://blog.csdn.net/hudashi/article/details/8394158a https://blog.csdn.net/mooneve/article/details/78821843 http://www.yishimei.cn/computer/700.html https://www.52pojie.cn/thread-726176-1-1.html