首页
论坛
专栏
课程
1

[原创]android破解实战:游戏蜂窝3.19版本破解记录

猪会被杀掉 2018-9-12 10:54 1394

游戏蜂窝破解记录

APK重打包测试

下载ApkTool

ApkTool下载地址

ApkTool安装说明

1.   运行apktool d target.apk反编译资源

2.   运行apktool b youxifengwo -o ReYXFW.apk 重打包APK

3.  uiautomatorviewersdktool目录下

生成签名密钥:

唤出CMD: 开始—运行—输入CMD后点确定或按ENTER回车键,唤出CMD后输入下面命令后按回车键:

cd /d C:\Program Files\Java\jdk1.7.0\bin

输入后按回车再输入下面命令后按回车

keytool -genkey -alias abc.keystore

-keyalg RSA -validity 20000 -keystore abc.keystore

abc可改为abc等,命令区分大小写。

执行命令后会出现下面步骤:

输入keystore密码:[密码不显示,输入密码按回车即可开

再次输入新密码:[密码 不显示,输入密码按回车即可开

您的名字与姓氏是什么?

[Unknown]  tttabc

您的组织单位名称是什么?

[Unknown]  www.tttabc.com

您的组织名称是什么?

[Unknown]  www.tttabc.com

您的组织名称是什么?

[Unknown]  www.tttabc.com

您所在的城市或区域名称是什么?

[Unknown]  New York

您所在的州或省份名称是什么?

[Unknown]  New York

该单位的两字母国家代码是什么

[Unknown]  CN

CN=abc, OU=www.tttabc.com, O=www.tttabc.com, L=New York, ST

=New York, C=CN 正确吗?

[]  Y

输入<abc.keystore>的主密码

(如果和 keystore 密码相同,按回车):

成功后将会在C:\Program Files\Java\jdk1.7.0\bin 下产生一个名为abc.keystore的文件

其中参数-validity为证书有效天数,这里我们写的大些20000天。还有在输入密码时没有回显,只管输入就可以了,一般位数建议使用20位,最后需要记下来后面还要用,整个过程如图:

接下来我们开始为apk文件签名了。

签名apk文件:

将要签名的APK放到C:\Program Files\Java\jdk1.7.0\bin

apk最好命名为简单的名字 如123.apk

唤出CMD: 开始—运行—输入CMD后点确定或按ENTER回车键,唤出CMD后输入下面命令后按回车键:

cd C:\Program Files\Java\jdk1.7.0\bin

输入后按回车

再输入下面命令后按回车

jarsigner -verbose -keystore abc.keystore -signedjar 123x.apk new_target.apk abc.keystore

然后输入密码按回车

就可以生 成签名的apk文件,这里输入文件abc.apk,最终生成123x.apkandroid签名后的APK执行文件。下面提示输入的密码和keytool输入的一样就行了 。

如果是修改APKZIP格式刷机ROM需要签名推荐用auto-sign签名,简单方便:

下载 auto-sign.zip ,运行需安装JAVA jdkauto-sign解压到如E盘下,将需要签名的APKZIP放到 auto-sign签名工具同目录下,运行auto-sign签名批处理工具即可自动签名。

安装APK测试:

Adb install 123x.apk

安卓设备上运行重打包过的apk正常登录提示签名错误,说明APK文件有检查apk的签名,第一步绕过重打包签名验证.

开始逆向和反编译破解加密解密的数据

抓取登录数据包:

下载数据包抓取工具charles,工具的使用请自行搜索;通过数据包发现登录请求的数据回答是显示签名错误,现在开始对比正常的数据包,一个正常登录的数据包里面的数据是被加密过了的;现在开始尝试解密数据包,先反编译APK,如果没被加密,反编译的方法请自行搜索;现在开始寻找APK里面的登录验证解密函数.

调试和反编译APK查看加密解密函数:

先上传IDAPRO的调试支持,使用SU权限运行.

adb push android_server /data/local/tmp/

adb shell chmod 777 /data/local/tmp/android_server

su /data/local/tmp/android_server

adb forward tcp:23946 tcp:23946

运行adb logcat ActivityManager:I *:s查看Android应用包/Activity.

再运行命令等待IDAPRO附加调试.

adb shell am start -D -n com.cyjh.gundam/.fengwo.ui.activity.WelcomeActivity

IDAPRO附加进程命令:

Debugger - > Attach -> Remote ArmLinux/Android debugger

 

这种方法尝试之后好像不能调试到Dalvik虚拟机.

现在开始dex文件的反编译-dex2jarjd-gui.

1.   d2j-dex2jar.bat classes2.dex 生成classes2-dex2jar.jar

2.   下载jd-gui打开classes2-dex2jar.jar

写个SO HOOK掉解密函数:

下载xposed编译一个Hook插件拦截解密函数,分析整理解密函数与原始数据包并对应到URL(范例).

去掉APK自校验重新打包(lib/xxx/ libcjencrypt.so):

.text:F3E69478 decrypt; DATA XREF: .data:F3E7D030o

.text:F3E69478 ; __unwind {

.text:F3E69478 PUSH            {R4-R7,LR}

.text:F3E6947A ADD             R7, SP, #0xC

.text:F3E6947C PUSH.W          {R8,R9,R11}

.text:F3E69480 MOV             R9, R1

.text:F3E69482 MOV             R1, R3

.text:F3E69484 MOV             R8, R2

.text:F3E69486 MOV             R6, R0

.text:F3E69488 BL              sub_F3E694C4

.text:F3E6948C MOV             R4, R0

.text:F3E6948E LDR             R0, =(off_F3E7D004 - 0xF3E69494)

.text:F3E69490 ADD             R0, PC; off_F3E7D004

.text:F3E69492 LDR             R1, [R0]; "8CF8BD517174351E61BBCF776B3B83376195D65"

.text:F3E69494 MOV             R0, R4; s1

.text:F3E69496 BLX             strcmp; apk checksum

.text:F3E6949A MOV             R5, R0

.text:F3E6949C MOV             R0, R4; ptr

.text:F3E6949E BLX             free

.text:F3E694A2 CBZ             R5, loc_F3E694AC

.text:F3E694A4 MOVS            R0, #0

.text:F3E694A6 POP.W           {R8,R9,R11}

.text:F3E694AA POP             {R4-R7,PC}

.text:F3E694AC ; ---------------------------------------------------------------------------

.text:F3E694AC

.text:F3E694AC loc_F3E694AC; CODE XREF: decrypt+2Aj

.text:F3E694AC MOV             R0, R6

.text:F3E694AE MOV             R1, R9

.text:F3E694B0 MOV             R2, R8

.text:F3E694B2 POP.W           {R8,R9,R11}

.text:F3E694B6 POP.W           {R4-R7,LR}

.text:F3E694BA B.W             sub_F3E68C88

.text:F3E694BA ; End of function decrypt

VIP权限:

.method public setIsVip(I)V

    .locals 4

    .param p1, "isVip"    # I

 

    .prologue

    .line 274

      

    iput p1, p0, Lcom/cyjh/gundam/model/UserInfo;->IsVip:I

      

       const v0, 0x1

       iput v0, p0, Lcom/cyjh/gundam/model/UserInfo;->IsVip:I

      

    .line 275

    return-void

.end method

CODE:00704F1C # Source file: UserInfo.java

CODE:00704F1C public int com.cyjh.gundam.model.UserInfo.getIsVip()

CODE:00704F1C this = v1                               # CODE XREF: VipPresenter_setUserInfo@VL+Ap

CODE:00704F1C                                         # LeftMenuFragment_setInfo@VL:loc_6BE372p ...

CODE:00704F1C                 .prologue_end

CODE:00704F1C                 .line 270

CODE:00704F1C                 iget                            v0, this, stru_B09E4

CODE:00704F20                 const/4                         v0, 1

CODE:00704F22

CODE:00704F22 locret:

CODE:00704F22                 return                          v0

CODE:00705046 Method End

VIP过期时间:

.method public setVIPExpireTime(Ljava/lang/String;)V

    .locals 4

    .param p1, "VIPExpireTime"    # Ljava/lang/String;

 

    .prologue

    .line 282

      

    iput-object p1, p0, Lcom/cyjh/gundam/model/UserInfo;->VIPExpireTime:Ljava/lang/String;

      

      

       const-string/jumbo v0, "2022-12-31"

       iput v0, p0, Lcom/cyjh/gundam/model/UserInfo;->VIPExpireTime:Ljava/lang/String;

 

    .line 283

    return-void

.end method

CODE:0070503C # Source file: UserInfo.java

CODE:0070503C public java.lang.String com.cyjh.gundam.model.UserInfo.getVIPExpireTime()

CODE:0070503C this = v1                               # CODE XREF: LeftMenuFragment_setInfo@VL+DEp

CODE:0070503C                                         # LeftMenuFragment_setInfo@VL+F2p ...

CODE:0070503C                 .prologue_end

CODE:0070503C                 .line 278

CODE:0070503C                 iget-object                     v0, this, stru_B0A4C

CODE:00705040                 const-string/jumbo              v0, a20221231 # "2022-12-31"

CODE:00705046

CODE:00705046 locret:

CODE:00705046                 return-object                   v0

CODE:00705046 Method End

VIP类型:

.method public setVIPType(I)V

    .locals 4

    .param p1, "VIPType"    # I

 

    .prologue

    .line 110

 

    iput p1, p0, Lcom/cyjh/gundam/model/UserInfo;->VIPType:I

      

       const v0, 0x2

       iput v0, p0, Lcom/cyjh/gundam/model/UserInfo;->VIPType:I

      

    .line 111

    return-void

.end method

CODE:00705058 # Source file: UserInfo.java

CODE:00705058 public int com.cyjh.gundam.model.UserInfo.getVIPType()

CODE:00705058 this = v1                               # CODE XREF: LeftMenuFragment_setInfo@VL+162p

CODE:00705058                                         # LoginManager_updateUserInfo@VLL+3Cp

CODE:00705058                 .prologue_end

CODE:00705058                 .line 106

CODE:00705058                 iget                            v0, this, stru_B0A54

CODE:0070505C                 const/4                         v0, 2

CODE:0070505E

CODE:0070505E locret:

CODE:0070505E                 return                          v0

CODE:0070505E Method End

去除时间限制:

com.cyjh.gundam.manager. LoginManager.java

.method public getDisCountSecond()J

    .locals 2

 

    .prologue

    .line 965

    invoke-virtual {p0}, Lcom/cyjh/gundam/manager/LoginManager;->isLoginV70()Z

 

    move-result v0

 

    if-eqz v0, :cond_0

 

    .line 966

    iget-object v0, p0, Lcom/cyjh/gundam/manager/LoginManager;->mInfo:Lcom/cyjh/gundam/model/LoginResultInfo;

 

    iget-wide v0, v0, Lcom/cyjh/gundam/model/LoginResultInfo;->DisCountSecond:J

 

    .line 968

    :goto_0

       const-wide/32 v0, 0x10000

    return-wide v0

 

    :cond_0

    const-wide/16 v0, 0x0

       const-wide/32 v0, 0x10000

 

    goto :goto_0

.end method

 

.method public getFreeSecond()J

    .locals 2

 

    .prologue

    .line 975

    invoke-virtual {p0}, Lcom/cyjh/gundam/manager/LoginManager;->isLoginV70()Z

 

    move-result v0

 

    if-eqz v0, :cond_0

 

    .line 976

    iget-object v0, p0, Lcom/cyjh/gundam/manager/LoginManager;->mInfo:Lcom/cyjh/gundam/model/LoginResultInfo;

 

    iget-wide v0, v0, Lcom/cyjh/gundam/model/LoginResultInfo;->FreeSecond:J

 

    .line 978

    :goto_0

       const-wide/32 v0, 0x10000

    return-wide v0

 

    :cond_0

    const-wide/16 v0, 0x0

       const-wide/32 v0, 0x10000

 

    goto :goto_0

.end method

免登录打开脚本支持的游戏:

a)  源码文件夹(com.cyjh.gundam.fengwo,“com\cyjh\gundam\fengwo”)

b)  搜索isLoginV70 函数调用,smali里面修改返回值免登录.

“我的脚本”免登录:

a)  源码com.cyjh.gundam.utils.IntentUtil.java

