android 文字绘制

概要结论

android framework视频课 表明 文字绘制 和 方法 *measure**drawText* 有关

补充 framework视频课程

  1. 测量

  2. 绘制

frida盲拦截 *measure**drawText*

oneplus3 : APatch低版本正常(root) --> ... 、 tina--eadb --> frida-server-arm64

*measure* 有界面文本

*drawText* 无界面文本

gdb断

draw

以下这三个方法很重要,

txt 复制代码
#0  0x00000070ee108f7c in android::Canvas::drawText(unsigned short const*, int, int, int, float, float, minikin::Bidi, android::Paint const&, android::Typeface const*, minikin::MeasuredText*)@plt () from target:/system/lib64/libandroid_runtime.so
#1  0x00000070ee196a50 in android::CanvasJNI::drawTextString(_JNIEnv*, _jobject*, long, _jstring*, int, int, float, float, int, long) () from target:/system/lib64/libandroid_runtime.so
#2  0x00000000731d7e88 in android.view.RecordingCanvas.nDrawText [DEDUPED] () from target:/system/framework/arm64/boot-framework.oat

android::CanvasJNI::drawTextStringstatic(c++本地方法) 因而frida以调试符号表找不到该方法

measure
txt 复制代码
#0  0x00000070eb2b7318 in android::MinikinUtils::measureText(android::Paint const*, minikin::Bidi, android::Typeface const*, unsigned short const*, unsigned long, unsigned long, unsigned long, float*) () from target:/system/lib64/libhwui.so
#1  0x00000070ee1abd10 in android::PaintGlue::getRunAdvance___CIIIIZI_F(_JNIEnv*, _jclass*, long, _jcharArray*, int, int, int, int, unsigned char, int) () from target:/system/lib64/libandroid_runtime.so
#2  0x00000000731aa190 in android.graphics.Paint.nGetRunAdvance () from target:/system/framework/arm64/boot-framework.oat

以下是记录 可以不看

gdb 断 android::Canvas::drawText

前提

eadb安装: https://gitee.com/imagg/tiann--eadb/blob/z/main/README.md

gdb查看例子应用的主线程中函数android::Canvas::drawText(含有坐标x、y)调用栈

结论: 该函数android::Canvas::drawText : http://androidxref.com/9.0.0_r3/xref/frameworks/base/libs/hwui/hwui/Canvas.cpp#159

gdb --pid $(pidof com.example.myapplication)

break drawText

info breakpoints

txt 复制代码
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   <MULTIPLE>         
	breakpoint already hit 1 time
2.1                         y   0x00000070eb29e914 <GrRenderTargetContext::drawText(GrClip const&, SkPaint const&, SkMatrix const&, char const*, unsigned long, float, float, SkIRect const&)@plt+4>
2.2                         y   0x00000070eb367400 <SkCanvas::drawText(void const*, unsigned long, float, float, SkPaint const&)+28>
2.3                         y   0x00000070eb4672e8 <GrRenderTargetContext::drawText(GrClip const&, SkPaint const&, SkMatrix const&, char const*, unsigned long, float, float, SkIRect const&)+32>
2.4                         y   0x00000070eb658580 <android::Canvas::drawText(unsigned short const*, int, int, int, float, float, minikin::Bidi, android::Paint const&, android::Typeface const*, minikin::MeasuredText*)+36>
2.5                         y   0x00000070ee108f7c <android::Canvas::drawText(unsigned short const*, int, int, int, float, float, minikin::Bidi, android::Paint const&, android::Typeface const*, minikin::MeasuredText*)@plt+4>

continue , 在android手机该应用界面上做某操作(迫使界面文字变化), 则命中断点

Thread 1 "e.myapplication" hit Breakpoint 2, 0x00000070ee108f7c in android::Canvas::drawText(unsigned short const*, int, int, int, float, float, minikin::Bidi, android::Paint const&, android::Typeface const*, minikin::MeasuredText*)@plt () from target:/system/lib64/libandroid_runtime.so

