BLHeliSuite32逆向(二)

Crack,Reverse

Views:  times Updated on October 18, 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地址每次启动都会不一样,但是总体每次运行到这个位置的时候,某个寄存器里面一定存的就是这个地址

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]

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

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


# 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值,总算找到了解析的地方

解析函数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

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


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补齐

内存对比,完全符合,我就懒得看具体代码了。唯一这里担心一点,那就是他把抛弃的前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

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

串口数据格式

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

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

总体调用流程

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 # must need
# 这个值来源不明
mem[local11] = 0x29A1FA54 # [ebp+edx*4-0x34] # must need
mem[local12] = 0x9E81C901 # must need
mem[local13] = 0x81FBC617 # must need
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 byte2hex(data):
    lin = '%02X' % data
    return "0x"+"".join(lin)

pd = ""
for i in range(0, 64, 2):
    #print ((decrypt_mem[i + 0] & 0x00FF0000) >> 16)
    data = byte2hex((decrypt_mem[i + 0] & 0x00FF0000) >> 16)
    pd = data+" "
    #print(data)    
    data = byte2hex((decrypt_mem[i + 0] & 0xFF000000) >> 24)
    pd += data+" "
    #print(data)
    data = byte2hex((decrypt_mem[i + 1] & 0x000000FF) >> 0)
    pd += data+" "
    #print(data)
    data = byte2hex((decrypt_mem[i + 1] & 0x0000FF00) >> 8)
    pd += data+" "
    #print(data)
    data = byte2hex((decrypt_mem[i + 1] & 0x00FF0000) >> 16)
    pd += data+" "
    #print(data)
    data = byte2hex((decrypt_mem[i + 1] & 0xFF000000) >> 24)
    pd += data
    #print(data)
    print(pd)

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

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

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

这几个值是核心用来解密的密钥,不同版本可能密钥会出现不同,需要调试看

mem[local10] = 0x318234B4 # must need
mem[local11] = 0x29A1FA54 # [ebp+edx*4-0x34] # must need
mem[local12] = 0x9E81C901 # must need
mem[local13] = 0x81FBC617 # must need

Summary

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

Quote

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

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