BLHeliSuite32逆向(二)

Crack,Reverse

Updated on July 20, 2021 Posted by elmagnifico on July 16, 2021

Foreword

继续上篇,markdown内容一多了,typora里再写就非常卡了,复制粘贴也不舒服,大概也有20000词而已,所以这里再开一篇

串口读取

CheckStrACK

找了半天没看到实际收串口数据的代码,最后才发现好像这个CheckStrAck的地方里面有串口数据相关的内容。这个函数名简直坑爹。

_Unit108.TBootloader.CheckStrACK
00704390        push        ebp
00704391        mov         ebp,esp
00704393        push        ecx
00704394        mov         ecx,0B
00704399        push        0
0070439B        push        0
0070439D        dec         ecx
0070439E>       jne         00704399
007043A0        xchg        ecx,dword ptr [ebp-4]
007043A3        push        ebx
007043A4        push        esi
007043A5        push        edi
007043A6        mov         dword ptr [ebp-10],ecx
# ecx=0x103 刚好是传输时 电调发送来的259个字节
007043A9        mov         esi,edx
007043AB        mov         ebx,eax
007043AD        xor         eax,eax
007043AF        push        ebp
007043B0        push        704AF9
007043B5        push        dword ptr fs:[eax]
007043B8        mov         dword ptr fs:[eax],esp
007043BB        mov         byte ptr [ebp-11],0
007043BF        mov         byte ptr [ebp-17],0
007043C3        lea         eax,[ebp-4]
007043C6        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
007043CC        call        @DynArrayClear
007043D1        mov         word ptr [ebp-16],0
007043D7        mov         byte ptr [ebx+0A1],0FF;TBootloader.FLastACK:byte
007043DE        cmp         byte ptr [ebx+0B4],0FD;TBootloader.FLastCMD:byte
007043E5>       je          007043EE
007043E7        mov         eax,ebx
007043E9        call        00704198
007043EE        call        006DB734
007043F3        test        al,al
007043F5>       je          0070445C
007043F7        call        006D91CC
007043FC        mov         dword ptr [ebx+108],eax;TBootloader.FStartTime:Int64
00704402        mov         dword ptr [ebx+10C],edx;TBootloader.?f10C:Integer
00704408        cmp         byte ptr [ebp+8],0
0070440C>       je          00704418
0070440E        mov         eax,1
00704413        call        006DBF4C
00704418        cmp         byte ptr [ebx+0B4],0B;TBootloader.FLastCMD:byte
# 1.跳转
0070441F>       je          00704448
00704421        push        704B1C;'<'
00704426        push        dword ptr [ebx+0E8];TBootloader.FInfName:string
0070442C        push        704B2C;': '
00704431        lea         eax,[ebp-28]
00704434        mov         edx,3
00704439        call        @UStrCatN
0070443E        mov         eax,dword ptr [ebp-28]
00704441        call        006DC07C
00704446>       jmp         00704452
# 1.继续
00704448        mov         eax,704B40;'<BOOLOADER ANSWER: '
0070444D        call        006DC07C
00704452        mov         eax,1
00704457        call        006DBF4C
0070445C        mov         eax,ebx
0070445E        call        TBootloader.GetReadTimeOut
00704463        mov         word ptr [ebp-14],ax
00704467        cmp         byte ptr [ebx+0B4],0B;TBootloader.FLastCMD:byte
# 2.跳转
0070446E>       jne         007044ED
00704470        cmp         byte ptr [ebx+0E4],0;TBootloader.FFVTLinkerMode:Boolean
00704477>       jne         007044ED
00704479        mov         edx,32
0070447E        mov         eax,ebx
00704480        call        TBootloader.SetReadTimeOut
00704485        lea         ecx,[ebp-2C]
00704488        mov         edx,1
0070448D        mov         eax,ebx
0070448F        call        TBootloader.RecvString
00704494        mov         edx,dword ptr [ebp-2C]
00704497        mov         eax,esi
00704499        mov         ecx,dword ptr ds:[404B48];TArray<System.Byte>
0070449F        call        @DynArrayAsg
007044A4        mov         eax,dword ptr [esi]
007044A6        test        eax,eax
007044A8>       je          007044AF
007044AA        sub         eax,4
007044AD        mov         eax,dword ptr [eax]
007044AF        test        eax,eax
007044B1>       jle         0070451D
007044B3        mov         edx,dword ptr [ebp-10]
007044B6        add         edx,32
007044B9        mov         eax,ebx
007044BB        call        TBootloader.SetReadTimeOut
007044C0        lea         ecx,[ebp-34]
007044C3        mov         edx,dword ptr [ebp-10]
007044C6        dec         edx
007044C7        mov         eax,ebx
007044C9        call        TBootloader.RecvString
007044CE        mov         edx,dword ptr [ebp-34]
007044D1        lea         ecx,[ebp-30]
007044D4        mov         eax,dword ptr [esi]
007044D6        call        006D5954
007044DB        mov         edx,dword ptr [ebp-30]
007044DE        mov         eax,esi
007044E0        mov         ecx,dword ptr ds:[404B48];TArray<System.Byte>
007044E6        call        @DynArrayAsg
007044EB>       jmp         0070451D
# 2.继续
007044ED        mov         edx,dword ptr [ebp-10]
007044F0        mov         eax,ebx
007044F2        call        TBootloader.CalcCMDAckTimeOut
007044F7        mov         edx,eax
007044F9        mov         eax,ebx
007044FB        call        TBootloader.SetReadTimeOut
00704500        lea         ecx,[ebp-38]
00704503        mov         edx,dword ptr [ebp-10]
00704506        mov         eax,ebx
# 上面的edx 是读取长度 eax应该是存放的数组或者地址
00704508        call        TBootloader.RecvString
# 结束以后 这句就是把地址给回来,edx中存储的内容就是真正的数据
0070450D        mov         edx,dword ptr [ebp-38]

这个数据和我用串口同时监听到的数据一样

  • 实际上这个串口buff地址每次启动都会不一样,但是总体每次运行到这个位置的时候,某个寄存器里面一定存的就是这个地址

image-20210716172235050

