阶段性PJ某软件APK

更新时间:2021年10月8日

一、PJ基础信息

APK版本号1.0.4/3,基于机顶盒MH301、CM211-2(魔百盒)

基于MAC地址进行认证,每次开机APK都要与服务器进行通讯,如果没有找到授权信息,会在页面左下角显示小对话框,

“警告:尊敬的用户,软件未获得使用权限,请和软件服务商联系。”

此时可以设置认证地址和用户名、密码,设置完进入正常页面后,焦点丢失无法操作。

二、PJ工具

1、集成PJ工具,AndroidCrackTool,MAC专用,版本2.5.1 10-11;

2、apktool,用于对APK的解包和封包,版本2.6.0;

3、签名工具,signapk.jar,以及密钥对platform.x509.pem,platform.pk8;

4、adb,用于apk安装,调试信息、日志信息获取等,brew安装即可。

三、PJ思路

之前的一个同学整理了一些思路,可行和不可行的都列了,也是这次重新PJ的一个起点

1、adb获取当前activity的布局XML,查看resource_id,通过resource_id查询反编译代码定位UI资源,程序设计view分离且经过混淆,定位后需要确认hide、gone逻辑并插桩验证;——验证后找到authview进行隐藏,运行发现实际隐藏的是鉴权进度条页,失败;

2、控制弹框出现:方法同上,弹框为静态资源加动态布局加载实现,根据关键字找到对应dialog的builder,将展示逻辑去除——成功隐藏鉴权弹框

3、调整URL、ID、PWD,方法同上,搜索对应resource_id或关键字符串进行修改、赋值——成功修改默认URL、ID、PWD。

这次的破解思路借鉴了同样的方法,就是通过修改代码来隐藏鉴权弹框,这样即使是没有授权,但不影响用户使用遥控器操作界面,风险就是没有鉴权,除了弹框之外,还可能会有功能的屏蔽会在特定情况下影响使用。

四、PJ步骤

1、利用apktools对APK进行反编译,得到资源目录、dex文件、smali文件等;

java -jar apktools.jar d iptv1.4.apk

2、在资源目录res下查找告警信息

grep 您的软件未获得使用权限 -r *

可以搜索到res/values/strings.xml,即常用的字符串资源文件中,有对应的提示信息

3、利用AndroidCrackTool,将dex文件转换成jar文件,用jdgui打开可以看到所有的java文件

选择File-Save all sources,可以将所有java文件存下来,便于在命令行模式下独立查找

4、在jdGUI搜索tip_message_unauthorized,发现除了在对应列表的头文件R$string.class等类似的信息外,就只有在com.cm.webos.lincensesdk中的f.class有两处访问

###### com.cm.webos.lincensesdk包中的f.class ######
###### 第一处 ######
  void p(int paramInt)
  {
    StringBuilder localStringBuilder = new StringBuilder();
    localStringBuilder.append("sendError : ");
    localStringBuilder.append(paramInt);
    com.cm.webos.utilssdk.e.a(localStringBuilder.toString());
    if ((paramInt == 1001) && (!this.f.d("2001"))) {
      s(this.a.getString(R.string.tip_message_unauthorized_default), "2001", false);
    }
  }
  
###### 第二处 ######
          paramArrayOfByte = (InstantMessaging)locale.k(paramArrayOfByte, InstantMessaging.class);
          int i = paramArrayOfByte.opstate;
          if (1 == i)
          {
            localObject = f.this;
            if (TextUtils.isEmpty(paramArrayOfByte.content)) {
              paramArrayOfByte = f.b(f.this).getString(R.string.tip_message_unauthorized_default);
            } else {
              paramArrayOfByte = paramArrayOfByte.content;
            }
            f.e((f)localObject, paramArrayOfByte, "2001", false);
          }  

5、从第一处结果进行分析,预估如果p函数的入参是1001,就会取值未授权信息,于是在代码目录中查找1001相关信息

