ART TI

באנדרואיד 8.0 ומעלה, ממשק כלי העבודה של ART (ART TI) חושף חלקים פנימיים של זמן ריצה, ומאפשר למפתחי פרופילים ולניפוי באגים להשפיע על התנהגות זמן הריצה של אפליקציות. זה יכול לשמש כדי ליישם כלי ביצועים חדישים המסופקים להטמעת סוכנים מקוריים בפלטפורמות אחרות.

רכיבי זמן ריצה פנימיים חשופים לסוכנים שנטענו לתהליך זמן הריצה. אלה מתקשרים עם ה-ART באמצעות שיחות ישירות והתקשרויות חוזרות. זמן הריצה תומך במספר סוכנים כך שניתן להפריד בין דאגות שונות של פרופיל אורתוגונלי. סוכנים יכולים להיות מסופקים עם תחילת זמן הריצה (כאשר dalvikvm או app_process מופעלים), או לצרף לתהליך שכבר פועל.

מכיוון שהיכולת לבצע מכשירים ולשנות התנהגות של אפליקציה וזמן ריצה היא חזקה מאוד, שני אמצעי בטיחות שולבו ב-ART TI:

  • ראשית, הקוד החושף את ממשק הסוכן, JVMTI, מיושם כתוסף זמן ריצה, לא כמרכיב ליבה של זמן הריצה. טעינת הפלאגין עשויה להיות מוגבלת, כך שניתן לחסום סוכנים מלמצוא כל אחת מנקודות הממשק.
  • שנית, גם המחלקה ActivityManager וגם תהליך זמן הריצה מאפשרים רק לסוכנים לצרף לאפליקציות שניתנות לאיפוי. אפליקציות שניתנות לניפוי שגיאות נחתמו על ידי המפתחים שלהן לצורך ניתוח ומכשיר, ואינן מופצות למשתמשי קצה. חנות Google Play אינה מתירה הפצה של אפליקציות שניתנות לניפוי באגים. זה מבטיח שאפליקציות רגילות (כולל רכיבי ליבה) לא ניתנות למכשיר או לתמרן.

לְעַצֵב

הזרימה הכללית והקישוריות באפליקציה מאובזרת מוצגת באיור 1 .

Flow and interconnection in an instrumented app
איור 1. זרימה וחיבור של אפליקציה מאובזרת

תוסף ART libopenjdkjvmti חושף את ה-ART TI, שנועד להתאים לצרכים והאילוצים של הפלטפורמה:

  • הגדרה מחדש של מחלקה מבוססת על קבצי Dex , המכילים רק הגדרת מחלקה אחת, במקום קבצי מחלקה.
  • ממשקי API בשפת Java עבור מכשור והגדרה מחדש אינם נחשפים.

ה-ART TI תומך גם בפרופילים של Android Studio.

טען או צרף סוכן

כדי לצרף סוכן בזמן ההפעלה, השתמש בפקודה זו כדי לטעון גם את התוסף JVMTI וגם את הסוכן הנתון:

dalvikvm -Xplugin:libopenjdkjvmti.so -agentpath:/path/to/agent/libagent.so …

לא קיימים אמצעי בטיחות כאשר סוכן נטען בזמן ההפעלה, אז זכור שזמן ריצה שהופעל ידנית מאפשר שינוי מלא ללא אמצעי בטיחות. (זה מאפשר בדיקת ART.)

הערה: זה לא חל על אפליקציות רגילות (כולל שרת המערכת) במכשיר. אפליקציות מחולקות מזיגוטה שכבר פועלת, ותהליך זיגוטה אינו רשאי לטעון סוכנים.

כדי לצרף סוכן לאפליקציה שכבר פועלת, השתמש בפקודה זו:

adb shell cmd activity attach-agent [process]
/path/to/agent/libagent.so[=agent-options]

אם הפלאגין JVMTI עדיין לא נטען, צירוף סוכן יטען גם את התוסף וגם את ספריית הסוכן.

