首页 > 解决方案 > 使用java字节码编辑器追加行后缺少'while'语句

问题描述

我的java源代码不见了,所以我需要直接编辑.class。这是我需要修改的整个 .class 文件中的特定方法主体,JD GUI 的反编译视图:

  public static BigDecimal countKilosonName(TicketInfo paramTicketInfo)
  {
    int i = 0;
    BigDecimal localBigDecimal = new BigDecimal(0);
    while (i < paramTicketInfo.getLinesCount())
    {
      String str1 = paramTicketInfo.getLine(i).getProductName();
      int j = (int)paramTicketInfo.getLine(i).getMultiply();
      Pattern localPattern = Pattern.compile("\\([+-]?([0-9]*[.])?[0-9]+ (kg|KG|Kg|kG)\\)");
      Matcher localMatcher = localPattern.matcher(str1);
      String str2 = "";
      if (localMatcher.find())
      {
        str2 = localMatcher.group();
        String str3 = str2.replaceAll(" (?i)kg", "").replaceAll("\\(", "").replaceAll("\\)", "");
        double d = j * Double.parseDouble(str3);
        localBigDecimal = localBigDecimal.add(BigDecimal.valueOf(d));
        paramTicketInfo.getLine(i).setProperty("product.name.altered", paramTicketInfo.getLine(i).getProductName().replace("(" + str3 + " kg)", "(" + d + " kg)"));
      }
      i++;
    }
    return localBigDecimal;
  }

这是开始的字节码编辑器:

iconst_0
istore_1
new java/math/BigDecimal
dup
iconst_0
invokespecial java/math/BigDecimal/<init>(I)V
astore_2
iload_1
aload_0
invokevirtual com/openbravo/pos/ticket/TicketInfo/getLinesCount()I
if_icmpge 92
aload_0
iload_1
invokevirtual com/openbravo/pos/ticket/TicketInfo/getLine(I)Lcom/openbravo/pos/ticket/TicketLineInfo;
invokevirtual com/openbravo/pos/ticket/TicketLineInfo/getProductName()Ljava/lang/String;
astore_3
aload_0
iload_1
invokevirtual com/openbravo/pos/ticket/TicketInfo/getLine(I)Lcom/openbravo/pos/ticket/TicketLineInfo;
invokevirtual com/openbravo/pos/ticket/TicketLineInfo/getMultiply()D
d2i
istore 4
ldc_w "\([+-]?([0-9]*[.])?[0-9]+ (kg|KG|Kg|kG)\)"
invokestatic java/util/regex/Pattern/compile(Ljava/lang/String;)Ljava/util/regex/Pattern;
astore 5
aload 5
aload_3
invokevirtual java/util/regex/Pattern/matcher(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;
astore 6
ldc ""
astore 7
aload 6
invokevirtual java/util/regex/Matcher/find()Z
ifeq 90
aload 6
invokevirtual java/util/regex/Matcher/group()Ljava/lang/String;
astore 7
aload 7
ldc_w " (?i)kg"
ldc ""
invokevirtual java/lang/String/replaceAll(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
ldc_w "\("
ldc ""
invokevirtual java/lang/String/replaceAll(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
ldc_w "\)"
ldc ""
invokevirtual java/lang/String/replaceAll(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
astore 8
iload 4
i2d
aload 8
invokestatic java/lang/Double/parseDouble(Ljava/lang/String;)D
dmul
dstore 9
aload_2
dload 9
invokestatic java/math/BigDecimal/valueOf(D)Ljava/math/BigDecimal;
invokevirtual java/math/BigDecimal/add(Ljava/math/BigDecimal;)Ljava/math/BigDecimal;
astore_2
aload_0
iload_1
invokevirtual com/openbravo/pos/ticket/TicketInfo/getLine(I)Lcom/openbravo/pos/ticket/TicketLineInfo;
ldc_w "product.name.altered"
aload_0
iload_1
invokevirtual com/openbravo/pos/ticket/TicketInfo/getLine(I)Lcom/openbravo/pos/ticket/TicketLineInfo;
invokevirtual com/openbravo/pos/ticket/TicketLineInfo/getProductName()Ljava/lang/String;
new java/lang/StringBuilder
dup
invokespecial java/lang/StringBuilder/<init>()V
ldc_w "("
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
aload 8
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
ldc_w " kg)"
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
new java/lang/StringBuilder
dup
invokespecial java/lang/StringBuilder/<init>()V
ldc_w "("
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
dload 9
invokevirtual java/lang/StringBuilder/append(D)Ljava/lang/StringBuilder;
ldc_w " kg)"
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
invokevirtual java/lang/String/replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
invokevirtual com/openbravo/pos/ticket/TicketLineInfo/setProperty(Ljava/lang/String;Ljava/lang/String;)V
iinc 1 1
goto 8
aload_2
areturn

在第 84 行我替换:

invokevirtual java/lang/StringBuilder/append(D)Ljava/lang/StringBuilder;

invokestatic java/math/BigDecimal/valueOf(D)Ljava/math/BigDecimal;
invokevirtual java/lang/StringBuilder/append(Ljava/math/BigDecimal;)Ljava/lang/StringBuilder;

我的目的是更改源代码:

... .setProperty("product.name.altered", paramTicketInfo.getLine(i).getProductName().replace("(" + str3 + " kg)", "(" + d + " kg)"));

... .setProperty("product.name.altered", paramTicketInfo.getLine(i).getProductName().replace("(" + str3 + " kg)", "(" + BigDecimal.valueOf(d) + " kg)"));

因为我使用 double 得到了一个已知的长小数问题,所以我需要将其更改为 BigDecimal。

但是,当我单击 Java 字节码编辑器上的 Save method 按钮时,出现问题,然后当我使用 JD GUI 再次打开 .class 时,该行while (i < paramTicketInfo.getLinesCount())消失并替换为 only for (;;)d虽然从到的线路变化BigDecimal.valueOf(d)看起来不错。抱歉,如果我很可能缺少基本的 .class 字节码知识。我的计划是,如果字节码编辑成功,我将使用 ASM 生成新类来重新计算 stackmaptable,然后使用 7-zip 将其附加到 .jar 文件中。非常感谢。

标签: javabytecodedecompiler

解决方案


推荐阅读