ROMIMAGE工具解析(ARM平台)

来源:互联网 发布:wdcp php版本升级 编辑:程序博客网 时间:2024/04/30 20:02

一.wince6 OS 编译大体过程

build (public code)->sysgen->build (BSP)->buildrel->makeimg, 其中makeimg 命令调用romimage.exe (运行该命令romimage.exe ce.bib )产生最终的nk.bin 。其中ce.bibmerge 了系统中所有bib 文件( 当然包括config.bibplatform.bib)

 

二.ce.bib 中的内容包含四大部分

1. MEMORY section 划分内存块

格式:Name        Start       Size        Type

Name :唯一名称

Start :每块内存base address

Size :划分大小

Type "rom_8" "rom_16" "romx8" "ram" "ramimage" "nandimage" "reserved" "fixupvar" "extension" "chain information" 详细解释请参考http://msdn.microsoft.com/en-us/library/ms923584.aspx

Romimage.exe 解析该部分内容,如果有一块内存区域没有指定type 并且Name“reserve”type 就被指定为reserve

2. CONFIG section 设置配置变量

    AUTOSIZE

格式:AUTOSIZE=OFF|ON

默认为OFFconfig.bib 中定义RAM 用于进程和存储对象内存区域,RAMIMAGE 用于保存image 。如果为ONRAMRAMIMAGE 合并成一个部分,从低地址开始预留RAMIMAGE 大小,其余大小作为RAM

 

BOOTJUMP

格式:BOOTJUMP =address|NONE

默认为NONE ,内核启动从OALstartup 地址执行。如果指定一个在RAMIMAGE 范围的值,那就从指定的地址开始执行

 

COMPRESSION

格式:COMPRESSION = OFF|ON

默认为ON ,对于文件,默认全部压缩,对于模块默认压缩可写部分。如果模块在.bib 中定义时具有C 属性(表明压缩模块所有部分),那么当前这个选项就忽略了

 

FSRAMPERCENT

格式:FSRAMPERCENT=number 

文件系统分配的内存的百分比。

例如number0xAABBCCDD, 那么文件系统分配的内存的百分比为(0xAA+0xBB+0xCC

+0xDD)/1024

 

KERNELFIXUPS
格式:KERNELFIXUPS=OFF|ON

默认值为ON 。如果为ONromimage.exe 具有Base Relocations

 

PROFILE

格式PROFILE =OFF|ON

默认为OFF。如果为ON,使用symbols(文件map信息)

3.MODULES section定义OS镜像包含哪些模块,并指定模块被加载到那块内存区域

   格式:Name      Path   Memory   Type

Name :模块名

Path :真实的模块地址

Memory :该模块被加载到那块内存区域,区域为MEMORY section 部分的name

Type 模块的存放属性

  • S :系统文件
  • H :隐藏文件
  • R 只压缩模块的资源部分(默认模块是不压缩的)
  • C :压缩模块所有部分
  • D :禁止调试
  • N :标志模块是非信任的
  • P :忽略CPU 类型
  • Q: 双模式,如果该模块为user mode ,这时会在kernel mode 上也对应一个K.+ 模块名
  • K :指定模块为kernel mode
  • Z like kernel mode
  • X :指定romimage.exe 对此模块验证签名
  • M :运行时加载整个模块,而不是按需分页

 

  4. FILE section 定义OS 镜像包含哪些文件,并指定文件被加载到那块内存区域

   格式:Name    Path    Memory    Type

Name :文件名

Path :真实的文件地址

Memory :该文件被加载到那块内存区域,区域为MEMORY section 部分的name

Type 模块的存放属性

  • S :系统文件
  • H :隐藏文件
  • Q: 双模式,如果该文件为user mode ,这时会在kernel mode 上也对应一个K.+ 文件名
  • U :不压缩(默认压缩)

 

