- 积分
- 813
- 实力分
- 点
- 金钱数
- 两
- 技术分
- 分
- 贡献分
- 分
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
主题:西门子手机Flash修改入门
作者:Cool_Lang
摘要:
本文讲述了了西门子手机Flash(FireWare)修改的相关知识,简单的实现了一个Patch,并以图形菜单的Patch展示了Flash修改的强大。
关键字:Siemens Flash Patch
--------------------------------------------------------------------------------
很抱歉,以前答应大家的,一直没时间写。看到越来越多的朋友向加入到这个行列中来,却苦于入门乏术,因此写下这篇教程。
这些东西是我做修改以来总结的一些经验,因为我也是用6688后(15/3/2003)学的这些东西,有些可能不是很准确,还请大家看后共同讨论。
一、Flash修改的必要工具
1、Hex编辑器:UltraEdit,我推荐UltraEdit,因为它比起其他的编辑器界面友好,功能强大(这篇文章就是用它写的)。
2、Flash工具:UniSinmens,V_KLAY, KSie, zSiemens。这些工具各有千秋,最好是备齐。
3、反汇编工具:ADIS16X,IDA。这两个应该是必须的,他们的侧重点不同。IDA用来汇编整个Flash。而ADIS16X可以汇编小文件,或直接编写指令。
4、辅助工具:Fbytes,Fmenu,(RizaPN)C166 Compiler,C166 JMP(ACiD [mrp])。这些工具都很有用,比如Fbytes可以模糊查找某些Bytes。
5、其他工具:科学计算器,FFMod,Cool_Image,LanguageEditor。这些工具也起到一定的用处。其中语言编辑器很重要,因为它可以到处说有的字串资源,但只能在英文98下运行。我会放上55和56的字串表(中文不能显示,只能对照着英文的使用)。
5、编程手册:80C166处理器手册,汇编指令手册
二、Flash修改的预备知识
1、80C166的一些知识。
至于处理器的信息我就不介绍了(我也不懂),大家可以看166的手册。我只说一些和Flash紧密相关的存储器知识。166的架构和其他所有的嵌入式系统一样,分为内存和外存。段页式寻址。寻址空间16M。每段(seg)为0x10000,每个页(page)是0x4000。内存储器也就是RAM,我在Flash中看到的最大Page是37,所以RAM大小应该是880KB(0x4000 X 0x37)。6688系列的外存分为两部分6M的Flash(用的是INTEL的88C2和88C4)和MMC。6M的Flash被映射到0xA00000,进行统一寻址。而MMC则作为Dos的Fat格式的文件系统进行挂载,无需多说。其中6M的Flash又分为Rom部分和EEPROM,这么划分只是用法的不同。比如大家熟知的EEPROM指的是从5F0000开始的64KB。还有EE_FS。这个叫法是历史原因。早期的手机FLASJ(ROM)和EEPROM(存储动态数据)是分开的。现在只是用Flash的不同部分来处理。
Flash地址和文件地址的转换,在手机内部是用统一的16M地址来处理Flash的。所以有如下公式
FlashAddress = FileAddress + 0xA00000。而转换为页地址则为
FlashAddress / 0x4000 = Page ;FlashAddress % 0x4000 = Offset。
例如DAAF1234这个指令,DA表示CALLS函数调用。而AF5678则是被调函数的地址,其中AF是段地址(seg),而7856H(地位在前,高位在后)则是段内偏移量。
FlashAddress = 0xAF7856,转换为文件地址则为0xF7856。
Page = 0xAF7856 / 4000H = 0x2BD, offset = 0x7856 % 4000H = 0x3856。
在一些资源(Image,Ringtone,Fonts)的索引中,地址就是以(page,offset)的方式存储,而在EEPROM索引中,是以FlashAddress的方式存储的。
2、常用指令的问题。
在我们的修改中,见到的大多数指令都很简单,不外乎CALL,MOV,JPR,ADD,SUB等,只需注意一下段内跳转和段间跳转即可。还有EXTP等系列指令,在修改中经常见到。他是临时更换页地址的指令,比如D7 40 34 00,为EXTP #32 #1。#32(临时页地址),#1(有效指令数)。表示下面的1条指令的页地址为32H。还需要注意的是乘和除使用乘法寄存器MD进行操作。比如Mul op1,op2执行的操作时MD=op1*op2。32位寄存器MD的地址是FF0C。MDL是FF0C,而MDH是FF0E。除法时则是先把被除数放入MD。DIV op执行的是(MDL)=(MD)/(op1),(MDH)=(MD)mod(op1)。
3、常用资源的索引格式
这些我在《半月谈》里曾说过一些,不是很详细,这里再说一下。
Image索引格式:
00 Byte 图片高度Higth
01 Byte 图片宽度Weigth
02 Word unhnown
04 Word 页内偏移OFFSET
06 Word 页地址PAGE
例如
ID:1
0x5F0000 (索引表开始地址) 04 04 01 00 FA 3F A1 03
PAGE = 03A1
OFFSET = 3FFA
FlashAddress = (0x03A1 * 0x4000 + 3FFA) = 0xE87FFA
ImageFileAddress 0x487FFA = FlashAddress - 0xA000000
Ringtong索引格式:
00 Word RingID
02 Word 页内偏移OFFSET
04 Word 页地址PAGE
例如
ID:0(从0开始)
0x44E522 (索引表开始地址) 00 00 00 00 93 03
PAGE = 0393
OFFSET = 0000
FlashAddress = (0x0393 * 0x4000 + 0000) = 0xE4C000
ImageFileAddress 0x44C000 = FlashAddress - 0xA000000
Fonts索引格式
这个我还不是很清楚,就不班门弄斧了。
索引开始于0x4E4DA6:
ID:1
0B 20 7E 00 02 00 00 00 A1 03
EEP索引格式:
Offset Size Description
------ ----- ----------------------------------------------
00 BYTE Record starting marker [00,F0,FC] 记录标志为00,F0或FC
00= Unused block? 不用的Block
F0= Deleted block? 删除的Block
FC= Used block? 当前有效的Block
01 BYTE Version. [00..05]
Always zero in LBA_FS & EE_FS blocks.
Only EELITE blocks that has 04 & 05.
02 WORD Size
04 DWORD Linear address of data 此处为FlashAddress
08 WORD ID 为平常说的BlockXX,如Block67
0A BYTE ??? [00,01,02]
Always zero in EEFULL & EELITE blocks.
Always 02 in LBA_FS & EE_FS blocks.
0B BYTE Record ending marker [00,F0,FC,FF]
FF= No more record
EEPROM分为EEFULL和EELITE。EEFULL主要是和机器软件的相关配置有关的内容,而EELITE更多的是和设备信息有关的内容
例如:
Block ID:71(47H)
FC 01 C8 00 74 F9 FF 00 47 00 00 FC
FC 开始标志,当前有效
01 版本
C8 00文件大小00C8H = 200
74 F9 FF 00Block地址,为Flash地址00FFF974H,转换为文件地址为FFF974H - A00000H 5FF974
47 00Block ID 0047H , 0047H = 71
00 在EELITE 中为 0
FC结束标志。
4、寄存器的习惯用法
在Flash程序中,一些寄存器有固定的习惯用法。R12,R13,R14,R15作为传入参数,而R4和R5作为传出参数,R0被用为系统栈。例如下面的指令:
Mov [-R0],R6
.......
Mov R6,[R0+]
就是一次常见的压栈过程。下面是一个C语言中库函数strchr的汇编实现:
seg199:84CC strchr:
seg199:84CC
seg199:84CC push DPP0 //R12也是传入参数,offset
seg199:84CE mov DPP0, r13 //传入参数,Page
seg199:84D2 mov r1, r14 //传入参数,查找的char
seg199:84D4 calls 1, sub_10240 //这是一个库函数,执行的比较功能
seg199:84D8 cmpb rl1, rh1
seg199:84DA jmpr cc_NZ, loc_C784E6 //如果未找到,跳到失败处理
seg199:84DC mov r4, r12 //找到返回,R4未找到的offset
seg199:84DE mov r5, DPP0 //r5 page
seg199:84E2 pop DPP0
seg199:84E4 rets
seg199:84E6 Failed:
seg199:84E6 mov r5, #0 //为找到返回空
seg199:84E8 mov r4, #0
seg199:84EA pop DPP0
seg199:84EC rets
Push指令很少使用,常见的是将当前Page压栈.而对运行中的数据大多使用R0的栈. |
|