grep 1001 -r *
com/google/android/apps/muzei/render/GLTextureView.java:      //   1001: aload 21
com/google/android/apps/muzei/render/GLTextureView.java:      //   998	1001	996	finally
com/google/android/apps/muzei/render/GLTextureView.java:      //   1001	1004	1075	finally
com/google/android/material/R$style.java:  public static final int Theme_MaterialComponents_Light_NoActionBar = 2131821001;
com/cm/webos/jvmgame/MainActivity.java:  public final int JVM_STOP = 1001;
com/cm/webos/jvmgame/MainActivity.java:      case 1001:
com/cm/webos/app/upgrade/sdk/UpgradeIntentService.java:      com.cm.webos.app.upgrade.sdk.c.a.a(paramb, "1001");
com/cm/webos/app/upgrade/sdk/b/a.java:              com.cm.webos.app.upgrade.sdk.c.a.a(localb, "1001");
com/cm/webos/virtualtouch/R$style.java:  public static final int Theme_MaterialComponents_Light_NoActionBar = 2131821001;
com/cm/webos/iptvsdk/WebViewExt.java:  private static final int MSG_SURFACEVIEW_CHANGEPOS = 1001;
com/cm/webos/iptv/R$style.java:  public static final int Theme_MaterialComponents_Light_NoActionBar = 2131821001;
com/cm/webos/iptv/R$string.java:  public static final int error_auth_1001 = 2131755122;
com/cm/webos/iptv/IptvActivity.java:          if (j == 1001) {
com/cm/webos/iptv/c/e.java:        if ((!((String)localObject).equals("1000")) && (!((String)localObject).equals("10000")) && (!((String)localObject).equals("1001")) && (!((String)localObject).equals("0025"))) {
com/cm/webos/iptv/c/a.java:        if (!str.equals("10010")) {}
com/cm/webos/iptv/c/a.java:            paramString = "10010";
com/cm/webos/iptv/c/a.java:      this.c.put("10010", this.a.getResources().getString(2131755189));
com/cm/webos/iptv/c/a.java:      this.c.put("1001", this.a.getResources().getString(2131755122));
com/cm/webos/itv/settings/R$style.java:  public static final int Theme_MaterialComponents_Light_NoActionBar = 2131821001;
com/cm/webos/lincensesdk/e.java:      f.g().p(1001);
com/cm/webos/lincensesdk/e.java:      f.g().p(1001);
com/cm/webos/lincensesdk/e.java:            if (((JSONObject)localObject4).getInt("resultCode") == 1001)
com/cm/webos/lincensesdk/e.java:              f.g().p(1001);
com/cm/webos/lincensesdk/f.java:    if ((paramInt == 1001) && (!this.f.d("2001"))) {
com/cm/webos/lincensesdk/MessageReceiver.java:            ((f)localObject).p(1001);
com/cm/webos/lincensesdk/MessageReceiver.java:          ((f)localObject).p(1001);
pl/droidsonroids/gif/d.java:    d locald4 = new d("INVALID_SCR_DIMS", 15, 1001, "Invalid screen size, dimensions must be positive");

从结果简单分析,主要是e.java中的结果21、22、24,共调用了3次,以及在MessageReceiver.java中的26、27,共调用两次。

于是打开对应的文件进行修改,在第一步反编译的smali目录下(smali/com/cm/webos/lincensesdk)找到对应的文件e.smali、e$b.smali和MessageReceiver.smali,进行修改

(1)e.smali文件

修改1001为1000,即0x3e9改为0x3e8,这样两次调用就变成了p(1000),不会触发弹出框;

(2)e$b.smali文件

在251行,修改变量v6的值1001为1000,即0x3e9改为0x3e8。

在253行,增加一个变量v11,值为0x3e9。

在255行,将判断比较的变量由v6改为v11,即判断条件不变,还是确认是1001,即由 if-ne v3, v6, :cond_1,改为if-ne v3, v11, :cond_1。

(3)MessageReceiver.smali文件

修改1001为1000,即0x3e9改为0x3e8,这样调用就变成了p(1000),不会触发弹出框;

6、使用apktools进行重新打包,并进行签名,在机顶盒上传安装。

## 重新生成APK
java -jar apktools.jar b iptv1.4
## 重新生成的apk在iptv1.4/dist/目录下

## 对APK进行签名
java -jar signapk.jar platform.x509.pem platform.pk8 iptv1.4.apk iptv1.4sign.apk

## 在机顶盒上覆盖安装APK
adb connect 192.168.10.23
adb install -r iptv1.4sign.apk

经过1~6步骤后,机顶盒启动APK后不会弹出窗口提示“未获得使用权限”,但是会出现新的提示“体验时间即将过期,如需继续使用,请和软件服务商联系”。

7、在jdGUI中继续搜索tip_message_unauthorized,发现除了在对应列表的头文件R$string.class等类似的信息外,就只有在com.cm.webos.lincensesdk中的f.class有两处访问

###### com.cm.webos.lincensesdk包中的f.class ######
###### 第一处 ######
          else if (2 == i)
          {
            localObject = f.this;
            if (TextUtils.isEmpty(paramArrayOfByte.content)) {
              paramArrayOfByte = f.b(f.this).getString(R.string.tip_message_expire1_default);
            } else {
              paramArrayOfByte = paramArrayOfByte.content;
            }
            f.e((f)localObject, paramArrayOfByte, "2002", true);
          }

  
###### 第二处 ######
  class c
    implements Runnable
  {
    c() {}
    
    public void run()
    {
      if (!f.f(f.this).d("2001"))
      {
        f localf = f.this;
        f.e(localf, f.b(localf).getString(R.string.tip_message_expire1_default), "2002", false);
      }
    }
  }

简单分析觉得第二处更有问题,在第一步反编译的smali目录下(smali/com/cm/webos/lincensesdk)找到对应的文件f$c.smali,把57~73行删除,即对应到上述代码块的25~26行。

最后重复步骤6,完成所有的修改和打包。

五、PJ后问题及解决思路

1、播放问题,视频播放时出现第一次可以,第二次无法打开的问题,规律性的出现。

用adb查看日志,发现无法打开的时候,MediaControl模块报invalid user,怀疑为播放器也进行了授权有效性的检测。

但发现这个信息很可能出在libCTC_MediaControl.so中,而找了半天的IDA pro在MAC上无法安装,所以暂时就先放弃,通过前端页面多次调用播放器看能否绕过此问题。

2、设置页面的用户名、密码默认值

第8、9步中,认证地址已经修改,本来还想修改用户名和密码,但在编译后的samli文件中把所有的空值聚合成了一个,想通过增加一个变量(值为“1”),结果代码应该没有语法问题,但是打包上传后无法打开,所以暂时放弃。

后续可尝试思路——直接修改.java源文件,然后编译成.smali文件。

六、PJ过程命令参考-MAC版

1、adb查找当前的UI布局

adb shell uiautomator dump /sdcard/ui.xml

adb pull /sdcard/ui.xml 

2、adb查找当前的Activity

adb shell "dumpsys window w | grep name="

查看当前栈顶的Activity

adb shell "dumpsys activity | grep mFocusedActivity"

3、adb查看应用日志

adb logcat

查看具体应用进程,可先用ps | grep com.cm.webos.iptv找到进程号

adb logcat | grep <pid>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值