00704510        mov         eax,esi
00704512        mov         ecx,dword ptr ds:[404B48];TArray<System.Byte>
00704518        call        @DynArrayAsg
0070451D        call        006DB734
00704522        test        al,al
00704524>       je          00704537
00704526        call        006D91CC
0070452B        mov         dword ptr [ebx+110],eax;TBootloader.FEndTime:Int64
00704531        mov         dword ptr [ebx+114],edx;TBootloader.?f114:Pointer
00704537        mov         edx,dword ptr [esi]
00704539        mov         eax,edx
0070453B        test        eax,eax
0070453D>       je          00704544
0070453F        sub         eax,4
00704542        mov         eax,dword ptr [eax]
00704544        test        eax,eax
00704546>       jle         00704681
0070454C        mov         eax,edx
0070454E        test        eax,eax
00704550>       je          00704557
00704552        sub         eax,4
00704555        mov         eax,dword ptr [eax]
# 这里exa=0x103 而[ebp-10]也是103,所以这里跳转了
# 此时edx指向了串口buff,所以关注edx就行了
00704557        cmp         eax,dword ptr [ebp-10]
# 3.跳转
0070455A>       jge         0070461A
00704560        lea         ecx,[ebp-8]
00704563        mov         edx,0A
00704568        mov         eax,ebx
0070456A        call        TBootloader.RecvString
0070456F        mov         eax,dword ptr [ebp-8]
00704572        test        eax,eax
00704574>       je          0070457B
00704576        sub         eax,4
00704579        mov         eax,dword ptr [eax]
0070457B        test        eax,eax
0070457D>       jle         007045D3
0070457F        lea         ecx,[ebp-3C]
00704582        mov         eax,dword ptr [esi]
00704584        mov         edx,dword ptr [ebp-8]
00704587        call        006D5954
0070458C        mov         edx,dword ptr [ebp-3C]
0070458F        mov         eax,esi
00704591        mov         ecx,dword ptr ds:[404B48];TArray<System.Byte>
00704597        call        @DynArrayAsg
0070459C        call        006DB734
007045A1        test        al,al
007045A3>       je          007045D3
007045A5        mov         edi,dword ptr [ebp-8]
007045A8        test        edi,edi
007045AA>       je          007045B1
007045AC        sub         edi,4
007045AF        mov         edi,dword ptr [edi]
007045B1        lea         edx,[ebp-44]
007045B4        mov         eax,edi
007045B6        call        IntToStr
007045BB        mov         ecx,dword ptr [ebp-44]
007045BE        lea         eax,[ebp-40]
007045C1        mov         edx,704B74;'Repeated Read: '
007045C6        call        @UStrCat3
007045CB        mov         eax,dword ptr [ebp-40]
007045CE        call        006DBFB4
007045D3        mov         eax,dword ptr [esi]
007045D5        test        eax,eax
007045D7>       je          007045DE
007045D9        sub         eax,4
007045DC        mov         eax,dword ptr [eax]
007045DE        cmp         eax,dword ptr [ebp-10]
007045E1>       jl          007045E7
007045E3        mov         al,1
007045E5>       jmp         007045F8
007045E7        mov         eax,dword ptr [ebp-8]
007045EA        test        eax,eax
007045EC>       je          007045F3
007045EE        sub         eax,4
007045F1        mov         eax,dword ptr [eax]
007045F3        test        eax,eax
007045F5        sete        al
007045F8        test        al,al
007045FA>       je          00704560
00704600        call        006DB734
00704605        test        al,al
00704607>       je          0070461A
00704609        call        006D91CC
0070460E        mov         dword ptr [ebx+110],eax;TBootloader.FEndTime:Int64
00704614        mov         dword ptr [ebx+114],edx;TBootloader.?f114:Pointer
# 3.继续
0070461A        mov         eax,dword ptr [esi]
0070461C        test        eax,eax
0070461E>       je          00704625
00704620        sub         eax,4
00704623        mov         eax,dword ptr [eax]
00704625        dec         eax
00704626        mov         edx,dword ptr [esi]
# 这里eax是最后一个字符 也就是 30 ack
00704628        movzx       eax,byte ptr [edx+eax]
0070462C        mov         byte ptr [ebx+0A1],al;TBootloader.FLastACK:byte
# 这里就是判定是否接收到了ack,因为是30,不同,所以跳转了
00704632        cmp         byte ptr [ebx+0A0],0;TBootloader.FbrOK:byte
# 4.跳转
00704639>       jne         00704656
0070463B        movzx       eax,byte ptr [ebx+0A1];TBootloader.FLastACK:byte
00704642        cmp         al,30
00704644>       jb          00704681
00704646        cmp         al,3F
00704648>       ja          00704681
0070464A        mov         byte ptr [ebx+0A0],al;TBootloader.FbrOK:byte
00704650        mov         byte ptr [ebp-11],1
00704654>       jmp         00704681
# 4.继续
00704656        movzx       eax,byte ptr [ebx+0A1];TBootloader.FLastACK:byte
# 这里就发现实际上是OK,和30相等,所以继续
0070465D        cmp         al,byte ptr [ebx+0A0];TBootloader.FbrOK:byte
00704663>       jne         0070466B
00704665        mov         byte ptr [ebp-11],1
# 这里小跳了一下
00704669>       jmp         00704681
0070466B        cmp         byte ptr [ebx+0A1],0C1;TBootloader.FLastACK:byte
00704672>       jne         00704681
00704674        cmp         byte ptr [ebx+0B4],0FD;TBootloader.FLastCMD:byte
0070467B>       jne         00704681
0070467D        mov         byte ptr [ebp-11],1
# 这里继续
00704681        mov         edx,dword ptr [esi]
00704683        mov         eax,edx
00704685        test        eax,eax
00704687>       je          0070468E
00704689        sub         eax,4
0070468C        mov         eax,dword ptr [eax]
0070468E        cmp         eax,3
00704691>       jle         00704889
# 这里又比较了一下ack 不相等,所以继续
00704697        cmp         byte ptr [ebx+0B4],0B;TBootloader.FLastCMD:byte
0070469E>       je          0070478D
007046A4        mov         byte ptr [ebp-17],1
007046A8        mov         edi,edx
007046AA        test        edi,edi
007046AC>       je          007046B3
007046AE        sub         edi,4
007046B1        mov         edi,dword ptr [edi]
007046B3        mov         dword ptr [ebp-1C],edx
007046B6        cmp         dword ptr [ebp-1C],0
007046BA>       je          007046C7
007046BC        mov         eax,dword ptr [ebp-1C]
007046BF        sub         eax,4
007046C2        mov         eax,dword ptr [eax]
007046C4        mov         dword ptr [ebp-1C],eax
007046C7        dec         edi
007046C8        mov         eax,dword ptr [esi]
007046CA        movzx       eax,byte ptr [eax+edi-2]
007046CF        mov         byte ptr [ebp-48],al
007046D2        mov         eax,dword ptr [ebp-1C]
007046D5        dec         eax
007046D6        mov         edx,dword ptr [esi]
007046D8        movzx       eax,byte ptr [edx+eax-1]
007046DD        mov         byte ptr [ebp-47],al
007046E0        lea         eax,[ebp-48]
007046E3        lea         ecx,[ebp-4]
007046E6        mov         edx,1
007046EB        call        006D59C4
007046F0        mov         eax,dword ptr [esi]
007046F2        test        eax,eax
007046F4>       je          007046FB
007046F6        sub         eax,4
007046F9        mov         eax,dword ptr [eax]
007046FB        mov         edx,dword ptr [esi]
007046FD        mov         dword ptr [ebp-20],edx
00704700        cmp         dword ptr [ebp-20],0
00704704>       je          00704711
00704706        mov         edx,dword ptr [ebp-20]
00704709        sub         edx,4
0070470C        mov         edx,dword ptr [edx]
0070470E        mov         dword ptr [ebp-20],edx
00704711        dec         eax
00704712        mov         edx,dword ptr [esi]
00704714        movzx       eax,byte ptr [edx+eax-1]
00704719        shl         eax,8
0070471C        mov         edx,dword ptr [ebp-20]
0070471F        dec         edx
00704720        mov         ecx,dword ptr [esi]
00704722        movzx       edx,byte ptr [ecx+edx-2]
00704727        add         ax,dx
# 上面搞了半天就是把最后2个校验的值,拼到了一起,变成了一个16bits的数据
0070472A        mov         word ptr [ebp-16],ax
0070472E        mov         edi,dword ptr [esi]
00704730        test        edi,edi
00704732>       je          00704739
00704734        sub         edi,4
00704737        mov         edi,dword ptr [edi]
00704739        sub         edi,3
0070473C        push        edi
0070473D        mov         eax,esi
0070473F        mov         ecx,1
00704744        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
0070474A        call        @DynArraySetLength
0070474F        add         esp,4
00704752        mov         edx,dword ptr [esi]
00704754        mov         eax,ebx
# 操作这么一通就是为了计算crc,不过至少这里追到了串口buff,后面就好找了。
00704756        call        TBootloader.StringCrc
0070475B        mov         word ptr [ebx+0BE],ax;TBootloader.LastInCRC:word
00704762        movzx       eax,word ptr [ebx+0BE];TBootloader.LastInCRC:word
00704769        cmp         ax,word ptr [ebp-16]
# 这里是crc校验通过了,所以跳走了
# 5.跳转
0070476D>       je          0070478D
0070476F        mov         byte ptr [ebp-11],0
00704773        mov         byte ptr [ebx+0A1],0CA;TBootloader.FLastACK:byte
0070477A        call        006DB734
0070477F        test        al,al
00704781>       je          0070478D
00704783        mov         eax,704BA0;'Wrong CRC of received String'
00704788        call        006DBFB4
# 5.继续
0070478D        call        006DB734
00704792        test        al,al
00704794>       je          00704A51
0070479A        lea         ecx,[ebp-4C]
0070479D        mov         eax,dword ptr [esi]
0070479F        mov         edx,dword ptr [ebp-4]
007047A2        call        006D5954
007047A7        mov         eax,dword ptr [ebp-4C]
007047AA        push        eax
007047AB        mov         eax,ebx
007047AD        call        TBootloader.AllowLog
007047B2        mov         edx,eax
007047B4        mov         ecx,800
# 这里就是恢复了串口buff 
007047B9        pop         eax
007047BA        call        006DC174
007047BF        cmp         byte ptr [ebp-17],0
007047C3>       je          007047D9
007047C5        push        1
007047C7        movzx       ecx,word ptr [ebx+0BE];TBootloader.LastInCRC:word
007047CE        movzx       edx,word ptr [ebp-16]
007047D2        mov         eax,ebx
007047D4        call        00706584
007047D9        lea         eax,[ebp-0C]
007047DC        push        eax
007047DD        movzx       edx,byte ptr [ebx+0A1];TBootloader.FLastACK:byte
007047E4        xor         ecx,ecx
007047E6        mov         eax,ebx
007047E8        call        00705B90
007047ED        mov         eax,704BE8;'ACK: '
007047F2        call        006DC090
007047F7        mov         eax,dword ptr [ebp-0C]
007047FA        call        006DC0A4
007047FF        mov         eax,704C00;'Time elapsed (ms): '
00704804        call        006DBFA0
00704809        mov         eax,dword ptr [ebx+110];TBootloader.FEndTime:Int64
0070480F        mov         edx,dword ptr [ebx+114];TBootloader.?f114:Pointer
00704815        sub         eax,dword ptr [ebx+108]
0070481B        sbb         edx,dword ptr [ebx+10C]
00704821        push        edx
00704822        push        eax
00704823        lea         eax,[ebp-50]
# 这里基本上都是在做log相关的内容,把数据转string 显示出来
00704826        call        IntToStr
0070482B        mov         eax,dword ptr [ebp-50]
0070482E        call        006DC004
00704833        mov         eax,1
00704838        call        006DBF64
0070483D        mov         esi,dword ptr [esi]
0070483F        test        esi,esi
00704841>       je          00704848
00704843        sub         esi,4
00704846        mov         esi,dword ptr [esi]
00704848        lea         edx,[ebp-54]
0070484B        mov         eax,esi
0070484D        call        IntToStr
00704852        mov         eax,dword ptr [ebp-54]
00704855        or          ecx,0FFFFFFFF
00704858        mov         edx,0FF
0070485D        call        006DBD18
00704862        or          ecx,0FFFFFFFF
00704865        mov         edx,0FF0000
0070486A        mov         eax,704C34;' Bytes '
0070486F        call        006DBD18
00704874        or          ecx,0FFFFFFFF
00704877        mov         edx,0FF00FF
0070487C        mov         eax,dword ptr [ebp-0C]
0070487F        call        006DBD18
# 6.跳转
00704884>       jmp         00704A51
00704889        mov         eax,edx
0070488B        test        eax,eax
0070488D>       je          00704894
0070488F        sub         eax,4
00704892        mov         eax,dword ptr [eax]
00704894        dec         eax
00704895>       jle         007048C0
00704897        mov         byte ptr [ebp-11],0
0070489B        call        006DB734
007048A0        test        al,al
007048A2>       je          007048AE
007048A4        mov         eax,704C50;'Wrong Size of received String'
007048A9        call        006DBFB4
007048AE        mov         eax,esi
007048B0        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
007048B6        call        @DynArrayClear
007048BB>       jmp         00704A51
007048C0        mov         eax,edx
007048C2        test        eax,eax
007048C4>       je          007048CB
007048C6        sub         eax,4
007048C9        mov         eax,dword ptr [eax]
007048CB        dec         eax
007048CC>       jne         0070499F
007048D2        call        006DB734
007048D7        test        al,al
007048D9>       je          00704A51
007048DF        mov         eax,[0084158C];^gvar_0085C668
007048E4        cmp         dword ptr [eax],4
007048E7>       jge         007048FF
007048E9        cmp         byte ptr [ebx+0A1],0C1;TBootloader.FLastACK:byte
007048F0>       jne         007048FF
007048F2        cmp         byte ptr [ebx+0B4],0FD;TBootloader.FLastCMD:byte
007048F9>       je          00704A51
007048FF        mov         eax,ebx
00704901        call        TBootloader.AllowLog
00704906        mov         edx,eax
00704908        mov         eax,dword ptr [esi]
0070490A        mov         ecx,800
0070490F        call        006DC174
00704914        lea         eax,[ebp-0C]
00704917        push        eax
00704918        movzx       edx,byte ptr [ebx+0A1];TBootloader.FLastACK:byte
0070491F        xor         ecx,ecx
00704921        mov         eax,ebx
00704923        call        00705B90
00704928        mov         eax,704BE8;'ACK: '
0070492D        call        006DC090
00704932        mov         eax,dword ptr [ebp-0C]
00704935        call        006DC0A4
0070493A        mov         eax,704C00;'Time elapsed (ms): '
0070493F        call        006DBFA0
00704944        mov         eax,dword ptr [ebx+110];TBootloader.FEndTime:Int64
0070494A        mov         edx,dword ptr [ebx+114];TBootloader.?f114:Pointer
00704950        sub         eax,dword ptr [ebx+108]
00704956        sbb         edx,dword ptr [ebx+10C]
0070495C        push        edx
0070495D        push        eax
0070495E        lea         eax,[ebp-58]
00704961        call        IntToStr
00704966        mov         eax,dword ptr [ebp-58]
00704969        call        006DC004
0070496E        mov         eax,1
00704973        call        006DBF64
00704978        or          ecx,0FFFFFFFF
0070497B        mov         edx,80
00704980        mov         eax,704C98;' ACK: '
00704985        call        006DBD18
0070498A        or          ecx,0FFFFFFFF
0070498D        mov         edx,0FF00FF
00704992        mov         eax,dword ptr [ebp-0C]
00704995        call        006DBD18
0070499A>       jmp         00704A51
0070499F        mov         dword ptr [ebp-24],edx
007049A2        cmp         dword ptr [ebp-24],0
007049A6>       je          007049B3
007049A8        mov         eax,dword ptr [ebp-24]
007049AB        sub         eax,4
007049AE        mov         eax,dword ptr [eax]
007049B0        mov         dword ptr [ebp-24],eax
007049B3        cmp         dword ptr [ebp-24],0
007049B7>       jne         00704A51
007049BD        call        006DB734
007049C2        test        al,al
007049C4>       je          00704A51
007049CA        mov         eax,[0084158C];^gvar_0085C668
007049CF        cmp         dword ptr [eax],3
007049D2>       jge         007049DD
007049D4        cmp         byte ptr [ebx+0B4],0B;TBootloader.FLastCMD:byte
007049DB>       je          00704A51
007049DD        mov         eax,704C00;'Time elapsed (ms): '
007049E2        call        006DBFA0
007049E7        mov         eax,dword ptr [ebx+110];TBootloader.FEndTime:Int64
007049ED        mov         edx,dword ptr [ebx+114];TBootloader.?f114:Pointer
007049F3        sub         eax,dword ptr [ebx+108]
007049F9        sbb         edx,dword ptr [ebx+10C]
007049FF        push        edx
00704A00        push        eax
00704A01        lea         eax,[ebp-5C]
00704A04        call        IntToStr
00704A09        mov         eax,dword ptr [ebp-5C]
00704A0C        call        006DC004
00704A11        mov         eax,1
00704A16        call        006DBF64
00704A1B        lea         eax,[ebp-0C]
00704A1E        push        eax
00704A1F        movzx       edx,byte ptr [ebx+0A1];TBootloader.FLastACK:byte
00704A26        xor         ecx,ecx
00704A28        mov         eax,ebx
00704A2A        call        00705B90
00704A2F        or          ecx,0FFFFFFFF
00704A32        mov         edx,80
00704A37        mov         eax,704C98;' ACK: '
00704A3C        call        006DBD18
00704A41        or          ecx,0FFFFFFFF
00704A44        mov         edx,0FF00FF
00704A49        mov         eax,dword ptr [ebp-0C]
00704A4C        call        006DBD18
# 6.继续
00704A51        call        006DB734
00704A56        and         al,byte ptr [ebp+8]
00704A59>       je          00704A65
00704A5B        mov         eax,1
00704A60        call        006DBF64
00704A65        cmp         byte ptr [ebx+0B4],0FD;TBootloader.FLastCMD:byte
00704A6C>       je          00704A75
00704A6E        mov         eax,ebx
00704A70        call        00704154
00704A75        mov         eax,ebx
00704A77        call        TBootloader.GetReadTimeOut
00704A7C        movzx       esi,word ptr [ebp-14]
00704A80        cmp         eax,esi
00704A82>       je          00704A8D
00704A84        mov         edx,esi
00704A86        mov         eax,ebx
00704A88        call        TBootloader.SetReadTimeOut
00704A8D        xor         eax,eax
00704A8F        pop         edx
00704A90        pop         ecx
00704A91        pop         ecx
00704A92        mov         dword ptr fs:[eax],edx
00704A95        push        704B00
00704A9A        lea         eax,[ebp-5C]
00704A9D        mov         edx,4
00704AA2        call        @UStrArrayClr
00704AA7        lea         eax,[ebp-4C]
00704AAA        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
00704AB0        call        @DynArrayClear
00704AB5        lea         eax,[ebp-44]
00704AB8        mov         edx,2
00704ABD        call        @UStrArrayClr
00704AC2        lea         eax,[ebp-3C]
00704AC5        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
00704ACB        mov         ecx,5
00704AD0        call        @FinalizeArray
00704AD5        lea         eax,[ebp-28]
00704AD8        call        @UStrClr
00704ADD        lea         eax,[ebp-0C]
00704AE0        call        @UStrClr
00704AE5        lea         eax,[ebp-8]
00704AE8        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
00704AEE        mov         ecx,2
00704AF3        call        @FinalizeArray
00704AF8        ret
00704AF9>       jmp         @HandleFinally
00704AFE>       jmp         00704A9A
00704B00        movzx       eax,byte ptr [ebp-11]
00704B04        pop         edi
00704B05        pop         esi
00704B06        pop         ebx
00704B07        mov         esp,ebp
00704B09        pop         ebp
00704B0A        ret         4

