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

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

上级 e3fdbafd
......@@ -13,6 +13,8 @@ import java.util.Map.Entry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.api.ICodeInfo;
import jadx.api.plugins.input.data.AccessFlags;
......@@ -46,6 +48,7 @@ import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.api.plugins.input.data.AccessFlagsScope.FIELD;
......@@ -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;
public class Smali {
private static final Logger LOG = LoggerFactory.getLogger(Smali.class);
private static SmaliInsnDecoder insnDecoder = null;
......@@ -219,7 +223,15 @@ public class Smali {
writeFields(smali, clsData, fields, colWidths);
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();
});
......@@ -451,48 +463,45 @@ public class Smali {
if (types.isEmpty()) {
return false;
}
int paramCount = 0;
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;
}
ILocalVar[] params = new ILocalVar[codeReader.getRegistersCount()];
IDebugInfo dbgInfo = codeReader.getDebugInfo();
if (dbgInfo != null) {
for (ILocalVar var : dbgInfo.getLocalVars()) {
if (var.getRegNum() == regNum) {
int i = writeParamInfo(smali, line, regNum, paramStart, var.getName(), var.getType());
regNum += i;
paramStart += i;
paramCount++;
// collect only method parameters
if (var.getStartOffset() <= 0) {
params[var.getRegNum()] = var;
}
}
}
for (; paramCount < types.size(); paramCount++) {
int i = writeParamInfo(smali, line, regNum, paramStart, "", types.get(paramCount));
regNum += i;
paramStart += i;
}
return true;
}
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)) {
int paramStart = 0;
int regNum = line.smaliMthNode.getParamRegStart();
if (!hasStaticFlag(mth.getAccessFlags())) {
// add 'this' register
line.addRegName(regNum, "p0");
line.smaliMthNode.setParamReg(regNum, "p0");
regNum++;
dbgInfoName = "p" + (paramNum + 1);
line.addRegName(regNum, dbgInfoName);
line.smaliMthNode.setParamReg(regNum, dbgInfoName);
return 2;
paramStart++;
}
for (String paramType : types) {
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) {
......
......@@ -8,6 +8,8 @@ import org.slf4j.LoggerFactory;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.SmaliTest;
import static org.assertj.core.api.Assertions.assertThat;
class DbgSmaliTest extends SmaliTest {
private static final Logger LOG = LoggerFactory.getLogger(DbgSmaliTest.class);
......@@ -17,10 +19,20 @@ class DbgSmaliTest extends SmaliTest {
}
@Test
void test() {
void testSwitch() {
disableCompilation();
ClassNode cls = getClassNodeFromSmali("switch", "SwitchTest");
Smali disasm = Smali.disassemble(cls);
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.
先完成此消息的编辑!
想要评论请 注册