三.Romiamge.exe 处理过程(non multixip

    1. syn module name ,如果namepath 中模块名不相等,就从MODULES section path 拷贝(同时拷贝它对应的pdb, map, rel 文件)到本目录以name 命名

    2. 使nk.exeMODULES section 的第一个module

    3. 使具有“Z ”属性的模块在前半部分,一般是NK.exekitl.dllkernel.dll (这三个家伙将被loadstatic mapped cached 区间,从RAMIMAGE start address 开始)

    4. 如果AUTOSIZE=ON ,合并RAMRAMIMAGE

    6. 定位每个module load address 偏移 地址 relocation 偏移 地址

     7. 如果模块不具有Z 属性, 根据config PROFILE 值,如果为ON ,从module 文件或者对应的map 文件得到symbol 信息。读取nk.map 得到pTOC offset

    8. 重定位模块 image pages 地址

RAMIMAGE 开始地址为base address 。如果moduleNK.exe ,对于.kdataalign 64K ,其它情况align 4K

    7. Fix up relocation ,根据.reloc 段和.rel 文件。

8. 压缩module

9. 如果module 具有X type ,签名处理

10. 压缩FILE section ,如果COMPRESSION=ON ,压缩所有file

11. compact image . 由于alignpage ,所剩下没使用ram pace 。收集未填充数据的ram ,标记为hole ram 。移动module readwrite section 到未利用的ram address 中,移动module 头信息和setcion tablehole ram address.

12. 设置Copylist 链表信息类型为 COPYentry

typedef struct COPYentry {

    ULONG    ulSource ;               // copy source address

    ULONG    ulDest ;                 // copy destination address

    ULONG    ulCopyLen ;              // copy length

    ULONG    ulDestLen ;               // copy destination length

                                    // (zero fill to end if > ulCopyLen)

} COPYentry ;

If (模块具有Z 属性,不等于.kdata section 的读写段,例如.data section )

{

                    COPYentry::ulSource   = o32_obj ::o32_dataptr ;// 对应段的头信息

                   COPYentry::ulDest     = o32_obj ::o32_realaddr ;

                    COPYentry::ulCopyLen = o32_obj ::min_size ();

              COPYentry::ulDestLen = o32_obj ::o32_vsize ;

}

o32_obj image section file 结构为

typedef struct o32_obj {                /* .EXE memory object table entry    */

    unsigned char        o32_name [E32OBJNAMEBYTES ];/* Object name            */

    unsigned long        o32_vsize ;      /* Virtual memory size              */

    unsigned long        o32_rva ;        /* Object relative virtual address  */

    unsigned long        o32_psize ;      /* Physical file size of init. data */

    unsigned long        o32_dataptr ;    /* Image pages offset               */

    unsigned long        o32_realaddr ;   /* pointer to actual                */

    unsigned long        o32_access ;     /* assigned access                  */

    unsigned long        o32_temp3 ;

    unsigned long        o32_flags ;      /* Attribute flags for the object   */

} o32_obj , *LPo32_obj ;

13. 创建NK.bin magic B000FF/n image startimage length 到文件中。

14. module/file toc hole ram 得到ROMHDR 的在实际内存中的load address romhdr_offset (第一个满足sizeofROMHDR )大小的hole ram 块),写romhdr_offset + sizeofROMHDR )值(地址),tocs 大小 size tocs check sum 到文件,写tocs 内容到文件

MODULE toc ,结构:

typedef struct TOCentry {           // MODULE BIB section structure

    DWORD dwFileAttributes ;

    FILETIME ftTime ;

    DWORD nFileSize ;

    LPSTR    lpszFileName ;

    ULONG    ulE32Offset ;            // Offset to E32 structure ,文件头偏移

    ULONG    ulO32Offset ;            // Offset to O32 structure ,第一个image 段偏移

    ULONG    ulLoadOffset ;           // MODULE load buffer offset

} TOCentry , *LPTOCentry ;

  FILE toc, 结构:

typedef struct FILESentry {         // FILES BIB section structure

    DWORD dwFileAttributes ;

    FILETIME ftTime ;

    DWORD nRealFileSize ;

    DWORD nCompFileSize ;

    LPSTR    lpszFileName ;

    ULONG    ulLoadOffset ;           // FILES load buffer offset

} FILESentry , *LPFILESentry ;

 

15. MODULE 到文件中,各个section data( 格式:地址(o32_obj::o32_dataptr), 大小,checksum data), 各个module 头信息,section 头信息,module 文件名

16. FILE data 到文件

17. ROM signature 到文件。依次写入AddressRAMIMAGE start address + 0x40length2*sizeofDWORD ), check sumData 0x43454345 (“ECEC ”),romhdr_offset.

