Android APK 리패키징 시 리소스 파일에 대한 FileNotFoundException 현상
drawable/abc_vector_test with resource ID 0x7f070076
Introduction
안드로이드 apk 파일을 unzip 했다가 다시 zip 하여 파일로 묶을 때 아래와 같은 crash 가 터진다.
특정 기능에서 터지는 건줄 알았는데 그냥 변경사항 없이 unzip-zip 하여도 crash 가 발생하여 이에 대하여 살펴본 내용을 기록하였다.
What is that
apk 를 디컴파일 후 다시 리패키징하면서 아래와 같은 Exception 이 나온다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
Process: com.redacted.redacted.redacted.android.release, PID: 23726
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.redacted.redacted.redacted.android.release/com.redacted.redacted.redacted.android.sample.MainActivity}: android.content.res.Resources$NotFoundException: Drawable com.redacted.redacted.redacted.android.release:drawable/abc_vector_test with resource ID #0x7f070076
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4169)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4325)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2574)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
Caused by: android.content.res.Resources$NotFoundException: Drawable com.redacted.redacted.redacted.android.release:drawable/abc_vector_test with resource ID #0x7f070076
Caused by: android.content.res.Resources$NotFoundException: File res/hq.xml from drawable resource ID #0x7f070076
at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:1040)
at android.content.res.ResourcesImpl.loadDrawable(ResourcesImpl.java:724)
at android.content.res.Resources.loadDrawable(Resources.java:1072)
at android.content.res.Resources.getDrawableForDensity(Resources.java:1051)
at android.content.res.Resources.getDrawable(Resources.java:990)
at android.content.Context.getDrawable(Context.java:823)
at androidx.appcompat.widget.r2.f(SourceFile:52)
at androidx.appcompat.widget.r2.e(SourceFile:1)
at androidx.appcompat.widget.r2.f(SourceFile:14)
at d.j0.o(SourceFile:55)
at d.j0.x(SourceFile:1)
at d.j0.f(SourceFile:8)
at d.k.a(SourceFile:19)
at androidx.activity.n.onCreate(SourceFile:31)
at androidx.fragment.app.y.onCreate(SourceFile:1)
at com.redacted.redacted.redacted.android.sample.MainActivity.onCreate(SourceFile:1)
at android.app.Activity.performCreate(Activity.java:8591)
at android.app.Activity.performCreate(Activity.java:8570)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4150)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4325)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2574)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
Caused by: android.content.res.Resources$NotFoundException: File res/hq.xml from xml type drawable resource ID #0x7f070076
at android.content.res.ResourcesImpl.loadXmlResourceParser(ResourcesImpl.java:1382)
at android.content.res.ResourcesImpl.loadXmlDrawable(ResourcesImpl.java:1070)
at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:1012)
at android.content.res.ResourcesImpl.loadDrawable(ResourcesImpl.java:724)
at android.content.res.Resources.loadDrawable(Resources.java:1072)
at android.content.res.Resources.getDrawableForDensity(Resources.java:1051)
at android.content.res.Resources.getDrawable(Resources.java:990)
at android.content.Context.getDrawable(Context.java:823)
at androidx.appcompat.widget.r2.f(SourceFile:52)
at androidx.appcompat.widget.r2.e(SourceFile:1)
at androidx.appcompat.widget.r2.f(SourceFile:14)
at d.j0.o(SourceFile:55)
at d.j0.x(SourceFile:1)
at d.j0.f(SourceFile:8)
at d.k.a(SourceFile:19)
at androidx.activity.n.onCreate(SourceFile:31)
at androidx.fragment.app.y.onCreate(SourceFile:1)
at com.redacted.redacted.redacted.android.sample.MainActivity.onCreate(SourceFile:1)
at android.app.Activity.performCreate(Activity.java:8591)
at android.app.Activity.performCreate(Activity.java:8570)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4150)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4325)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2574)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
Caused by: java.io.FileNotFoundException: res/hq.xml
이 exception 에서 살펴볼 수 있는 것은 crash 는 가장 위쪽이 원인 부분으로 이해하면 된다.
사람이 종종 몸이 아프면 병원가서 내과에서 진찰을 받아 몸의 정확히 어디가 아픈지 몸 속 깊숙하게 생체 신호를 확인하는 것처럼.
최하단은 시스템의 프로세스 실행 중 걸린 부분을 스택 형식으로 거꾸로 출력한 것이다.
Exploring Different Perspectives
해당 오류를 보면 Resources$NotFoundException
리소스를 찾을 수 없다는 걸 볼 수 있으며 해당 리소스에 대한 정보는 res/hq.xml
라는 걸 알 수 있다.
이에 대하여 apk 안에 해당 파일을 살펴보겠다.
1
2
3
4
% unzip -l target_app.apk | grep -i "hq"
752 01-01-1981 01:01 res/HQ.xml
612 01-01-1981 01:01 res/hq.xml
%
빌드된 apk 를 보면 2개의 파일이 정상적으로 포함된 걸 볼 수 있다. 문제가 되는 파일들에 대하여 hash 를 보면 아래와 같이 확인할 수 있다.
1
2
4f0f979d4b7dcf7854d21cc0ad7185aab86df70566eb92ee2aac05c09653b469 HQ.xml
0ae53e8ca5e9514bd6b674b8795834cc8889ad4b64bfc2bd0c7dc712332daa11 hq.xml
이번엔 리패키징한 상태에서 파일을 찾아보곘다.
1
2
3
4
% unzip -l target_app_repacking.apk | grep "hq"
% unzip -l target_app_repacking.apk | grep "HQ"
612 05-12-2025 00:53 res/HQ.xml
%
리패키징 했을 때 res/HQ.xml, res/hq.xml 파일중 res/hq.xml 은 보이지 않는 걸 확인할 수 있다.
해당 파일에 대하여 hash 를 구하면 아래와 같이 res/HQ.xml 의 정보가 res/hq.xml 로 overwrite 된 값이 나온다.
1
0ae53e8ca5e9514bd6b674b8795834cc8889ad4b64bfc2bd0c7dc712332daa11 res/HQ.xml
이는 나중에 알고보니 macOS 에서 대소문자를 구분하지 못해서 파일이 씹힌 결과다.
If you find any errors, please let me know by comment or email. Thank you.