b)  定位函数toMyScriptActivity里面的isLoginV70,修改返回值

强制免费使用脚本.

a)  源码文件夹(com\cyjh\gundam\fengwoscript\)

b)  搜索isLogin函数调用, 修改返回值.

c)  源码文件夹(com.cyjh.gundam.fengwoscript.model.manager. HeartAndPermManager.java)

d)  搜索函数checkRunPerm,修改里面的判断语句viprunperminfo.KickedOutviprunperminfo.BanRunviprunperminfo.TryExpired实现强制选择目标脚本,进入

本地挂机按钮界面,按钮默认状态被禁止.

e)  源码文件夹(com.cyjh.gundam.fengwoscript.ui.help. SzScriptInfoSetHelp.java)

f)  搜索函数setInfo,修改vipadresultinfo.RunPerm.Runvipadresultinfo.RunPerm.Try实现恢复本地挂机按钮,但是无法弹出外挂对话框.

g)  源码文件夹(com.cyjh.gundam.fengwoscript.model.manager. HeartAndPermManager.java)

h)  找到函数isRun,修改viprunperminfo.KickedOutviprunperminfo.BanRunviprunperminfo.TryExpired,实现弹出外挂设置对话框.

i)  源码文件夹(com.cyjh.gundam.fengwo.pxkj.script.ui.presenter. ScriptRunPresenter.java)

