AKU的版本号,AKU的build number
可以通过注册表来获得
HKLM\SYSTEM\Versions\Aku
package的版本号
Flash.bin被分成了几个分区。每个分区是由package组成的。每个package都有自己的版本号
如果是update package还有previous version.
package 可能有interface. interface还有自己的版本号码。


OS的version
GetVersionEx
获取操作系统的版本信息
This function obtains extended information about the version of the OS that is currently running。 CeGetVersionEx (RAPI) is the RAPI version of this function.
它返回了这样一个结构
typedef struct _OSVERSIONINFO{
  DWORD dwOSVersionInfoSize;//结构体的大小=0x114
  DWORD dwMajorVersion;//os的主版本
  DWORD dwMinorVersion;//os的次版本
  DWORD dwBuildNumber;//os的build number
  DWORD dwPlatformId; //平台标识符,在wince中主要是VER_PLATFORM_WIN32_CE
  TCHAR szCSDVersion[128];//Null-terminated string that provides arbitrary additional information about the OS.对于平台的描述字串
} OSVERSIONINFO;

ROM version
oem自己定义的版本号码

SWV
在DM中使用的版本号

FWV
在DM中使用的版本号

工作中做FOTA时遇到了一些问题,专门看了一下GetVersionEx的实现过程。简单的分析了一下


GetVersionEx
其中的buildnumber是通过MSXIPKernel的pkg包的版本决定的。
它通过查找下面两个GUID来查找MSXIPKERNEL
b5332311-48f1-4b76-ad70-8efa5db8fa3a
723fb954-d931-4348-b672-82a188e587b5


aCccccccccccccc  DCB "cccccccccccccccccc",0
    DCB 0
aAddhijridate  unicode  0, <AddHijriDate>,0 ; DATA XREF: .text:off_1003A53Co
    DCW 0
aAddhijridatete  unicode  0, <AddHijriDateTemp>,0  ; DATA XREF: .text:off_1003A540o
    DCW 0
aControlpanelIn  unicode  0, <ControlPanel\International>,0 ; DATA XREF: .text:off_1003A544o
    DCW 0
aCecredfree  unicode  0, <CeCredFree>,0 ; DATA XREF: .text:off_1003D850o
    DCW 0
aCecredread  unicode  0, <CeCredRead>,0 ; DATA XREF: .text:off_1003D854o
    DCW 0
aSecur32_dll  unicode  0, <secur32.dll>,0 ; DATA XREF:  .text:off_1003D858o
dword_10003300  DCD 0x723FB954,  0x4348D931, 0xA18272B6,  0xB587E588, 0xB5332311
          ; DATA XREF: .text:off_1003D9CCo
    DCD 0x4B7648F1,  0xFA8E70AD, 0x3AFAB85D
aWindows  unicode  0, <\Windows>,0  ; DATA XREF: .text:off_1003D9D0o
    DCW 0
aPkg_setbaselin  DCB "Pkg_SetBaselineDirectories",0 ; DATA XREF: .text:off_1003D9E0o
    DCB 0
aPkg_openpackag  DCB "Pkg_OpenPackageByGUID",0 ; DATA XREF: .text:off_1003D9DCo
    DCW 0
aPkg_getpkginfo  DCB "Pkg_GetPkgInfo",0  ; DATA XREF: .text:off_1003D9D8o
    DCB 0
aPkg_close  DCB "Pkg_Close",0       ; DATA XREF: .text:off_1003D9D4o
    DCW 0
aPackageinfoapi  unicode  0, <PackageInfoAPI.DLL>,0 ; DATA XREF: .text:off_1003D9E4o
    DCW 0
    ALIGN 0x10
    
; =============== S U B  R O U T  I N E =======================================


sub_1003D864        ; CODE XREF: GetVersionExW+14p
          ; DATA XREF: .pdata:1007F430o