ReadFlash

这里结束了以后又回到了TBootloader.ReadFlash

_Unit108.TBootloader.ReadFlash
...
# 设置地址
00702CEB        call        TBootloader.SendCMDSetAddress
00702CF0        test        al,al
00702CF2>       je          00702D8A
00702CF8        mov         edx,ebx
00702CFA        mov         eax,dword ptr [ebp-8]
# 开始读
00702CFD        call        TBootloader.SendCMDFlashRead
00702D02        test        al,al
00702D04>       je          00702D8A
00702D0A        push        1
00702D0C        lea         ecx,[edi+3]
00702D0F        lea         edx,[ebp-4]
00702D12        mov         eax,dword ptr [ebp-8]
# 检测是否有ack,这里之前漏掉了,实际上这里非常重要
00702D15        call        TBootloader.CheckStrACK
00702D1A        test        al,al
00702D1C>       je          00702D8A
00702D1E        inc         dword ptr [ebp-0C]
00702D21        call        006DB734
00702D26        test        al,al
00702D28>       je          00702DA6
00702D2A        mov         eax,dword ptr [ebp-4]
00702D2D        mov         dword ptr [ebp-1C],eax
00702D30        cmp         dword ptr [ebp-1C],0
00702D34>       je          00702D41
00702D36        mov         eax,dword ptr [ebp-1C]
00702D39        sub         eax,4
00702D3C        mov         eax,dword ptr [eax]
00702D3E        mov         dword ptr [ebp-1C],eax
# 应该是log 显示读了多少字节内容
00702D41        push        702EFC;'('
00702D46        lea         edx,[ebp-28]
00702D49        mov         eax,dword ptr [ebp-1C]
00702D4C        call        IntToStr
00702D51        push        dword ptr [ebp-28]
00702D54        push        702F0C;' Bytes)'
00702D59        lea         eax,[ebp-24]
00702D5C        mov         edx,3
00702D61        call        @UStrCatN
00702D66        mov         eax,dword ptr [ebp-24]
00702D69        or          ecx,0FFFFFFFF
00702D6C        mov         edx,0FF0000
00702D71        call        006DBD18
00702D76        or          ecx,0FFFFFFFF
00702D79        mov         edx,8000
# 依然是log显示ok
00702D7E        mov         eax,702F28;'OK'
00702D83        call        006DBD18
# 1.这里跳转
00702D88>       jmp         00702DA6
00702D8A        inc         esi
00702D8B        call        006DB734
00702D90        test        al,al
00702D92>       je          00702DA6
00702D94        or          ecx,0FFFFFFFF
00702D97        mov         edx,0FF
00702D9C        mov         eax,702F3C;'FAILED'
00702DA1        call        006DBD18
# 1.这里继续
00702DA6        cmp         dword ptr [ebp-0C],0
00702DAA>       jg          00702DB5
00702DAC        cmp         esi,3
00702DAF>       jle         00702CE4
00702DB5        cmp         dword ptr [ebp-0C],0
00702DB9>       jle         00702DEA
00702DBB        lea         ecx,[ebp-2C]
00702DBE        mov         eax,dword ptr [ebp+8]
00702DC1        mov         eax,dword ptr [eax]
00702DC3        mov         edx,dword ptr [ebp-4]
00702DC6        call        006D5954
00702DCB        mov         edx,dword ptr [ebp-2C]
00702DCE        mov         eax,dword ptr [ebp+8]
00702DD1        mov         ecx,dword ptr ds:[404B48];TArray<System.Byte>
# 这里好像在动态申请内存?想把串口buff内容拿走?
00702DD7        call        @DynArrayAsg
# 这里结束以后 就让0x19F1F0中存储的就是串口buff的地址了
00702DDC        add         word ptr [ebp-18],di
00702DE0        sub         dword ptr [ebp-10],edi
00702DE3        mov         eax,edi
00702DE5        call        006F50FC
00702DEA        cmp         dword ptr [ebp-10],0
00702DEE>       je          00702DFA
00702DF0        cmp         dword ptr [ebp-0C],1
00702DF4>       jge         00702CC4
00702DFA        xor         eax,eax
00702DFC        pop         edx
00702DFD        pop         ecx
00702DFE        pop         ecx
00702DFF        mov         dword ptr fs:[eax],edx
00702E02        push        702E69
00702E07        movzx       eax,byte ptr [ebp-15]
00702E0B        call        006F5204
00702E10        cmp         dword ptr [ebp-10],0
00702E14>       jne         00702E1C
00702E16        cmp         dword ptr [ebp-0C],1
# 2.这里跳转
00702E1A>       jge         00702E59
00702E1C        lea         eax,[ebp-30]
00702E1F        push        eax
00702E20        lea         eax,[ebp-3C]
00702E23        push        eax
00702E24        mov         eax,dword ptr [ebp-8]
00702E27        movzx       edx,byte ptr [eax+0A1];TBootloader.FLastACK:byte
00702E2E        mov         cl,1
00702E30        mov         eax,dword ptr [ebp-8]
00702E33        call        00705B90
00702E38        mov         eax,dword ptr [ebp-3C]
00702E3B        mov         dword ptr [ebp-38],eax
00702E3E        mov         byte ptr [ebp-34],11
00702E42        lea         edx,[ebp-38]
00702E45        xor         ecx,ecx
00702E47        mov         eax,702F58;'Error reading from Flash!\n(%s)'
00702E4C        call        006D5800
00702E51        mov         eax,dword ptr [ebp-30]
00702E54        call        006DF680
# 2.这里继续
00702E59        mov         eax,dword ptr [ebp-8]
00702E5C        call        00704114
00702E61        ret
00702E62>       jmp         @HandleFinally
00702E67>       jmp         00702E07
00702E69        xor         eax,eax
00702E6B        pop         edx
00702E6C        pop         ecx
00702E6D        pop         ecx
00702E6E        mov         dword ptr fs:[eax],edx
00702E71        push        702EB7
00702E76        lea         eax,[ebp-3C]
00702E79        call        @UStrClr
00702E7E        lea         eax,[ebp-30]
00702E81        call        @UStrClr
00702E86        lea         eax,[ebp-2C]
00702E89        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
00702E8F        call        @DynArrayClear
00702E94        lea         eax,[ebp-28]
00702E97        mov         edx,3
00702E9C        call        @UStrArrayClr
00702EA1        lea         eax,[ebp-4]
00702EA4        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
00702EAA        call        @DynArrayClear
00702EAF        ret
00702EB0>       jmp         @HandleFinally
00702EB5>       jmp         00702E76
00702EB7        pop         edi
00702EB8        pop         esi
00702EB9        pop         ebx
00702EBA        mov         esp,ebp
00702EBC        pop         ebp
00702EBD        ret         4

Send_cmd_DeviceReadFlash

继续返回就回到了 Send_cmd_DeviceReadFlash