ניתן לצרף סוכן רק לאפליקציה פועלת המסומנת כניתנת לניפוי באגים (חלק מהמניפסט של האפליקציה, כאשר התכונה android:debuggable מוגדרת כ- true בצומת האפליקציה). גם המחלקה ActivityManager וגם ה-ART מבצעות בדיקות לפני מתן אפשרות לצרף סוכן. המחלקה ActivityManager בודקת את פרטי האפליקציה הנוכחיים (הנגזרים מנתוני המחלקה PackageManager ) עבור הסטטוס הניתן לניפוי באגים, וזמן הריצה בודק את המצב הנוכחי שלה, שהוגדר בעת הפעלת האפליקציה.

מיקומי סוכן

זמן הריצה צריך לטעון סוכנים לתהליך הנוכחי, כך שהסוכן יוכל להתחבר אליו ישירות ולתקשר איתו. ה-ART עצמו אגנוסטי לגבי המיקום הספציפי ממנו מגיע הסוכן. המחרוזת משמשת לשיחת dlopen . הרשאות מערכת הקבצים ומדיניות SELinux מגבילים את הטעינה בפועל.

כדי לספק סוכנים שניתן להפעיל על ידי אפליקציה הניתנת לניפוי, בצע את הפעולות הבאות:

  • הטמע את הסוכן בספריית הספרייה של ה-APK של האפליקציה.
  • השתמש run-as כדי להעתיק את הסוכן לספריית הנתונים של האפליקציה.

ממשקי API

השיטה הבאה נוספה ל- android.os.Debug .

/**
     * Attach a library as a jvmti agent to the current runtime, with the given classloader
     * determining the library search path.
     * Note: agents may only be attached to debuggable apps. Otherwise, this function will
     * throw a SecurityException.
     *
     * @param library the library containing the agent.
     * @param options the options passed to the agent.
     * @param classLoader the classloader determining the library search path.
     *
     * @throws IOException if the agent could not be attached.
     * @throws a SecurityException if the app is not debuggable.
     */
    public static void attachJvmtiAgent(@NonNull String library, @Nullable String options,
            @Nullable ClassLoader classLoader) throws IOException {

ממשקי API אחרים של אנדרואיד

הפקודה attach-agent גלויה לציבור. פקודה זו מצרף סוכן JVMTI לתהליך פועל:

adb shell 'am attach-agent com.example.android.displayingbitmaps
\'/data/data/com.example.android.displayingbitmaps/code_cache/libfieldnulls.so=Ljava/lang/Class;.name:Ljava/lang/String;\''

הפקודות am start -P ו- am start-profiler/stop-profiler דומות לפקודה attach-agent.

JVMTI

תכונה זו חושפת את JVMTI API לסוכנים (קוד מקורי). היכולות החשובות כוללות:

  • הגדרה מחדש של כיתה.
  • מעקב אחר הקצאת חפצים ואיסוף אשפה.
  • איטרציה על כל האובייקטים בערימה, בעקבות עץ ההתייחסות של אובייקטים.
  • בדיקת ערימות שיחות Java.
  • השעיה (וחידוש) כל השרשורים.

יכולות שונות עשויות להיות זמינות בגרסאות שונות של אנדרואיד.

תְאִימוּת

תכונה זו זקוקה לתמיכה בזמן ריצה ליבה שזמינה רק ב-Android 8.0 ואילך. יצרני המכשירים אינם צריכים לבצע שינויים כדי ליישם תכונה זו. זה חלק מ-AOSP.

מַתַן תוֹקֵף

CTS בודק את הדברים הבאים באנדרואיד 8 ומעלה:

  • בדיקות שסוכנים מצמידים לאפליקציות שניתנות לניפוי, ולא מצליחים לצרף לאפליקציות שאינן ניתנות לניפוי.
  • בודק את כל ממשקי ה-API של JVMTI המיושמים
  • בודק שהממשק הבינארי עבור סוכנים יציב

בדיקות נוספות נוספו לאנדרואיד 9 ומעלה, ונכללות במבחני CTS עבור מהדורות אלו.