From bbf4cb36c9544e1a9187f984117afdc66ca4c4d8 Mon Sep 17 00:00:00 2001 From: nitram84 Date: Tue, 3 Dec 2024 23:40:32 +0100 Subject: [PATCH] feat: replace constants in annotations of method arguments --- .../jadx/core/dex/visitors/ModVisitor.java | 18 +++++++++- .../android/TestResConstReplace3.java | 33 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 jadx-core/src/test/java/jadx/tests/integration/android/TestResConstReplace3.java diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java index 7cde76d3113..9ec4adf40e7 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java @@ -14,6 +14,7 @@ import jadx.api.plugins.input.data.annotations.EncodedValue; import jadx.api.plugins.input.data.annotations.IAnnotation; import jadx.api.plugins.input.data.attributes.JadxAttrType; +import jadx.api.plugins.input.data.attributes.types.AnnotationMethodParamsAttr; import jadx.api.plugins.input.data.attributes.types.AnnotationsAttr; import jadx.core.dex.attributes.AFlag; import jadx.core.dex.attributes.AType; @@ -279,12 +280,27 @@ private void replaceConstInAnnotations(ClassNode cls) { if (cls.root().getArgs().isReplaceConsts()) { replaceConstsInAnnotationForAttrNode(cls, cls); cls.getFields().forEach(f -> replaceConstsInAnnotationForAttrNode(cls, f)); - cls.getMethods().forEach(m -> replaceConstsInAnnotationForAttrNode(cls, m)); + cls.getMethods().forEach((m) -> { + replaceConstsInAnnotationForAttrNode(cls, m); + replaceConstsInAnnotationForMethodParamsAttr(cls, m); + }); } } + private void replaceConstsInAnnotationForMethodParamsAttr(ClassNode cls, MethodNode m) { + AnnotationMethodParamsAttr paramsAnnotation = m.get(JadxAttrType.ANNOTATION_MTH_PARAMETERS); + if (paramsAnnotation == null) { + return; + } + paramsAnnotation.getParamList().forEach(annotationsList -> replaceConstsInAnnotationsAttr(cls, annotationsList)); + } + private void replaceConstsInAnnotationForAttrNode(ClassNode parentCls, AttrNode attrNode) { AnnotationsAttr annotationsList = attrNode.get(JadxAttrType.ANNOTATION_LIST); + replaceConstsInAnnotationsAttr(parentCls, annotationsList); + } + + private void replaceConstsInAnnotationsAttr(ClassNode parentCls, AnnotationsAttr annotationsList) { if (annotationsList == null) { return; } diff --git a/jadx-core/src/test/java/jadx/tests/integration/android/TestResConstReplace3.java b/jadx-core/src/test/java/jadx/tests/integration/android/TestResConstReplace3.java new file mode 100644 index 00000000000..c2db8498509 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/android/TestResConstReplace3.java @@ -0,0 +1,33 @@ +package jadx.tests.integration.android; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import org.junit.jupiter.api.Test; + +import jadx.tests.api.IntegrationTest; + +import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat; + +public class TestResConstReplace3 extends IntegrationTest { + + @Retention(RetentionPolicy.RUNTIME) + public @interface UsesAndroidResource { + int value() default 0; + } + + @UsesAndroidResource(17039370 /* android.R.string.ok */) + public static class TestCls { + public void test(@UsesAndroidResource(17039370 /* android.R.string.ok */) int i) { + } + } + + @Test + public void test() { + disableCompilation(); + assertThat(getClassNode(TestCls.class)) + .code() + .containsOne("import android.R;") + .countString(2, "@TestResConstReplace3.UsesAndroidResource(R.string.ok)"); + } +}