_Unit108.TBLBInterface.Send_cmd_DeviceReadFlash
...
0070822F        lea         eax,[ebp-10]
00708232        push        eax
00708233        mov         eax,dword ptr [ebp-4]
00708236        mov         eax,dword ptr [eax+40];TBLBInterface.FBootloader:TBootloader
00708239        mov         ecx,ebx
0070823B        mov         edx,esi
# 主要是这里读flash
0070823D        call        TBootloader.ReadFlash
# 这里基本就能看出来,前面动态申请的内存在这里又放出来了
00708242        mov         edx,dword ptr [ebp-10]
00708245        mov         eax,dword ptr [ebp-8]
00708248        mov         ecx,dword ptr ds:[404B48];TArray<System.Byte>
0070824E        call        @DynArrayAsg
00708253        mov         eax,dword ptr [ebp-4]
00708256        call        00709C6C
0070825B        mov         eax,dword ptr [ebp-8]
0070825E        mov         eax,dword ptr [eax]
00708260        test        eax,eax
00708262>       je          00708269
00708264        sub         eax,4
00708267        mov         eax,dword ptr [eax]
# 不过到这里的时候,串口buff中尾巴上的ack还有crc都被去掉了,所以数据头也变成了100而不是103了
# 这应该就是后面处理的256字节数据了
00708269        movzx       edx,bx
0070826C        cmp         eax,edx
0070826E        sete        byte ptr [ebp-9]
00708272        xor         eax,eax
00708274        pop         edx
00708275        pop         ecx
00708276        pop         ecx
00708277        mov         dword ptr fs:[eax],edx
0070827A        push        70835A
0070827F        call        006DB734
00708284        test        al,al
00708286>       je          0070833A
0070828C        mov         eax,[0084158C];^gvar_0085C668
00708291        cmp         dword ptr [eax],1
00708294>       jle         007082E5
00708296        mov         eax,dword ptr [ebp-4]
00708299        mov         eax,dword ptr [eax+40];TBLBInterface.FBootloader:TBootloader
0070829C        call        TBootloader.AllowLog
007082A1        test        al,al
# 1.这里跳转
007082A3>       je          007082E5
...
# 1.这里继续
007082E5        mov         eax,1
007082EA        call        006DBF64
007082EF        mov         ebx,dword ptr [ebp-8]
007082F2        mov         ebx,dword ptr [ebx]
007082F4        test        ebx,ebx
007082F6>       je          007082FD
007082F8        sub         ebx,4
007082FB        mov         ebx,dword ptr [ebx]
007082FD        push        7083EC;'('
00708302        lea         edx,[ebp-20]
00708305        mov         eax,ebx
00708307        call        IntToStr
0070830C        push        dword ptr [ebp-20]
0070830F        push        7083FC;' Bytes)'
00708314        lea         eax,[ebp-1C]
00708317        mov         edx,3
0070831C        call        @UStrCatN
00708321        mov         eax,dword ptr [ebp-1C]
00708324        or          ecx,0FFFFFFFF
00708327        mov         edx,0FF0000
0070832C        call        006DBD18
00708331        movzx       eax,byte ptr [ebp-9]
00708335        call        006DBE1C
0070833A        ret
0070833B>       jmp         @HandleFinally
00708340>       jmp         0070827F
00708345        lea         edx,[ebp-24]
00708348        mov         eax,708418;'Bootloader version does not support reading of flash memory!'
0070834D        call        006D5894
00708352        mov         eax,dword ptr [ebp-24]
00708355        call        006DF5E4
0070835A        xor         eax,eax
0070835C        pop         edx
0070835D        pop         ecx
0070835E        pop         ecx
0070835F        mov         dword ptr fs:[eax],edx
00708362        push        70838A
00708367        lea         eax,[ebp-24]
0070836A        mov         edx,5
0070836F        call        @UStrArrayClr
00708374        lea         eax,[ebp-10]
00708377        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
0070837D        call        @DynArrayClear
00708382        ret
00708383>       jmp         @HandleFinally
00708388>       jmp         00708367
0070838A        movzx       eax,byte ptr [ebp-9]
0070838E        pop         esi
0070838F        pop         ebx
00708390        mov         esp,ebp
00708392        pop         ebp
00708393        ret         4

后面就是一连串的返回,又回到了ReadDeviceSetupSection

ReadDeviceSetupSection

007D8611        call        TBLBInterface.Send_cmd_DeviceReadBLHeliSetupSection
# OD调试,发现当Send_cmd_DeviceReadBLHeliSetupSection执行完成以后,256字节就读取上来了,所以要追他
007D8616        mov         byte ptr [ebp-9],al
007D8619>       jmp         007D8632
...
007D8632        cmp         byte ptr [ebp-9],0
007D8636>       je          007D878B
007D863C        mov         eax,dword ptr [ebp-8]
007D863F        call        TBLHeliInterfaceManager.DeviceBootloaderRev
007D8644        push        eax
007D8645        mov         eax,dword ptr [ebp-8]
007D8648        call        TBLHeliInterfaceManager.BLHeliStored
007D864D        pop         edx
007D864E        mov         byte ptr [eax+0D3],dl;TBLHeli.FBootloaderRev:byte
007D8654        mov         eax,dword ptr [ebp-8]
007D8657        call        TBLHeliInterfaceManager.BLHeliStored
007D865C        mov         edx,dword ptr [ebp-8]
007D865F        mov         edx,dword ptr [edx+32C];TBLHeliInterfaceManager.FLastReadSetupMem:TArray<System.Byte>
007D8665        mov         ecx,ebx
# 前面edx已经存储了串口buff的地址,然后这里就带着这个地址进入到了 ReadSetupFromBinString
007D8667        call        TBLHeli.ReadSetupFromBinString
...

ReadSetupFromBinString

_Unit102.TBLHeli.ReadSetupFromBinString
006EA350        push        ebp
006EA351        mov         ebp,esp
006EA353        push        ecx
006EA354        mov         ecx,0A
006EA359        push        0
006EA35B        push        0
006EA35D        dec         ecx
006EA35E>       jne         006EA359
006EA360        push        ecx
006EA361        xchg        ecx,dword ptr [ebp-4]
006EA364        push        ebx
006EA365        push        esi
006EA366        push        edi
006EA367        mov         byte ptr [ebp-0D],cl
006EA36A        mov         ebx,edx
006EA36C        mov         dword ptr [ebp-8],eax
006EA36F        xor         eax,eax
006EA371        push        ebp
006EA372        push        6EA99F
006EA377        push        dword ptr fs:[eax]
006EA37A        mov         dword ptr fs:[eax],esp
# 这里的 eax = 289d380 [289d380] = 6e2bbc
006EA37D        mov         eax,dword ptr [ebp-8]

看起来是个程序地址,我跳过去看了一下

image-20210717111029804

这里倒是没什么,但是再往下,可以看到这里的名字基本上全都是对应的参数值!

image-20210717111042758


# TBLHeli中就是存储配置的对象,这里进行了初始化
006EA380        call        TBLHeli.Init
006EA385        mov         byte ptr [ebp-0E],4
006EA389        xor         ecx,ecx
006EA38B        push        ebp
006EA38C        push        6EA952
006EA391        push        dword ptr fs:[ecx]
006EA394        mov         dword ptr fs:[ecx],esp
006EA397        mov         edx,ebx
006EA399        mov         eax,edx
006EA39B        test        eax,eax
006EA39D>       je          006EA3A4
006EA39F        sub         eax,4
006EA3A2        mov         eax,dword ptr [eax]
006EA3A4        mov         dword ptr [ebp-0C],eax
# 这里是在比 串口数据长度,如果是F800 就是往下走
# 这里是100,所以跳转了
006EA3A7        cmp         dword ptr [ebp-0C],0F800
# 0.跳转
006EA3AE>       jle         006EA3DF
...
# 0.继续 这里继续不相等,继续跳转
006EA3DF        cmp         dword ptr [ebp-0C],7C00
# 跳转
006EA3E6>       jle         006EA417
...
# 继续
006EA417        mov         eax,dword ptr [ebp-0C]
006EA41A        push        eax
006EA41B        lea         eax,[ebp-4]
006EA41E        push        eax
006EA41F        xor         ecx,ecx
006EA421        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006EA427        mov         eax,ebx
006EA429        call        @DynArrayCopyRange
006EA42E        cmp         dword ptr [ebp-0C],90
# 跳转
006EA435>       jge         006EA445
...
# 继续
006EA445        mov         edx,dword ptr ds:[841290];^gvar_00839100
006EA44B        movzx       edx,byte ptr [edx]
006EA44E        mov         eax,dword ptr [ebp-4]
# 这个函数不知道是干啥的,先放着
006EA451        call        006D5CE4
006EA456        test        al,al
# 跳转
006EA458>       je          006EA468
...
# 继续
006EA468        push        ebp
# 关键点
006EA469        call        006EA090

这个没名字函数开始跳过了,然后往下走的时候发现TESC_Layout的值就直接有了,都直接存在内存里了,大概就在串口buff地址上面的0xA0个地址左右,但是却没看到解析过程,这个地址每次都不会清,导致你就算再读一次,这个地址东西还是在,所以每次重启以后,重新找这个地址,然后就能看到了。

上面的是解析内容,下面的是串口raw值,总算找到了解析的地方

image-20210717115950567

解析函数sub_006EA090

看一下这里是怎么解析的

_Unit102.sub_006EA090
006EA090        push        ebp
006EA091        mov         ebp,esp
006EA093        push        0
006EA095        push        ebx
006EA096        xor         eax,eax
006EA098        push        ebp
006EA099        push        6EA340
006EA09E        push        dword ptr fs:[eax]
006EA0A1        mov         dword ptr fs:[eax],esp
006EA0A4        mov         eax,dword ptr [ebp+8]
006EA0A7        mov         eax,dword ptr [eax-8]
006EA0AA        mov         byte ptr [eax+0B8],0
006EA0B1        mov         eax,dword ptr [ebp+8]
006EA0B4        mov         eax,dword ptr [eax-4]
006EA0B7        lea         edx,[eax+60]
006EA0BA        mov         eax,dword ptr [ebp+8]
006EA0BD        mov         eax,dword ptr [eax-8]
# 这里先跳过,不知道是干嘛
006EA0C0        call        TBLHeli.ReadMCU
ReadMCU
_Unit102.TBLHeli.ReadMCU
006E9BF4        push        ebp
006E9BF5        mov         ebp,esp
006E9BF7        add         esp,0FFFFFFB4
006E9BFA        push        esi
006E9BFB        push        edi
006E9BFC        xor         ecx,ecx
# 这里就是清空内容
006E9BFE        mov         dword ptr [ebp-4],ecx
006E9C01        mov         dword ptr [ebp-8],ecx
006E9C04        mov         dword ptr [ebp-0C],ecx
006E9C07        mov         dword ptr [ebp-10],ecx
006E9C0A        mov         dword ptr [ebp-14],ecx
006E9C0D        mov         dword ptr [ebp-18],ecx
006E9C10        mov         dword ptr [ebp-1C],ecx
006E9C13        mov         dword ptr [ebp-20],ecx
# 这里esi=buff[96]
006E9C16        mov         esi,edx
006E9C18        lea         edi,[ebp-4C]
006E9C1B        mov         ecx,8
# 这里就是在赋值,把buff内容移动到堆栈里,重复8次,符合上面的清空操作
# 具体为堆栈的19f120-19f13c中
006E9C20        rep movs    dword ptr [edi],dword ptr [esi]
006E9C22        mov         dword ptr [ebp-24],eax
006E9C25        xor         eax,eax
006E9C27        push        ebp
006E9C28        push        6EA07D
006E9C2D        push        dword ptr fs:[eax]
006E9C30        mov         dword ptr fs:[eax],esp
006E9C33        mov         byte ptr [ebp-25],4
006E9C37        mov         eax,dword ptr [ebp-24]
# 287d380 这里理论上是BLHeli的基址
# +50 就变成了ESC_MCU的变量位置
006E9C3A        add         eax,50;TBLHeli.FEep_ESC_MCU:TESC_MCU
006E9C3D        mov         ecx,0FF
006E9C42        mov         edx,20
# 这里就是用FF填充0x20个字节,说白了就是在给ESC_MUC的string初始化
006E9C47        call        @FillChar
006E9C4C        mov         eax,dword ptr [ebp-24]
006E9C4F        lea         edx,[eax+50];TBLHeli.FEep_ESC_MCU:TESC_MCU
006E9C52        lea         eax,[ebp-4C]
006E9C55        mov         ecx,20
# 这里就是把堆栈里刚才拿到的8个字节 又给放回到了ESC_MUC的位置上
006E9C5A        call        Move