j)  搜索vipadresultinfo.RunPerm.KickedOut,修改掉判断语句.

k)  源码文件夹(com.cyjh.gundam.fengwoscript.presenter. ScriptInfoPresenter.java)

l)  找到函数startScriptOnClick,修改vipadresultinfo.RunPerm.Runvipadresultinfo.RunPerm.Try触发本地挂机按钮事件强制运行脚本,脚本运行后马上停止.

m)  源码文件夹(com.cyjh.gundam.fengwoscript.model.manager. HeartAndPermManager.java)

n)  搜索onEventMainThread检测线程函数,修改vipscriptheartinfo.Status状态值为3,即可实现强制使用脚本.

o)  找到源码文件夹(com.cyjh.gundam.activity. GunDamMainActivity.java)

p)  定位到函数setBottomDataByPreData,(首页、"TargetType": 6,(云手机、TargetType": 8),(我的、"TargetType": 7,),(免Root脚本、"TargetType": 11,(变态游戏、  "TargetType": 9)。分别对应到APK的底下菜单栏处理。

q)  找到源码文件夹(com.cyjh.gundam.fengwoscript.ui.help. SzScriptInfoSetHelp.java)

r)  找到函数setInfo,修改vipadresultinfo.EachTryTime语句关闭剩余试用的提示.