该函数android::Canvas::drawText : http://androidxref.com/9.0.0_r3/xref/frameworks/base/libs/hwui/hwui/Canvas.cpp#159

gdb下获得该函数的demangle名

gdb 复制代码
set print demangle off
(gdb) info symbol 0x00000070ee108f7c
_ZN7android6Canvas8drawTextEPKtiiiffN7minikin4BidiERKNS_5PaintEPKNS_8TypefaceEPNS3_12MeasuredTextE@plt + 4 in section .plt of target:/system/lib64/libandroid_runtime.so
(gdb) set print demangle on 
(gdb) info symbol 0x00000070ee108f7c
android::Canvas::drawText(unsigned short const*, int, int, int, float, float, minikin::Bidi, android::Paint const&, android::Typeface const*, minikin::MeasuredText*)@plt + 4 in section .plt of target:/system/lib64/libandroid_runtime.so

backtrace

txt 复制代码
#0  0x00000070ee108f7c in android::Canvas::drawText(unsigned short const*, int, int, int, float, float, minikin::Bidi, android::Paint const&, android::Typeface const*, minikin::MeasuredText*)@plt () from target:/system/lib64/libandroid_runtime.so
#1  0x00000070ee196a50 in android::CanvasJNI::drawTextString(_JNIEnv*, _jobject*, long, _jstring*, int, int, float, float, int, long) () from target:/system/lib64/libandroid_runtime.so
#2  0x00000000731d7e88 in android.view.RecordingCanvas.nDrawText [DEDUPED] () from target:/system/framework/arm64/boot-framework.oat

#省略的 基本是 #267~#297 的重复  ,猜测 每个重复是一个java方法的调用 , (本地native) gdb视角看到的(解释性)java方法调用
#267 0x000000009b3c645c in android.view.Choreographer.doCallbacks ()
#268 0x000000009b3c83e0 in android.view.Choreographer.doFrame ()
#269 0x000000706a6c4b8c art_quick_invoke_stub
#270 0x000000706a2336bc in art::ArtMethod::Invoke
#271 0x000000706a3e6b40 in art::interpreter::ArtInterpreterToCompiledCodeBridge
#272 0x000000706a3e0bf0 art::interpreter::DoCall2
#273 0x000000706a6942d0 MterpInvokeVirtual
#274 0x000000706a6b7198 ExecuteMterpImpl
#275 0x000000706a3bad50 art::interpreter::Execute
#276 0x000000706a3c0900 art::interpreter::ArtInterpreterToInterpreterBridge
#277 0x000000706a3e0bd4 art::interpreter::DoCall2
#278 0x000000706a695224 in MterpInvokeInterface () from target:/system/lib64/libart.so
#279 0x000000706a6b7398 ExecuteMterpImpl
#280 0x000000706a3bad50 art::interpreter::Execute
#281 0x000000706a3c0900 art::interpreter::ArtInterpreterToInterpreterBridge
#282 0x000000706a3e0bd4 art::interpreter::DoCall2
#283 0x000000706a695798 in MterpInvokeStatic () from target:/system/lib64/libart.so
#284 0x000000706a6b7318 ExecuteMterpImpl
#285 0x000000706a3bad50 art::interpreter::Execute
#286 0x000000706a3c0900 art::interpreter::ArtInterpreterToInterpreterBridge
#287 0x000000706a3e0bd4 art::interpreter::DoCall2
#288 0x000000706a6942d0 MterpInvokeVirtual
#289 0x000000706a6b7198 ExecuteMterpImpl
#290 0x000000706a3bad50 art::interpreter::Execute
#291 0x000000706a3c0900 art::interpreter::ArtInterpreterToInterpreterBridge
#292 0x000000706a3e0bd4 art::interpreter::DoCall2
#293 0x000000706a695798 in MterpInvokeStatic () from target:/system/lib64/libart.so
#294 0x000000706a6b7318 ExecuteMterpImpl
#295 0x000000706a3bad50 art::interpreter::Execute
#296 0x000000706a684a98 artQuickToInterpreterBridge
#297 0x000000706a6cdd00 art_quick_to_interpreter_bridge

