Projects STRLCPY jadx Commits df38a642
🤬
  • ■ ■ ■ ■ ■
    jadx-gui/src/main/java/jadx/gui/device/debugger/SmaliDebugger.java
    skipped 1285 lines
    1286 1286   @Override
    1287 1287   public String getType() {
    1288 1288   String gen = getSignature();
    1289  - return gen.isEmpty() ? this.slot.signature : gen;
     1289 + if (gen == null || gen.isEmpty()) {
     1290 + return this.slot.signature;
     1291 + }
     1292 + return gen;
    1290 1293   }
    1291 1294   
    1292 1295   @NonNull
    skipped 10 lines
    1303 1306   @Override
    1304 1307   public int getEndOffset() {
    1305 1308   return (int) (slot.codeIndex + slot.length);
     1309 + }
     1310 + 
     1311 + @Override
     1312 + public boolean isMarkedAsParameter() {
     1313 + return false;
    1306 1314   }
    1307 1315   }
    1308 1316   
    skipped 68 lines
  • ■ ■ ■ ■ ■ ■
    jadx-gui/src/main/java/jadx/gui/device/debugger/smali/Smali.java
    skipped 284 lines
    285 285   writeMethodDef(smali, mth, line);
    286 286   ICodeReader codeReader = mth.getCodeReader();
    287 287   if (codeReader != null) {
     288 + int regsCount = codeReader.getRegistersCount();
    288 289   line.smaliMthNode.setParamRegStart(getParamStartRegNum(mth));
    289  - line.smaliMthNode.setRegCount(codeReader.getRegistersCount());
     290 + line.smaliMthNode.setRegCount(regsCount);
    290 291   Map<Long, InsnNode> nodes = new HashMap<>(codeReader.getUnitsCount() / 2);
    291 292   line.smaliMthNode.setInsnNodes(nodes, codeReader.getUnitsCount());
    292  - line.smaliMthNode.initRegInfoList(codeReader.getRegistersCount(), codeReader.getUnitsCount());
     293 + line.smaliMthNode.initRegInfoList(regsCount, codeReader.getUnitsCount());
    293 294   
    294 295   smali.incIndent();
    295  - smali.startLine(".registers ")
    296  - .add("" + codeReader.getRegistersCount())
    297  - .startLine();
     296 + smali.startLine(".registers ").add(Integer.toString(regsCount));
     297 + 
    298 298   writeTries(codeReader, line);
    299  - if (formatMthParamInfo(mth, smali, codeReader, line)) {
    300  - smali.startLine();
     299 + IDebugInfo debugInfo = codeReader.getDebugInfo();
     300 + List<ILocalVar> localVars = debugInfo != null ? debugInfo.getLocalVars() : Collections.emptyList();
     301 + formatMthParamInfo(mth, smali, line, regsCount, localVars);
     302 + if (debugInfo != null) {
     303 + formatDbgInfo(debugInfo, localVars, line);
    301 304   }
     305 + smali.newLine();
    302 306   smali.startLine();
    303  - if (codeReader.getDebugInfo() != null) {
    304  - formatDbgInfo(codeReader.getDebugInfo(), line);
    305  - }
    306 307   // first pass to fill payload offsets for switch instructions
    307 308   codeReader.visitInstructions(insn -> {
    308 309   Opcode opcode = insn.getOpcode();
    skipped 149 lines
    458 459   }
    459 460   }
    460 461   
    461  - private boolean formatMthParamInfo(IMethodData mth, SmaliWriter smali, ICodeReader codeReader, LineInfo line) {
     462 + private void formatMthParamInfo(IMethodData mth, SmaliWriter smali, LineInfo line,
     463 + int regsCount, List<ILocalVar> localVars) {
    462 464   List<String> types = mth.getMethodRef().getArgTypes();
    463 465   if (types.isEmpty()) {
    464  - return false;
    465  - }
    466  - ILocalVar[] params = new ILocalVar[codeReader.getRegistersCount()];
    467  - IDebugInfo dbgInfo = codeReader.getDebugInfo();
    468  - if (dbgInfo != null) {
    469  - for (ILocalVar var : dbgInfo.getLocalVars()) {
    470  - // collect only method parameters
    471  - if (var.getStartOffset() <= 0) {
    472  - params[var.getRegNum()] = var;
    473  - }
    474  - }
     466 + return;
    475 467   }
    476 468   int paramStart = 0;
    477 469   int regNum = line.smaliMthNode.getParamRegStart();
    skipped 4 lines
    482 474   regNum++;
    483 475   paramStart++;
    484 476   }
     477 + if (localVars.isEmpty()) {
     478 + return;
     479 + }
     480 + ILocalVar[] params = new ILocalVar[regsCount];
     481 + for (ILocalVar var : localVars) {
     482 + if (var.isMarkedAsParameter()) {
     483 + params[var.getRegNum()] = var;
     484 + }
     485 + }
     486 + smali.newLine();
    485 487   for (String paramType : types) {
    486  - String name;
    487  - String type;
    488 488   ILocalVar param = params[regNum];
    489 489   if (param != null) {
    490  - name = Utils.getOrElse(param.getName(), "");
    491  - type = Utils.getOrElse(param.getSignature(), paramType);
    492  - } else {
    493  - name = "";
    494  - type = paramType;
     490 + String name = Utils.getOrElse(param.getName(), "");
     491 + String type = Utils.getOrElse(param.getSignature(), paramType);
     492 + String varName = "p" + paramStart;
     493 + smali.startLine(String.format(".param %s, \"%s\" # %s", varName, name, type));
     494 + line.addRegName(regNum, varName);
     495 + line.smaliMthNode.setParamReg(regNum, varName);
    495 496   }
    496  - String varName = "p" + paramStart;
    497  - smali.startLine(String.format(".param %s, \"%s\" # %s", varName, name, type));
    498  - line.addRegName(regNum, varName);
    499  - line.smaliMthNode.setParamReg(regNum, varName);
    500 497   int regSize = isWideType(paramType) ? 2 : 1;
    501 498   regNum += regSize;
    502 499   paramStart += regSize;
    503 500   }
    504  - return true;
    505 501   }
    506 502   
    507 503   private static int getParamStartRegNum(IMethodData mth) {
    skipped 50 lines
    558 554   smali.startLine(".end annotation");
    559 555   }
    560 556   
    561  - private void formatDbgInfo(IDebugInfo dbgInfo, LineInfo line) {
     557 + private void formatDbgInfo(IDebugInfo dbgInfo, List<ILocalVar> localVars, LineInfo line) {
    562 558   dbgInfo.getSourceLineMapping().forEach((codeOffset, srcLine) -> {
    563 559   if (codeOffset > -1) {
    564 560   line.addDebugLineTip(codeOffset, String.format(".line %d", srcLine), "");
    565 561   }
    566 562   });
    567  - for (ILocalVar localVar : dbgInfo.getLocalVars()) {
    568  - String type = localVar.getSignature();
    569  - if (type == null || type.trim().isEmpty()) {
    570  - type = localVar.getType();
     563 + for (ILocalVar localVar : localVars) {
     564 + if (localVar.isMarkedAsParameter()) {
     565 + continue;
    571 566   }
    572  - if (localVar.getStartOffset() > -1) {
    573  - line.addTip(
    574  - localVar.getStartOffset(),
    575  - String.format(".local v%d", localVar.getRegNum()),
    576  - String.format(", \"%s\":%s", localVar.getName(), type));
     567 + String type = localVar.getType();
     568 + String sign = localVar.getSignature();
     569 + String longTypeStr;
     570 + if (sign == null || sign.trim().isEmpty()) {
     571 + longTypeStr = String.format(", \"%s\":%s", localVar.getName(), type);
     572 + } else {
     573 + longTypeStr = String.format(", \"%s\":%s, \"%s\"", localVar.getName(), type, localVar.getSignature());
    577 574   }
    578  - if (localVar.getEndOffset() > -1) {
    579  - line.addTip(
    580  - localVar.getEndOffset(),
    581  - String.format(".end local v%d", localVar.getRegNum()),
    582  - String.format(" # \"%s\":%s", localVar.getName(), type));
    583  - }
     575 + line.addTip(
     576 + localVar.getStartOffset(),
     577 + ".local " + formatVarName(line.smaliMthNode, localVar),
     578 + longTypeStr);
     579 + line.addTip(
     580 + localVar.getEndOffset(),
     581 + ".end local " + formatVarName(line.smaliMthNode, localVar),
     582 + String.format(" # \"%s\":%s", localVar.getName(), type));
     583 + }
     584 + }
     585 + 
     586 + private String formatVarName(SmaliMethodNode smaliMthNode, ILocalVar localVar) {
     587 + int paramRegStart = smaliMthNode.getParamRegStart();
     588 + int regNum = localVar.getRegNum();
     589 + if (regNum < paramRegStart) {
     590 + return "v" + regNum;
    584 591   }
     592 + return "p" + (regNum - paramRegStart);
    585 593   }
    586 594   
    587 595   private void writeEncodedValue(SmaliWriter smali, EncodedValue value, boolean wrapArray) {
    skipped 485 lines
  • ■ ■ ■ ■ ■
    jadx-gui/src/main/java/jadx/gui/device/debugger/smali/SmaliMethodNode.java
    skipped 93 lines
    94 94   protected void setParamReg(int regNum, String name) {
    95 95   SmaliRegister r = regList.get(regNum);
    96 96   r.setParam(name);
    97  - r.setStartOffset(-1);
    98 97   }
    99 98   
    100 99   protected void setParamRegStart(int paramRegStart) {
    skipped 9 lines
  • ■ ■ ■ ■ ■ ■
    jadx-gui/src/main/java/jadx/gui/device/debugger/smali/SmaliRegister.java
    skipped 32 lines
    33 33   }
    34 34   
    35 35   protected void setStartOffset(int off) {
    36  - if (startOffset == -1 && !isParam) {
    37  - startOffset = off;
    38  - return;
    39  - }
    40 36   if (off < startOffset) {
    41 37   startOffset = off;
    42 38   }
    skipped 27 lines
    70 66   @Override
    71 67   public int getEndOffset() {
    72 68   return endOffset;
     69 + }
     70 + 
     71 + @Override
     72 + public boolean isMarkedAsParameter() {
     73 + return isParam;
    73 74   }
    74 75  }
    75 76   
  • ■ ■ ■ ■
    jadx-gui/src/test/java/jadx/gui/device/debugger/smali/DbgSmaliTest.java
    skipped 32 lines
    33 33   Smali disasm = Smali.disassemble(cls);
    34 34   String code = disasm.getCode();
    35 35   LOG.debug("{}", code);
    36  - assertThat(code).doesNotContain("Failed to write method");
     36 + assertThat(code)
     37 + .doesNotContain("Failed to write method")
     38 + .doesNotContain(".param p1")
     39 + .contains(".local p1, \"arg0\":Landroid/widget/AdapterView;, \"Landroid/widget/AdapterView<*>;\"");
    37 40   }
    38 41  }
    39 42   
  • ■ ■ ■ ■ ■
    jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/sections/debuginfo/DebugInfoParser.java
    skipped 95 lines
    96 96   int nameId = in.readUleb128p1();
    97 97   String name = ext.getString(nameId);
    98 98   if (name != null && i < argsCount) {
    99  - int regNum = argRegs[i];
    100  - startVar(new DexLocalVar(regNum, name, argTypes.get(i)), -1);
     99 + DexLocalVar paramVar = new DexLocalVar(argRegs[i], name, argTypes.get(i));
     100 + startVar(paramVar, addr);
     101 + paramVar.markAsParameter();
    101 102   varsInfoFound = true;
    102 103   }
    103 104   }
    skipped 113 lines
  • ■ ■ ■ ■ ■ ■
    jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/sections/debuginfo/DexLocalVar.java
    skipped 6 lines
    7 7  import jadx.plugins.input.dex.sections.SectionReader;
    8 8   
    9 9  public class DexLocalVar implements ILocalVar {
     10 + private static final int PARAM_START_OFFSET = -1;
     11 + 
    10 12   private final int regNum;
    11 13   private final String name;
    12 14   private final String type;
    skipped 63 lines
    76 78   @Override
    77 79   public int getStartOffset() {
    78 80   return startOffset;
     81 + }
     82 + 
     83 + public void markAsParameter() {
     84 + startOffset = PARAM_START_OFFSET;
     85 + }
     86 + 
     87 + @Override
     88 + public boolean isMarkedAsParameter() {
     89 + return startOffset == PARAM_START_OFFSET;
    79 90   }
    80 91   
    81 92   @Override
    skipped 27 lines
  • ■ ■ ■ ■ ■
    jadx-plugins/jadx-java-input/src/main/java/jadx/plugins/input/java/data/attributes/debuginfo/JavaLocalVar.java
    skipped 61 lines
    62 62   }
    63 63   
    64 64   @Override
     65 + public boolean isMarkedAsParameter() {
     66 + return false;
     67 + }
     68 + 
     69 + @Override
    65 70   public int hashCode() {
    66 71   int result = regNum;
    67 72   result = 31 * result + name.hashCode();
    skipped 32 lines
  • ■ ■ ■ ■ ■ ■
    jadx-plugins/jadx-plugins-api/src/main/java/jadx/api/plugins/input/data/ILocalVar.java
    skipped 14 lines
    15 15   int getStartOffset();
    16 16   
    17 17   int getEndOffset();
     18 + 
     19 + /**
     20 + * Hint if variable is a method parameter.
     21 + * Can be incorrect and shouldn't be trusted.
     22 + */
     23 + boolean isMarkedAsParameter();
    18 24  }
    19 25   
Please wait...
Page is in error, reload to recover