我可以反编译和编辑类文件的最有效方法是什么?我真的只想编辑文件中的一行代码,但JBE(java ByteCode Editor)不允许我更改浮点常量.
反编译该类并重新编译将无法正常工作,因为我已经尝试过这种方法,我会遇到很多依赖项错误,并且会出现名称错误.我怎样才能有效地解决这个问题?
谢谢
我需要将一个非常大的字典导入到python中,并且我遇到了一些意想不到的内存瓶颈.字典有形式,
d = {(1,2,3):(1,2,3,4), (2,5,6)=(4,2,3,4,5,6), ... }
Run Code Online (Sandbox Code Playgroud)
所以每个键都是一个3元组,每个值都是一个相对较小的任意大小的元组(可能永远不会超过30个元素).使字典变大的原因是键的数量.我正在使用的一个较小的例子大约有247257个键.我通过模拟生成这个字典,所以我可以写出一个定义这个字典的文本文件,对于我刚刚提到的例子,这是一个94MB的文件.我遇到的瓶颈是初始编译为python字节代码会占用大约14GB的内存.所以我第一次导入字典时,我看到RAM使用率上升了,经过10秒后,所有内容都被加载了.如果已生成.pyc文件,则导入几乎是即时的.使用pympler,我已经确定这个字典在内存中只有大约200 MB.这是什么交易?关于如何将此字典加载到python或至少编译为字节代码,我还有其他选项吗?我正在用C++运行生成模拟,我无法以任何我需要的格式编写文件.那里有没有选项(python库等)?我正在与一些需要这些数据作为字典的软件接口,所以请不要在该领域提出其他建议.另外,如果你想知道,我已经在文本文件中定义了字典,就像上面的定义一样,
d = {}
d[1,2,3] = (1,2,3,4)
d[2,5,6] = (4,2,3,4,5,6)
...
Run Code Online (Sandbox Code Playgroud)
两者在编译到字节代码时都提供相同的内存峰值.事实上,第二个似乎稍差,这对我来说是令人惊讶的.必须有一些方法来驯服初始编译需要的ram数量.看起来它应该能够以某种方式一次编译一个键值对.有任何想法吗?
其他信息:使用python 2.6.5
我找不到关于这个主题的很多信息.看起来jswat可以用来完成这个,但我找不到任何一步一步的教程.
我想知道为什么以下字节码中的异常(用于抛出异常)是重复的.
NEW java/lang/IllegalArgumentException
DUP
INVOKESPECIAL java/lang/IllegalArgumentException <init> ()V
ATHROW
Run Code Online (Sandbox Code Playgroud) 我试图获取Java程序的方法参数的值.我正在使用ASM来检测字节码并获取这些值.但是,我遇到了一些麻烦.
这是用于检测代码的visitCode()方法.它正在做的是:
.
@Override
public void visitCode() {
int paramLength = paramTypes.length;
// Create array with length equal to number of parameters
mv.visitIntInsn(Opcodes.BIPUSH, paramLength);
mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
mv.visitVarInsn(Opcodes.ASTORE, paramLength);
// Fill the created array with method parameters
int i = 0;
for (Type tp : paramTypes) {
mv.visitVarInsn(Opcodes.ALOAD, paramLength);
mv.visitIntInsn(Opcodes.BIPUSH, i);
if (tp.equals(Type.BOOLEAN_TYPE) || tp.equals(Type.BYTE_TYPE) || tp.equals(Type.CHAR_TYPE) || tp.equals(Type.SHORT_TYPE) || tp.equals(Type.INT_TYPE))
mv.visitVarInsn(Opcodes.ILOAD, i);
else if (tp.equals(Type.LONG_TYPE)) {
mv.visitVarInsn(Opcodes.LLOAD, i);
i++;
}
else if (tp.equals(Type.FLOAT_TYPE))
mv.visitVarInsn(Opcodes.FLOAD, i);
else if …Run Code Online (Sandbox Code Playgroud) 我最近一直在使用Java库'ASM',它用于在运行时修改字节码,以防人们不知道,而且我无法在ASM 4上找到一个教程.除了官方手册之外ASM 4,它引用了甚至不存在的ASM类.
我想知道是否有人知道该库的任何教程,其中包括基本到中间事物,例如将一些代码插入到方法中.
问题是创建现有对象的动态增强版本.
我不能修改对象的Class.相反,我必须:
Class添加到现有对象的接口是:
public interface EnhancedNode {
Node getNode();
void setNode(Node node);
Set getRules();
void setRules(Set rules);
Map getGroups();
void setGroups(Map groups);
}
Run Code Online (Sandbox Code Playgroud)
有了Byte Buddy,我设法子类化并实现了我的界面.问题是委托给包装对象.我发现这样做的唯一方法是使用反射太慢(我对应用程序负载很重,性能很关键).
到目前为止我的代码是:
Class<? extends Node> proxyType = new ByteBuddy()
.subclass(node.getClass(), ConstructorStrategy.Default.IMITATE_SUPER_TYPE_PUBLIC)
.method(anyOf(finalNode.getClass().getMethods())).intercept(MethodDelegation.to(NodeInterceptor.class))
.defineField("node", Node.class, Visibility.PRIVATE)
.implement(EnhancedNode.class).intercept(FieldAccessor.ofBeanProperty())
.defineField("groups", Map.class, Visibility.PRIVATE)
.implement(EnhancedNode.class).intercept(FieldAccessor.ofBeanProperty())
.defineField("rules", Set.class, Visibility.PRIVATE)
.implement(EnhancedNode.class).intercept(FieldAccessor.ofBeanProperty())
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
enhancedClass = (Class<N>) proxyType;
EnhancedNode enhancedNode = (EnhancedNode) enhancedClass.newInstance();
enhancedNode.setNode(node);
Run Code Online (Sandbox Code Playgroud)
Node子类/包装的对象在哪里.在NodeInterceptor被调用的方法前锋getNode财产.
这里的代码NodeInterceptor: …
当天早些时候,我正在大量尝试使用docstrings和dis模块,并且遇到了一些我似乎找不到答案的东西.
首先,我创建一个test.py包含以下内容的文件:
def foo():
pass
Run Code Online (Sandbox Code Playgroud)
就是这样,没有别的.
然后我打开一个解释器来观察程序的字节码.你可以这样得到它:
code = compile(open('test.py').read(), '', 'exec')
Run Code Online (Sandbox Code Playgroud)
第一个参数是字符串形式的代码,第二个参数用于调试目的(将其留空即可),而第三个参数是模式.我都试过single和exec.结果是一样的.
在此之后,您可以使用反编译字节码dis.
>>> import dis
>>> dis.dis(code)
Run Code Online (Sandbox Code Playgroud)
字节码输出是这样的:
1 0 LOAD_CONST 0 (<code object foo at 0x10a25e8b0, file "", line 1>)
3 MAKE_FUNCTION 0
6 STORE_NAME 0 (foo)
9 LOAD_CONST 1 (None)
12 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
合理的,对于这样一个简单的脚本.它也是有道理的.
然后我尝试通过命令行编译它,如下所示:
$ python -m py_compile test.py
Run Code Online (Sandbox Code Playgroud)
这导致生成字节码并将其放置在test.pyc文件中.内容可以再次拆卸:
>>> import dis
>>> dis.dis(open('test.pyc').read())
Run Code Online (Sandbox Code Playgroud)
这是输出:
>> 0 ROT_THREE
1 <243> 2573
>> 4 …Run Code Online (Sandbox Code Playgroud) 列表推导将其代码直接放在使用它们的函数中,如下所示:
>>> dis.dis((lambda: [a for b in c]))
1 0 BUILD_LIST 0
3 LOAD_GLOBAL 0 (c)
6 GET_ITER
>> 7 FOR_ITER 12 (to 22)
10 STORE_FAST 0 (b)
13 LOAD_GLOBAL 1 (a)
16 LIST_APPEND 2
19 JUMP_ABSOLUTE 7
>> 22 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
而生成器表达式和字典/集合理解主要放在一个单独的嵌套函数中,如下所示:
>>> dis.dis((lambda: {a for b in c}))
1 0 LOAD_CONST 1 (<code object <setcomp> at 0x7ff41a3d59b0, file "<stdin>", line 1>)
3 MAKE_FUNCTION 0
6 LOAD_GLOBAL 0 (c)
9 GET_ITER
10 CALL_FUNCTION 1
13 RETURN_VALUE
>>> dis.dis((lambda: {a for …Run Code Online (Sandbox Code Playgroud) 我正在学习ASM库来生成字节码.在某些时候我犯了一些错误的局部变量类型,并得到一个错误:
Exception in thread "main" java.lang.VerifyError: Bad local variable type
Exception Details:
Location:
Loops.start()V @56: aload_1
Reason:
Type top (current frame, locals[1]) is not assignable to reference type
Stackmap Table:
full_frame(@24,{Object[#2],Object[#9]},{Integer})
full_frame(@25,{Object[#2],Object[#9]},{Integer,Integer})
same_locals_1_stack_item_frame(@44,Integer)
full_frame(@45,{Object[#2],Object[#9]},{Integer,Integer})
full_frame(@48,{Object[#2]},{Integer})
full_frame(@80,{Object[#2],Integer},{Integer})
full_frame(@81,{Object[#2],Integer},{Integer,Integer})
full_frame(@87,{Object[#2]},{Integer})
full_frame(@119,{Object[#2],Integer},{Integer})
full_frame(@120,{Object[#2],Integer},{Integer,Integer})
same_locals_1_stack_item_frame(@123,Integer)
Run Code Online (Sandbox Code Playgroud)
问题并不难找到并修复,但我很好奇这个堆栈图表是什么东西?
bytecode ×10
java ×7
python ×3
byte-buddy ×1
class ×1
clojure ×1
decorator ×1
dictionary ×1
disassembly ×1
editor ×1
jvm ×1
memory ×1
pyc ×1