#298 0x000000706a6c4e50 in art_quick_invoke_static_stub () from target:/system/lib64/libart.so
#299 0x000000706a2336dc in art::ArtMethod::Invoke
#300 0x000000706a5ca9b8 in art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*) () from target:/system/lib64/libart.so
#301 0x000000706a5cc50c in art::InvokeMethod(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jobject*, _jobject*, unsigned long) () from target:/system/lib64/libart.so
#302 0x000000706a55aefc in art::Method_invoke(_JNIEnv*, _jobject*, _jobject*, _jobjectArray*) () from target:/system/lib64/libart.so
#303 0x0000000071d4e6d8 in java.lang.Class.getDeclaredMethodInternal [DEDUPED] () from target:/system/framework/arm64/boot.oat
#304 0x000000706a6c4b8c art_quick_invoke_stub
#305 0x000000706a2336bc in art::ArtMethod::Invoke
#306 0x000000706a3e6b40 in art::interpreter::ArtInterpreterToCompiledCodeBridge
#307 0x000000706a3e0bf0 art::interpreter::DoCall2
#308 0x000000706a6942d0 MterpInvokeVirtual
#309 0x000000706a6b7198 ExecuteMterpImpl
#310 0x000000706a3bad50 art::interpreter::Execute
#311 0x000000706a684a98 artQuickToInterpreterBridge
#312 0x000000706a6cdd00 art_quick_to_interpreter_bridge
#313 0x00000000739ca418 in com.android.internal.os.ZygoteInit.main () from target:/system/framework/arm64/boot-framework.oat
#314 0x000000706a6c4e50 in art_quick_invoke_static_stub () from target:/system/lib64/libart.so
#315 0x000000706a2336dc in art::ArtMethod::Invoke
#316 0x000000706a5ca9b8 in art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*) () from target:/system/lib64/libart.so
#317 0x000000706a5ca5bc in art::InvokeWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list) () from target:/system/lib64/libart.so
#318 0x000000706a4cc4d8 in art::JNI::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list) () from target:/system/lib64/libart.so
#319 0x00000070ee111088 in _JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...) () from target:/system/lib64/libandroid_runtime.so
#320 0x00000070ee113a14 in android::AndroidRuntime::start(char const*, android::Vector<android::String8> const&, bool) () from target:/system/lib64/libandroid_runtime.so
#321 0x00000064a06401a0 in main ()
相关推荐
一颗青果1 小时前
【Linux】详解shell代码实现(上)
linux·运维·服务器·前端·chrome·算法·1024程序员节
weixin_SAG3 小时前
7天掌握SQL - 第三天:MySQL实践与索引优化
android·sql·mysql
疯狂的皮卡6 小时前
【安卓脚本】Android工程中文硬编码抽取
android
菜鸟、小高7 小时前
从0开始学PHP面向对象内容之常用设计模式(适配器,桥接,装饰器)
android·设计模式·php
网安_秋刀鱼7 小时前
API安全
web安全·网络安全·1024程序员节
找藉口是失败者的习惯8 小时前
Jetpack Compose 生命周期介绍
android·ui
测试小工匠9 小时前
移动端自动化环境搭建_Android
android·运维·自动化
二流小码农10 小时前
鸿蒙开发:自定义一个任意位置弹出的Dialog
android·ios·harmonyos
惜.己10 小时前
Jmeter中的定时器
测试工具·jmeter·1024程序员节
codeMaster__hyd10 小时前
使用IDEA构建springboot项目+整合Mybatis
java·linux·centos·intellij-idea·intellij idea·1024程序员节