s)  找到源码文件夹(com.cyjh.gundam.fengwoscript.ui.help. ScriptTopRaqViewHelp.java)

t)  找到函数setData,改为mFaqTv.setVisibility(0)关闭脚本使用常见问题.

u)  找到源码文件夹(com.cyjh.gundam.fengwoscript.presenter. ScriptInfoPresenter.java)

v)  找到函数isShowAd,改为返回false关闭非会员运行脚本展示广告.

 

心跳包线程:

com.cyjh.gundam.fengwoscript.presenter. ScriptInfoPresenter.java

{

      boolean flag = true;

      String s = com/cyjh/gundam/fengwoscript/presenter/ScriptInfoPresenter.getSimpleName();

      StringBuilder stringbuilder = (new StringBuilder()).append("PermStatueEvent -- \u5FC3\u8DF3\u662F\u5426\u8C03\u7528\uFF1A");

      if(permstatueevent.resultInfo != null)

            flag = false;

      CLog.i(s, stringbuilder.append(flag).toString());

      try

      {

            SZScriptInfo szscriptinfo = permstatueevent.resultInfo.ScriptInfo;

            if(szscriptinfo != null)

            {

                  mInfo.EncryptKey = szscriptinfo.EncryptKey;

                  mInfo.IsEncrypt = szscriptinfo.IsEncrypt;

                  mInfo.NewEncryptKey = szscriptinfo.NewEncryptKey;

                  mInfo.ScriptPath = szscriptinfo.ScriptPath;

                  loadScript(true);

            } else

            {

                  loadScript(false);

            }

      }

      catch(Exception exception) { }

}

心跳包检测跳过:

com.cyjh.gundam.fengwoscript.model. ScriptHeartModel.java

以下4个函数直接返回.

.method private load()V

    .locals 1

 

    .prologue

    .line 137

      

       return-void

      

    iget-object v0, p0, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->mListener:Lcom/kaopu/core/basecontent/http/inf/IUIDataListener;

 

    invoke-virtual {p0, v0}, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->loadData(Lcom/kaopu/core/basecontent/http/inf/IUIDataListener;)V

 

    .line 138

    return-void