18. TOC pointer 到文件, 依次写入AddressRAMIMAGE start address + 0x40 + 2*sizeofDWORD ),lengthsizeofDWORD ),check sumData TOC 偏移(romhdr_offset - RAMIMAGE start address

19. copylist 信息 到文件 . 依次写入Address 第一个满足 copylist 大小的hole ram 块地址 lengthcopylist 大小 check sumDatacopylist 大小

20. romhdr 信息. 依次写入Address romhdr_offset lengthsizeof( ROMHDR) check sumDataromhdr data.

ROMHDR 结构: typedef struct ROMHDR {

    ULONG    dllfirst ;               // first DLL address ,用户模式下第一个模块load address// 默认为0x4001c001

ULONG    dlllast ;                // last DLL address ,用户模式下最后一个模块load address

                                // 默认为0x4001c001

    ULONG    physfirst ;               // first physical address, RAMIMAGEstart address

    ULONG    physlast ;               // highest physical address ,一般为ROMHDR 的结束地址

    ULONG    nummods ;                // number of TOCentry's ,模块的个数

ULONG    ulRAMStart ;             // start of RAM, physlast align 64k

       

    ULONG    ulRAMFree ;              // start of RAM free space 所有Z 属性模块的各个段大小之和( 对于每个段的大小为align_page(max(o32_vsize, o32_psize)) )

    ULONG    ulRAMEnd ;               // end of RAM RAM type 结束地址

    ULONG    ulCopyEntries ;          // number of copy section entries ,  // Z 属性模块个数

    ULONG    ulCopyOffset ;           // offset to copy section

    ULONG    ulProfileLen ;           // length of PROFentries RAM

    ULONG    ulProfileOffset ;        // offset to PROFentries

    ULONG    numfiles ;                // number of FILES

    ULONG    ulKernelFlags ;          // optional kernel flags from ROMFLAGS .bib config option

    ULONG    ulFSRamPercent ;         // Percentage of RAM used for filesystem

                                        // from FSRAMPERCENT .bib config option

                                        // byte 0 = #4K chunks/Mbyte of RAM for filesystem 0-2Mbytes 0-255

                                        // byte 1 = #4K chunks/Mbyte of RAM for filesystem 2-4Mbytes 0-255

                                         // byte 2 = #4K chunks/Mbyte of RAM for filesystem 4-6Mbytes 0-255

                                        // byte 3 = #4K chunks/Mbyte of RAM for filesystem > 6Mbytes 0-255

 

    ULONG    ulDrivglobStart ;        // device driver global starting address

    ULONG    ulDrivglobLen ;          // device driver global length

    USHORT   usCPUType ;              // CPU (machine) Type

    USHORT   usMiscFlags ;            // Miscellaneous flags

    PVOID    pExtensions ;            // pointer to ROM Header extensions

    ULONG    ulTrackingStart ;        // tracking memory starting address

    ULONG    ulTrackingLen ;          // tracking memory ending address

} ROMHDR ;

 

21. Address 0x00000000 length jump address check sum 0x00000000 到文件

22. image 大小到文件,重新fseek (image_file , 11, SEEK_SET ) ,写入image size(s_romhdr .physlast -s_romhdr .physfirst )

NK.bin 文件结构

 

"B000FF/x0A" //7 字节大小

ImageStartAddress, ImageLength //8 字节大小

  RecordAddress, RecordLength, RecordChecksum, Data…….// module/file toc 信息

 

RecordAddress, RecordLength, RecordChecksum, Data…// modulese 信息

           

RecordAddress, RecordLength, RecordChecksum, Data…// files 信息

           

RecordAddress, RecordLength, RecordChecksum, Data 0x43454345 // ROM signature

           

RecordAddress, RecordLength, RecordChecksum, Data 0x43454345 // TOC pointer

           

RecordAddress, RecordLength, RecordChecksum, Data 0x43454345 // copylist 信息

           

RecordAddress, RecordLength, RecordChecksum, Data 0x43454345 // romhdr 信息

           

0x00000000 , JumpAddress , 0x00000000 // 启动地址startup 地址

本文粗鲁地分析了ROMIMAGE 工具,欢迎大家拍砖, 把我的错误暴露在阳光下 ……

 

 

 

原创粉丝点击