Android锁机软件分析
作者:云在天(Harry)吾爱破解
所用工具
安卓模拟器
Eclipse
JEB2
Android Killer
行为分析
这个木马是以一个软件【刺激战场辅助盒子】为载体,释放的锁机病毒。我们直接在模拟器里运行这个载体,让他释放这个病毒,释放路径为:system/app/hl.apk然后提取出来,分析。
附运行截图:
看到这个图,应该就能判断这个密码肯定是个固定的密码,至于是什么,我们反编译后看
反编译
- 拖入Android Killer 查看入口点
- 然后把dex从APK里拖出来,然后拖到JEB2里面去,找AK提示的入口点。
-
@Override public void onCreate(Bundle arg16) {
Class v10;
MainActivity v0 = this;
ADRTLogCatReader.onContext(v0, "com.aide.ui");
super.onCreate(arg16);
Intent v7 = null;
Intent v8 = null;
MainActivity v9 = v0;
try {
v10 = Class.forName("com.k7.qq2856437148.K7");
}
catch(ClassNotFoundException v7_1) {
throw new NoClassDefFoundError(v7_1.getMessage());
}
super(((Context)v9), v10);
v0.startService(v7);
Intent v5 = new Intent();
v5.setAction("android.intent.action.MAIN");
v5.addCategory("android.intent.category.HOME");
v0.startActivity(v5);
}
我们可以看到,它先初始化了com.k7.qq2856437148.K7类,然后调用了这个类,那我们就跟下这个类我们看下它监听的这个事件
@Override public void onClick(View arg15) {
Class v9;
100000000 v0 = this;
100000000 v6 = v0;
try {
if(v6.this$0.et.getText().toString().isEmpty()) {
return;
}
if(!v0.this$0.et.getText().toString().equals(new StringBuffer().append("").append(v0.this$0.k7).toString())) {
return;
}
Intent v6_2 = null;
Intent v7 = null;
K7 v8 = v0.this$0;
try {
v9 = Class.forName("com.k7.qq2856437148.K71");
}
catch(ClassNotFoundException v6_3) {
goto label_70;
}
super(((Context)v8), v9);
v6_2.setFlags(268435456);
v0.this$0.startService(v6_2);
v0.this$0.mWindowManager.removeView(v0.this$0.mFloatLayout);
v0.this$0.stopSelf();
return;
label_70:
throw new NoClassDefFoundError(v6_3.getMessage());
}
catch(Exception v6_1) {
}
}
从代码我们可以看到,如果输入的文本等于k7就加载下一个类,那我们看前面的截图,k7是如何定义的:在book这个类里通过一个K7的函数返回的。所以我们直接在eclipse里写下这个代码,调试一下就是曾唔名潇洒,现唔民K7,那这就是第一层的密码,我们试一试,果然不错,然后我们进入了下一层
- 第二层截图:有了随机数,那我们猜测解锁和这个随机数有关,我们继续跟那个类,和前一个类一样,定义了几个变量,因为这复制会乱码,还是上图我们看代码知道,这个随机数是经过k78这个函数处理过再显示出来的,我们再去看一看这个k78,发现并没有逆算法,但我们通过上面的代码可以看到随机数是9位的,那我们只能穷举这个随机数了,这里说一个小技巧,9位可以分割成4位和5位,这样运算速度会提升很多。还是在eclipse里写,代码我会附在后面。然后我们知道序列号后,就可以计算出k7,k8的值,然后我们再看监听的这个事件我们能看到,它对比了输入值和经过md5计算后的k7的值对比,如果相同就加载下一个类,我们就不具体看这个md5算法了,很普通的算法。还是写在eclipse里,计算一下出结果【766f8dd9f6f462bcb2a661ea25d36516】。然后我们进入下一层,也就是最后一层。
- 第三层截图: 然后我们继续追那个加载的类,还是和之前一样,定义了几个变量 生成序列号的方法还是和之前一样,所以我们还是继续套用之前的计算方法。然后我们看这次对比的是什么这次对比的是输入值和以k6为参数生成sha1后又生成md5的值,然后才执行remove命令,所以我们还是在eclipse里写出来,经过计算,得到【5736fabb1dcced03dcc77c41d87a134f】,然后确定就移除,停止服务了,到这里就成功解锁了
后续
用文件管理器进入system/app/里把hl.apk删掉就可以彻底解锁了。
解锁源码
package com.lzc;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
import java.io.UnsupportedEncodingException;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
public class lzc4 {
static String hexString = "0123456789";
private static String[] strDigits=new String[]{"9", "8", "7", "6", "5", "4", "3", "2", "1", "0", "a", "b", "c", "d", "e", "f"};
public static void main(String[] args) {
//{"ā", "①", "÷", "∷", "●", "©", "®", "★", "※", "/"};
System.out.println("Crack By 云在天 (Harry) www.52pojie.cn");
System.out.println("第一层密码:曾唔名潇洒,现唔民K7");
System.out.println("请输入第2层手机屏幕上的随机序号:");
Scanner scan = new Scanner(System.in);
String lock2 = null;
try {
lock2 = scan.next();
}
catch (Exception e) {
e.printStackTrace();
}
int lock2xlh = 0;
String lock2_1=null;
String lock2_2=null;
int i=0;
for (i=0;i<100000;++i)
{
if(lock2.substring(0, 5).equals(k78(new StringBuffer().append("").append(i).toString())))
{
lock2_1=""+i;
break;
}
}
for(i=0;i<10000;++i)
{
if(lock2.substring(5, lock2.length()).equals(k78(new StringBuffer().append("").append(i).toString())))
{
lock2_2=""+i;
break;
}
}
lock2xlh=Integer.valueOf(lock2_1+lock2_2).intValue();
long k8 = ((long)(lock2xlh * 10));
long K7 = k8 % (((long)10000));
System.out.println("第二层密码:"+GetMD5Code(new StringBuffer().append("").append(K7).toString()));
System.out.println("请输入第三层手机屏幕上的随机序号:");
try {
lock2 = scan.next();
}
catch (Exception e) {
e.printStackTrace();
scan.close();
System.exit(0);
}
scan.close();
for(i=0;i<100000;++i)
{
if(lock2.substring(0, 5).equals(k78(new StringBuffer().append("").append(i).toString())))
{
lock2_1=""+i;
break;
}
}
for( i=0;i<10000;++i)
{
if(lock2.substring(5, lock2.length()).equals(k78(new StringBuffer().append("").append(i).toString())))
{
lock2_2=""+i;
break;
}
}
lock2xlh=Integer.valueOf(lock2_1+lock2_2).intValue();
K7 = ((long)(lock2xlh % 10000));
k8 = K7 * (((long)9999));
long k9 = k8 + (((long)2001));
long k6 = k9 % (((long)1000));
System.out.println("第三层密码:"+GetMD5Code(getSha1(new StringBuffer().append("").append(k6).toString())));
System.out.println("解锁成功,如果不成功,请到论坛下回帖!");
}
public static String K7(String arg22) {
String v5 = Base64.encode("李时珍 陈独秀".getBytes()).replaceAll("\\D+", "");
Integer v7 = new Integer(new StringBuffer(v5).reverse().toString());
char[] v8 = arg22.toCharArray();
int v9=0;
for(v9 = 0; v9 < v8.length; ++v9) {
v8[v9] = ((char)(v8[v9] ^ v7.intValue()));
}
String v12 = new StringBuffer(new String(Base64.decode(new String(v8)))).reverse().toString();
Integer v13 = new Integer(v5);
char[] v14 = v12.toCharArray();
int v15=0;
for(v15 = 0; v15 < v14.length; ++v15) {
v14[v15] = ((char)(v14[v15] ^ v13.intValue()));
}
return new String(v14);
}
public static String k78(String arg14) {
byte[] v2 = arg14.getBytes();
StringBuilder v3 = new StringBuilder(v2.length * 2);
int v4=0;
for(v4 = 0; v4 < v2.length; ++v4) {
v3.append(hexString.charAt((v2[v4] & 15) >> 0));
}
String v4_1 = "";
String[] v5 = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
String[] v6 = new String[]{"K", "七", "贼", "妈", "帅", "他", "码", "了", "个", "逼"};
int v7;
for(v7 = 0; v7 < 10; ++v7) {
if(v7 == 0) {
v4_1 = v3.toString().replace(v5[v7], v6[v7]);
}
v4_1 = v4_1.replace(v5[v7], v6[v7]);
}
return v4_1;
}
public static String GetMD5Code(String arg9) {
String v2 = null;
String v0 = arg9;
try {
new String(v0);
v2 = byteToString(MessageDigest.getInstance("MD5").digest(v0.getBytes()));
}
catch(NoSuchAlgorithmException v5) {
v5.printStackTrace();
}
return v2;
}
private static String byteToArrayString(byte arg10) {
int v2 = arg10;
if(v2 < 0) {
v2 += 256;
}
return new StringBuffer().append(strDigits[v2 / 16]).append(strDigits[v2 % 16]).toString();
}
private static String byteToString(byte[] arg9) {
byte[] v0 = arg9;
StringBuffer v2 = new StringBuffer();
int v3=0;
for(v3 = 0; v3 < v0.length; ++v3) {
v2.append(byteToArrayString(v0[v3]));
}
return v2.toString();
}
public static String getSha1(String arg17) {
String v0 = arg17;
if(v0 != null && v0.length() != 0) {
char[] v2 = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
MessageDigest v3 = null;
try {
v3 = MessageDigest.getInstance("SHA1");
} catch (NoSuchAlgorithmException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
try {
v3.update(v0.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
byte[] v4 = v3.digest();
int v5 = v4.length;
char[] v6 = new char[v5 * 2];
int v7 = 0;
int v8=0;
for(v8 = 0; v8 < v5; ++v8) {
int v9 = v4[v8];
int v12 = v7;
++v7;
v6[v12] = v2[v9 >>> 4 & 15];
v12 = v7;
++v7;
v6[v12] = v2[v9 & 15];
}
v0 = new String(v6);
}
else {
v0 = null;
}
return v0;
}
}
使用方法:直接运行bat文件
附件:
解锁工具.zip
(73.81 KB, 下载次数: 449)
样本:
hl.zip
(44.03 KB, 下载次数: 695)