.end method

 

.method private pauseHear()V

    .locals 0

 

    .prologue

    .line 116

      

       return-void

      

    invoke-direct {p0}, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->removeHeart()V

 

    .line 117

    return-void

.end method

 

.method private resumeHear()V

    .locals 2

 

    .prologue

    .line 122

      

       return-void

      

    const/4 v0, 0x2

 

    iput v0, p0, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->mStartOrStop:I

 

    .line 123

    iget-object v0, p0, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->mPathModel:Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartPathModel;

 

    const/4 v1, 0x0

 

    invoke-virtual {v0, v1}, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartPathModel;->setCount(I)V

 

    .line 128

    iget v0, p0, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->mHeartbeatInterval:I

 

    if-gtz v0, :cond_0

 

    .line 129

    const/16 v0, 0x12c

 

    iput v0, p0, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->mHeartbeatInterval:I

 

    .line 131

    :cond_0

    iget v0, p0, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->mHeartbeatInterval:I

 

    mul-int/lit16 v0, v0, 0x3e8

 

    invoke-direct {p0, v0}, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->sendHeartHandler(I)V

 

    .line 132

    return-void

.end method

 

.method public startHear(I)V

    .locals 3

    .param p1, "time"    # I

 

    .prologue

      

       return-void

      

    const/4 v2, 0x1

 

    .line 108

    iput p1, p0, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->mHeartbeatInterval:I

 

    .line 109

    iput v2, p0, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->mStartOrStop:I

 

    .line 110

    iget-object v0, p0, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->mPathModel:Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartPathModel;

 

    const/4 v1, 0x0

 

    invoke-virtual {v0, v1}, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartPathModel;->setCount(I)V

 

    .line 111

    invoke-direct {p0, v2}, Lcom/cyjh/gundam/fengwoscript/model/ScriptHeartModel;->sendHeartHandler(I)V

 

    .line 112

    return-void

.end method

 

免登录运行脚本分析:

PXJY脚本心跳请求.

目录: com.cyjh.gundam.fengwo.pxkj.script.ui.presenter

源码:

ScriptInfoViewPresenter.java ScriptHeartAndPermManager.java

ScriptManager.java

ScriptRunPermModel.java

 

ScriptInfoViewPresenter.java

加载脚本心跳请求函数

public void load()

{

  iView.showLoading();

  ScriptHeartAndPermManager.getInstance().loadScriptPerm();

}

开始函数

public void start()

{

  Log.i(com/cyjh/gundam/fengwo/pxkj/script/ui/presenter/ScriptInfoViewPresenter.getSimpleName(), "start()");

  mInfo = CurrOpenAppManager.getInstance().getScriptInfo();

  mScriptFileCompleteReceiver.registerReceiver(BaseApplication.getInstance(), new IntentFilter("pxkj_action_script_file_complete"));

  IntentFilter intentfilter = new IntentFilter();

  intentfilter.addAction("0x1_scriptinfo");

  LocalBroadcastManager.getInstance(iView.getCurrentContext()).registerReceiver(mScriptInfoReceiver, intentfilter);

  load();

}

ScriptHeartAndPermManager.java

发送GetRunPerm心跳请求.

public void loadScriptPerm()

{

  mRunPermModel = new ScriptRunPermModel(CurrOpenAppManager.getInstance().getScriptInfo());

  mRunPermModel.load();

}

收到心跳回答包,并且发送toLocalBradcastForScriptInfo通知脚本信息,

public void uiDataSuccess(Object obj)

{

  isRunPermLoading = false;

  BaseResultWrapper baseresultwrapper = (BaseResultWrapper)obj;

  if(baseresultwrapper != null && baseresultwrapper.code.intValue() == 1)

  {

      VipAdResultInfo vipadresultinfo = (VipAdResultInfo)baseresultwrapper.data;

      if(vipadresultinfo != null && vipadresultinfo.ScriptInfo != null)

        IntentUtil.toLocalBradcastForScriptInfo(1, vipadresultinfo.ScriptInfo);

      else

        IntentUtil.toLocalBroadcastForScriptperm(vipadresultinfo);

  }

}

ScriptInfoViewPresenter.java

接受toLocalBradcastForScriptInfo通知信息,并下载脚本.

public void onReceive(Context context, Intent intent)

{

  Log.i(com/cyjh/gundam/fengwo/pxkj/script/ui/presenter/ScriptInfoViewPresenter.getSimpleName(), "onrecive:");

  SZScriptInfo szscriptinfo = (SZScriptInfo)intent.getParcelableExtra("0x1_key_scriptinfo_bundle");

  if(szscriptinfo != null)

  {

      mInfo.EncryptKey = szscriptinfo.EncryptKey;

      mInfo.EncryptKey = szscriptinfo.NewEncryptKey;

      mInfo.ScriptPath = szscriptinfo.ScriptPath;

      mInfo.IsEncrypt = szscriptinfo.IsEncrypt;

      loadScript();

  }

}

FengWoScript心跳检查:

com.cyjh.gundam.fengwoscript.presenter. ScriptInfoPresenter.java

public void onEventMainThread(com.cyjh.gundam.fengwoscript.event.Event.PermStatueEvent permstatueevent)

{

  boolean flag = true;

  String s = com/cyjh/gundam/fengwoscript/presenter/ScriptInfoPresenter.getSimpleName();

  StringBuilder stringbuilder = (new StringBuilder()).append("PermStatueEvent -- \u5FC3\u8DF3\u662F\u5426\u8C03\u7528\uFF1A");

  if(permstatueevent.resultInfo != null)

  flag = false;

  CLog.i(s, stringbuilder.append(flag).toString());

  try

  {

        SZScriptInfo szscriptinfo = permstatueevent.resultInfo.ScriptInfo;

        if(szscriptinfo != null)

        {

          mInfo.EncryptKey = szscriptinfo.EncryptKey;

          mInfo.IsEncrypt = szscriptinfo.IsEncrypt;

          mInfo.NewEncryptKey = szscriptinfo.NewEncryptKey;

          mInfo.ScriptPath = szscriptinfo.ScriptPath;

          loadScript(true);

        } else

        {

          loadScript(false);

        }

  }

  catch(Exception exception) { }

}

协议回答的UUID检查绕过:

1.  源码文件夹: com.cyjh.gundam.utils. UUIDManager.java

2.  修改UUIDManager.getInstance().isExist的返回值为true

3.  修改UUIDManager.getInstance().generateUUID生成一个固定UUID

4.  “1c59f8d2-a569-4968-ba4c-89488b3f1f34”

跳过对GetRunPerm协议的处理:

1.  源码文件夹: com/cyjh/gundam/utils/DesUtils.java

2.  找到解密函数decode_new,修改其让其跳过对GetRunPerm协议的回答进行解密,我们的服务器返回明文字符串,让其正常解析。下面是添加后的代码。

.method public decode_new2(Ljava/lang/String;Landroid/content/Context;)Ljava/lang/String;

    .locals 4

    .param p1, "paramString"    # Ljava/lang/String;

    .param p2, "paramContext"    # Landroid/content/Context;

 

    .prologue

    .line 41

    const-string/jumbo v2, "myhook"

 

    const-string/jumbo v3, "decode_new"

 

    invoke-static {v2, v3}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I

 

    .line 42

    const-string/jumbo v0, "1c59f8d2-a569-4968-ba4c-89488b3f1f34"

 

    .line 43

    .local v0, "code":Ljava/lang/String;

    const/4 v2, 0x0

 

    const/16 v3, 0x24

 

    invoke-virtual {p1, v2, v3}, Ljava/lang/String;->substring(II)Ljava/lang/String;

 

    move-result-object v1

 

    .line 45

    .local v1, "str2":Ljava/lang/String;

    invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

 

    move-result v2

 

    if-eqz v2, :cond_0

 

    .line 49

    .end local p1    # "paramString":Ljava/lang/String;

    :goto_0

    return-object p1

 

    .restart local p1    # "paramString":Ljava/lang/String;

    :cond_0

    const-string/jumbo p1, ""

 

    goto :goto_0

.end method

.method public decode_new(Ljava/lang/String;Landroid/content/Context;)Ljava/lang/String;

    .locals 4

    .param p1, "data"    # Ljava/lang/String;

    .param p2, "context"    # Landroid/content/Context;

    .annotation system Ldalvik/annotation/Throws;

        value = {

            Ljava/lang/Exception;

        }

    .end annotation

 

    .prologue

    .line 130

    invoke-static {p1}, Landroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z

 

    move-result v2

 

    if-eqz v2, :cond_0

 

    .line 131

    const-string/jumbo v2, ""

 

    .line 152

    :goto_0

    return-object v2

 