var_14C    = -0x14C
var_144    = -0x144
var_12C    = -0x12C
var_128    = -0x128
var_FA    = -0xFA
var_E8    = -0xE8
var_20    = -0x20

    STMFD  SP!, {R4-R9,LR}//保存中间 registr
    SUB  SP, SP,  #0x130//预留局部变量空间
    LDR  R3, =unk_1007B9D4
    LDR  R3, [R3]
    STR  R3, [SP,#0x14C+var_20]
    LDR  R0, =aPackageinfoapi //PackageInfoAPI.DLL
    MOV  R4, #0
    BL  LoadLibraryW
    MOVS  R7, R0        //R7保存LoadLibraryW获得的handle
    BEQ  loc_1003D9A8
    LDR  R1, =aPkg_setbaselin
    MOV  R3, #0
    MOV  R0, R7
    STR  R3, [SP,#0x14C+var_14C]
    BL  GetProcAddressA
    LDR  R1, =aPkg_openpackag
    MOV  R6, R0         //R6中保存Pkg_SetBaselineDirectories
    MOV  R0, R7
    BL  GetProcAddressA
    LDR  R1, =aPkg_getpkginfo
    MOV  R5, R0         //R5中保存Pkg_OpenPackageByGUID
    MOV  R0, R7
    BL  GetProcAddressA
    LDR  R1, =aPkg_close
    MOV  R9, R0
    MOV  R0, R7  
    BL  GetProcAddressA
    MOV  R8, R0
    CMP  R6, #0      //R6中保存Pkg_SetBaselineDirectories
    BEQ  loc_1003D990
    CMP  R5, #0      //R5中保存Pkg_OpenPackageByGUID
    BEQ  loc_1003D990
    CMP  R9, #0          //R9   Pkg_getpkginfo
    BEQ  loc_1003D990
    CMP  R8, #0           //R8中保存Pkg_close的指针
    BEQ  loc_1003D990
    LDR  R1, =aWindows    //R1是windows目录字串
    ADD  R0, SP,  #0x14C+var_144 //局部的一个字串数组
    MOV  R2, #0x12          //字串拷贝的字节大小
    BL  memcpy            //拷贝了这个字串
    MOV  R1, #9            //cchFileList大小为9
    ADD  R0, SP,  #0x14C+var_144  //可以看出Pkg_SetBaselineDirectories设定的是windows目录
    MOV  LR, PC    //下面要BX所以保存PC到LR
    BX  R6        //R6中保存Pkg_SetBaselineDirectories
    CMP  R0, #0           //判断是否成功     
    BMI  loc_1003D990    //判断是否成功
    LDR  R6, =dword_10003300  //这里保存了一个GUID
    ADD  R1, SP,  #0x14C+var_14C//HPKG* phPkg 
    ADD  R0, R6,  #0x10  //R6指向GUID16个字节之后的GUID,一共有2个GUID,这个是第二个
    MOV  LR, PC         //下面要BX所以保存PC到LR
    BX  R5             //R5中保存Pkg_OpenPackageByGUID
    CMP  R0, #0         //判断是否成功
    BPL  loc_1003D950
    ADD  R1, SP,  #0x14C+var_14C //R1指向HPKG* phPkg 
    MOV  R0, R6        //R6指向GUID这个是第一个
    MOV  LR, PC          //下面要BX所以保存PC到LR   
    BX  R5              //R5中保存Pkg_OpenPackageByGUID,调用该函数
    CMP  R0, #0
    BMI  loc_1003D990 //不成功的情况下

loc_1003D950        ; CODE XREF: sub_1003D864+D0j //这里是成功的情况下
    MOV  R2, #0x40
    MOV  R1, #0
    ADD  R0, SP,  #0x14C+var_128
    BL  memset
    MOV  R2, #0xC8
    MOV  R1, #0
    ADD  R0, SP,  #0x14C+var_E8
    BL  memset
    MOV  R3, #0x10C
    LDR  R0, [SP,#0x14C+var_14C]
    STR  R3, [SP,#0x14C+var_12C]
    ADD  R1, SP,  #0x14C+var_12C//报粗info信息
    MOV  LR, PC 
    BX  R9    //R9   Pkg_getpkginfo
    CMP  R0, #0
    LDRPLH  R4, [SP,#0x14C+var_FA]//获得wBuildNumber ,R4中保存的就是buildnumber是在结构体VersionInfo中的(12c-FA=0x32= 50)

loc_1003D990        ; CODE XREF: sub_1003D864+74j//如果出错的情况下退出,正常退出也走这里
          ; sub_1003D864+7Cj ...
    LDR  R0, [SP,#0x14C+var_14C]
    CMP  R0, #0
    MOVNE  LR, PC
    BXNE  R8 //R8中保存Pkg_close的指针
    MOV  R0, R7
    BL  FreeLibrary

loc_1003D9A8        ; CODE XREF: sub_1003D864+24j
    LDR  R3, =unk_1007BAE0 //这里其实是返回值
    MOV  R2, #1
    STMIA  R3, {R2,R4}//第一个数值保存为1,第二个数值保存为
    LDR  R0, [SP,#0x14C+var_20]
    BL  sub_1006DAA8
    ADD  SP, SP,  #0x130
    LDMFD  SP!, {R4-R9,LR}
    BX  LR
; End of function sub_1003D864

; ---------------------------------------------------------------------------
off_1003D9C8  DCD unk_1007BAE0  ; DATA XREF: sub_1003D864:loc_1003D9A8r
off_1003D9CC  DCD dword_10003300  ; DATA XREF: sub_1003D864+B8r
off_1003D9D0  DCD aWindows    ; DATA XREF: sub_1003D864+90r
          ; "\\Windows"
off_1003D9D4  DCD aPkg_close    ; DATA XREF: sub_1003D864+5Cr
          ; "Pkg_Close"
off_1003D9D8  DCD aPkg_getpkginfo  ; DATA XREF: sub_1003D864+4Cr
          ; "Pkg_GetPkgInfo"
off_1003D9DC  DCD aPkg_openpackag  ; DATA XREF: sub_1003D864+3Cr
          ; "Pkg_OpenPackageByGUID"
off_1003D9E0  DCD aPkg_setbaselin  ; DATA XREF: sub_1003D864+28r
          ; "Pkg_SetBaselineDirectories"
off_1003D9E4  DCD aPackageinfoapi  ; DATA XREF: sub_1003D864+14r
          ; "PackageInfoAPI.DLL"
off_1003D9E8  DCD unk_1007B9D4  ; DATA XREF: sub_1003D864+8r
; Exported entry  17. GetVersionEx
; Exported entry 717. GetVersionExW

; =============== S U B  R O U T  I N E =======================================
/*
typedef struct _OSVERSIONINFO{
  DWORD dwOSVersionInfoSize;
  DWORD dwMajorVersion;
  DWORD dwMinorVersion;
  DWORD dwBuildNumber;
  DWORD dwPlatformId;
  TCHAR szCSDVersion[128];
} OSVERSIONINFO;
*/
    EXPORT GetVersionExW
GetVersionExW        ; DATA XREF: .pdata:1007F438o
    STMFD  SP!, {R4,R5,LR}  ; GetVersionEx
    MOV  R4, R0
    LDR  R5, =unk_1007BAE0 //R5中存放unk_1007BAE0的地址
    LDR  R3, [R5]          //R3为获取R5所指向的int的值
    CMP  R3, #0            //看R3是否为0
    BLEQ  sub_1003D864  //如果R3中的值为0,则执行sub_1003D864
    LDR  R3, [R5,#4]       //获取Build number
    MOV  R0, #2      //表示minor version
    MOV  LR, #3       //表示platformid
    MOV  R2, #0x114  //dwOSVersionInfoSize =R2=0x114
    MOV  R1, #5   //Major version
    MOV  R5, #0   
    ADD  R12, R4, #8     //指向minorversion
    STMIA  R12, {R0,R3,LR}//保存minor version, buildnumber, 以及platformid
    MOV  R0, #1   //返回1,表示成功
    STR  R2, [R4] //dwOSVersionInfoSize =R2=0x114
    STR  R1, [R4,#4] //dwMajorVersion = R1= 5
    STRH  R5, [R4,#0x14]
    LDMFD  SP!, {R4,R5,LR}
    BX  LR
; End of function GetVersionExW


sub_1006DAA8        ; CODE XREF: sub_1000AA8C+F4p //这个函数是干什么的?大概是堆栈的检查动作具体没看
          ; sub_1000ABEC+11Cp ...

var_C    = -0xC
var_8    = -8
var_4    = -4
arg_4    =  4

    LDR  R12, =unk_1007B9D4
    LDR  R12, [R12]
    CMP  R0, R12
    MOVEQS  R12, R0,LSR#16
    BXEQ  LR

loc_1006DABC        ; DATA XREF: .pdata:100813A8o
    STR  LR, [SP,#var_4]!
    SUB  SP, SP,  #0xC
    LDR  R12, =unk_1007B9D0
    LDR  R12, [R12]
    STR  R12, [SP,#0xC+var_4]
    LDR  R12, =unk_1007B9D4
    LDR  R12, [R12]
    STR  R12, [SP,#0xC+var_8]
    LDR  R12, =0xB064
    STR  R12, [SP,#0xC+var_C]
    BL  __report_gsfailure
    ADD  SP, SP,  #0xC
    LDR  LR, [SP],#arg_4
    BX  LR
; End of function sub_1006DAA8

; ---------------------------------------------------------------------------
off_1006DAF4  DCD unk_1007B9D4  ; DATA XREF: sub_1006DAA8r
          ; sub_1006DAA8+28r
off_1006DAF8  DCD unk_1007B9D0  ; DATA XREF: sub_1006DAA8+1Cr
dword_1006DAFC  DCD 0xB064    ; DATA XREF: sub_1006DAA8+34r