这部分数据是直接平移过来的

image-20210717162449070


006E9C5F        push        20
006E9C61        lea         eax,[ebp-4]
006E9C64        mov         ecx,1
006E9C69        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006E9C6F        call        @DynArraySetLength
006E9C74        add         esp,4
006E9C77        lea         eax,[ebp-4C]
006E9C7A        mov         ecx,20
006E9C7F        mov         edx,dword ptr [ebp-4]
# 这里大概就是又申请了一个空间,然后把刚才的32个字节又传进去了
006E9C82        call        Move
006E9C87        mov         eax,dword ptr [ebp-24]
006E9C8A        xor         edx,edx
# 这里进行初始化 edx=0
006E9C8C        mov         dword ptr [eax+0B4],edx;TBLHeli.FMCU_DeviceID:Integer
006E9C92        mov         eax,dword ptr [ebp-24]
006E9C95        mov         byte ptr [eax+0D2],0;TBLHeli.FMCUManufacturer:TMCUManufacturer
006E9C9C        mov         eax,dword ptr [ebp-24]
006E9C9F        mov         byte ptr [eax+0D1],0;TBLHeli.FIs_64k:Boolean
006E9CA6        xor         edx,edx
006E9CA8        push        ebp
006E9CA9        push        6E9D00
006E9CAE        push        dword ptr fs:[edx]
006E9CB1        mov         dword ptr fs:[edx],esp
006E9CB4        xor         eax,eax
006E9CB6        mov         dword ptr [ebp-8],eax
006E9CB9        lea         edx,[ebp-8]
006E9CBC        mov         eax,[00839640];^'#BLHeli_32*'
006E9CC1        call        0043691C
006E9CC6        mov         eax,[00839640];^'#BLHeli_32*'
006E9CCB        test        eax,eax
006E9CCD>       je          006E9CD4
006E9CCF        sub         eax,4
006E9CD2        mov         eax,dword ptr [eax]
006E9CD4        mov         ecx,eax
006E9CD6        mov         edx,dword ptr [ebp-8]
006E9CD9        mov         eax,dword ptr [ebp-4]
006E9CDC        call        CompareMem
006E9CE1        mov         byte ptr [ebp-26],al
006E9CE4        xor         eax,eax
006E9CE6        pop         edx
006E9CE7        pop         ecx
006E9CE8        pop         ecx
006E9CE9        mov         dword ptr fs:[eax],edx
006E9CEC        push        6E9D07
006E9CF1        lea         eax,[ebp-8]
006E9CF4        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
# 这里是又把这个变量清空了
006E9CFA        call        @DynArrayClear
006E9CFF        ret
006E9D00>       jmp         @HandleFinally
006E9D05>       jmp         006E9CF1
# 这里判定相同了,所以跳转
006E9D07        cmp         byte ptr [ebp-26],0
# 跳转
006E9D0B>       je          006EA061
006E9D11        mov         byte ptr [ebp-25],3
006E9D15        mov         eax,[00839640];^'#BLHeli_32*'
006E9D1A        test        eax,eax
006E9D1C>       je          006E9D23
006E9D1E        sub         eax,4
006E9D21        mov         eax,dword ptr [eax]
006E9D23        lea         edx,[ebp-4]
006E9D26        mov         ecx,eax
006E9D28        xor         eax,eax
006E9D2A        xchg        eax,edx
006E9D2B        call        006D5A78
006E9D30        xor         edx,edx
006E9D32        push        ebp
006E9D33        push        6E9D8A
006E9D38        push        dword ptr fs:[edx]
006E9D3B        mov         dword ptr fs:[edx],esp
006E9D3E        xor         eax,eax
006E9D40        mov         dword ptr [ebp-0C],eax
006E9D43        lea         edx,[ebp-0C]
006E9D46        mov         eax,[00839644];^'STM32F051x6#'
006E9D4B        call        0043691C
006E9D50        mov         eax,[00839644];^'STM32F051x6#'
006E9D55        test        eax,eax
006E9D57>       je          006E9D5E
006E9D59        sub         eax,4
006E9D5C        mov         eax,dword ptr [eax]
006E9D5E        mov         ecx,eax
006E9D60        mov         edx,dword ptr [ebp-0C]
006E9D63        mov         eax,dword ptr [ebp-4]
006E9D66        call        CompareMem
006E9D6B        mov         byte ptr [ebp-27],al
006E9D6E        xor         eax,eax
006E9D70        pop         edx
006E9D71        pop         ecx
006E9D72        pop         ecx
006E9D73        mov         dword ptr fs:[eax],edx
006E9D76        push        6E9D91
006E9D7B        lea         eax,[ebp-0C]
006E9D7E        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006E9D84        call        @DynArrayClear
006E9D89        ret
006E9D8A>       jmp         @HandleFinally
006E9D8F>       jmp         006E9D7B
006E9D91        cmp         byte ptr [ebp-27],0
006E9D95>       je          006E9DB3
006E9D97        mov         eax,dword ptr [ebp-24]
006E9D9A        mov         dword ptr [eax+0B4],3306;TBLHeli.FMCU_DeviceID:Integer
006E9DA4        mov         eax,dword ptr [ebp-24]
006E9DA7        mov         byte ptr [eax+0D2],1;TBLHeli.FMCUManufacturer:TMCUManufacturer
006E9DAE>       jmp         006EA051
006E9DB3        xor         edx,edx
006E9DB5        push        ebp
006E9DB6        push        6E9E0D
006E9DBB        push        dword ptr fs:[edx]
006E9DBE        mov         dword ptr fs:[edx],esp
006E9DC1        xor         eax,eax
006E9DC3        mov         dword ptr [ebp-10],eax
006E9DC6        lea         edx,[ebp-10]
006E9DC9        mov         eax,[00839648];^'STM32F031x6#'
006E9DCE        call        0043691C
006E9DD3        mov         eax,[00839648];^'STM32F031x6#'
006E9DD8        test        eax,eax
006E9DDA>       je          006E9DE1
006E9DDC        sub         eax,4
006E9DDF        mov         eax,dword ptr [eax]
006E9DE1        mov         ecx,eax
006E9DE3        mov         edx,dword ptr [ebp-10]
006E9DE6        mov         eax,dword ptr [ebp-4]
006E9DE9        call        CompareMem
006E9DEE        mov         byte ptr [ebp-28],al
006E9DF1        xor         eax,eax
006E9DF3        pop         edx
006E9DF4        pop         ecx
006E9DF5        pop         ecx
006E9DF6        mov         dword ptr fs:[eax],edx
006E9DF9        push        6E9E14
006E9DFE        lea         eax,[ebp-10]
006E9E01        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006E9E07        call        @DynArrayClear
006E9E0C        ret
006E9E0D>       jmp         @HandleFinally
006E9E12>       jmp         006E9DFE
006E9E14        cmp         byte ptr [ebp-28],0
006E9E18>       je          006E9E36
006E9E1A        mov         eax,dword ptr [ebp-24]
006E9E1D        mov         dword ptr [eax+0B4],1F06;TBLHeli.FMCU_DeviceID:Integer
006E9E27        mov         eax,dword ptr [ebp-24]
006E9E2A        mov         byte ptr [eax+0D2],1;TBLHeli.FMCUManufacturer:TMCUManufacturer
006E9E31>       jmp         006EA051
006E9E36        xor         edx,edx
006E9E38        push        ebp
006E9E39        push        6E9E90
006E9E3E        push        dword ptr fs:[edx]
006E9E41        mov         dword ptr fs:[edx],esp
006E9E44        xor         eax,eax
006E9E46        mov         dword ptr [ebp-14],eax
006E9E49        lea         edx,[ebp-14]
006E9E4C        mov         eax,[00839650];^'GD32F150x6#'
006E9E51        call        0043691C
006E9E56        mov         eax,[00839650];^'GD32F150x6#'
006E9E5B        test        eax,eax
006E9E5D>       je          006E9E64
006E9E5F        sub         eax,4
006E9E62        mov         eax,dword ptr [eax]
006E9E64        mov         ecx,eax
006E9E66        mov         edx,dword ptr [ebp-14]
006E9E69        mov         eax,dword ptr [ebp-4]
006E9E6C        call        CompareMem
006E9E71        mov         byte ptr [ebp-29],al
006E9E74        xor         eax,eax
006E9E76        pop         edx
006E9E77        pop         ecx
006E9E78        pop         ecx
006E9E79        mov         dword ptr fs:[eax],edx
006E9E7C        push        6E9E97
006E9E81        lea         eax,[ebp-14]
006E9E84        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006E9E8A        call        @DynArrayClear
006E9E8F        ret
006E9E90>       jmp         @HandleFinally
006E9E95>       jmp         006E9E81
006E9E97        cmp         byte ptr [ebp-29],0
006E9E9B>       je          006E9EB9
006E9E9D        mov         eax,dword ptr [ebp-24]
006E9EA0        mov         dword ptr [eax+0B4],3406;TBLHeli.FMCU_DeviceID:Integer
006E9EAA        mov         eax,dword ptr [ebp-24]
006E9EAD        mov         byte ptr [eax+0D2],2;TBLHeli.FMCUManufacturer:TMCUManufacturer
006E9EB4>       jmp         006EA051
006E9EB9        xor         edx,edx
006E9EBB        push        ebp
006E9EBC        push        6E9F13
006E9EC1        push        dword ptr fs:[edx]
006E9EC4        mov         dword ptr fs:[edx],esp
006E9EC7        xor         eax,eax
006E9EC9        mov         dword ptr [ebp-18],eax
006E9ECC        lea         edx,[ebp-18]
006E9ECF        mov         eax,[00839654];^'GD32F350x6#'
006E9ED4        call        0043691C
006E9ED9        mov         eax,[00839654];^'GD32F350x6#'
006E9EDE        test        eax,eax
006E9EE0>       je          006E9EE7
006E9EE2        sub         eax,4
006E9EE5        mov         eax,dword ptr [eax]
006E9EE7        mov         ecx,eax
006E9EE9        mov         edx,dword ptr [ebp-18]
006E9EEC        mov         eax,dword ptr [ebp-4]
006E9EEF        call        CompareMem
006E9EF4        mov         byte ptr [ebp-2A],al
006E9EF7        xor         eax,eax
006E9EF9        pop         edx
006E9EFA        pop         ecx
006E9EFB        pop         ecx
006E9EFC        mov         dword ptr fs:[eax],edx
006E9EFF        push        6E9F1A
006E9F04        lea         eax,[ebp-18]
006E9F07        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006E9F0D        call        @DynArrayClear
006E9F12        ret
006E9F13>       jmp         @HandleFinally
006E9F18>       jmp         006E9F04
006E9F1A        cmp         byte ptr [ebp-2A],0
006E9F1E>       je          006E9F3C
006E9F20        mov         eax,dword ptr [ebp-24]
006E9F23        mov         dword ptr [eax+0B4],3506;TBLHeli.FMCU_DeviceID:Integer
006E9F2D        mov         eax,dword ptr [ebp-24]
006E9F30        mov         byte ptr [eax+0D2],2;TBLHeli.FMCUManufacturer:TMCUManufacturer
006E9F37>       jmp         006EA051
006E9F3C        xor         edx,edx
006E9F3E        push        ebp
006E9F3F        push        6E9F96
006E9F44        push        dword ptr fs:[edx]
006E9F47        mov         dword ptr fs:[edx],esp
006E9F4A        xor         eax,eax
006E9F4C        mov         dword ptr [ebp-1C],eax
006E9F4F        lea         edx,[ebp-1C]
006E9F52        mov         eax,[0083964C];^'STM32L431x6#'
006E9F57        call        0043691C
006E9F5C        mov         eax,[0083964C];^'STM32L431x6#'
006E9F61        test        eax,eax
006E9F63>       je          006E9F6A
006E9F65        sub         eax,4
006E9F68        mov         eax,dword ptr [eax]
006E9F6A        mov         ecx,eax
006E9F6C        mov         edx,dword ptr [ebp-1C]
006E9F6F        mov         eax,dword ptr [ebp-4]
006E9F72        call        CompareMem
006E9F77        mov         byte ptr [ebp-2B],al
006E9F7A        xor         eax,eax
006E9F7C        pop         edx
006E9F7D        pop         ecx
006E9F7E        pop         ecx
006E9F7F        mov         dword ptr fs:[eax],edx
006E9F82        push        6E9F9D
006E9F87        lea         eax,[ebp-1C]
006E9F8A        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006E9F90        call        @DynArrayClear
006E9F95        ret
006E9F96>       jmp         @HandleFinally
006E9F9B>       jmp         006E9F87
006E9F9D        cmp         byte ptr [ebp-2B],0
006E9FA1>       je          006E9FC9
006E9FA3        mov         eax,dword ptr [ebp-24]
006E9FA6        mov         dword ptr [eax+0B4],2B06;TBLHeli.FMCU_DeviceID:Integer
006E9FB0        mov         eax,dword ptr [ebp-24]
006E9FB3        mov         byte ptr [eax+0D2],1;TBLHeli.FMCUManufacturer:TMCUManufacturer
006E9FBA        mov         eax,dword ptr [ebp-24]
006E9FBD        mov         byte ptr [eax+0D1],1;TBLHeli.FIs_64k:Boolean
006E9FC4>       jmp         006EA051
006E9FC9        xor         edx,edx
006E9FCB        push        ebp
006E9FCC        push        6EA023
006E9FD1        push        dword ptr fs:[edx]
006E9FD4        mov         dword ptr fs:[edx],esp
006E9FD7        xor         eax,eax
006E9FD9        mov         dword ptr [ebp-20],eax
006E9FDC        lea         edx,[ebp-20]
006E9FDF        mov         eax,[00839658];^'STM32G071x6#'
006E9FE4        call        0043691C
006E9FE9        mov         eax,[00839658];^'STM32G071x6#'
006E9FEE        test        eax,eax
006E9FF0>       je          006E9FF7
006E9FF2        sub         eax,4
006E9FF5        mov         eax,dword ptr [eax]
006E9FF7        mov         ecx,eax
006E9FF9        mov         edx,dword ptr [ebp-20]
006E9FFC        mov         eax,dword ptr [ebp-4]
006E9FFF        call        CompareMem
006EA004        mov         byte ptr [ebp-2C],al
006EA007        xor         eax,eax
006EA009        pop         edx
006EA00A        pop         ecx
006EA00B        pop         ecx
006EA00C        mov         dword ptr fs:[eax],edx
006EA00F        push        6EA02A
006EA014        lea         eax,[ebp-20]
006EA017        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006EA01D        call        @DynArrayClear
006EA022        ret
006EA023>       jmp         @HandleFinally
006EA028>       jmp         006EA014
006EA02A        cmp         byte ptr [ebp-2C],0
006EA02E>       je          006EA051
006EA030        mov         eax,dword ptr [ebp-24]
006EA033        mov         dword ptr [eax+0B4],4706;TBLHeli.FMCU_DeviceID:Integer
006EA03D        mov         eax,dword ptr [ebp-24]
006EA040        mov         byte ptr [eax+0D2],1;TBLHeli.FMCUManufacturer:TMCUManufacturer
006EA047        mov         eax,dword ptr [ebp-24]
006EA04A        mov         byte ptr [eax+0D1],1;TBLHeli.FIs_64k:Boolean
006EA051        mov         eax,dword ptr [ebp-24]
006EA054        cmp         dword ptr [eax+0B4],0;TBLHeli.FMCU_DeviceID:Integer
006EA05B>       jle         006EA061
006EA05D        mov         byte ptr [ebp-25],0
# 继续
006EA061        xor         eax,eax
006EA063        pop         edx
006EA064        pop         ecx
006EA065        pop         ecx
006EA066        mov         dword ptr fs:[eax],edx
006EA069        push        6EA084
006EA06E        lea         eax,[ebp-4]
006EA071        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006EA077        call        @DynArrayClear
006EA07C        ret
006EA07D>       jmp         @HandleFinally
006EA082>       jmp         006EA06E
006EA084        movzx       eax,byte ptr [ebp-25]
006EA088        pop         edi
006EA089        pop         esi
006EA08A        mov         esp,ebp
006EA08C        pop         ebp
006EA08D        ret