:cond_0

    invoke-virtual {p0, p1, p2}, Lcom/mfwfz/game/utils/DesUtils;->decode_new2(Ljava/lang/String;Landroid/content/Context;)Ljava/lang/String;

 

    move-result-object v0

 

    .local v0, "str":Ljava/lang/String;

    if-eqz v0, :cond_3

 

    .line 58

    .end local v0    # "str":Ljava/lang/String;

    return-object v0

 

    .restart local v0    # "str":Ljava/lang/String;

 

    .line 134

:cond_3

    if-nez p2, :cond_2

 

    .line 135

    invoke-static {}, Lcom/mfwfz/game/application/BaseApplication;->getInstance()Lcom/mfwfz/game/application/BaseApplication;

 

    move-result-object v2

 

    if-nez v2, :cond_1

 

    .line 136

    const-string/jumbo v2, "decode"

 

    const-string/jumbo v3, "\u62a5\u9519decode: context=null"

 

    invoke-static {v2, v3}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I

 

    .line 137

    const-string/jumbo v2, ""

 

    goto :goto_0

 

    .line 139

    :cond_1

    invoke-static {}, Lcom/mfwfz/game/application/BaseApplication;->getInstance()Lcom/mfwfz/game/application/BaseApplication;

 

    move-result-object p2

 

    .line 143

    :cond_2

    :try_start_0

    new-instance v0, Lcom/cyjh/cjencrypt/CJEncrypt;

 

    invoke-direct {v0}, Lcom/cyjh/cjencrypt/CJEncrypt;-><init>()V

 

    .line 144

    .local v0, "cjEncrypt":Lcom/cyjh/cjencrypt/CJEncrypt;

    invoke-virtual {v0, p1}, Lcom/cyjh/cjencrypt/CJEncrypt;->setSource(Ljava/lang/String;)V

 

    .line 145

    const/4 v2, 0x2

 

    invoke-virtual {v0, v2}, Lcom/cyjh/cjencrypt/CJEncrypt;->setCryptType(I)V

 

    .line 146

    const/4 v2, 0x0

 

    invoke-virtual {v0, v2}, Lcom/cyjh/cjencrypt/CJEncrypt;->setPurpose(I)V

 

    .line 147

    const/4 v2, 0x0

 

    invoke-virtual {v0, v2}, Lcom/cyjh/cjencrypt/CJEncrypt;->setIndex(I)V

 

    .line 148

    new-instance v2, Lcom/cyjh/cjencrypt/EncryptJni;

 

    invoke-direct {v2}, Lcom/cyjh/cjencrypt/EncryptJni;-><init>()V

 

    invoke-virtual {v2, v0, p2}, Lcom/cyjh/cjencrypt/EncryptJni;->Encrypt(Lcom/cyjh/cjencrypt/CJEncrypt;Landroid/content/Context;)Ljava/lang/String;

    :try_end_0

    .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0

 

    move-result-object v2

 

    goto :goto_0

 

    .line 149

    .end local v0    # "cjEncrypt":Lcom/cyjh/cjencrypt/CJEncrypt;

    :catch_0

    move-exception v1

 

    .line 150

    .local v1, "e":Ljava/lang/Exception;

    invoke-virtual {v1}, Ljava/lang/Exception;->printStackTrace()V

 

    .line 152

    const-string/jumbo v2, ""

 

    goto :goto_0

.end method

 

反编译修改包名:

  利用apktool拆包

  首先更改AndroidManifest.xml里面的包名

  全局更改com.xxx.xxxx类似的包名

  全局更改smali类型代码的包名字符串Lcom/xxx/xxxx

  全局更改所有com/xxx/xxxx文件夹的名称,因为java文件里面要求包名和文件夹路径要对应

  apktool b打包apk

  jarsigner 签名 ,安装apk

 

KILL 掉统计信息:

1.   替换程序中的url.

2.   url被加密则让其url加载错误.

屏蔽掉开启外挂后回到游戏蜂窝:

源码文件夹: Lcom/mfwfz/game/fengwoscript/ui/help/ScriptTopViewHelp

