-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request / RFC] 配合 FontManagerService 将字体文件安装到 data 分区 #46
Comments
我好像看到了很多可能性,比如用
|
/**
* Parses XML representing {@link android.graphics.fonts.FontFamilyUpdateRequest}.
*
* <p>The format is like:
* <pre>{@code
* <fontFamilyUpdateRequest>
* <family name="family-name">
* <font name="postScriptName"/>
* </family>
* </fontFamilyUpdateRequest>
* }</pre>
*/ /**
* Read a {@link Family} instance from <family> element in XML
*
* For the XML format, see {@link Font} class comment.
*
* @param parser an XML parser that points <family> element.
* @return an {@link Family} instance
*/ /**
* Font object used for update.
*
* Here is an example of Family/Font XML.
* <family name="my-sans">
* <font name="MySans" weight="400" slant="0" axis="'wght' 400 'ital' 0" index="0" />
* <font name="MySans" weight="400" slant="0" axis="'wght' 400 'ital' 1" index="0" />
* <font name="MySans" weight="400" slant="0" axis="'wght' 700 'ital' 0" index="0" />
* <font name="MySans" weight="400" slant="0" axis="'wght' 700 'ital' 1" index="0" />
* </family>
*
* @see Font#readFromXml(XmlPullParser)
* @see Font#writeToXml(TypedXmlSerializer, Font)
* @see Family#readFromXml(XmlPullParser)
* @see Family#writeFamilyToXml(TypedXmlSerializer, Family)
*/ |
看来读取 fontFileName = mParser.buildFontFileName(tempNewFontFile); UpdatableFontDir(File filesDir, FontFileParser parser, FsverityUtil fsverityUtil,
File configFile) {
this(filesDir, parser, fsverityUtil, configFile,
System::currentTimeMillis,
(map) -> SystemFonts.getSystemFontConfig(map, 0, 0)
);
}
// For unit testing
UpdatableFontDir(File filesDir, FontFileParser parser, FsverityUtil fsverityUtil,
File configFile, Supplier<Long> currentTimeSupplier,
Function<Map<String, File>, FontConfig> configSupplier) {
mFilesDir = filesDir;
mParser = parser;
mFsverityUtil = fsverityUtil;
mConfigFile = new AtomicFile(configFile);
mCurrentTimeSupplier = currentTimeSupplier;
mConfigSupplier = configSupplier;
} @Nullable
private UpdatableFontDir createUpdatableFontDir() {
// Never read updatable font files in safe mode.
if (mIsSafeMode) return null;
// If apk verity is supported, fs-verity should be available.
if (!VerityUtils.isFsVeritySupported()) return null;
String[] certs = mContext.getResources().getStringArray(
R.array.config_fontManagerServiceCerts);
if (mDebugCertFilePath != null && (Build.IS_USERDEBUG || Build.IS_ENG)) {
String[] tmp = new String[certs.length + 1];
System.arraycopy(certs, 0, tmp, 0, certs.length);
tmp[certs.length] = mDebugCertFilePath;
certs = tmp;
}
return new UpdatableFontDir(new File(FONT_FILES_DIR), new OtfFontFileParser(),
new FsverityUtilImpl(certs), new File(CONFIG_XML_FILE));
}
// ...
private void initialize() {
synchronized (mUpdatableFontDirLock) {
mUpdatableFontDir = createUpdatableFontDir();
if (mUpdatableFontDir == null) {
setSerializedFontMap(serializeSystemServerFontMap());
return;
}
mUpdatableFontDir.loadFontFileMap();
updateSerializedFontMap();
}
} @Override
public String getPostScriptName(File file) throws IOException {
ByteBuffer buffer = mmap(file);
try {
return FontFileUtil.getPostScriptName(buffer, 0);
} finally {
unmap(buffer);
}
} /**
* Analyze name OpenType table and return PostScript name.
*
* IllegalArgumentException will be thrown for invalid font data.
* null will be returned if not found or the PostScript name is invalid.
*
* @param buffer a buffer of OpenType font
* @param index a font index
* @return a post script name or null if it is invalid or not found.
*/ |
我知道为啥说fallback改不了了((( // We should keep the first font family (config.getFontFamilies().get(0)) because it's used
// as a fallback font. See SystemFonts.java. |
<head>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="2.002"/>
<!-- ... -->
</head> |
|
https://learn.microsoft.com/en-us/typography/opentype/spec/head 是一个定点数,而且整个文件有 checksum。 可能要写点 java 然后用 app_process 跑,顺便把现在那堆正则 xml 换掉( |
好了,我研究完了,我现在的猜测是你想不再通过替换或新增任何文件的方式,修改字体? 目前我们替换和新增的文件有:
如果想不修改任何文件,那是不可能的。至少 |
这个2.002的fontRevision是我用fonttool跑出来的,我很确定他是字体版本号 |
如果你想隐藏这个模块的话,是不是可以用Zygisk来做这个模块?可惜我完全不会Zygisk |
我重新思考了一下,你只是希望在 |
对,主要是要在 /data 里找个应用能访问的地方 不过我又想了一下,应用还是可以在 /system 下面随便找一堆文件 stat 拿设备号,感觉意义不是太大( 真要藏模块可能要上增量更新的同款 dm-snapshot 了 |
|
背景
/proc/self/maps
中会显示通过mmap
映射的文件名和对应的设备号,通过 VFS 机制(Magisk 的 bind mount 或 KernelSU 的 overlayfs)修改的字体文件会显示 data 分区的设备号,从而触发部分应用的风控策略。要消除此类痕迹,需要 VFS 路径与对应设备号匹配(即路径显示
/data/xxxxxx
),或将对应地址替换为 memfd 映射(Shamiko)。PoC
Android 12 提供了通过 OTA 单独更新字体文件的方法:https://source.android.com/docs/core/fonts/custom-font-fallback
字体文件受 fs-verity 以及签名验证保护(Android 12-13 为 fs-verity 签名验证,Android 14 为用户态签名验证),FontManagerService 启动时会删除 /data/fonts 下验证失败的文件。
echo 0 > /proc/sys/fs/verity/require_signatures
config_fontManagerServiceCerts
追加自签名证书以下步骤是以 Android 13 为例。
其他信息
cmd font clear
主动删除所有热更新字体The text was updated successfully, but these errors were encountered: