我想在运行时在android应用程序中注入代码.我曾尝试使用dx工具在sdcard中生成dexfile,但是当我想要实例化时,它会失败.是否有任何工具可以注入生成新dalvik字节码的代码?我正在研究一些库,aspecjt或guice for android.使用脚本语言更好吗?
谢谢人们:)
我有兴趣在字节级别手动将IPTC字段注入JPG文件.JPEG文件具有多个具有可观大小标记的元数据段.IPTC的细分容器是:
App13 - 以.开头FF ED XX XX ..
8BIM IPTC文本元数据 - 以38 42 49 4D 04 04 00 00 00 00 XX XX ..
IPTC字段以1C 02 50 XX XX ..(0x50 = 80,IPTC字段#80)开始.
(XX XX = 2个字节的长度字,描述了所提到的段数据的大小).
JPEG文件和元数据中是否还有其他尺寸标记可供查找?在使用自定义IPTC字段附加元数据片段时是否必须增加其大小?
如何添加可用于已包含IPTC段的所有JPEG图像的自定义元数据字段(例如#225)?
在C#中工作,但这是关于字节操作的问题所以我猜语言并不重要.
如果我想使用字节码检测实现分析器,我应该使用JVMTI编写本机代理还是应该使用该包编写java代理?java.lang.instrument
如果我想使用像ASM这样的库- 如果你想创建一个严肃的探查器似乎是强制性的 - 我必须使用java代理.这使我感到困惑,因为我认为本机代理可以完成Java代理可以做的所有事情.但对我来说,编写java代理似乎更容易.
还有替代品吗?是否应该使用java代理和本地代理组合?
我想在Python中做一些字节码操作(想想遗传编程).
我在Python源代码树的crashers测试部分遇到了一个测试用例:
破碎的字节码对象很容易使解释器崩溃.这不是固定的.
因此问题,如何验证给定的调整字节代码,它不会崩溃解释器?它甚至可能吗?
测试源,在http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html之后
cc = (lambda fc=(
lambda n: [
c for c in
().__class__.__bases__[0].__subclasses__()
if c.__name__ == n
][0]
):
fc("function")(
fc("code")(
0, 0, 0, 0, "KABOOM", (), (), (), "", "", 0, ""
), {}
)()
)
Run Code Online (Sandbox Code Playgroud)
这里,该模块定义cc了如果被调用则mymod.cc()崩溃解释器.虽然这是一个非常棘手的例子,"KABOOM"它使用自定义字节码创建新的代码对象,然后运行它.
我接受一些验证预定义字节码的东西,例如来自.pyc文件.
我有一个(混淆)方法,我使用ASM打印,输出如下:
METHOD: m(ZB)Lcc;
--------------------------------------
L0:
{
ALOAD_0
GETFIELD d/x I
LDC 2036719157
IMUL
ISTORE
GOTO L1
}
L2:
{
ALOAD_6
ICONST_0
LDC -373364649
ALOAD_0
GETFIELD d/at I
IMUL
ICONST_0
INVOKEVIRTUAL cc/y(III)V
GOTO L3
}
L4:
{
ACONST_NULL
ARETURN
}
L5:
{
ILOAD_1
IFEQ L6
LDC -723220973
ALOAD_0
GETFIELD d/an I
IMUL
ISTORE
LDC 1671960653
ALOAD_0
GETFIELD d/ad I
IMUL
ISTORE
GOTO L7
}
L8:
{
LDC 1955946639
ALOAD_0
GETFIELD d/au I
IMUL
IFEQ L9
ILOAD_2
ICONST_1
IF_ICMPEQ L10
NEW …Run Code Online (Sandbox Code Playgroud) 我需要在Android UI Framework中的各种视图类上代理方法,例如TextView.特别TextView#setText(int resId).此方法不是界面的一部分.因此,Java 代理将无法工作,因为它仅适用于接口.我需要使用字节码操作.
我发现了一个名为dexmaker的图书馆似乎很有希望.我假设我需要进行运行时字节代码操作,因为Android View类实际上只能在设备上使用.Dexmaker可以在具体类上代理公共方法.然后我注意到这TextView#setText(int resId)是莫名其妙的最终结果.在TextView类本身就是非final.
我想我可以派dexmaker来支持非final类的最终方法.这可能吗?如果不是,我不想启动这个项目.这对我的库来说是一个巨大的胜利,因为开发人员不需要为他们的视图提供子类,接口或手动静态方法调用.我的图书馆需要知道何时在特定视图上设置文本.代理是完美的设计模式.
我使用classloader和Unsafe :: definedAnonymous()来加载生成的字节码byte [].classLoader.loadClass()返回的Class的使用成功,而它c.getMethod()在哪个c=Unsafe.defineAnonymousClass()API中失败.那么生成的字节码是错的吗?
我的代码:
MainInliner loader = new MainInliner();
Class<?> c =null;
byte[] bytes = ...
if(args[0].equals("0")){
c = loader.loadClass(name, bytes, 0, bytes.length); // Classloader.loadClass.
}else{
c = Unsafe.defineAnonymousClass(Hoster, bytes, null);
}
Method m = c.getMethod("main", new Class<?>[] { String[].class });
Run Code Online (Sandbox Code Playgroud)
错误是:
Exception Details:
Location:
code/sxu/asm/example/Caller.test(II)V @98: lload_3
Reason:
Type integer (current frame, locals[3]) is not assignable to long
Current Frame:
bci: @98
flags: { }
locals: { 'code/sxu/asm/example/Caller', integer, integer, integer, integer, integer, integer, …Run Code Online (Sandbox Code Playgroud) java classloader dynamic-class-loaders bytecode-manipulation java-bytecode-asm
我正在通过十六进制编辑器修改Java类字节码,我想强制一个方法总是返回true.
pop以恢复堆栈高度,因为它接收参数.iconst_1后跟ireturn.public static boolean test(java.lang.String);
descriptor: (Ljava/lang/String;)Z
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=5, locals=12, args_size=1
0: nop
1: nop
2: nop
3: nop
4: nop
[...]
1886: nop
1887: nop
1888: pop
1889: iconst_1
1890: ireturn
Run Code Online (Sandbox Code Playgroud)
但是在执行它时,我收到以下错误
java.lang.VerifyError: (class: com/example/test/TestBytecode, method: test signature: (Ljava/lang/String;)Z) Inconsistent stack height 0 != 1
Run Code Online (Sandbox Code Playgroud)
注意:有或没有pop结果完全相同.
反汇编一些Java 8代码我发现invokestatic接口中的一些静态方法调用(特别是这个java.util.function.Function.identity())在const pool中使用了InterfaceMethodRef; 这是javap -s -c -v p告诉我的:
15: invokestatic #66 // InterfaceMethod java/util/function/Function.identity:()Ljava/util/function/Function;
Run Code Online (Sandbox Code Playgroud)
根据JVM 8规范,这是不可能的,当我在带有Java 7(major version=51)版本的classfile中使用此指令时,它已在此指令上抛出VerifyError.
但是,当我将主要版本更改为时52,它开始像魅力一样工作.请注意,我在Oracle JDK 1.8.0_60上运行.我想知道为什么需要进行这种更改(调用的方法是静态链接的,不是吗?)以及是否记录在任何地方.
可能知道,刚刚由new字节码分配的对象没有被初始化,因此不是a java.lang.Object.如果我进行运行时字节码操作并将该对象提供给方法,JVM会抱怨甚至崩溃(因为我给它的"东西"不是a java.lang.Object).
所以,我的问题是,什么时候对象"完全"初始化,即成为java.lang.Object?那是构造函数(<init>):
java.lang.Object.<init>?