- 积分
- 213
- 实力分
- 点
- 金钱数
- 两
- 技术分
- 分
- 贡献分
- 分
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
以下是狼大的SFE教程,转到本版供大家学习,后面几个跟贴有具体的使用实例: (顶楼附了SFE.exe软件)
[Patch工具]sfe使用详解
作者:Coollang
看到大家做补丁时好像还在使用一些过时的工具,比如我在用ultraedit搭建Patch开发环境里面说到的KeilC166,还有在输出注释方面的费尽排版。实在心有不忍,这里给大家介绍一下RizaPN创作的工具sfe,全名是siemens flash explorer,即“西门子Flash浏览器”,这给大家造成了假象,仿佛是类似于smelter一样的工具。实际上仅仅是sfe开始的功能,而sfe最强大的功能是他的开发能力,可以做到汇编C166生成vkp、bin等格式及行汇编,可以反汇编vkp,bin。而且甚至可以做到debugC166的程序。说起sfe的好处,那真是说也说不完!下面我就给大家介绍一下sfe的主要功能,并重点说一下patch所用到的、极大增强效率的功能。
我们先看一下Riza对它的介绍:
CODE:[Copy to clipboard]sfe is my mini tools (around 50KB compressed exe file) to explore
Siemens mobile phone flash file. Using this tools,
we can do this following task :
- search for free area inside the fullflash file (to put our patch),
- binary copy, from any offset & source file to any offset & destination,
- compare two files, and get the popular (patch) differences format,
- find byte sequences with '?' (match with any digit) capability,
- extract language data from fullflash file,
- convert any text to language data,
- extract menu structure and their entry-point,
- C166 assembler and disassembler (yes! they are included!),
- and even C166 debugger (yes! finally!)
从sfe的开发历史来看,Riza从2003年的12月就开始了开发,那时我还在用Keil和ultraedit的集成环境。早期只是集成了Riza的一些工具,如fbytes、fmenu等,后来增加了汇编功能和语言包的处理。本质上说做Patch的都是些不安于现状、力图对环境有所改变的人,而Riza做得更为彻底!
我忘了自己从什么时候开始用的sfe,不过从那之后我就再也没有用过Keil(应该是从短消息计数开始,04-8)。并见证了sfe走向完美,起码对于C166的Patch来说,几乎是极致了!不啰嗦了,下面从简单功能开始分块说一下sfe的主要功能:
sfe是一个控制台工具,你可以通过在98下运行Command和在2K/XP下运行CMD进入控制台。sfe的命令格式如下:
CODE:[Copy to clipboard]>sfe
Usage : sfe <cmd> <parameters>
cmd: incopy binary copy
[c]omp compare
[d]isasm C166 disassembly
[f]ind find bytes sequences or display file in hexa
nfo file info
[l]ang language data information
[m]enu explore menu structure
[p]atch patching stuff
[0]free search for free area
[a]sm C166 assembler
[r]un run C166 binary file
Just enter sfe <cmd> to get more help for the specific <cmd>
Add minus (-) sign before command to run it in verbose mode.
在实际使用中,我发现恰好相反的是加-会抑制verbose模式。
而不加参数可以看命令的格式,如下:
CODE:[Copy to clipboard]>sfe a
Usage : sfe asm <asmfile[,name[,outfile]]> [<flag[,outsize[,baseAddr]]>] [<origFile>]
name : patch name to be displayed (skip=all patches)
outfile : output file
flag : output format
-> n : or without flag, normal
-> d : complete (debugging purposes)
-> p : patch format
outsize : display output size perline
baseAddr : baseAddr used in the patch format
origFile : original fullflash file
下面分别说一下sfe的功能
1、搜索Flash中的空闲区域。
这个没什么好说的了,如果要扩展功能的话,总要找一些地方放自己的代码,这个功能就是搜索Flash中全FF的部分,命令格式如下:
CODE:[Copy to clipboard]Usage : sfe 0free <binfile> [numbytes]
numbytes : number of byte 'FF' to be searched (default=0x300)
Search for Free Area:
=====================
> sfe 0 ; get help
> sfe 0 binfile.bin ; search free area (default = 0x300 bytes)
> sfe 0 binfile.bin 1000 ; search for 0x1000 free bytes
没有什么可说的,除了一个参数来指定最小的视为空闲Block的单位。
2、二进制格式拷贝。
Riza早期单独写过一个这样的工具,后来集成的sfe中来了,命令格式如下:
CODE:[Copy to clipboard]Usage : sfe bincopy <srcfile[,pos[,size]]> <dsfile[,pos]>
Binary Copy:
============
> sfe b ; get help
> sfe b src.bin dst.bin ; copy src.bin to dst.bin
> sfe b src.bin,20 dst.bin ; copy src.bin, offset 0x20 to dst.bin
> sfe b src.bin,20,100 dst.bin ; copy src.bin, offset 0x20 size 0x100 to dst.bin
> sfe b src.bin,20,100 dst.bin,200 ; copy src.bin, offset 0x20 size 0x100 to dst.bin offset 0x200
主要功能是把一个binary文件copy到另一个当中,可以指定偏移和拷贝数量。
3、文件比较。
类似于控制台下的FC工具,主要是用来比较二进制文件,有相当多的控制选项,命令格式如下:
CODE:[Copy to clipboard]Usage : sfe find <srcfile[,pos[,size]]> <mark> [<dspbyte[,start]>]
sfe find <srcfile[,pos[,size]]> <addr[,size]>
mark(comma separated):
blank anybyte
00-FF value
0?-F? low part match
?0-?F high part match
example : E6,F?,,03
dspbyte : number of byte to be displayed
start : relatif start position to be displayed
Compare Files:
==============
> sfe c ; get help
> sfe c src.bin dst.bin ; compare src.bin and dst.bin
> sfe c src.bin,20 dst.bin ; compare src.bin from offset 0x20 with dst.bin
> sfe c src.bin,20,100 dst.bin ; compare src.bin from offset 0x20 with dst.bin for 0x100 bytes
> sfe c src.bin,20,100 dst.bin,300 ; compare src.bin from offset 0x20 with dst.bin from offset 0x300
> sfe c src.bin,20 dst.bin a00000 ; compare and use a00000 as an output display base address
> sfe c src.bin,20 dst.bin a00000,16 ; compare, use base address, and the size of each line is 16 bytes
> sfe c src.bin,20 dst.bin a00000,16,all ; display all data from src.bin offset 0x20 and dst.bin (not only the differences)
实际上,早期的Patch没有V_KLAY这样的工具,只能是直接在binary文件上修改,这个功能还是很有效的。
4、查找字节序列
这个功能早期是fbytes工具的功能,主要是在Flash中寻找具有字节特征的位置,比如某些指令,具有相同的操作码,但是不同位置的操作数不同,这是可以用??来进行模糊查找。对于在Flash中移植Patch时还是很有意义的,比如查找某个函数的调用情况,或者在不同机型中查找具有特定特征的指令。
CODE:[Copy to clipboard]Usage : sfe find <srcfile[,pos[,size]]> <mark> [<dspbyte[,start]>]
sfe find <srcfile[,pos[,size]]> <addr[,size]>
mark(comma separated):
blank anybyte
00-FF value
0?-F? low part match
?0-?F high part match
example : E6,F?,,03
dspbyte : number of byte to be displayed
start : relatif start position to be displayed
Find Byte Sequences:
====================
> sfe f ; get help
> sfe f src.bin e6,f?,,20,e6 ; search for 'E6 F? ?? 20 E6' sequences ? is match with any digit, blank is match with any byte
> sfe f src.bin,200 e6,f?,,20,e6 ; same search but from offset 0x200
> sfe f src.bin e6,f?,,20,e6 10 ; same search but displaying 10 bytes
> sfe f src.bin e6,f?,,20,e6 10,4 ; same search, display 10 bytes starting from 4 previous bytes
> sfe f src.bin 1234 ; display content of src.bin file (hexa format) starting from address, 80 bytes
> sfe f src.bin 100:1000,8 ; same but display address 100:1000 (page:offset) for total 8 bytes.
5、语言包的支持功能
sfe的语言包功能包括导出Flash中语言包的所有字串,显示Flash中的特定ID的字串,以及语言包中某个语言的字串等。其中支持文字到到语言包格式的转换。不过对中文的支持有点问题。
此外Riza在最新版本中添加了一些对语言包文件的支持,这个主要是为把特定程序作为语言包格式加载而作的准备,因为LG1的机器支持加载语言包和T9,其中语言包被加载到Flash的特定位置,利用这一特征,可以把bin格式的修改做成语言包的格式加载到Flash中。
CODE:[Copy to clipboard]Usage : sfe l[c] <bin|lng-file> [<ID|-langno|'string|+hexcode> [<langno>]]
ID : text id (hexa) to be displayed
langno : language no to be displayed (all text)
string : string to be converted
hexcode : list of hexa code (space separated) to be decoded
langno : language no to be used for convertion
lc : check and correct LNG file
Extract Language Data:
======================
> sfe l ; get help
> sfe l src.bin ; extract all data from the 1st language including the extended text data
> sfe l src.bin 200 ; display string ID 200
> sfe l src.bin 200 2 ; display string ID 200 from the 3rd language data (1st=0,2nd=1...)
> sfe l src.bin -1 ; extract all data from the 2nd language
> sfe l src.bin -all ; extract all existing language data
> sfe l src.bin 'Testing ; convert 'Testing' text
> sfe l src.bin 'Testing 1 ; convert 'Testing' text using langID 1
> sfe l src.bin "+41 8C 91 56 4F" ; convert hexa data to text
> sfe l scr.bin 200,"<95>Test" ; generate patch data to modify stringID 200 with text "<95>Test"
> sfe l test.lng ; check LNG file test.lng for CRC and size data
> sfe lc test.lng ; check and correct CRC and size data of test.lng
6、Menu的支持功能
因为在西门子的手机中,某些菜单项有特定的格式,这个我在入门里面说过。而Riza是最早发现这个格式的人,并完成了fmenu程序,用来根据菜单文字来在Flash中查找菜单项结构,并可以确定此菜单的响应函数。
CODE:[Copy to clipboard]Usage : sfe menu <binfile>
Extract Menu:
=============
> sfe m ; get help
> sfe m src.bin ; extract menu structure and entry-point
7、Patch功能
这个功能是用来把VKP格式的Patch应用到二进制文件中去,和V_KLay的应用到文件功能类似,可知做到应用和撤销Patch。此外,在新版本的程序中,Riza为了支持Bin格式的Patch,需要一个从VKP格式的Patch生成二进制文件的功能,也在P功能里支持。
CODE:[Copy to clipboard]Usage : sfe <patch|pd> <binfile> <patchfile> [<baseaddr>[,<patchID>[,undo]]]
binfile : binary file to be patched
baseaddr : the 1st 2 hexa digit for baseaddr
patchID : patch name
undo : undo the patch
pd : binary file will always re-created
Patching:
=========
> sfe p ; get help
> sfe p sl45_44.bin patch.txt 44,BCI ; apply BCI patch for address 44zzzz from
patch file patch.txt to file sl45_44.bin
> sfe p sl45_44.bin p.txt 44,BCI,u ; undo BCI patch from patch file p.txt and
bin file sl45_44.bin for address 44zzzz
> sfe p binfile.bin p.txt 00,BCI ; create bin file binfile.bin from BCI patch
file p.txt for address 00zzzz
8、C166汇编
这个就是sfe最重要的功能,可以看到前面的功能都有类似的工具提供,而这个是sfe独一无二的,对于Patcher来说也是做得最好的。我在这里只是简单的介绍一下常用功能,在后面会详细的举例介绍汇编功能。
sfe的汇编功能可以说主要就是为patch而作的,所以对于patch来说,用起来非常的得心应手。sfe建立了一套自己的汇编规则,来支持patch。比如sfe支持VKP格式的直接输出,同时支持基址的设定。支持随意用org指令来设定Progrma Counter,来达到任意定位程序的功能,这一个是非常有意义的。此外,还支持行汇编功能。
CODE:[Copy to clipboard]Usage : sfe asm <asmfile[,name[,outfile]]> [<flag[,outsize[,baseAddr]]>] [<origFile>]
name : patch name to be displayed (skip=all patches)
outfile : output file
flag : output format
-> n : or without flag, normal
-> d : complete (debugging purposes)
-> p : patch format
outsize : display output size perline
baseAddr : baseAddr used in the patch format
origFile : original fullflash file
Assembler:
==========
> sfe a ; get help
> sfe a src.asm ; compile src.asm
> sfe a src.asm d ; compile src.asm, complete (debug) output
> sfe a "mov r12, #1234h" ; inline assembler
> sfe a "mov r2,r1 ; sub r2,#1" ; multiline inline assembler
> sfe a src.asm,TST ; compile patch TST from src.asm
> sfe a src.asm,TST p ; same function, patched display output
> sfe a src.asm,TST p,10 ; same function, 0x10 bytes perline output
> sfe a src.asm,TST p,10,a00000 ; same function, base address = 0xa00000
> sfe a s.asm,TST p,10 org.bin ; include the original values from org.bin
*) See Assembler Part to get more 'assembler' function detail
9、C166反汇编功能
sfe的反汇编功能支持常规的从bin格式的文件中反汇编的功能,可以支持设定bin文件的开始汇编地址和长度,以及bin文件的基址。很有意义的功能就是sfe支持从vkp格式的文件中直接反汇编,这是一个非常方便的功能,在此之前,如果patch发布者没有发布源码的话,那其他人就只能把此vkp用IDC刷入IDA中进行反汇编了。此外,sfe为了支持显示任意图片的DrawImage功能,增加了解析BMP图片的功能,可以把BMP反汇编成内部的资源格式,下面的例子中会详细讲解一下。我没有试过这个功能对彩色图片的支持情况。
CODE:[Copy to clipboard]Usage : sfe disasm <file[,pos[,size]]> [<baseaddr>,<flag>]
file : binary, patch, or BMP file
pos : start position to be disassembled
size : number of byte to be read from the file
baseaddr : base address to be used
flag : p for patch format
Disassembler:
=============
> sfe d ; get help
> sfe d src.bin ; decompile src.bin
> sfe d src.bin,200 ; decompile from offset 0x200
> sfe d src.bin,200,100 ; same function, but only 0x100 bytes
> sfe d src.bin,200,100 a00000 ; same function with base address for
output A00000
> sfe d src.bin,200,101 a00000 ; same function, but directly stop if
'RETS' command is founded before end
> sfe d src.bin,200,101 a00000,p ; same function, asm ready output
> sfe d t.txt,27e000,101 ; disassembler from patch file t.txt
> sfe d image.bmp ; disasm bitmap (1 bit format), assembler output
> sfe d image.bmp,8,8 10,10,img1 ; same function but for image at position 8,8
with size 10x10, name it as img1
10、Debug功能
sfe还提供了一个类似于dos下debug工具那样的调试环境,利用它可以进行一些非平台相关的调试工作,比如一个独立的算法,或者一个字符串处理的功能,都可以利用这个调试工具进行调试。sfe还可以加载一个文件作为RAM的内容。用这样的工具可以很容易的发现一些汇编时的笔误,比如将mov R6,#6写成mov R6, 6这种情况。我还从没用过这个功能。
CODE:[Copy to clipboard]Usage : sfe run <file[,pos[,size]]> [baseAddr[,flag[,memFile]]]
file : C166 binary or assembler file
pos : file offset
size : size of bytecode
baseAddr: disassembler base address
flag : run options
memFile : memory configuration file
Debugger:
=========
> sfe r ; get help
> sfe r src.bin ; run bytecode from src.bin
> sfe r src.asm ; run assembler command from src.asm
> sfe r src.asm ,n ; same function, normal display output
> sfe r src.bin,200 ; run from offset 0x200
> sfe r src.bin,200,100 ; run 0x100 bytes from offset 0x200
> sfe r src.bin b00000 ; run with base address B00000
> sfe r src.bin ,,src.mem ; run with memory file src.mem
> sfe r src.bin ,ri,src.mem ; run interractive debugger
Interractive Debugger:
======================
> h ; get help
> g a00000 ; goto address a00000
> g 37:3800 ; goto address 37:3800 (37*0x4000+3800 = DF800)
> d ; dump memory (current address)
> d a00000 ; dump memory address a00000
> d a00000 200 ; dump memory address a00000, size 0x200
> d r ; dump registers
> a ; inline assembler
> a c7d530 ; inline assembler at address c7d530
> u ; display unassembler
> u a00020 ; display unassembler address a00020
> r ; run 1 command, current address
> r 1 ; run 1 command (skip call), current address
> r 0 ; run until return
> r -c7d580 ; run until address c7d580
> q ; quit
*) All command without argument will change the current address
介绍完了所有手册上的东西,就重点说一下自己平时经常用到的功能。
第一个就是反汇编VKP的功能,不过这个要注意,VKP的格式要符合0xNNNN: XXXX YYYY这样的,如果中间的空格多于一个的话,就会反汇编的面貌全非。此外,sfe不能正确地处理vkp中的数据部分,只能自己来手工处理一下,如下面的例子:
CODE:[Copy to clipboard]0x35E748: F0C8F0D9 DAF6002F
0x562F00: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F0C8F0D9E6FE2000DAF60403D7400D00
0x562F10: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F2F4E6255C14D740D803D4442E2FF0C8
0x562F20: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F0D9F0E4DAF60403F0C8F0D9DB000A54
0x562F30: FFFFFFFFFFFFFFFFFFFFFFFF 015403540454065408540954
这个是修改待机日期增加星期的一个patch,那么我们把它存到文件patch.txt里,然后用下面的命令来反汇编它。不过因为sfe的限制,我们只能指定一个pos:
CODE:[Copy to clipboard]>sfe d patch.txt,562F00,101 A00000,p
;Siemens Flash Explorer v2.51c (c)Dec.03 by RizaPN <rizapn@yahoo.com>
;File patch.txt (pos=0x0,sz=0x141,rd=0x141) buffered
;Disassembly: offset=0x0, size=0x141, baseAddr=0xA00000
org 0F62F00h
mov r12, r8
mov r13, r9
mov r14, #20h
calls 0F6h, 304h
extp #0Dh, #1
mov r4, 25E6h
shl r4, #1
extp #3D8h, #1
mov r4, [r4+#2F2Eh]
mov r12, r8
mov r13, r9
mov r14, r4
calls 0F6h, 304h
mov r12, r8
mov r13, r9
rets
bfldl 0FEA8h, #1, #54h
addb 0FEA8h, 5404h
add 0FEA8h, #5408h
addb rh2, #4
end
知里面562F00是开始地址,101表示到ret结束,当然也可给出具体的size或者一个大的size来汇编从562F00开始的部分。A00000表示基址,p表示汇编格式,如果不加p就是如下输出:
CODE:[Copy to clipboard]>sfe d patch.txt,562F00,1000 A00000,
;Siemens Flash Explorer v2.51c (c)Dec.03 by RizaPN <rizapn@yahoo.com>
;File patch.txt (pos=0x0,sz=0x141,rd=0x141) buffered
;Disassembly: offset=0x0, size=0x141, baseAddr=0xA00000
562F00: F0 C8 : mov r12, r8
562F02: F0 D9 : mov r13, r9
562F04: E6 FE 20 00 : mov r14, #20h
562F08: DA F6 04 03 : calls 0F6h, loc_F60304
562F0C: D7 40 0D 00 : extp #0Dh, #1
562F10: F2 F4 E6 25 : mov r4, 365E6h ; (000D:25E6)
562F14: 5C 14 : shl r4, #1
562F16: D7 40 D8 03 : extp #3D8h, #1
562F1A: D4 44 2E 2F : mov r4, [r4+#2F2Eh]
562F1E: F0 C8 : mov r12, r8
562F20: F0 D9 : mov r13, r9
562F22: F0 E4 : mov r14, r4
562F24: DA F6 04 03 : calls 0F6h, loc_F60304
562F28: F0 C8 : mov r12, r8
562F2A: F0 D9 : mov r13, r9
562F2C: DB 00 : rets
;------------------------------------------------------------
562F2E: 0A 54 01 54 : bfldl mem_FEA8, #1, #54h
562F32: 03 54 04 54 : addb mem_FEA8, 5404h
562F36: 06 54 08 54 : add mem_FEA8, #5408h
562F3A: 09 54 : addb rh2, #4
可以看到,sfe不能正确地识别数据部分,就是从562F2E开始的中文星期定义。
除此以外,sfe的反汇编指令里面还包括了处理单色bmp图片的功能,在siemens的黑白机中,图片一般是如下格式:
CODE:[Copy to clipboard]struct bmpheader{
byte width;
byte height
word flag;
word offset;
word page;
}
其中offset和page指向具体的图片内容。大家都使用过DrawPredefImage的函数,传入一个图片ID来显示预置图片,实际上,还可以给定一个bmpheader来显示任意图片,在6688中,这个函数是DrawImage->0D111CAh。它接受的参数是一个bmpheader的结构体和显示的区域,此外就是和DrawPredefImage一样的显示位置。我们看一下下面的Patch:
CODE:[Copy to clipboard];-------------------------------------------
;#name ICI. IME Change Icon
;-------------------------------------------
;[0F63400h - 0F634FFh]
'6688V55 -D- 05.03.04 - coollang[SPGC] - 另一个输入法图标替换[563400h - 5634FFh]
'【Flash修改】另一个输入法图标替换
'适用:6688V55
'作者:coollang[SPGC]
'版本:V1.0
'说明:这个和sOLO的功能是一样的,不过用了另一个显示图片的函数,图片数据在补丁中
' 不会有图片冲突,此外我在切换输入法的地方调用了一下SetCurrentIME,更新了
' 数据,所以在切换输入时也会正常显示。
org 0E4B290h
calls IME_CorrectImage
org 0E3A178h
calls IME_SetCurrentIME
org 0F63400h
IME_CorrectImage:
calls 0D9E6F2h
cmpb rl4, #06h
jmpr cc_Z, IME_CorrectImage_06
IME_DisableBiHua:
cmpb rl4, #08h
jmpr cc_Z, IME_CorrectImage_08
calls DrawImageByIndex
rets
IME_CorrectImage_06:
mov r4, #pof(hdr_IME)
mov r5, #pag(hdr_IME)
jmpr cc_UC, IME_CorrectImage_Draw
IME_CorrectImage_08:
mov r4, #pof(hdr_IME2)
mov r5, #pag(hdr_IME2)
IME_CorrectImage_Draw:
mov [-r0], r5
mov [-r0], r4
mov r14, #74
mov r15, #8
calls drawImage
add r0, #4
rets
IME_SetCurrentIME:
mov r12, r8
mov r13, r9
calls 0E3B852h ;GetContextIME
mov r12, r4
calls 0D9E6E6h ;SetCurrentIME
mov r12, r8
mov r13, r9
rets
'图片数据,用sfe 2.51生成.
hdr_IME:
db 74,8,1,0
dw pof(bmp_IME),pag(bmp_IME)
bmp_IME:
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x01,0x00,0x78,0x03,0x00,0x00,0x03,0x00,0x00,0x00
db 0x03,0x00,0x40,0x04,0x80,0x54,0x04,0x80,0x28,0x00
db 0x01,0x00,0x70,0x04,0x80,0x38,0x04,0x80,0x7C,0x00
db 0x01,0x00,0x08,0x03,0x80,0x10,0x04,0x80,0x28,0x00
db 0x01,0x00,0x08,0x00,0x80,0x38,0x04,0x80,0x7C,0x00
db 0x01,0x00,0x70,0x07,0x00,0x54,0x03,0x00,0x28,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
hdr_IME2:
db 74,8,1,0
dw pof(bmp_IME2),pag(bmp_IME2)
bmp_IME2:
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x1F,0x00,0xE0,0x03,0x00,0x00,0x03,0x00,0x00,0x00
db 0x01,0x01,0x10,0x04,0x80,0x54,0x04,0x80,0x28,0x00
db 0x02,0x00,0xE0,0x04,0x80,0x38,0x04,0x80,0x7C,0x00
db 0x04,0x01,0x10,0x03,0x80,0x10,0x04,0x80,0x28,0x00
db 0x08,0x01,0x10,0x00,0x80,0x38,0x04,0x80,0x7C,0x00
db 0x08,0x00,0xE0,0x07,0x00,0x54,0x03,0x00,0x28,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
';如果不想改变笔画输入法的图片,取消下面的注释
org IME_DisableBiHua
nop
nop
nop
这是另一个输入法图标的源码,从这里面我们可以看到sfe汇编的很多先进用法。其中hdr_IME和hdr_IME2是用sfe生成的。命令如下:
CODE:[Copy to clipboard]>sfe -d bh.bmp,0,0 74,8,IME
;bh.bmp 74x8 pixels (0,0 74x8)
hdr_IME:
db 74,8,1,0
dw pof(bmp_IME),pag(bmp_IME)
bmp_IME:
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x1F,0x00,0xE0,0x03,0x00,0x00,0x03,0x00,0x00,0x00
db 0x01,0x01,0x10,0x04,0x80,0x54,0x04,0x80,0x28,0x00
db 0x02,0x00,0xE0,0x04,0x80,0x38,0x04,0x80,0x7C,0x00
db 0x04,0x01,0x10,0x03,0x80,0x10,0x04,0x80,0x28,0x00
db 0x08,0x01,0x10,0x00,0x80,0x38,0x04,0x80,0x7C,0x00
db 0x08,0x00,0xE0,0x07,0x00,0x54,0x03,0x00,0x28,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
这里面,你可以指定图片中开始的位置和大小,或者是不指定,如下面的格式:
CODE:[Copy to clipboard]>sfe -d bh.bmp ,,IME
下面我们具体说一下sfe的编译功能,这个我感觉是sfe最强大的功能。下面是sfe支持的语法!
CODE:[Copy to clipboard]Specific Assembler Mnemonic:
============================
*) All standard C166 mnemonic is implemented.
*) Character ; is used to put the remark (anywhere in the line)
*) "Non-standard" mnemonic implemented are :
#include filename ; include commands from filename (definitions)
#define var value ; set variable var = value
var equ value ; set var = value
db 'X',36h ; define byte(s)
dw 1234h,0,'AB' ; define word(s)
org ; set the current address
base ; set base Address (output address in the patch format
will be (currentAddress-baseAddress)
end ; end of processed file
;#name XXX.string ; patch name definition (XXX)
' ; printed as remark in the patch output
'' ; printed as <enter> in the patch output
'; ; printed as remark, and all the following code is remarked
until '' is found
;' ; remark will be printed also in the patch output
+ - * / % ; add, sub, mul, div, and mod operation
>> > < << ; shr and shl operation
& && | || ^ ^^ ; and, or, xor operation
val1:val2 ; page operation (val = val1 * 0x4000 + val2)
page(value),
pag(value),
p(value) ; page value (= value / 0x4000)
pof(value),
q(value) ; offset of page value (= value mod 0x4000)
segment(value),
seg(value),
s(value) ; segment value (= value div 0xFFFF)
offset(value),
ofs(value),
sof(value),
o(value) ; offset of segment value (= value mod 0xFFFF)
其中比较特殊的是:
1、org。org用来指定程序计数器的地址,也就是PC的地址,相当于指定汇编开始的地址。
2、base。base可以指定基址,这个主要用来辅助sfe转换内部地址到文件偏移用的。
3、;#name XXX.string。patch名定义,sfe支持在一个文件内定义多个patch的机制,就是用name来指定patch名,不过我的建议是,尽量不要把太多的patch放在一个文件里,那样的编译速度是非常慢的,几乎难以忍受,我的感觉是sfe编译所有的patch,然后输出特定的patch。
4、sfe的注释功能,这是sfe最强大的功能了,通过增加注释的格式,来控制生成的vkp的各种说明文字,使注释不仅仅是开发时的说明文字,而是直接输出到终极的patch中。具体的格式有:
a、; 普通注释
b、' 注释会被输出到生成的vkp中。
c、'' 在输出中增加一个换行。
d、'; 以下所有的代码会作为注释输出,直到遇见一个 ''。这个用来提供某些选项时非常有效,比如常见的“要想xxx取消一下三行的注释”。
e、;' 一般是在vkp的补丁内容后面添加注释,和'不同的是不换行。
5、page,segment和offset族。这些主要是因为C166是段页式寻址的,用来指定线性地址的段和页以及段内和页内偏移。但是我推荐你使用标准的pof,pag,seg,sof。因为这样把程序移植到别的编译器上比较方便。
[ 本帖最后由 Xinshou 于 2005-12-31 10:20 编辑 ] |
|