■ ■ ■ ■ ■ ■
jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
| skipped 26 lines |
27 | 27 | | import jadx.core.dex.trycatch.ExceptionHandler; |
28 | 28 | | import jadx.core.utils.InstructionRemover; |
29 | 29 | | |
| 30 | + | import java.util.ArrayList; |
30 | 31 | | import java.util.List; |
31 | 32 | | |
32 | 33 | | import org.slf4j.Logger; |
| skipped 111 lines |
144 | 145 | | } else { |
145 | 146 | | replaceInsn(block, insnNumber, co); |
146 | 147 | | if (co.isNewInstance()) { |
147 | | - | removeAssignChain(instArgAssignInsn, remover, InsnType.NEW_INSTANCE); |
| 148 | + | InsnNode newInstInsn = removeAssignChain(instArgAssignInsn, remover, InsnType.NEW_INSTANCE); |
| 149 | + | if (newInstInsn != null) { |
| 150 | + | RegisterArg instArg = newInstInsn.getResult(); |
| 151 | + | RegisterArg resultArg = co.getResult(); |
| 152 | + | if (!resultArg.equals(instArg)) { |
| 153 | + | // replace all usages of 'instArg' with result of this constructor instruction |
| 154 | + | for (RegisterArg useArg : new ArrayList<RegisterArg>(instArg.getSVar().getUseList())) { |
| 155 | + | RegisterArg dup = resultArg.duplicate(); |
| 156 | + | InsnNode parentInsn = useArg.getParentInsn(); |
| 157 | + | parentInsn.replaceArg(useArg, dup); |
| 158 | + | dup.setParentInsn(parentInsn); |
| 159 | + | resultArg.getSVar().use(dup); |
| 160 | + | } |
| 161 | + | } |
| 162 | + | } |
148 | 163 | | } |
149 | 164 | | ConstructorInsn replace = processConstructor(mth, co); |
150 | 165 | | if (replace != null) { |
| skipped 18 lines |
169 | 184 | | */ |
170 | 185 | | private static ConstructorInsn processConstructor(MethodNode mth, ConstructorInsn co) { |
171 | 186 | | MethodNode callMth = mth.dex().resolveMethod(co.getCallMth()); |
172 | | - | if (callMth != null |
173 | | - | && callMth.getAccessFlags().isSynthetic() |
174 | | - | && allArgsNull(co)) { |
175 | | - | // if all arguments is null => replace with default constructor |
176 | | - | ClassNode classNode = mth.dex().resolveClass(callMth.getParentClass().getClassInfo()); |
177 | | - | boolean passThis = co.getArgsCount() >= 1 && co.getArg(0).isThis(); |
178 | | - | String ctrId = "<init>(" + (passThis ? TypeGen.signature(co.getArg(0).getType()) : "") + ")V"; |
179 | | - | MethodNode defCtr = classNode.searchMethodByName(ctrId); |
180 | | - | if (defCtr != null) { |
181 | | - | ConstructorInsn newInsn = new ConstructorInsn(defCtr.getMethodInfo(), co.getCallType(), co.getInstanceArg()); |
182 | | - | newInsn.setResult(co.getResult()); |
183 | | - | return newInsn; |
184 | | - | } |
| 187 | + | if (callMth == null |
| 188 | + | || !callMth.getAccessFlags().isSynthetic() |
| 189 | + | || !allArgsNull(co)) { |
| 190 | + | return null; |
185 | 191 | | } |
186 | | - | return null; |
| 192 | + | ClassNode classNode = mth.dex().resolveClass(callMth.getParentClass().getClassInfo()); |
| 193 | + | if (classNode == null) { |
| 194 | + | return null; |
| 195 | + | } |
| 196 | + | boolean passThis = co.getArgsCount() >= 1 && co.getArg(0).isThis(); |
| 197 | + | String ctrId = "<init>(" + (passThis ? TypeGen.signature(co.getArg(0).getType()) : "") + ")V"; |
| 198 | + | MethodNode defCtr = classNode.searchMethodByName(ctrId); |
| 199 | + | if (defCtr == null) { |
| 200 | + | return null; |
| 201 | + | } |
| 202 | + | ConstructorInsn newInsn = new ConstructorInsn(defCtr.getMethodInfo(), co.getCallType(), co.getInstanceArg()); |
| 203 | + | newInsn.setResult(co.getResult()); |
| 204 | + | return newInsn; |
187 | 205 | | } |
188 | 206 | | |
189 | 207 | | private static boolean allArgsNull(InsnNode insn) { |
| skipped 13 lines |
203 | 221 | | /** |
204 | 222 | | * Remove instructions on 'move' chain until instruction with type 'insnType' |
205 | 223 | | */ |
206 | | - | private static void removeAssignChain(InsnNode insn, InstructionRemover remover, InsnType insnType) { |
| 224 | + | private static InsnNode removeAssignChain(InsnNode insn, InstructionRemover remover, InsnType insnType) { |
207 | 225 | | if (insn == null) { |
208 | | - | return; |
| 226 | + | return null; |
209 | 227 | | } |
210 | 228 | | remover.add(insn); |
211 | 229 | | InsnType type = insn.getType(); |
212 | 230 | | if (type == insnType) { |
213 | | - | return; |
| 231 | + | return insn; |
214 | 232 | | } |
215 | 233 | | if (type == InsnType.MOVE) { |
216 | 234 | | RegisterArg arg = (RegisterArg) insn.getArg(0); |
217 | | - | removeAssignChain(arg.getAssignInsn(), remover, insnType); |
| 235 | + | return removeAssignChain(arg.getAssignInsn(), remover, insnType); |
218 | 236 | | } |
| 237 | + | return null; |
219 | 238 | | } |
220 | 239 | | |
221 | 240 | | /** |
| skipped 134 lines |