这个ReadMCU,就这么没头没尾的结束了,也就赋值了一下,初始化了一下变量,然后没有任何判定就出去。

继续 sub_006EA090


006EA0C5        mov         ebx,eax
006EA0C7        cmp         bl,4
006EA0CA>       jne         006EA324
006EA0D0        mov         eax,dword ptr [ebp+8]
006EA0D3        cmp         dword ptr [eax-0C],0C0
006EA0DA>       jl          006EA324
006EA0E0        mov         eax,dword ptr [ebp+8]
006EA0E3        mov         eax,dword ptr [eax-0C]
006EA0E6        push        eax
006EA0E7        lea         eax,[ebp-4]
006EA0EA        push        eax
006EA0EB        mov         eax,dword ptr [ebp+8]
006EA0EE        mov         eax,dword ptr [eax-4]
006EA0F1        xor         ecx,ecx
006EA0F3        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006EA0F9        call        @DynArrayCopyRange
006EA0FE        push        0
# 这个是传入的变量 串口buff地址
006EA100        mov         eax,dword ptr [ebp+8]
006EA103        add         eax,0FFFFFFFC
006EA106        xor         ecx,ecx
# edx=0x407C00 应该是某个变量地址或者返回的变量地址 
006EA108        mov         dx,7C00
# 这里面是整个内存就解析完成了
# 这里eax传入的buff地址,edx应该是新申请的地址
006EA10C        call        006E1B48
006E1B48
_Unit102.sub_006E1B48
006E1B48        push        ebp
006E1B49        mov         ebp,esp
006E1B4B        add         esp,0FFFFFFCC
006E1B4E        push        ebx
006E1B4F        push        esi
006E1B50        push        edi
006E1B51        mov         ebx,ecx
006E1B53        mov         word ptr [ebp-6],dx
006E1B57        mov         dword ptr [ebp-4],eax
006E1B5A        movzx       edx,byte ptr [ebp+8]
006E1B5E        movzx       eax,word ptr [ebp-6]
006E1B62        call        006E1CF4
006E1B67        mov         byte ptr [ebp-19],al
006E1B6A        movzx       eax,byte ptr [ebp-19]
# od这里提示是switch case,al这里就是1,所以继续
006E1B6E        sub         al,1
006E1B70>       jb          006E1B7D
# 1.跳转
006E1B72>       je          006E1B89
...
# 1.继续 case 1
006E1B89        test        bl,bl
# 2.跳转
006E1B8B>       je          006E1BA1
...
# 2.继续
006E1BA1        lea         edx,[ebp-34]
006E1BA4        mov         eax,839620
006E1BA9        mov         ecx,10
# 这里是把一个内容给移动过来了,不知道有什么用
006E1BAE        call        Move
# 3.jump
006E1BB3>       jmp         006E1BC7
...
# 3.here
006E1BC7        xor         eax,eax
006E1BC9        mov         dword ptr [ebp-14],eax
# 4.jump
006E1BCC>       jmp         006E1C80
# 5.here 双循环,这里是最外侧
006E1BD1        mov         ebx,dword ptr ds:[839634];0x9E3779B9* gvar_00839634
# 这里很奇怪 ebx = 0x9E3779B9*0x20 = 0xC6EF3720 这个很重要后面要考
006E1BD7        imul        ebx,dword ptr ds:[839630];0x20 gvar_00839630
# 这里eax又等于buff地址了
006E1BDE        mov         eax,dword ptr [ebp-4]
006E1BE1        mov         eax,dword ptr [eax]
# edx=0 当个计数器?
006E1BE3        mov         edx,dword ptr [ebp-14]
# 这里其实就是eax地址往前走,应该是在遍历了
006E1BE6        add         eax,edx
006E1BE8        lea         edx,[ebp-10]
006E1BEB        mov         ecx,8
# 这里是把eax中的8字节 赋值到edx的堆栈中,edx的堆栈是19f158,固定的
006E1BF0        call        Move
006E1BF5        mov         eax,[00839630];0x20 gvar_00839630
# 这句很迷啊,这个外部变量一定是20,然后这个与操作,必然成立啊
006E1BFA        test        eax,eax
006E1BFC>       jle         006E1C5F
006E1BFE        mov         dword ptr [ebp-20],eax
# 7.here 这里是内循环

