系统字库置换原理.docx
- 文档编号:9686800
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:32
- 大小:28.57KB
系统字库置换原理.docx
《系统字库置换原理.docx》由会员分享,可在线阅读,更多相关《系统字库置换原理.docx(32页珍藏版)》请在冰豆网上搜索。
系统字库置换原理
唔……那个……
十一无聊,找点事来干……就把一直想看的这个稍微弄了……
个人技术和精力所限……有些小的实现细节还没有完全弄清,不过应该不影响程序思路
贴上来供大家批评指教……
系统字库置换原理
唔……这个东西大家应该都知道了……TPU发明的,能够将简体字库内置的办法
基本思路首先介绍如下(细节上稍微详细一点)
写一个新的PRX替换原PRX,其中所有函数的NID保持跟原函数一致
//插入解释,NID是PSP系统用于Import函数的基础,NID保持一致就可以进行函数替换了
PRX被调用的同时也加载了原来的libfont.prx
对于大部分函数,只是进行了简单的转向操作;少部分函数则进行一些重定向,完成替换字库调用的目的
好了,思路介绍完毕
今天让我们看看,TPU到底是怎么实现这个目的的
说明:
因为大量配图就要大量截图,而鄙人实在太懒,所以这个就跳过了……抱歉
首先我们从MHP2G的简体中文版中提取出替换的PRX。
因为是集成在DATA.BIN里的模块,而且缺乏文件名,事实上揪出来的过程也费了一番劲。
功夫不负有心人,终于被我们提出来了。
打开文件扫一眼,我们找到了模块名:
fontfuck
(唔……请相信真的是这个名字)
作为对照,我们同时取个原版的LibFont.prx。
自然,下一步是祭出prxtool。
注意,如果你不想看着通篇的NID发愣的话,请加上SilverSpring提供的NID库进行分析。
首先对出入口进行初步分析:
Name:
fontfuck
Attrib:
0000
Version:
1.1
GP:
0000B070
Exports:
Export0,Namesyslib,Functions1,Variables1,flags80000000
Functions:
0xD632ACDB[0x00000168]-module_start
Variables:
0xF01D73A7[0x00001440]-module_info
Export1,NamesceLibFont,Functions15,Variables0,flags00010000
Functions:
0x67F17ED7[0x00000A94]-sceFontNewLib
0x574B6FBC[0x0000070C]-sceFontDoneLib
0x27F6E642[0x00000704]-sceFontGetNumFontList
0xBC75D85B[0x000006FC]-sceFontGetFontList
0x099EF33C[0x000006F4]-sceFontFindOptimumFont
0x681E61A7[0x000006EC]-sceFontFindFont
0xA834319D[0x00000858]-sceFontOpen
0x57FCB733[0x000006E4]-sceFontOpenUserFile
0x3AEA8CB6[0x000006DC]-sceFontClose
0x0DA7535E[0x0000068C]-sceFontGetFontInfo
0xDCC80C2F[0x000004F8]-sceFontGetCharInfo
0x5C3E4A9E[0x000004F0]-sceFontGetCharImageRect
0x980F4895[0x00000380]-sceFontGetCharGlyphImage
0xCA1E6945[0x00000378]-sceFontGetCharGlyphImage_Clip
0xEE232411[0x00000370]-sceFontSetAltCharacterCode
Imports:
Import0,NamesceLibFttt,Functions27,Variables0,flags00090011
Functions:
0x67F17ED7[0x00001240]-sceLibFttt_67F17ED7
0x574B6FBC[0x00001248]-sceLibFttt_574B6FBC
0x48293280[0x00001250]-sceLibFttt_48293280
0x27F6E642[0x00001258]-sceLibFttt_27F6E642
0xBC75D85B[0x00001260]-sceLibFttt_BC75D85B
0x099EF33C[0x00001268]-sceLibFttt_099EF33C
0x681E61A7[0x00001270]-sceLibFttt_681E61A7
0x2F67356A[0x00001278]-sceLibFttt_2F67356A
0x5333322D[0x00001280]-sceLibFttt_5333322D
0xA834319D[0x00001288]-sceLibFttt_A834319D
0x57FCB733[0x00001290]-sceLibFttt_57FCB733
0xBB8E7FE6[0x00001298]-sceLibFttt_BB8E7FE6
0x3AEA8CB6[0x000012A0]-sceLibFttt_3AEA8CB6
0x0DA7535E[0x000012A8]-sceLibFttt_0DA7535E
0xDCC80C2F[0x000012B0]-sceLibFttt_DCC80C2F
0x5C3E4A9E[0x000012B8]-sceLibFttt_5C3E4A9E
0x980F4895[0x000012C0]-sceLibFttt_980F4895
0xCA1E6945[0x000012C8]-sceLibFttt_CA1E6945
0x74B21701[0x000012D0]-sceLibFttt_74B21701
0xF8F0752E[0x000012D8]-sceLibFttt_F8F0752E
0x472694CD[0x000012E0]-sceLibFttt_472694CD
0x3C4B7E82[0x000012E8]-sceLibFttt_3C4B7E82
0xEE232411[0x000012F0]-sceLibFttt_EE232411
0xAA3DE7B5[0x000012F8]-sceLibFttt_AA3DE7B5
0x48B06520[0x00001300]-sceLibFttt_48B06520
0x568BE516[0x00001308]-sceLibFttt_568BE516
0x5DCF6858[0x00001310]-sceLibFttt_5DCF6858
Import1,NameIoFileMgrForUser,Functions5,Variables0,flags40010000
Functions:
0x810C4BC3[0x00001318]-sceIoClose
0x109F50BC[0x00001320]-sceIoOpen
0x6A638D83[0x00001328]-sceIoRead
0x42EC03AC[0x00001330]-sceIoWrite
0x68963324[0x00001338]-sceIoLseek32
Import2,NameModuleMgrForUser,Functions2,Variables0,flags40010000
Functions:
0x977DE386[0x00001340]-sceKernelLoadModule
0x50F0C1EC[0x00001348]-sceKernelStartModule
Import3,NameStdioForUser,Functions1,Variables0,flags40010000
Functions:
0xA6BAB2E9[0x00001350]-sceKernelStdout
Import4,NameSysMemUserForUser,Functions3,Variables0,flags40000000
Functions:
0x237DBD4F[0x00001358]-sceKernelAllocPartitionMemory
0xB6D61D02[0x00001360]-sceKernelFreePartitionMemory
0x9D9A5BA1[0x00001368]-sceKernelGetBlockHeadAddr
Import5,NameThreadManForUser,Functions4,Variables0,flags40010000
Functions:
0xCEADEB47[0x00001370]-sceKernelDelayThread
0x446D8DE6[0x00001378]-sceKernelCreateThread
0xF475845D[0x00001380]-sceKernelStartThread
0x809CE29B[0x00001388]-sceKernelExitDeleteThread
Done
正如我们所料,Export库被命名为了sceLibFont,里面函数的NID也全部保持一致。
因此我们才能正常导出API名称。
继续往下看到Imports,一个叫sceLibFttt的导入库引起了我们注意。
这是什么?
仔细看一看后面跟的NID,跟LibFont里的NID一模一样嘛
因为NID是有损的SHA1摘要,因此出现重NID的可能性非常非常小,唯一的解释:
同名函数。
需要从哪里导入同名函数呢?
答案只有原PRX。
由此我们猜测,TPU将原来的LibFont.prx的模块名修改成了sceLibFttt,再进行导入。
将ISO带的原版LIBFONT进行提取,其中的内容证实了我们的猜想。
确定了反向思路以后,我们来看一看MHP2G到底是怎么调用那些模块的
经过对BOOT的反汇编,我们得到的结论是,游戏采用sceUtilityLoadModule这个API进行了装载,而不是惯常看到的sceKernelLoadModule
稍微有些出乎意料,不过并不影响我们接下来的工作
经过一些观察,我们注意到一个有意思的情况
就是在fontfuck的末尾(0x1960)出现了.data段,里面的内容是2958个uint16
因为PGF系统字库是采用Unicode编码作为寻字基础,我们猜测这些就是Unicode码
首先记在这里
好了,下一步没有任何疑问
prxool-npsplibdoc.xml-wfontfuck.prx>>fontfuck.txt
反汇编开始
//说明一点,这之后有关系统API的接口将全部直接运用而不加以说明——包括PSPSDK里提供的和没有提供的。
//具体可参见PSPSDK的头文件,和PSPdevsrc1这个泄漏的开发包
作为一个库模块,事实上原本的Libfont是并不包括module_start这个函数的
//说明,module_start是模块被调用的时候运行的那个函数,类似于类机制里面的构造函数的作用
不过既然是一个外壳,又需要装载其它模块,显然写一个module_start是很好的选择
因此我们直接跳到module_start
//此函数隶属syslib库,NID为0xD632ACDB;当然,有libdoc的时候不需要知道这个
;Subroutinemodule_start-Address0x00000168
;Exportedinsyslib
module_start:
;Refs:
0x00001498
0x00000168:
0x27BDFFF0'...''-addiu $sp,$sp,-16
0x0000016C:
0xAFB10004'....'-sw $s1,4($sp)
0x00000170:
0xAFB00000'....'-sw $s0,0($sp)
0x00000174:
0x00A08821'!
...'-move $s1,$a1
0x00000178:
0x00808021'!
...'-move $s0,$a0
0x0000017C:
0x3C050000'...<'-lui $a1,0x0
0x00000180:
0x3C040000'...<'-lui $a0,0x0
;Dataref0x00001634"fontfuck"
0x00000184:
0x24841634'4..$'-addiu $a0,$a0,5684
;Textrefsub_00000294(0x00000294)
0x00000188:
0x24A50294'...$'-addiu $a1,$a1,660
0x0000018C:
0x24060019'...$'-li $a2,25
0x00000190:
0x24070800'...$'-li $a3,2048
0x00000194:
0x00004021'!
@..'-move $t0,$zr
0x00000198:
0xAFBF0008'....'-sw $ra,8($sp)
0x0000019C:
0x0C0004DE'....'-jal sceKernelCreateThread
0x000001A0:
0x00004821'!
H..'-move $t1,$zr
0x000001A4:
0x00402021'!
@.'-move $a0,$v0
0x000001A8:
0x02002821'!
(..'-move $a1,$s0
0x000001AC:
0x04400003'..@.'-bltz $v0,loc_000001BC
0x000001B0:
0x02203021'!
0.'-move $a2,$s1
0x000001B4:
0x0C0004E0'....'-jal sceKernelStartThread
0x000001B8:
0x00000000'....'-nop
loc_000001BC:
;Refs:
0x000001AC
0x000001BC:
0x8FBF0008'....'-lw $ra,8($sp)
0x000001C0:
0x8FB10004'....'-lw $s1,4($sp)
0x000001C4:
0x8FB00000'....'-lw $s0,0($sp)
0x000001C8:
0x00001021'!
...'-move $v0,$zr
0x000001CC:
0x03E00008'....'-jr $ra
0x000001D0:
0x27BD0010'...''-addiu $sp,$sp,16
映入眼帘的是非常简单的结构,显然是开启一个线程进行操作
还原以后的代码大抵如此
intmodule_start(SceSizeargs,void*argp)
{
SceUIDth=sceKernelCreateThread("fontfuck",sub_00000294,0x19,0x800,0,NULL);
if(th>0)
sceKernelStartThread(th,args,argp);
return0;
}
//其实这段代码完全没有还原的必要,这里纯粹无聊……
可见主线程需要我们进sub_294了,追
;Subroutinesub_00000294-Address0x00000294
sub_00000294:
;Refs:
0x00000188
0x00000294:
0x27BDFFF8'...''-addiu $sp,$sp,-8
0x00000298:
0x3C040000'...<'-lui $a0,0x0
0x0000029C:
0xAFB00000'....'-sw $s0,0($sp)
;Dataref0x00001664"FontfuckStart!
\n"
0x000002A0:
0x24841664'd..$'-addiu $a0,$a0,5732
0x000002A4:
0xAFBF0004'....'-sw $ra,4($sp)
0x000002A8:
0x0C000420'...'-jal sub_00001080
0x000002AC:
0x3C100000'...<'-lui $s0,0x0
0x000002B0:
0x3C020000'...<'-lui $v0,0x0
0x000002B4:
0x3C030000'...<'-lui $v1,0x0
;Dataref0x00001678"disc0:
/PSP_GAME/USRDIR/oldfont.prx"
0x000002B8:
0x26041678'x..&'-addiu $a0,$s0,5752
;Dataref0x00003144...0x000000000x000000000x000000000x00000000
0x000002BC:
0xAC403144'D1@.'-sw $zr,12612($v0)
0x000002C0:
0x0C000091'....'-jal sub_00000244
;Dataref0x00005150...0x000000000x000000000x000000000x00000000
0x000002C4:
0xAC605150'PQ`.'-sw $zr,20816($v1)
0x000002C8:
0x04400024'$.@.'-bltz $v0,loc_0000035C
0x000002CC:
0x3C040000'...<'-lui $a0,0x0
0x000002D0:
0x3C020000'...<'-lui $v0,0x0
loc_000002D4:
;Refs:
0x00000368
;Dataref0x0000314C...0x000000000x000000000x000000000x00000000
0x000002D4:
0x2444314C'L1D$'-addiu $a0,$v0,12620
0x000002D8:
0x3C030000'...<'-lui $v1,0x0
0x000002DC:
0x3C020000'...<'-lui $v0,0x0
;Dataref0x0000515C...0x000000000x000000000x000000000x00000000
0x000002E0:
0x2463515C'\Qc$'-addiu $v1,$v1,20828
;Dataref0x0000514C...0x000000000x000000000x000000000x00000000
0x000002E4:
0x2442514C'LQB$'-addiu $v0,$v0,20812
0x000002E8:
0x2405FFFF'...$'-li $a1,-1
loc_000002EC:
;Refs:
0x000002F8
0x000002EC:
0xA4850000'....'-sh $a1,0($a0)
0x000002F0:
0x24840002'...$'-addiu $a0,$a0,2
0x000002F4:
0xA4600000'..`.'-sh $zr,0($v1)
0x000002F8:
0x1482FFFC'....'-bne $a0,$v0,loc_000002EC
0x000002FC:
0x24630002'..c$'-addiu $v1,$v1,2
0x00000300:
0x3C060000'...<'-lui $a2,0x0
0x00000304:
0x3C020000'...<'-lui $v0,0x0
;Dataref0x0000312C...0x000000000
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 系统 字库 置换 原理