Col-E / Recaf

The modern Java bytecode editor
https://recaf.coley.software
MIT License
6.05k stars 466 forks source link

Support "INVOKEDYNAMIC" instruction #131

Closed nevinhappy closed 5 years ago

nevinhappy commented 5 years ago

Feature_Name

support :INVOKEDYNAMIC


When I was trying to use "edit with assembler" function on a jar file which is obfuscated by ZKM. It show up "The instruction INVOKEDYNAMIC is unsupported". I think maybe it's not supported by CFR decompiler . but I can edit the function by "Edit instructions". And after try to use this tools, it's really powerful on the GUI interface compare to JByteMod. but I have several ideas about the function :: 1, Make the decompilers configurable (CRF, Fernflower, Procyon, ...), there is not a pretty decompiler for anyone , so just like eclipse 's plugin "Enhanced Class Decompiler" to integrate them. 2, "Search class " function on active class list . Usually there are lots of class, and this tool most used for those jar file which protected by Obfuscators . 3, “Make opned class window be multi-tabs ”: this makes open several class and show them in multi-tabs.

Extra details:

Col-E commented 5 years ago

The assembler is not related to CFR, I just didn't write a sub-assembler for InvokeDynamic yet. It's on the todo list. I've not gotten around to it yet because it is the hardest instruction to implement an assembler for. The instruction has a lot of data required for it to be used and I'm not sure how to represent it in the assembler. The standard instructions list window supports it fine. The displayed value on the list is hiding a lot of the detail of how the instruction works, which is only shown when you attempt to edit it. The assembler does not have the ability to hide information, since it requires all the information to be right there in order to be compiled.


  1. Been on the todo list a while, even before #118 but I've considered it to be low priority. I chose CFR because it works well in most cases, is relatively small in size, is highly configurable, and is in active development. The next decompiler I would add would probably be fernflower, then procyon.

  2. Can you be more specific? Im not sure what Search class function on active class list . means. Do this refer to the classes you currently have open in the tabbed panel?

  3. I'm using JavaFx for the user interface and I don't know if there's a control that supports this. Even so, I think this could lead to a cluttered looking UI if there were too many tabs opened adjacent to one another. Do you have an example image of how this would look in another program?


Thanks, I'm glad you like using it :+1:

nevinhappy commented 5 years ago

Sorry for my expression of "Search class function on active class list. ", Actually I mean that Classes list filter on the left list . And for point 3, the GUI of jd-gui is an example of show muti-tabs.

Col-E commented 5 years ago

Search class function on active class list

jd-gui is an example

So you mean like this?

image

nevinhappy commented 5 years ago

It could be like this . Please check the attachment for the detail . Sorry for late response . Here is the detail : 1, Current left list : image

2, THe function I mentioned : image

At 2019-06-22 04:09:21, "Matt" notifications@github.com wrote:

Search class function on active class list

jd-gui is an example

So you mean like this?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

Col-E commented 5 years ago

I've replicated the class search in another issue. Back to the primary issue adding INDY support. Here is why adding INVOKEDYNAMIC (INDY) support is not a simple task:

public static String toString(Iterable<AccessFlag> flags) {
    return JOINER.join(Iterables.filter(flags, flag -> flag != ACC_SUPER));
}

There is one lambda here (flag -> flag != ACC_SUPER), and it gets translated into this complicated instruction.

Another example:

private final void addSaveHook() {
    Runtime.getRuntime().addShutdownHook(new Thread(() -> save()));
}

() -> save() becomes this

There's a lot of data here to represent. Thankfully the bootstrap method is the same for a majority of cases. I'm thinking for adding INDY support by aliasing common boostrap method values to names. The one shown in these screenshots would be DEFAULT for instance. The problem is that not all INDY instructions follow the same layout. Most of them are similar in structure to what's shown in the screenshots, but not all of them. True INDY support will be VERY complicated... so that's why realistically INDY will only be supported in common cases like this, where lots of assumptions can be made without any problems coming up.

Col-E commented 5 years ago

The assembler in 2.0.0 now supports INVOKEDYNAMIC. Due to large changes I won't be able to easily backport it to 1.X but not to worry, 2.0.0 will come out eventually :smiley:

The ability to change the decompiler will be supported in 2.0.0 (Currently looking at CFR/FernFlower)

The class search in the display tree will also be supported in 2.0.0.