# 这里第一步就是把前面赋值的8字节中,前4字节给了esi 也就是buff的前4个字节
006E1C01        mov         esi,dword ptr [ebp-10]
006E1C04        mov         eax,esi
# 这里eax就是前4字节,然后左移4位
006E1C06        shl         eax,4
006E1C09        mov         edx,esi
# edx右移5位
006E1C0B        shr         edx,5
# 然后eax和edx取异或
006E1C0E        xor         eax,edx
#再加回原来的值
006E1C10        add         eax,esi
# 这里ebx = C6EF3720 这个ebx就是前面从外部拿出来的值
006E1C12        mov         edx,ebx
006E1C14        shr         edx,0B
006E1C17        and         edx,3
# 这里突然来了ebp ,这个ebp之前没注意是什么
006E1C1A        mov         edx,dword ptr [ebp+edx*4-34]
# 这里又让原始值加上了这个新得到的值
006E1C1E        add         edx,ebx
# ecx=0x7c00
006E1C20        movzx       ecx,word ptr [ebp-6]
# edx 又加上了这个值
006E1C24        add         edx,ecx
# 还有一个异或
006E1C26        xor         eax,edx
# 这里把eax给回写了 整个计算的结果1存在这里
006E1C28        sub         dword ptr [ebp-0C],eax
006E1C2B        sub         ebx,dword ptr ds:[839634];gvar_00839634
006E1C31        mov         edi,dword ptr [ebp-0C]
006E1C34        mov         eax,edi
006E1C36        shl         eax,4
006E1C39        mov         edx,edi
006E1C3B        shr         edx,5
006E1C3E        xor         eax,edx
006E1C40        add         eax,edi
006E1C42        mov         edx,3
006E1C47        and         edx,ebx
006E1C49        mov         edx,dword ptr [ebp+edx*4-34]
006E1C4D        add         edx,ebx
006E1C4F        movzx       ecx,word ptr [ebp-6]
006E1C53        add         edx,ecx
006E1C55        xor         eax,edx
# 上面的计算类似,结果2存储在这里
006E1C57        sub         dword ptr [ebp-10],eax
006E1C5A        dec         dword ptr [ebp-20]
# 7.jump
006E1C5D>       jne         006E1C01
# 当一轮循环结束以后
006E1C5F        mov         eax,dword ptr [ebp-4]
006E1C62        mov         eax,dword ptr [eax]
006E1C64        mov         edx,dword ptr [ebp-14]
006E1C67        lea         edx,[eax+edx]
006E1C6A        lea         eax,[ebp-10]
006E1C6D        mov         ecx,8
# 这里是将刚才计算完成的数据给移动到新地方 其实就在原buff数据的上面一点就是
006E1C72        call        Move
# 每次移动8个字节,刚好
# 这里让这两个变量+8了
006E1C77        add         dword ptr [ebp-14],8
006E1C7B        add         word ptr [ebp-6],8
# 4.here
# 重新读出来buff的地址
006E1C80        mov         eax,dword ptr [ebp-4]
006E1C83        mov         eax,dword ptr [eax]
006E1C85        mov         dword ptr [ebp-24],eax
# 这里是判定是否串口地址为0,也就是指针为空的情况
[ebp-24] 是buff的长度 0x100
006E1C88        cmp         dword ptr [ebp-24],0
006E1C8C>       je          006E1C99
006E1C8E        mov         eax,dword ptr [ebp-24]
006E1C91        sub         eax,4
006E1C94        mov         eax,dword ptr [eax]
006E1C96        mov         dword ptr [ebp-24],eax
006E1C99        mov         eax,dword ptr [ebp-24]
# 不知道为什么这里长度先-1,再-7,其实也就是减了8,但是这里没看到处理数据啊,怎么就减了呢
006E1C9C        dec         eax
006E1C9D        sub         eax,7
# 然后判定是否把buff遍历完了,没有就跳转 这里每次都是0x100-8和[ebp-14]比较,好奇怪,虽然[ebp-14]每次循环结束以后都会自动+8
006E1CA0        cmp         eax,dword ptr [ebp-14]
# 5.jump
006E1CA3>       jge         006E1BD1
006E1CA9        lea         eax,[ebp-34]
006E1CAC        xor         ecx,ecx
006E1CAE        mov         edx,10
006E1CB3        call        @FillChar
006E1CB8        movzx       eax,byte ptr [ebp-19]
006E1CBC        call        006E1D40
006E1CC1        test        al,al
006E1CC3>       je          006E1CCD
006E1CC5        mov         eax,dword ptr [ebp-4]
# 这个函数也很关键,他直接把内存给变得可读了,前面的循环内存还不太能读的样子
006E1CC8        call        006E1960
006E1CCD        pop         edi
006E1CCE        pop         esi
006E1CCF        pop         ebx
006E1CD0        mov         esp,ebp
006E1CD2        pop         ebp
006E1CD3        ret         4

这里基本就把所有数据解密完成了,但是解密只是解开了,但是后面还有一个流程把数据又整理了一下,整理之后数据的可读性一下就变强了很多很多,主要就是靠下面的函数实现的。

sub_006E1960

那就看一下他是怎么做的,发现核心好像是在这里啊

_Unit102.sub_006E1960
006E1960        push        ebx
006E1961        push        esi
006E1962        push        edi
006E1963        mov         edi,eax
006E1965        xor         esi,esi
# 1.跳转
006E1967>       jmp         006E197A
# 2.继续
006E1969        mov         eax,edi
006E196B        mov         ecx,2
006E1970        mov         edx,esi
# 这里应该是每次给定削减2个字节
006E1972        call        006D5A78
# 这里是字节指针+=6,他是基于给进去的指针+6,相当于是原字符的每8字节
006E1977        add         esi,6
# 1.继续
006E197A        mov         ebx,dword ptr [edi]
006E197C        test        ebx,ebx
006E197E>       je          006E1985
006E1980        sub         ebx,4
006E1983        mov         ebx,dword ptr [ebx]
# ebx只是一个计数器
006E1985        dec         ebx
006E1986        dec         ebx
# 判断结尾的
006E1987        cmp         esi,ebx
# 2.跳转
006E1989>       jl          006E1969
006E198B        pop         edi
006E198C        pop         esi
006E198D        pop         ebx
006E198E        ret

sub_006D5A78

这个比较短小

_Unit96.sub_006D5A78
006D5A78        push        ebx
006D5A79        mov         ebx,dword ptr ds:[404B48];TArray<System.Byte>
006D5A7F        push        ebx
# 只是单纯的把 404B48这个数组给进去了
006D5A80        call        0040D0EC
006D5A85        pop         ebx
006D5A86        ret

主要是下面这个函数,这个函数基本全程在赋值粘贴

System.sub_0040D0EC
0040D0EC        push        ebp
0040D0ED        mov         ebp,esp
0040D0EF        add         esp,0FFFFFFE4
0040D0F2        push        ebx
0040D0F3        push        esi
0040D0F4        push        edi
0040D0F5        mov         dword ptr [ebp-8],ecx
0040D0F8        mov         dword ptr [ebp-4],edx
0040D0FB        mov         ebx,eax
0040D0FD        cmp         dword ptr [ebx],0
# 判0,继续
0040D100>       je          0040D1D2
0040D106        mov         eax,dword ptr [ebx]
0040D108        sub         eax,8
# 拿到数组长度
0040D10B        mov         eax,dword ptr [eax+4]
0040D10E        cmp         dword ptr [ebp-4],0
0040D112>       jl          0040D1D2
0040D118        cmp         eax,dword ptr [ebp-4]
0040D11B>       jle         0040D1D2
0040D121        cmp         dword ptr [ebp-8],0
0040D125>       jle         0040D1D2
0040D12B        mov         edx,eax
0040D12D        sub         edx,dword ptr [ebp-4]
0040D130        sub         edx,dword ptr [ebp-8]
0040D133        mov         dword ptr [ebp-0C],edx
0040D136        cmp         dword ptr [ebp-0C],0
# 1.跳转
0040D13A>       jge         0040D141
0040D13C        xor         edx,edx
0040D13E        mov         dword ptr [ebp-0C],edx
# 1.继续
0040D141        mov         edx,dword ptr [ebp+8]
0040D144        movzx       edi,byte ptr [edx+1]
0040D148        add         edi,edx
0040D14A        mov         edx,edi
0040D14C        mov         esi,dword ptr [edx+2]
0040D14F        cmp         dword ptr [edx+6],
# 2.跳转
0040D153>       je          0040D15C
0040D155        mov         edx,dword ptr [edx+6]
0040D158        mov         edi,dword ptr [edx]
0040D15A>       jmp         0040D15E
# 2.继续
0040D15C        xor         edi,edi
0040D15E        mov         edx,dword ptr [ebp-4]
0040D161        imul        edx,esi
0040D164        mov         ecx,dword ptr [ebx]
0040D166        lea         edx,[ecx+edx]
0040D169        mov         dword ptr [ebp-18],edx
0040D16C        sub         eax,dword ptr [ebp-0C]
0040D16F        imul        esi
0040D171        mov         edx,dword ptr [ebx]
0040D173        lea         eax,[edx+eax]
0040D176        mov         dword ptr [ebp-14],eax
0040D179        test        edi,edi
# 3.跳转
0040D17B>       je          0040D1A5
0040D17D        mov         eax,dword ptr [ebp-0C]
0040D180        test        eax,eax
0040D182>       jle         0040D1B6
0040D184        mov         dword ptr [ebp-1C],eax
0040D187        push        1
0040D189        mov         ecx,edi
0040D18B        mov         edx,dword ptr [ebp-14]
0040D18E        mov         eax,dword ptr [ebp-18]
0040D191        call        CopyArray
0040D196        mov         eax,esi
0040D198        add         dword ptr [ebp-18],eax
0040D19B        add         dword ptr [ebp-14],eax
0040D19E        dec         dword ptr [ebp-1C]
0040D1A1>       jne         0040D187
0040D1A3>       jmp         0040D1B6
# 3.继续
0040D1A5        mov         ecx,dword ptr [ebp-0C]
0040D1A8        imul        ecx,esi
0040D1AB        mov         edx,dword ptr [ebp-18]
0040D1AE        mov         eax,dword ptr [ebp-14]
# 其实这里就是把整体256个字节,往左集体移动2个字节,后面不够的字符自动补0xFF
0040D1B1        call        Move
0040D1B6        mov         eax,dword ptr [ebp-4]
0040D1B9        add         eax,dword ptr [ebp-0C]
0040D1BC        mov         dword ptr [ebp-10],eax
0040D1BF        lea         eax,[ebp-10]
0040D1C2        push        eax
0040D1C3        mov         eax,ebx
0040D1C5        mov         ecx,1
0040D1CA        mov         edx,dword ptr [ebp+8]
0040D1CD        call        DynArraySetLength
0040D1D2        pop         edi
0040D1D3        pop         esi
0040D1D4        pop         ebx
0040D1D5        mov         esp,ebp
0040D1D7        pop         ebp
0040D1D8        ret         4

最后实现的结果就是,将原本解析出来的256字节,每8字节的前2字节给抛弃了,然后用剩下的字节重新对齐,拼成一个新的256字节,不够的字节用0xFF补齐

image-20210720165559845

内存对比,完全符合,我就懒得看具体代码了。唯一这里担心一点,那就是他把抛弃的前2个字节重新在某个地方又拼接了一下,然后又合成了一个新信息,如果有这样的话就坑爹了。

继续sub_006EA090


006EA111        mov         edx,dword ptr ds:[841290];^gvar_00839100
006EA117        movzx       edx,byte ptr [edx]
006EA11A        mov         eax,dword ptr [ebp+8]
006EA11D        mov         eax,dword ptr [eax-4]
006EA120        call        006D5CE4
006EA125        test        al,al
006EA127>       je          006EA130
006EA129        mov         bl,5
006EA12B>       jmp         006EA324
006EA130        mov         eax,dword ptr [ebp+8]
006EA133        mov         eax,dword ptr [eax-4]
006EA136        lea         edx,[eax+60]
006EA139        mov         eax,dword ptr [ebp+8]
006EA13C        mov         eax,dword ptr [eax-8]
# 这里又调用了一次读
006EA13F        call        TBLHeli.ReadMCU
006EA144        mov         ebx,eax
006EA146        cmp         bl,4
006EA149>       je          006EA172
006EA14B        mov         eax,dword ptr [ebp+8]
006EA14E        mov         eax,dword ptr [eax-8]
006EA151        mov         byte ptr [eax+0B8],1
006EA158        mov         eax,dword ptr [ebp+8]
006EA15B        mov         eax,dword ptr [eax-4]
006EA15E        test        eax,eax
006EA160>       je          006EA167
006EA162        sub         eax,4
006EA165        mov         eax,dword ptr [eax]
006EA167        mov         edx,dword ptr [ebp+8]
006EA16A        mov         dword ptr [edx-0C],eax
006EA16D>       jmp         006EA324
006EA172        mov         eax,dword ptr [ebp+8]
006EA175        mov         eax,dword ptr [eax-0C]
006EA178        push        eax
006EA179        mov         eax,dword ptr [ebp+8]
006EA17C        add         eax,0FFFFFFFC
006EA17F        push        eax
006EA180        xor         ecx,ecx
006EA182        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006EA188        mov         eax,dword ptr [ebp-4]
006EA18B        call        @DynArrayCopyRange
006EA190        push        1
006EA192        mov         eax,dword ptr [ebp+8]
006EA195        add         eax,0FFFFFFFC
006EA198        xor         ecx,ecx
006EA19A        mov         dx,0F800
006EA19E        call        006E1B48
006EA1A3        mov         edx,dword ptr ds:[841290];^gvar_00839100
006EA1A9        movzx       edx,byte ptr [edx]
006EA1AC        mov         eax,dword ptr [ebp+8]
006EA1AF        mov         eax,dword ptr [eax-4]
006EA1B2        call        006D5CE4
006EA1B7        test        al,al
006EA1B9>       je          006EA1C2
006EA1BB        mov         bl,5
# 1.跳转
006EA1BD>       jmp         006EA324
...
# 1.继续 基本就结束了
006EA324        xor         eax,eax
006EA326        pop         edx
006EA327        pop         ecx
006EA328        pop         ecx
006EA329        mov         dword ptr fs:[eax],edx
006EA32C        push        6EA347
006EA331        lea         eax,[ebp-4]
006EA334        mov         edx,dword ptr ds:[404B48];TArray<System.Byte>
006EA33A        call        @DynArrayClear
006EA33F        ret
006EA340>       jmp         @HandleFinally
006EA345>       jmp         006EA331
006EA347        mov         eax,ebx
006EA349        pop         ebx
006EA34A        pop         ecx
006EA34B        pop         ebp
006EA34C        ret