找到两个函数setData,找到内部调用,改为红色字体的值:

    .line 47

    iget-object v1, p0, Lcom/mfwfz/game/fengwoscript/ui/help/ScriptTopViewHelp;->mBackIv:Landroid/widget/ImageView;

 

    const/16 v2, 0x8

 

    invoke-virtual {v1, v2}, Landroid/widget/ImageView;->setVisibility(I)V

 

去广告的另一种方式:

修改android窗口布局的xml文件,本例去掉云挂机的广告(cloud_hook_entry_view.xml)(见下面的红色字体部分):

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout style="@style/hauto"

  xmlns:android="http://schemas.android.com/apk/res/android">

    <ImageView android:id="@id/cloudHookEntryImageView" android:layout_width="fill_parent" android:layout_height="52.0dip" android:src="@drawable/fw_ygj_enter_img2" android:scaleType="fitXY" />

</LinearLayout><?xml version="1.0" encoding="utf-8"?>

<LinearLayout style="@style/hauto"

  xmlns:android="http://schemas.android.com/apk/res/android">

    <ImageView android:id="@id/cloudHookEntryImageView" android:layout_width="0.0dip" android:layout_height="0.0dip" android:src="@drawable/fw_ygj_enter_img2" android:scaleType="fitXY" />

</LinearLayout>

 

关闭打开APP时弹出的“游戏蜂窝”加密广播:

源码文件夹:com/mfwfz/game/manager/alarmtask/AlarmTaskManager.java

找到函数showTaskNotification直接返回.

 

找按钮事件的另一种方式:

先找到按钮所在窗口的xml布局文件(一般res目录下),然后人工分析窗口的xml布局找到按钮的ID,再通过ID找到按钮的十六进制值,本例用“楚留香”挂机示范.


如果不能直接找到“云挂机”的按钮ID值和ID名称,先找左边的“本地挂机”ID名称“go_run_script_ly”,然后res目录搜索“go_run_script_ly”就能找到“云挂机”的ID名称“go_run_ygj_btn”,再然后搜索ID值就能找到相应的按钮事件。

 

更改AndroidManifest.xml的版本号:

先使用AXMLPrinter2.jar还原二进制的AndroidManifest.xml到字符串的AndroidManifest.xml.

java -jar AXMLPrinter2.jar  AndroidManifest.xml  >newxml.xml

然后打开WinHex搜索版本字符串,本例修改了两处“3.1.9升级为3.2.0,如下图:

第一处:


第二处:


云手机试用时间限制:

com\cyjh\gundam\fengwo\presenter\cloud\CloudHookHomePagePresenter.java

orderInfo.TryMinute

 

游戏蜂窝的技术优势:

a)   所有信息均从web服务器取到本地,也就是GoogleApple推荐的这种信息安全存取方式.

b)   一个帐号登录之后没有退出按钮,从根本上杜绝了垃圾帐号或者一台设备登录多个帐号的可能性;设备每次登录服务端都会判断设备是否在线,然后踢下在线的设备,保持一个帐号只能同时登录一个设备.

c)   每条发送到服务端的协议均有签名,签名不对的时候会务器拒绝回答.这里有个BUG,他是判断APK的自签名是不是与特定值有效,无效就拒绝计算协议的签名,其实应该把计算出来APK包的签名值也带入协议中放在服务器做判断APK包是否被修改过.

d)   判断自校验的代码没有做自校验,导致可以被随便修改.

e)   协议防重放攻击.

游戏蜂窝的技术劣势:

a)   不会善用APK加固程序,就算免费的也能做到很好的对抗APK包修改者,可能兼容性有一定的下降.



快讯:[看雪招聘]十八年来,看雪平台输出了大量安全人才,影响三代安全人才!

最后于 2018-9-14 16:35 被猪会被杀掉编辑 ,原因: 重新排版
本主题帖已收到 1 次赞赏,累计¥1.00
最新回复 (3)
mudebug 5天前
2
成功的让我这种付费用户得到强制更新且频繁掉线体验
baiafeu 3天前
3
楼主,有没有涉及过,例如叉叉助手付费脚本破解方面的知识呀?谢谢
javgo 3天前
4
蜂窝最新版本3.33,一修改dex就会闪退,应该是有dex校验,楼主有什么解决思路没有?
最后于 3天前 被javgo编辑 ,原因:
返回