From 9c63238b0e25de997b4bca79b1927ad9eea5f717 Mon Sep 17 00:00:00 2001 From: fa1conn Date: Mon, 31 Oct 2022 20:32:27 +0800 Subject: [PATCH 1/4] Fix StringAnalyzer bug and Add Integer.parseInt --- .../ConstantPropagationAnalysis.cpp | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/service/constant-propagation/ConstantPropagationAnalysis.cpp b/service/constant-propagation/ConstantPropagationAnalysis.cpp index 6ff65e8330a..fe8d284f6dc 100644 --- a/service/constant-propagation/ConstantPropagationAnalysis.cpp +++ b/service/constant-propagation/ConstantPropagationAnalysis.cpp @@ -772,9 +772,14 @@ bool BoxedBooleanAnalyzer::analyze_invoke( bool StringAnalyzer::analyze_invoke(const IRInstruction* insn, ConstantEnvironment* env) { - DexMethod* method = - resolve_method(insn->get_method(), opcode_to_search(insn)); - if (method == nullptr) { + const DexMethod* String_hashCode{ + static_cast(DexMethod::get_method("Ljava/lang/String;.hashCode:()I"))}; + const DexMethod* String_equals{ + static_cast(DexMethod::get_method("Ljava/lang/String;.equals:(Ljava/lang/Object;)Z"))}; + const DexMethod* Integer_parseInt{ + static_cast(DexMethod::get_method("Ljava/lang/Integer;.parseInt:(Ljava/lang/String;)I"))}; + const DexType* String_class{DexType::get_type("Ljava/lang/String;")}; + if(method == nullptr || (method->get_class() != String_class && method != Integer_parseInt)){ return false; } @@ -789,7 +794,7 @@ bool StringAnalyzer::analyze_invoke(const IRInstruction* insn, return nullptr; }; - if (method == method::java_lang_String_equals()) { + if (method == String_equals) { always_assert(insn->srcs_size() == 2); if (const auto* arg0 = maybe_string(0)) { if (const auto* arg1 = maybe_string(1)) { @@ -799,13 +804,20 @@ bool StringAnalyzer::analyze_invoke(const IRInstruction* insn, return true; } } - } else if (method == method::java_lang_String_hashCode()) { + } else if (method == String_hashCode) { always_assert(insn->srcs_size() == 1); if (const auto* arg0 = maybe_string(0)) { int64_t res = arg0->java_hashcode(); env->set(RESULT_REGISTER, SignedConstantDomain(res)); return true; } + }else if (method == Integer_parseInt){ + if (const auto* arg0 = maybe_string(0)) { + const char* int_ = arg0->c_str(); + int64_t res = atoi(int_); + env->set(RESULT_REGISTER, SignedConstantDomain(res)); + return true; + } } return false; From caccac0000ef79376a2114f7a6b0f60adff392f0 Mon Sep 17 00:00:00 2001 From: fa1conn Date: Mon, 31 Oct 2022 21:29:59 +0800 Subject: [PATCH 2/4] Fix StringAnalyzer bug and Add Integer.parseInt --- service/constant-propagation/ConstantPropagationAnalysis.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/service/constant-propagation/ConstantPropagationAnalysis.cpp b/service/constant-propagation/ConstantPropagationAnalysis.cpp index fe8d284f6dc..a14845d3276 100644 --- a/service/constant-propagation/ConstantPropagationAnalysis.cpp +++ b/service/constant-propagation/ConstantPropagationAnalysis.cpp @@ -779,6 +779,7 @@ bool StringAnalyzer::analyze_invoke(const IRInstruction* insn, const DexMethod* Integer_parseInt{ static_cast(DexMethod::get_method("Ljava/lang/Integer;.parseInt:(Ljava/lang/String;)I"))}; const DexType* String_class{DexType::get_type("Ljava/lang/String;")}; + auto method = insn->get_method(); if(method == nullptr || (method->get_class() != String_class && method != Integer_parseInt)){ return false; } From 448a1454cfbfe7430b74bcf1b39329ce729345dc Mon Sep 17 00:00:00 2001 From: fa1conn Date: Tue, 1 Nov 2022 09:06:23 +0800 Subject: [PATCH 3/4] Add Integer.parseInt --- libredex/WellKnownTypes.h | 3 ++- .../ConstantPropagationAnalysis.cpp | 18 ++++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/libredex/WellKnownTypes.h b/libredex/WellKnownTypes.h index 442d9092a98..f4824e31955 100644 --- a/libredex/WellKnownTypes.h +++ b/libredex/WellKnownTypes.h @@ -56,10 +56,11 @@ FOR_EACH(java_lang_Integer_valueOf, \ "Ljava/lang/Integer;.valueOf:(I)Ljava/lang/Integer;") \ FOR_EACH(java_lang_Integer_intValue, "Ljava/lang/Integer;.intValue:()I") \ + FOR_EACH(java_lang_Integer_parseInt, "Ljava/lang/Integer;.parseInt:(Ljava/lang/String;)I") \ FOR_EACH(java_lang_Throwable_fillInStackTrace, \ "Ljava/lang/Throwable;.fillInStackTrace:()Ljava/lang/Throwable;") \ FOR_EACH(java_lang_RuntimeException_init_String, \ "Ljava/lang/RuntimeException;.:(Ljava/lang/String;)V") \ FOR_EACH(java_lang_String_equals, \ "Ljava/lang/String;.equals:(Ljava/lang/Object;)Z") \ - FOR_EACH(java_lang_String_hashCode, "Ljava/lang/String;.hashCode:()I") + FOR_EACH(java_lang_String_hashCode, "Ljava/lang/String;.hashCode:()I") diff --git a/service/constant-propagation/ConstantPropagationAnalysis.cpp b/service/constant-propagation/ConstantPropagationAnalysis.cpp index a14845d3276..ae43fce85bb 100644 --- a/service/constant-propagation/ConstantPropagationAnalysis.cpp +++ b/service/constant-propagation/ConstantPropagationAnalysis.cpp @@ -772,15 +772,9 @@ bool BoxedBooleanAnalyzer::analyze_invoke( bool StringAnalyzer::analyze_invoke(const IRInstruction* insn, ConstantEnvironment* env) { - const DexMethod* String_hashCode{ - static_cast(DexMethod::get_method("Ljava/lang/String;.hashCode:()I"))}; - const DexMethod* String_equals{ - static_cast(DexMethod::get_method("Ljava/lang/String;.equals:(Ljava/lang/Object;)Z"))}; - const DexMethod* Integer_parseInt{ - static_cast(DexMethod::get_method("Ljava/lang/Integer;.parseInt:(Ljava/lang/String;)I"))}; - const DexType* String_class{DexType::get_type("Ljava/lang/String;")}; - auto method = insn->get_method(); - if(method == nullptr || (method->get_class() != String_class && method != Integer_parseInt)){ + DexMethod* method = + resolve_method(insn->get_method(), opcode_to_search(insn)); + if (method == nullptr) { return false; } @@ -795,7 +789,7 @@ bool StringAnalyzer::analyze_invoke(const IRInstruction* insn, return nullptr; }; - if (method == String_equals) { + if (method == method::java_lang_String_equals()) { always_assert(insn->srcs_size() == 2); if (const auto* arg0 = maybe_string(0)) { if (const auto* arg1 = maybe_string(1)) { @@ -805,14 +799,14 @@ bool StringAnalyzer::analyze_invoke(const IRInstruction* insn, return true; } } - } else if (method == String_hashCode) { + } else if (method == method::java_lang_String_hashCode()) { always_assert(insn->srcs_size() == 1); if (const auto* arg0 = maybe_string(0)) { int64_t res = arg0->java_hashcode(); env->set(RESULT_REGISTER, SignedConstantDomain(res)); return true; } - }else if (method == Integer_parseInt){ + }else if (method == method::java_lang_Integer_parseInt()){ if (const auto* arg0 = maybe_string(0)) { const char* int_ = arg0->c_str(); int64_t res = atoi(int_); From 17e492de63480539b8bfac2224bb9d9d0b57f554 Mon Sep 17 00:00:00 2001 From: fa1conn Date: Tue, 1 Nov 2022 09:21:15 +0800 Subject: [PATCH 4/4] Add Integer.parseInt --- libredex/Purity.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libredex/Purity.cpp b/libredex/Purity.cpp index 15ba9cd3a20..66fef47888e 100644 --- a/libredex/Purity.cpp +++ b/libredex/Purity.cpp @@ -188,6 +188,7 @@ static const std::string_view pure_method_names[] = { "Ljava/lang/Integer;.toString:(I)Ljava/lang/String;", "Ljava/lang/Integer;.toString:(II)Ljava/lang/String;", "Ljava/lang/Integer;.valueOf:(I)Ljava/lang/Integer;", + "Ljava/lang/Integer;.parseInt:(Ljava/lang/String;)I", "Ljava/lang/Long;.bitCount:(J)I", "Ljava/lang/Long;.compareTo:(Ljava/lang/Long;)I", "Ljava/lang/Long;.doubleValue:()D",