继续ReadSetupFromBinString

篇幅太长了,所以下一篇,配置解析

串口数据格式

image-20210716180115583

从0x50F6BE4开始,前四个字节描述数据长度,所以这里就是0x0000 0103,也就是259字节数据

这里有一个奇怪的值是从404B48 那个奇怪的地址读出来的

image-20210716182847388

总体调用流程

actReadSetupExecute 按键act
 DoBtnReadSetup 按键具体操作
  ReadSetupAll 读取配置信息
   ReadDeviceSetupSection 这里是操作去读
    Send_cmd_DeviceReadBLHeliSetupSection 发送读取命令,执行后就拿到了256字节
    ReadSetupFromBinString 这里就是关键,解析读上来的字符串,然后赋值给了BLHeli的各个参数
     TBLHeli.Init 参数存储的对象初始化
     BLHeliSu.006EA090 解密开始的函数
      BLHeliSu.006E1B48 解密循环函数
       BLHeliSu.006E1960 内存可读的开始
        BLHeliSu.006D5A78 偏移操作的函数
    ReadSetupFromBinString 的后续内容会读取所有配置,然后给BLHeli对象赋值
    
    ReadDeviceActivationStatus 第二次读,由于和电调配置无关,具体数据没解析
    ReadDeviceUUID_Str 第三次读,由于和电调配置无关,具体数据没解析
    
   CopyTo 这里就开始涉及显示的东西,其实就是给参数赋值
   SetupToControls 这里是把内容处理,显示到ui上

变量内存表

TBLHeli 基址为0x287D380
偏移
0xB4 MCU_DeviceID:Integer
0xD2 MCU_Manufacturer:
0xD1 Is_64K:Boolean
0x18 MCU:string 应该是名字之类的东西

串口buff 基址为 4FEA1C8或者52FA2D8 这片内存中有非常多的副本
他的上4个字节是长度00 01 00 00 256字节

数据解密流程

解密逻辑
原值为A,以4字节为单位
I = ( (A<<4) xor (A>>5) )+ A = eax

外部密钥设为 B = 0xC6EF3720=ebx 每次在循环开头更新
C = ( (B>>11) & 0x3 ) 这样拿到的C只是一个偏移量

ebp是什么呢? 应该是个变量基址,从外部传进来的,主要是存储堆栈地址
D = [ebp+C*4-34]的值
E = D + B
设 F = 0x7C00
G = E + F = edx
H = I  xor G

更新基址内容

外部变量 J=0x9E3779B9
local.3 -=H
B -= J = ebx

K = local.3
eax = L = (K<<4) xor (K>>5) + K
M = 3 & B
N = [ebp+M*4-0x34]
O = N + B
O += F
L = L xor O
local.4 -= L 

这样每次计算的内容都存储在local.3和local.4中了
每轮计算结束以后,将他们转存到了另一个地方,然后继续下8个字节计算。
当256字节全部计算完成以后,每8字节去掉前2字节后将其余字节拼在一起,然后形成可读配置

将核心循环转换成python就是这样了

import os
import sys

ds = {}
ds[0x839634] = 0x9E3779B9
ds[0x839630] = 0x20
local0 = 0x19F168
local1 = 0x19F164
local2 = 0x19F160  # [ebp-0x6]
local3 = 0x19F15C
local4 = 0x19F158
local5 = 0x19F154
local6 = 0x19F150
local7 = 0x19F14C
local8 = 0x19F148
local9 = 0x19F144
local10 = 0x19F140
local11 = 0x19F13C  # [ebp+edx*4-0x34]
local12 = 0x19F138
local13 = 0x19F134
local14 = 0x19F130
local15 = 0x19F12C
mem = {}
# uart buff addr
mem[local1] = 0x19F20C
mem[local2] = 0x7C00A1C8
mem[local3] = 0xD3617DCA  # buff 前4字节
mem[local4] = 0x154369FC  # buff 后4字节
mem[local5] = 0  # 这个值每次也+8
mem[local6] = 0x4
mem[local7] = 0x1513F8C
mem[local8] = 0x20  # count 
mem[local9] = 0x100
mem[local10] = 0x318234B4
# 这个值来源不明
mem[local11] = 0x29A1FA54  # [ebp+edx*4-0x34]
mem[local12] = 0x9E81C901
mem[local13] = 0x81FBC617
mem[local14] = 0x4
mem[local15] = 0x513F8C
mem[0x19F168 - 6] = 0x7C00  # [ebp-0x6] 这个值每次+8

mem[0x19F20C] = 0x4FEA1C8

ebp = 0x19F168

ebx = ds[0x839634]
ebx = ebx * ds[0x839630] & 0xFFFFFFFF
eax = mem[local1]
eax = mem[eax]  # 0x4FEA1C8
edx = mem[local5]
eax = eax + edx
edx = mem[local4]
ecx = 0x8
# move 准备工作
# mem[local4] = 0x7EAB1EA0
# mem[local5] = 0x625214C8
eax = ds[0x839630]  # 20

# uart buff
uart_buff = []
f = open(os.path.dirname(__file__) + "/rawdata.txt")
hex_data = f.read()
print(hex_data)
start = None
end = None

state = 0
for i in range(0, len(hex_data), 3):
    if (hex_data[i] + hex_data[i + 1]) == "03" and state == 0:
        state = 1
    elif (hex_data[i] + hex_data[i + 1]) == "00" and state == 1:
        state = 2
    elif (hex_data[i] + hex_data[i + 1]) == "00" and state == 2:
        state = 3
    elif (hex_data[i] + hex_data[i + 1]) == "F0" and state == 3:
        state = 4
        start = i + 3
        break
    else:
        state = 0
if start == None:
    print("no start,exit")
    sys.exit(0)

print(len(hex_data))
output_data = ""

n = 4
for i in range(start, start + 256 * 3, 3):
    print(hex_data[i], hex_data[i + 1])
    uart_buff.append("" + hex_data[i] + hex_data[i + 1])
    # uart_buff.append(int(""+hex_data[i] + hex_data[i + 1],base=16))

f.close()

print(uart_buff)

decrypt_mem = []

# loop1
mem[local8] = eax
for i in range(0, 0x100, 8):
    mem[local4] = int(uart_buff[i + 3] + uart_buff[i + 2] + uart_buff[i + 1] + uart_buff[i + 0], base=16)
    mem[local3] = int(uart_buff[i + 7] + uart_buff[i + 6] + uart_buff[i + 5] + uart_buff[i + 4], base=16)
    ebx = ds[0x839634]
    ebx = ebx * ds[0x839630] & 0xFFFFFFFF
    eax = mem[local1]
    eax = mem[eax]  # 0x4FEA1C8
    edx = mem[local5]
    eax = eax + edx
    edx = mem[local4]
    ecx = 0x8

    for i in range(32):
        # loop2
        esi = mem[local4]
        eax = esi
        eax = eax << 4 & 0xFFFFFFFF
        edx = esi
        edx = edx >> 5 & 0xFFFFFFFF
        eax = eax ^ edx
        eax = (eax + esi) & 0xFFFFFFFF
        edx = ebx
        edx = edx >> 0xB & 0xFFFFFFFF
        edx = edx & 0x3
        edx = mem[ebp + edx * 4 - 0x34]
        edx = (edx + ebx) & 0xFFFFFFFF
        ecx = mem[ebp - 0x6]
        edx = (edx + ecx) & 0xFFFFFFFF
        eax = eax ^ edx
        mem[local3] = (mem[local3] - eax) & 0xFFFFFFFF
        ebx = (ebx - ds[0x839634]) & 0xFFFFFFFF
        edi = mem[local3]
        eax = edi
        eax = eax << 4 & 0xFFFFFFFF
        edx = edi
        edx = edx >> 5 & 0xFFFFFFFF
        eax = eax ^ edx
        eax = (eax + edi) & 0xFFFFFFFF
        edx = 0x3
        edx = edx & ebx
        edx = mem[ebp + edx * 4 - 0x34]
        edx = (edx + ebx) & 0xFFFFFFFF
        ecx = mem[ebp - 0x6]
        edx = (edx + ecx) & 0xFFFFFFFF
        eax = eax ^ edx
        mem[local4] = (mem[local4] - eax) & 0xFFFFFFFF
        mem[local8] -= 1
        # loop2 end
    mem[local5] += 8
    mem[0x19F168 - 6] += 8

    decrypt_mem.append(mem[local4])
    decrypt_mem.append(mem[local3])

    # print(hex(mem[local4]))
    # print(hex(mem[local3]))

print(decrypt_mem)

def bytes2hex(data):
    lin = ['%02X' % i for i in data]
    return "".join(lin)

for i in range(0, 64, 2):
    print(hex((decrypt_mem[i + 0] & 0x00FF0000) >> 16).zfill(4) + hex((decrypt_mem[i + 0] & 0xFF000000) >> 24).replace("0x",'').zfill(2))

    print(hex((decrypt_mem[i + 1] & 0x000000FF)).zfill(4) + hex((decrypt_mem[i + 1] & 0x0000FF00) >> 8).replace("0x",'').zfill(2) + hex(
        (decrypt_mem[i + 1] & 0x00FF0000) >> 16).replace("0x",'').zfill(2) + hex((decrypt_mem[i + 1] & 0xFF000000) >> 24).replace("0x",'').zfill(2))

end = True


rawdata.txt中是本次读取的数据,类似于这样就行,可以自动解析出来正确的256字节配置

image-20210719184659222

目前每次解出来的数据是和反汇编看到的一模一样。最后的输出我将每8字节的前2字节去掉,然后就变成可读的字符串了,和内存的排布是一样的。

image-20210720200104954

当解密完成以后,如果有相关经验的可能可以从算法推出来是用什么加密的。至于为什么每次加密后的密文都不同,那就不知道了,难道是每次随机给进来的前2个字节是随机的?所以加密以后导致密文每次都不同?加密的那一段代码由于我没啥需求,就不继续破解了

Summary

总算是看到了解密流程,但是这个解密算法真的好复杂啊,看的我一脸懵逼,还好是找到了,也成功破解了加密的算法。剩下的就是把明文转换成对应的实际配置参数了。

Quote

https://www.52pojie.cn/thread-615448-1-1.html

http://www.youngroe.com/2019/07/01/Windows/delphi_reverse_summary/