未验证 提交 0fafcfa0 编写于 作者: S Skylot

fix(gui): improve smali disasm method param write (#1739)

上级 e3fdbafd
...@@ -13,6 +13,8 @@ import java.util.Map.Entry; ...@@ -13,6 +13,8 @@ import java.util.Map.Entry;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.api.ICodeInfo; import jadx.api.ICodeInfo;
import jadx.api.plugins.input.data.AccessFlags; import jadx.api.plugins.input.data.AccessFlags;
...@@ -46,6 +48,7 @@ import jadx.core.dex.instructions.args.RegisterArg; ...@@ -46,6 +48,7 @@ import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.api.plugins.input.data.AccessFlagsScope.FIELD; import static jadx.api.plugins.input.data.AccessFlagsScope.FIELD;
...@@ -67,6 +70,7 @@ import static jadx.api.plugins.input.insns.Opcode.SPARSE_SWITCH; ...@@ -67,6 +70,7 @@ import static jadx.api.plugins.input.insns.Opcode.SPARSE_SWITCH;
import static jadx.api.plugins.input.insns.Opcode.SPARSE_SWITCH_PAYLOAD; import static jadx.api.plugins.input.insns.Opcode.SPARSE_SWITCH_PAYLOAD;
public class Smali { public class Smali {
private static final Logger LOG = LoggerFactory.getLogger(Smali.class);
private static SmaliInsnDecoder insnDecoder = null; private static SmaliInsnDecoder insnDecoder = null;
...@@ -219,7 +223,15 @@ public class Smali { ...@@ -219,7 +223,15 @@ public class Smali {
writeFields(smali, clsData, fields, colWidths); writeFields(smali, clsData, fields, colWidths);
fields.clear(); fields.clear();
} }
writeMethod(smali, cls.getMethods().get(mthIndex[0]++), m, line); try {
writeMethod(smali, cls.getMethods().get(mthIndex[0]++), m, line);
} catch (Throwable e) {
IMethodRef methodRef = m.getMethodRef();
String mthFullName = methodRef.getParentClassType() + "->" + methodRef.getName();
smali.setIndent(0);
smali.startLine("Failed to write method: " + mthFullName + "\n" + Utils.getStackTrace(e));
LOG.error("Failed to write smali code for method: {}", mthFullName, e);
}
line.reset(); line.reset();
}); });
...@@ -451,48 +463,45 @@ public class Smali { ...@@ -451,48 +463,45 @@ public class Smali {
if (types.isEmpty()) { if (types.isEmpty()) {
return false; return false;
} }
int paramCount = 0; ILocalVar[] params = new ILocalVar[codeReader.getRegistersCount()];
int paramStart = 0;
int regNum = line.smaliMthNode.getParamRegStart();
if (!hasStaticFlag(mth.getAccessFlags())) {
line.addRegName(regNum, "p0");
line.smaliMthNode.setParamReg(regNum, "p0");
regNum += 1;
paramStart = 1;
}
IDebugInfo dbgInfo = codeReader.getDebugInfo(); IDebugInfo dbgInfo = codeReader.getDebugInfo();
if (dbgInfo != null) { if (dbgInfo != null) {
for (ILocalVar var : dbgInfo.getLocalVars()) { for (ILocalVar var : dbgInfo.getLocalVars()) {
if (var.getRegNum() == regNum) { // collect only method parameters
int i = writeParamInfo(smali, line, regNum, paramStart, var.getName(), var.getType()); if (var.getStartOffset() <= 0) {
regNum += i; params[var.getRegNum()] = var;
paramStart += i;
paramCount++;
} }
} }
} }
for (; paramCount < types.size(); paramCount++) { int paramStart = 0;
int i = writeParamInfo(smali, line, regNum, paramStart, "", types.get(paramCount)); int regNum = line.smaliMthNode.getParamRegStart();
regNum += i; if (!hasStaticFlag(mth.getAccessFlags())) {
paramStart += i; // add 'this' register
} line.addRegName(regNum, "p0");
return true; line.smaliMthNode.setParamReg(regNum, "p0");
}
private static int writeParamInfo(SmaliWriter smali, LineInfo line,
int regNum, int paramNum, String dbgInfoName, String type) {
smali.startLine(String.format(".param p%d, \"%s\":%s", paramNum, dbgInfoName, type));
String pName = "p" + paramNum;
line.addRegName(regNum, pName);
line.smaliMthNode.setParamReg(regNum, pName);
if (isWideType(type)) {
regNum++; regNum++;
dbgInfoName = "p" + (paramNum + 1); paramStart++;
line.addRegName(regNum, dbgInfoName); }
line.smaliMthNode.setParamReg(regNum, dbgInfoName); for (String paramType : types) {
return 2; String name;
String type;
ILocalVar param = params[regNum];
if (param != null) {
name = Utils.getOrElse(param.getName(), "");
type = Utils.getOrElse(param.getSignature(), paramType);
} else {
name = "";
type = paramType;
}
String varName = "p" + paramStart;
smali.startLine(String.format(".param %s, \"%s\" # %s", varName, name, type));
line.addRegName(regNum, varName);
line.smaliMthNode.setParamReg(regNum, varName);
int regSize = isWideType(paramType) ? 2 : 1;
regNum += regSize;
paramStart += regSize;
} }
return 1; return true;
} }
private static int getParamStartRegNum(IMethodData mth) { private static int getParamStartRegNum(IMethodData mth) {
......
...@@ -8,6 +8,8 @@ import org.slf4j.LoggerFactory; ...@@ -8,6 +8,8 @@ import org.slf4j.LoggerFactory;
import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.SmaliTest; import jadx.tests.api.SmaliTest;
import static org.assertj.core.api.Assertions.assertThat;
class DbgSmaliTest extends SmaliTest { class DbgSmaliTest extends SmaliTest {
private static final Logger LOG = LoggerFactory.getLogger(DbgSmaliTest.class); private static final Logger LOG = LoggerFactory.getLogger(DbgSmaliTest.class);
...@@ -17,10 +19,20 @@ class DbgSmaliTest extends SmaliTest { ...@@ -17,10 +19,20 @@ class DbgSmaliTest extends SmaliTest {
} }
@Test @Test
void test() { void testSwitch() {
disableCompilation(); disableCompilation();
ClassNode cls = getClassNodeFromSmali("switch", "SwitchTest"); ClassNode cls = getClassNodeFromSmali("switch", "SwitchTest");
Smali disasm = Smali.disassemble(cls); Smali disasm = Smali.disassemble(cls);
LOG.debug("{}", disasm.getCode()); LOG.debug("{}", disasm.getCode());
} }
@Test
void testParams() {
disableCompilation();
ClassNode cls = getClassNodeFromSmali("params", "ParamsTest");
Smali disasm = Smali.disassemble(cls);
String code = disasm.getCode();
LOG.debug("{}", code);
assertThat(code).doesNotContain("Failed to write method");
}
} }
.class LParamsTest;
.super Ljava/lang/Object;
.method public test(Landroid/widget/AdapterView;Landroid/view/View;IJ)V
.registers 10
.param p2, "arg1" # Landroid/view/View;
.param p3, "arg2" # I
.param p4, "arg3" # J
.annotation system Ldalvik/annotation/Signature;
value = {
"(",
"Landroid/widget/AdapterView",
"<*>;",
"Landroid/view/View;",
"IJ)V"
}
.end annotation
.prologue
.line 69
.local p1, "arg0":Landroid/widget/AdapterView;, "Landroid/widget/AdapterView<*>;"
iget-object v2, p0, LParamsTest;->this$0:Ltest/ColorListActivity;
.line 72
iget-object v2, v2, Ltest/ColorListActivity;->mSortedColorList:[Ljava/lang/String;
.line 75
aget-object v0, v2, p3
.line 80
.local v0, "colorString":Ljava/lang/String;
new-instance v1, Landroid/content/Intent;
.line 83
iget-object v2, p0, LParamsTest;->this$0:Ltest/ColorListActivity;
.line 86
const-class v3, Ltest/ColorItemActivity;
.line 89
invoke-direct {v1, v2, v3}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V
.line 94
.local v1, "intent":Landroid/content/Intent;
const-string v2, "colorString"
.line 97
invoke-virtual {v1, v2, v0}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;
.line 101
iget-object v2, p0, LParamsTest;->this$0:Ltest/ColorListActivity;
.line 104
invoke-virtual {v2, v1}, Ltest/ColorListActivity;->startActivity(Landroid/content/Intent;)V
.line 108
return-void
.end method
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册