设为首页收藏本站

中国莓论坛-黑莓论坛

 找回密码
 立即注册

用新浪微博连接

一步搞定

QQ登录

只需一步,快速开始

沈阳唯一全新黑莓中国电信买黑莓送话费活动重庆最牛X的黑莓专卖店9800红与白简直就是艺术品
太原唯一原装-富百家2层46上海实体/港行百老汇现货团购:黑莓9810全新=2599元买黑莓找老佛
查看: 3287|回复: 36

[软件测评&使用心得] 黑莓OS5.0系统断网问题深入研究——转自大神RAiN 在feelberry的帖子   [复制链接]

Rank: 3Rank: 3Rank: 3

升级  63.6%

  • TA的每日心情
    无聊
    2010-10-8 10:26:08
  • 签到天数: 45 天

    [LV.5]常住居民I

    UID
    1384
    积分
    818
    金币
    1311
    莓币
    8
    在线时间
    225 小时
    发表于 2010-8-18 16:25:19 |显示全部楼层
    本帖最后由 xubo_buaa 于 2010-8-18 20:35 编辑

    黑莓OS5.0系统断网问题深入研究

    原帖链接:http://www.feelberry.com/bbs/viewthread.php?tid=3414&extra=page%3D1


    黑莓OS5.0系统的断网问题一直是困扰众多莓友的重要问题,对此我也一直是耿耿于怀。最近看到一些帖子说只要修改软件的联网方式,使用cmwap接入即可绕过断网故障,我自己通过对Opera和Gmail的修改也证实了这一点,而这也是我对找出断网的原因产生了浓厚的兴趣。
    首先,我们来看两张截图:
       RIM_LOG_3.jpg
        RIM_LOG_4.jpg


    这是断网后试图用Opera打开网页时从手机工程模式下的Event Log中截取到的错误信息,包含从Opera开始调用网络连接到发生错误的调用堆栈信息。可以看到,导致Opera无法建立网络连接的错误发生在net_rim_os-4.cod中SocketHelper类的checkDataConnectivity函数中。
    从函数名来看,checkDataConnectivity就是在检测是否可以建立数据连接,那么这个函数为什么会抛出异常呢?让我们来看这个函数的反编译代码:
    static public final checkDataConnectivity(
            net.rim.device.cldc.io.utility.RIMConnectionParameters ); // address: 0  offset: 17525
    {
            enter_narrow  // 0: dd (221)
            ldc literal_110:"true" // 1: 28 (40)
            aload_0  // 2: 3f (63)
            getstatic_lib RETRY_NO_CONTEXT // RIMConnectionParameters // 3: 6e (110)
            invokevirtual java.lang.String getParameter(
                    net.rim.device.cldc.io.utility.RIMConnectionParameters, int ) // pc=2 // 4: 01 (1)
            invokevirtual_short .equals // idx=1 pc=2 // 5: de (222)
            istore_1  // 6: 4e (78)
            iload_1  // 7: 38 (56)
            ifeq Label18 // 8: 93 (147)
            invokestatic_lib assertRRISignatures(  ) // ControlledAccess // 9: 08 (8)
            goto Label18 // 10: a1 (161)
            astore_2  // 11: 57 (87)
            new_lib java.util.Calendar//java.util.Calendar // 12: b9 (185)
            dup  // 13: cf (207)
            aload_2  // 14: 41 (65)
            invokevirtual java.lang.String getMessage( java.lang.Throwable ) // pc=1 // 15: 01 (1)
            invokespecial_lib java.io.IOException.<init> // pc=2 // 16: 06 (6)
            athrow  // 17: bc (188)
    Label18:
            getstatic net.rim.device.cldc.io.socket.SocketHelper.field_15022 // 18: 6d (109)
            ifeq Label29 // 19: 93 (147)
            iload_1  // 20: 38 (56)
            ifne Label29 // 21: 96 (150)
            invokestatic_lib net.rim.device.cldc.io.datarecovery.DataRecovery getInstance(  )        // 22: 08 (8)
            invokevirtual boolean isConnectionAvailable(
                    net.rim.device.cldc.io.datarecovery.DataRecovery ) // pc=1 // 23: 01 (1)
            ifne Label29 // 24: 96 (150)
            new_lib java.util.Calendar//java.util.Calendar // 25: b9 (185)
            dup  // 26: cf (207)
            invokespecial_lib java.io.IOException.<init> // pc=1 // 27: 06 (6)
            athrow  // 28: bc (188)
    Label29:
            return  // 29: 1f (31)
    }
    由代码可见,这个函数主要是为了调用DataRecovery.isConnectionAvailable()函数,如果返回false,则抛出异常。到此可以基本断定,日志中IOException的出现是由于DataRecovery.isConnectionAvailable()函数返回了false。
    那么再来看DataRecovery.isConnectionAvailable()函数的反编译代码:
    public boolean isConnectionAvailable( net.rim.device.cldc.io.datarecovery.DataRecovery ); // address: 0
            offset: 16865
    {
            enter_narrow  // 0: dd (221)
            synch  // 1: 12 (18)
            aload_0_getfield ._errorLevel  // ofs = -1 ord = 0 addr = 3 // 2: 67 (103)
            bipush 4 // 3: 24 (36)
            if_icmpge Label7 // 4: 99 (153)
            iconst_1  // 5: 2c (44)
            ireturn  // 6: 18 (24)
    Label7:
            iconst_0  // 7: 23 (35)
            ireturn  // 8: 18 (24)
    }
    这个函数更简单,只要_errorLevel大于等于4,就返回false,否则返回true。
    难道说如此困扰我们的断网问题,其原因只是因为这个变量的值大于等于4?!而这个值又是如何变成大于等于4的?
    整个DataRecovery类中,仅有一个函数修改了_errorLevel的值:fileReport。
    fileReport函数比较长,此处就不全部列出了,仅截取其中与_errorLevel有关的部分:
    public fileReport( net.rim.device.cldc.io.datarecovery.DataRecovery, int, int, int ); // address: 0
            offset: 16514
    {
            iload_1  // 9: 38 (56)
            tableswitch :
                    tablesize=3
                    low=-1
                    table 0 default
                    -1 :         Label129
                    0 :         Label11
                    1 :         Label42
    Label11:
            ……
            aload_0_getfield ._errorLevel  // ofs = -1 ord = 0 addr = 3 // 19: 67 (103)
            bipush 4 // 20: 24 (36)
            if_icmplt Label28 // 21: 9b (155)
            aload_0  // 22: 3f (63)
            iconst_0  // 23: 23 (35)
            putfield ._errorLevel  // ofs = -1 ord = 0 addr = 3 // 24: 5f (95)
            ……
    Label28:
            aload_0  // 28: 3f (63)
            iconst_0  // 29: 23 (35)
            putfield ._errorLevel  // ofs = -1 ord = 0 addr = 3 // 30: 5f (95)
            ……
    Label42:
            aload_0  // 42: 3f (63)
            aload_0_getfield ._errorLevel  // ofs = -1 ord = 0 addr = 3 // 43: 67 (103)
            iconst_1  // 44: 2c (44)
            iadd  // 45: 7a (122)
            putfield ._errorLevel  // ofs = -1 ord = 0 addr = 3 // 46: 5f (95)
            ……
    Label129:
            ……
            return  // 131: 1f (31)
    }
    由函数可见,当fileReport的第一个参数值为0时,_errorLevel会被重置为0,而参数值为1时,_errorLevel会递增。
    也就是说系统在出现某种状况的时候,会用参数值1来调用DataRecovery.fileReport()函数,使_errorLevel值递增,当_errorLevel值累积到大于等于4的时候,我们的BB就断网了……

    事实真的是这样吗?我们结合以下现象来进行验证:
    1. 断网只影响GPRS、EDGE、3G、WIFI等联网方式,采用BIS、BES上网时不会断网;在连接字串中写明WAPGagewayIP等信息的也不会受断网影响
    我在JDE开发环境内写了一个小的网络连接测试程序,并用调试方式在模拟器上运行,运用JDE的VM Byte Code调试能力,结合反编译得到的代码对整个网络连接的建立过程进行了跟踪调试,结果证明,采用BIS、BES方式和写明WAPGagewayIP信息的,其连接过程中完全不会调用到SocketHelper.checkDataConnectivity()或DataRecovery.isConnectionAvailable()函数,而其它连接方式下,无论是用socket还是用http连接,都会调用SocketHelper.checkDataConnectivity(),并且没有任何分支语句用来跳过该函数。
    2. 断网只影响第三方应用程序,官方浏览器不受影响
    说到这个问题,我们要回头再看看SocketHelper.checkDataConnectivity()函数的代码,这回给出整理后的java代码,注意其中标红的部分:
    public final static checkDataConnectivity(RIMConnectionParameters parameters) throws IOException
    {
            boolean retryNoContext =
                    (parameters.getParameter(RIMConnectionParameters.RETRY_NO_CONTEXT).equals("true"));
            if (retryNoContext)
            {
                    try
                    {
                            ControlledAccess.assertRRISignatures();
                    }
                    catch (Throwable t)
                    {
                            throw new IOException(t.getMessage());
                    }
            }
            if (checkConnectivity && !retryNoContext)
            {
                    if (!DataRecovery.isConnectionAvailable())
                            throw new IOException();
            }
    }
    也就是说,如果连接字串中具备“;retrynocontext=true”属性,并且应用程序具备了RRI签名,就可以无视连接检测!而RRI签名是黑莓系统内核使用的签名,根本不对外公开!
    接下来不用说大家也该猜到了,我在系统浏览器HTTPStackAdapter类中的private final HttpConnection routine_17191(int, String, String, BrowserConfigRecord, int, int )函数内找到了添加retrynocontext属性后再建立连接的代码:
            getstatic_lib RETRY_NO_CONTEXT // RIMConnectionParameters // 87: 6e (110)
            ldc literal_125:"true" // 88: 28 (40)
            invokevirtual setParameter( net.rim.device.cldc.io.utility.RIMConnectionParameters, int,
                    java.lang.String ) // pc=3 // 89: 01 (1)
            ……
            invokestatic_lib javax.microedition.io.Connection open( net.rim.device.cldc.io.utility.URL, int,
                    boolean )  // RIMConnector // 186: 08 (8)
    这说明RIM知道网络连接有可能会有问题,却给自己开发的应用程序留了一个只有自己才能使用的后门!至于RIM是确实没有发现在DataRecovery的处理上有Bug还是有其它的原因大家自己猜想吧。

    从以上这些分析中我们可以看到,DataRecovery中的_errorLevel的值是决定我们的BB断不断网的关键。然而这仅仅是浮于表面的部分,隐藏在后面的是整个DataRecovery以及fileReport函数的处理机制。这些我没有做更深入的分析,希望有感兴趣的朋友做进一步的研究。

    下面再说说我是如何尝试解决断网问题,又是如何失败的。
    第一次尝试:
    既然调用fileReport函数并将第一个参数设置为0就可以将_errorLevel复位为0,那么我写个程序去调它一下不就行了!
    查api文档发现DataRecovery类没有公开,就自己根据反编译的结果写个简单的类,因为是要作为api使用的,因此所有方法都不用具体实现。编译后把原先的net_rim_api.jar解包,再把编译好的DataRecovery.class打包进去,api就造好了。
    接下来写好了程序,调试运行,一切OK!心情好的不得了!准备签名装手机时,噩梦到来,需要RIMAPPSA2签名(就是RRI签名)!这个我真的没有……不理会,把能签的签了,装机,结果因为缺少签名无法运行。
    此次尝试到此彻底失败。

    第二次尝试:
    调用DataRecovery.isConnectionAvailable()函数是在net_rim_os-4.cod中,直接修改这个模块的二进制代码,使其永远不抛出异常不就行了。
    找到模拟器目录下的net_rim_os.cod文件并解压,发现其数字签名是假的!这样修改内容就不会产生验证的问题了。
    用HEX编辑工具对net_rim_os-4.cod进行了修改后,重新打包生成net_rim_os.cod文件并覆盖回原目录。启动模拟器后报错,奇怪,数字签名是假的怎么还会报错?将模拟器清除一下再启动,OK了!
    接下来就是修改实际的net_rim_os.cod文件了。安装了484后再安装794混刷包,重新进行修改并覆盖原文件,最后刷机。过程一直很顺利,可结束的时候报出net_rim_os.cod文件签名无效,手机无法正常启动。怪了,怎么还有签名验证?再仔细一看,恍然大悟,模拟器里的文件签名是假的,可真正的刷机文件签名可是真的……
    此次尝试到此又彻底失败。

    第三次尝试:
    既然以上两次尝试都败在签名这里,那么有没有可能从根本上把签名验证废掉?
    在net_rim_cldc中找到了verifySignature函数,把这个函数咔嚓掉不就可以跳过验证机制了。重新修改后再刷机,再次失败,这回屏幕上显示一个错误代码,让重装软件。
    此次尝试到此再次彻底失败。

    现在我已经彻底没招儿了。
    哪位朋友如果与黑莓官方的人有联系,可以将上面的问题向他们反映反映。或者哪位英文比较好,帮忙把本文翻译翻译,贴到RIM官方论坛之类的地方,希望能引起他们的注意。

    再补充一点:
    我对比了OS4.7与OS5.0,发现4.7版本中根本没有SocketHelper类,在建立网络连接的过程中也不会调用DataRecovery.isConnectionAvailable()函数。也就是说验证网络是否能够连接这个机制是从OS5.0系统开始引入的,这也是OS4.7或以下系统不会断网的原因。
    已有 7 人评分金币 收起 理由
    albertwang1988 + 10 太强力了
    fd2306 + 10
    tcxss + 10
    1080016 + 10 不能不说,你非常强大,希望你能为我们bber ...
    js0726 + 7 完全不懂...
    ygrain + 10 大仙啊,虽然偶看不懂
    tokcecal + 10 感谢分享

    总评分: 金币 + 67   查看全部评分

    Rank: 3Rank: 3Rank: 3

    升级  63.6%

  • TA的每日心情
    无聊
    2010-10-8 10:26:08
  • 签到天数: 45 天

    [LV.5]常住居民I

    UID
    1384
    积分
    818
    金币
    1311
    莓币
    8
    在线时间
    225 小时
    发表于 2010-8-18 16:27:22 |显示全部楼层
    本帖最后由 xubo_buaa 于 2010-8-18 17:47 编辑

    也许是机型不一样其OS也不一样。8900 os4.6.1,在北京同样断网,且与5.0的频率和现象一模一样。

    所以,应该不是只有5.0才断。

    可是9000就是4.6不断,5.0断。

    -------

    另:

        断网肯定首先不能怨地域,因为别的品牌智能机在同一个地方就不断网。

        北京用BB 4.5就不断网。

        况且,rain已经把原因都找到了,明明就是os的问题。

    使用道具 举报

    Rank: 2Rank: 2

    升级  84%

  • TA的每日心情
    开心
    2011-2-26 08:54:15
  • 签到天数: 81 天

    [LV.6]常住居民II

    UID
    10954
    积分
    452
    金币
    10361
    莓币
    4
    在线时间
    103 小时
    发表于 2010-8-18 16:31:08 |显示全部楼层
    不会升级后的ROM反而不如老版本的,要是这样的话,也只有两个字了……失败!
    GSM-->>>>>CDMA!

    8700->8830->9530

    使用道具 举报

    Rank: 2Rank: 2

    升级  42%

  • TA的每日心情
    开心
    2011-4-11 23:20:43
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    UID
    5718
    积分
    326
    金币
    184
    莓币
    2
    在线时间
    142 小时
    发表于 2010-8-18 16:41:59 |显示全部楼层
    看看6.0会不会断啊
    bold 9000/9700

    使用道具 举报

    金牌会员

    Taio Cruz .

    Rank: 6Rank: 6

    升级  12.4%

  • TA的每日心情

    3 天前
  • 签到天数: 516 天

    [LV.9]以坛为家II

    UID
    6686
    积分
    3248
    金币
    1128
    莓币
    228
    在线时间
    479 小时

    热心会员 参与勋章 爱心天使 水军元老 终身成就

    发表于 2010-8-18 17:35:55 |显示全部楼层
    代码太乱了。。。。。我去原址看看····也迷糊的

    使用道具 举报

    版主

    【围观党】创始人

    Rank: 10Rank: 10

  • TA的每日心情
    奋斗
    2012-1-1 14:58:28
  • 签到天数: 381 天

    [LV.9]以坛为家II

    UID
    10
    积分
    3364
    金币
    14896
    莓币
    153
    在线时间
    640 小时

    热心会员 特别义工 优秀版主 黑莓精英 原创达人

    发表于 2010-8-18 17:42:39 |显示全部楼层
    断网更大的关系是当地啊....
    帝都那种重灾区...BB有不断的么...

    使用道具 举报

    Rank: 3Rank: 3Rank: 3

    升级  63.6%

  • TA的每日心情
    无聊
    2010-10-8 10:26:08
  • 签到天数: 45 天

    [LV.5]常住居民I

    UID
    1384
    积分
    818
    金币
    1311
    莓币
    8
    在线时间
    225 小时
    发表于 2010-8-18 17:46:18 |显示全部楼层
    断网更大的关系是当地啊....
    帝都那种重灾区...BB有不断的么...
    js0726 发表于 2010-8-18 17:42



        断网肯定首先不能怨地域,因为别的品牌智能机在同一个地方就不断网。

        北京用BB 4.5就不断网。

        况且,rain已经把原因都找到了,明明就是os的问题。

    使用道具 举报

    版主

    购物兔子

    Rank: 10Rank: 10

  • TA的每日心情

    昨天 11:56
  • 签到天数: 483 天

    [LV.9]以坛为家II

    UID
    2252
    积分
    5479
    金币
    6417
    莓币
    178
    在线时间
    1153 小时
    在用BB
    8900

    热心会员 特别义工 爱心天使 参与勋章 终身成就 优秀版主 黑莓精英

    发表于 2010-8-18 18:39:15 |显示全部楼层
    哥哥,你真牛X。。。

    我老老实实的看完了,虽然我没有看懂。
    但是也感觉到了你研究的认真!

    希望你能多研究出利于咱们国内BBer使用的好东西来!

    使用道具 举报

    Rank: 2Rank: 2

    升级  13.67%

  • TA的每日心情

    2010-12-11 17:56:09
  • 签到天数: 12 天

    [LV.3]偶尔看看II

    UID
    17545
    积分
    241
    金币
    225
    莓币
    0
    在线时间
    16 小时
    发表于 2010-8-18 19:33:50 |显示全部楼层
    深奥的问题

    使用道具 举报

    版主

    【围观党】创始人

    Rank: 10Rank: 10

  • TA的每日心情
    奋斗
    2012-1-1 14:58:28
  • 签到天数: 381 天

    [LV.9]以坛为家II

    UID
    10
    积分
    3364
    金币
    14896
    莓币
    153
    在线时间
    640 小时

    热心会员 特别义工 优秀版主 黑莓精英 原创达人

    发表于 2010-8-18 19:40:37 |显示全部楼层
    回复 7# xubo_buaa


       那同样的机型和OS为什么在别的地方就不断网...而帝都就必断呢....这也是个问题啊

    使用道具 举报

    Rank: 3Rank: 3Rank: 3

    升级  63.6%

  • TA的每日心情
    无聊
    2010-10-8 10:26:08
  • 签到天数: 45 天

    [LV.5]常住居民I

    UID
    1384
    积分
    818
    金币
    1311
    莓币
    8
    在线时间
    225 小时
    发表于 2010-8-18 20:31:33 |显示全部楼层
    回复  xubo_buaa


       那同样的机型和OS为什么在别的地方就不断网...而帝都就必断呢....这也是个问题啊 ...
    js0726 发表于 2010-8-18 19:40



        这就像造汽车和修公路,你能要求为了自己的汽车跑得快而只寄希望于把路都修得跟德国那几条不限速的高速公路那样吗?更重要的还是该练内功,提高自己车的动力、传动系统可靠性及效率、避震系统、操控系统。

        而这断网,就是因为RIM投机取巧或者懒惰或者只为了照顾自己的BES、BIS服务(也许就是要用断网逼迫所有用户上服务),Rain也在文中说到了:这说明RIM知道网络连接有可能会有问题,却给自己开发的应用程序留了一个只有自己才能使用的后门!至于RIM是确实没有发现在DataRecovery的处理上有Bug还是有其它的原因大家自己猜想吧。

    使用道具 举报

    金牌会员

    蓝天白云

    Rank: 6Rank: 6

    升级  60.85%

  • TA的每日心情
    开心
    2011-2-14 09:35:43
  • 签到天数: 155 天

    [LV.7]常住居民III

    UID
    5176
    积分
    4217
    金币
    1610
    莓币
    382
    在线时间
    443 小时

    热心会员 水军元老

    发表于 2010-8-18 20:46:38 |显示全部楼层
    我以前是每星期断网不低于5次,后来混刷了willboy的混刷包里的6.0的文件,现在每半个月断一次,后来又尝试刷willboy的最新包,刷机多次发现加入6.0.0.135的文件同样导致机器经常断网,无奈刷回135之前的那个混刷版本,现在又基本不断网了。真的很怪,有的人就不断网,有的人天天断网。
    Shawn

    使用道具 举报

    Rank: 2Rank: 2

    升级  25.67%

  • TA的每日心情
    开心
    前天 07:51
  • 签到天数: 134 天

    [LV.7]常住居民III

    UID
    21296
    积分
    277
    金币
    2621
    莓币
    0
    在线时间
    70 小时
    发表于 2010-8-18 21:00:00 |显示全部楼层
    高端了,看不懂,帮顶

    使用道具 举报

    Rank: 25

  • TA的每日心情

    2012-1-19 21:08:04
  • 签到天数: 217 天

    [LV.7]常住居民III

    UID
    1
    积分
    6646
    金币
    27447
    莓币
    546
    在线时间
    1258 小时
    在用BB
    9700
    8520

    爱心天使 黑莓精英 论坛贵宾 终身成就

    发表于 2010-8-18 21:10:03 |显示全部楼层
    断网,我觉得不单纯的是OS的问题,最简单的例子,同样的地方,我的联通3G从来不断网,但是朋友的移动一天要断好几次,同样机型,同样OS,他换了我的卡也不断网,换上他的就断。

    所以我个人认为这个和OS有一定的关系,但是和运营商的网络连接也有一定关于,这也可以看出BIS,BES不断网的原因了。

    使用道具 举报

    版主

    【跟风党】

    Rank: 10Rank: 10

  • TA的每日心情
    擦汗
    2012-1-22 18:27:29
  • 签到天数: 533 天

    [LV.9]以坛为家II

    UID
    4458
    积分
    6406
    金币
    3208
    莓币
    607
    在线时间
    842 小时
    在用BB
    9000

    黑莓精英 组织勋章 论坛贵宾 水军元老 原创达人

    发表于 2010-8-18 21:52:40 |显示全部楼层
    本帖最后由 su_meng2005 于 2010-8-19 00:29 编辑

    反编译啊。大神级别的。
    支持 Rain
    莓技术

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

     

    本论坛为公开交流平台,论坛所有言论及附属内容纯属发表者个人意见,与《中国莓论坛》立场无关。内容所涉及的版权和法律相关事宜请参考各自所有者的条款。
    如果认定侵犯了您的权利,请联系我们尽快处理。本论坛原创内容请联系本站后再行转载并务必保留我站信息。此声明修改不再另行通知,本论坛保留最终解释权。

    手机版|黑莓手机论坛 ( 陕ICP备09015793号 )  

    GMT+8, 2012-2-5 07:47 , Processed in 0.340544 second(s), 18 queries , Gzip On, Eaccelerator On.

    Powered by Discuz! X2

    © 2001-2011 Comsenz Inc.

    回顶部