crc 校验错误_修改某款lora固件库以支持接收错误数据包

4f8d6d5c3298da645257710bcfed4aef.png

本文为看雪论坛优秀文章 看雪论坛作者ID:二当家a 目前有一个需求,为了研究lora 在不同干扰情况下数据包字节错误的情况,我必须将错误的数据包也记录下来,即没有通过CRC校验的数据包。但是现有的lora固件,会直接将没有通过CRC的数据包丢弃,无法查看错误的情况。因此,有了这个记录。 针对的芯片 研究的是lora 2.4的通信,因此针对的芯片是sx1280的,这里就不把集成了该芯片的厂商说出来了。下面主要介绍一些思路。
整体过程为:
  • 提取共享库
  • 结合网上开源的代码,找到关键位置,思考修改的方案
  • 找到最优的修改方案,执行修改,并重新打包测试。

>>>>

提取共享库

厂商提供的是一个封装起来的LIB库,利用ubuntu 的file工具发现是一个AR格式的打包文件,搜索的解包的方式:(参考AR解压缩 https://www.thegeekstuff.com/2010/08/ar-command-examples/ ) 6dd6bb5622757b98e001e1c6c673304c.png
ar x name.lib
修改之后,可以用下面的方式打包回来:
ar cr dest.lib src1.o src2.o src3.o
其中后面的src1.o src2.o src3.o就是共享库。dest.lib是最终打包的文件 名。   之后,我发现其中的sx1280.0的库比较关键,就尝试专注分析该库。
还有另外两个厂商提供的封装库,提供了一些MAC层的操作。这里就叫manufactory.o.

>>>>

找到关键位置

我初步分析时,首先尝试分析manufactory.o.里面和MAC消息有关的操作。
我分析到两个关键的位置,1,正确接收到lora的消息时的操作。
else if ( a2 & 0x40 )   clear_event((unsigned __int8)s_phy_layer_task_id, 4);    stop_timerEx((unsigned __int8)s_phy_layer_task_id, 4);radio_raw_data = (unsigned __int8 *)msg_allocate(255);    if ( radio_raw_data )    {      *(_DWORD *)radio_raw_data_len = 0;      SX1280Hal::SetDirDisable((SX1280Hal *)&Radio);      clear_event((unsigned __int8)s_phy_layer_task_id, 76);      SX1280::GetPayload((SX1280 *)&Radio, radio_raw_data, radio_raw_data_len, 0xFFu);      SX1280::GetPacketStatus(&Radio, &PacketStatus);      SX1280Hal::SetDirEnable((SX1280Hal *)&Radio);     }
可以发现几个关键的步骤就是利用SX1280的库来获取payload并且存储起来。
另一个方面,我发现了几个处理lora接收错误情况的流程:
else if ( !s_PeriodBaseCount_flag )        {          SetRcMode();          send_cmd(9u);               // RX_ERROR_CMD        } else if ( a2 & 8 )                            // SAMPLE_MSG_RX_TIMEOUT_EVNT  {    clear_event((unsigned __int8)s_phy_layer_task_id, 4);    stop_timerEx((unsigned __int8)s_phy_layer_task_id, 4);    if ( s_tx_confirm_flag == 1 )    {      s_tx_confirm_flag = 0;      v24 = msg_allocate(32);      if ( v24 )      {        *(_BYTE *)v24 = 2;        *(_BYTE *)(v24 + 2) = 6;                // MAC_EVENT_TX_TIMEOUT_CMD        *(_BYTE *)(v24 + 3) = s_phy_layer_task_id;        *(_BYTE *)(v24 + 4) = Radio_packet_type;        *(_DWORD *)(v24 + 28) = 0;        *(_DWORD *)(v24 + 24) = 0;        msg_send((unsigned __int8)g_sample_task_id, v24);      }    }    else    {      v25 = msg_allocate(32);      if ( v25 )      {        *(_BYTE *)v25 = 2;        *(_BYTE *)(v25 + 2) = 9;                // MAC_EVNT_RX_ERROR_CMD        *(_BYTE *)(v25 + 3) = s_phy_layer_task_id;        *(_BYTE *)(v25 + 4) = Radio_packet_type;        *(_DWORD *)(v25 + 28) = 0;        *(_DWORD *)(v25 + 24) = 0;        msg_send((unsigned __int8)g_sample_task_id, v25);      }    }    result = v4 ^ 8;  }
那么基本的思路,就是在上述所有反馈了lora rx error的地方,仍然将上述SX1280获取和拷贝数据的操作添加在逻辑里面。 但是操作起来很复杂,拷贝payload的汇编代码整理一下有这些。而且对于某些条件跳转的地址,还得仔细的修改:
MOVS    R1, #4LDR     R0, =s_phy_layer_task_idLDRB    R0, [R0]BL      osal_clear_eventMOVS    R1, #4LDR     R0, =s_phy_layer_task_idLDRB    R0, [R0]BL      osal_stop_timerExMOVS    R0, #0xFFBL      osal_msg_allocateMOV     R9, R0CMP.W   R9, #0BEQ     loc_123CMOVS    R0, #0STR     R0, [SP,#0x28+radio_raw_data_len]LDR     R0, =Radio      ; thisBL      _ZN9SX1280Hal13SetDirDisableEv ; SX1280Hal::SetDirDisable(void)MOVS    R1, #0x4C ; 'L'LDR     R0, =s_phy_layer_task_idLDRB    R0, [R0]BL      osal_clear_eventMOVS    R3, #0xFF       ; unsigned __int8ADD     R2, SP, #0x28+radio_raw_data_len ; unsigned __int8 *MOV     R1, R9          ; unsigned __int8 *LDR     R0, =Radio      ; thisBL      _ZN6SX128010GetPayloadEPhS0_h ; SX1280::GetPayload(uchar *,uchar *,uchar)LDR     R1, =PacketStatusLDR     R0, =RadioBL      _ZN6SX128015GetPacketStatusEP14PacketStatus_t ; SX1280::GetPacketStatus(PacketStatus_t *)LDR     R0, =Radio      ; thisBL      _ZN9SX1280Hal12SetDirEnableEv ; SX1280Hal::SetDirEnable(void)
看到上述都是基于sx1280的操作,那么我想能不能直接在sx1280找到一些突破口。
然后发现sx1280的库实现时开源的。 sx1280(https://os.mbed.com/teams/Semtech/code/SX1280Lib/) 这是非常幸运的。我直接就搜索CRC有关的位置,发现在SX1280::ProcessIrqs( void )的这个函数里面,有这样一个逻辑:
if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )    {        if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )// 如果收到底层CRC不通过的ERROR,就向上层汇报IRQ_CRC_ERROR_CODE。那么MAC层就会根据这个error进行相应的处理,也即是上面看到的丢包处理。理论上,我们只要使得该语句永远为False就会一直跳转到下面的rxDone中,始终汇报数据包接收成功即可。        {            if( rxError != NULL )            {                rxError( IRQ_CRC_ERROR_CODE );            }        }        else        {            if( rxDone != NULL ) //这条基本都会true,因为rxDone是一个指针函数。            {                rxDone( );            }        }    }
正如代码中分析的,只要if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )永远为真,那么就可以上报数据包成功接收消息,那么就可以把错误的数据包保留。
如果收到底层CRC不通过的ERROR,就向上层汇报 IRQ_CRC_ERROR_CODE。 那么MAC层就会根据这个error进行相应的处理,也即是上面看到的丢包处理。 理论上,我们只要使得该语句永远为False就会一直跳转到下面的rxDone中,始终汇报数据包接收成功即可。

>>>>

最优方案的选择,修改测试

我们发现,直接修改sx1280是最简单的。 38cf0309d213ea46a7a406f9d68d3903.png 在0x228的代码位置,如果上述比较不等于0才会跳转执行下面的0x238的操作,即rxDone操作。 因此,只要将BNE loc_238修改成无条件跳转B loc_238即可。汇编中D1是BNE跳转,E0是无条件跳转即B。因此在对应位置如下修改: 28b656a4c2b567c11fa8f6c9822c7663.png 修改的工具路径是:edit->patch program->change byte,(IDA pro 7.0)。
修改完之后,再看看程序逻辑已经被修改: eebfa24822eeff08d118b284e2da8926.png 因此,我们修改一个字节就能够达到效果了。
保存修改。edit->patch program-> apply patched to input file ,就可以保存修改了。
再重新利用AR打包回来,测试效果, 发现错误的数据包也可以接受了。 f2998734a4a2cc18ccf2d572f4f7ae27.gif - End - bc42b84146073e6d4b508da33a1a037e.png

看雪ID:二当家a

https://bbs.pediy.com/user-554506.htm 

*本文由看雪论坛 二当家a 原创,转载请注明来自看雪社区。 e34c508c104146599f15e3f75ebd7cd2.png

推荐文章++++

6d08bb71a6980aae5e208f48ab0dfb5f.png

* 为了理解反汇编引擎而写的X86/X64反汇编引擎

* 捆绑包驱动锁首病毒分析

* **游戏逆向分析笔记

* 对宝马车载apps协议的逆向分析研究

* x86_64架构下的函数调用及栈帧原理

好书推荐a6537742040572d5f303e6cbc46c1fdb.png

﹀ ﹀ ﹀ dca88f7b65edd1dbaa7c11550c9308ce.png 公众号ID:ikanxue 官方微博:看雪安全 商务合作:wsc@kanxue.com ab21d1985c4b40e5367fb659c39ec1d7.gif
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值