Byte Code Injection for Dalvik through modified...

27170505_JsU0.jpg 27170505_JsU0.jpg
Sorry for bumping this old thread.

Tez, is there any progress on the injection? I need to do something
similar. But my problem is more difficult: I cannot build a customized
dalvik vm, I can only inject the "monitor" java code by native code
injection, which means firstly I have to inject native code into libdvm.so
like a virus, then the injected libdvm.so would load extra "monitor" java
code.
Currently I can inject instructions on the entry of any function whose
address is known. Which function from libdvm.so should I inject to get this
job done? Although with different versions the function name may be
different, I can handle this problem by injecting different native code
according to the version number.

Thanks
-Yao
- Show quoted text -

Tweet

Search Discussions

All GroupsAndroidandroid-platform

13 responses

  • Tez Tez at Mar 12, 2012 at 4:58 pm 27170506_QmZZ.png
    can you explain your mechanism in more detail?
    my arch. is different.

    -Earlence
    - Show quoted text -
  • 邓尧 邓尧 at Mar 13, 2012 at 10:34 am 27170506_QmZZ.png
    My approach works on arm-linux.

    1. Attach to the target process with ptrace() system call.
    2. Create a break point in the target process like a debugger.
    3. When the break point is hit, copy some bootstrap code (more on bootstrap
    code below) on the stack of the target process. The stack of the target
    process can be found by parsing /proc/<pid>/maps, the corresponding line
    entry ends with "[stack]"
    4. Replace the break point with a "bx ip" instruction (similar to "jmp" in
    x86), modify the value of register "ip", then resume the target process.
    The target process will execute the injected bootstrap code.

    About the bootstrap code:
    a). The first instruction of the bootstrap code is a break point. When this
    break point is hit, do the following:
    * Clear the break point created in step 2.
    * Replace the break point created in step a) with a "nop" instruction.
    * Replace the first instruction of the injected function with any illegal
    instruction, I picked "0xdead" for THUMB code, "0xdeaddead" for ARM code.
    * Resume the target process
    b) The bootstrap code just register a signal handler for SIGILL with
    sigaction() system call. The third argument of the signal handler is a
    pointer to a "struct ucontext_t" structure (This structure isn't defined in
    android NDK, but can simply copy one from a gnu cross toolchain). In side
    the signal handler we can do anything we like.
    c) Modify the "pc" register of the "ucontext_t" register and return from
    the signal handler, the target process will jump to the corresponding
    address.
    d) After the jump in step c), first restore the registers (the values of
    the registers are saved in the "ucontext_t" structure), then execute the
    first instruction of the injected function if the instruction is position
    independent, otherwise interpret it (I haven't implemented this part yet,
    better to do the interpretation before returning from the signal handler).
    e) execute the rest of the injected function or return to its caller.

    BTW, according to C standard the behavior of returning from a SIGILL
    handler is undefined, but on arm-linux it just works.

    Thanks
    -Yao
    - Show quoted text -
  • 邓尧 邓尧 at Mar 13, 2012 at 11:26 am 27170506_QmZZ.png
    - Show quoted text -

    I made a mistake, the kernel will restore the registers according to the
    values saved in the "ucontext_t" structure automatically, sorry for this.

    Thanks
    -Yao
    - Show quoted text -
  • Tez Tez at Mar 13, 2012 at 4:25 pm 27170506_QmZZ.png
    as far as a linux process is concerned, this may work.
    but I am afraid that this is not going to work as far as Java is
    concerned.
    The VM interprets instructions, and thus the injection should
    manipulate the VM state.
    From the point of view of a linux process, this information is not
    accessible.

    from a process point of view, the address of an instruction could be
    the same in 2 cases, but the java code being executed at that point is
    something else altogether.

    this is a wrong approach. you have to inject into the bytecode stream
    and not native code stream

    -Earlence
    - Show quoted text -
  • Tez Tez at Mar 13, 2012 at 4:29 pm 27170506_QmZZ.png
    but if you still want to try,
    you can use the following function

    dvmGetMethodCode

    this is called to load a methods code when it is about to be executed.

    -Earlence
    - Show quoted text -
  • 邓尧 邓尧 at Mar 14, 2012 at 9:17 am 27170506_QmZZ.png
    I understand this problem. Since I cannot build a customized dalvikvm, I
    cannot get access to the bytecode stream unless native code is injected
    first.
    dvmGetMethodCode isn't a good function to inject, it's an inline function
    defined in a header file, it could be easy inlined into its caller. IMO,
    it's better to modify the bytecode stream right after loading it, but I
    haven't figured out how dalvik loads a bytecode stream.

    -Yao
    - Show quoted text -
  • Tez Tez at Mar 14, 2012 at 2:49 pm 27170506_QmZZ.png
    inject in the caller of dvmGetMethodCode in that case.

    -Earlence
    - Show quoted text -
  • Tez Tez at Mar 14, 2012 at 5:08 pm 27170506_QmZZ.png
    the other thing that came to mind is that this could be inefficient.
    essentially, the injection point would stop execution each time the
    function is called, since you have to check which method is going to
    be executed.

    -Earlence
    - Show quoted text -
  • 邓尧 邓尧 at Mar 14, 2012 at 6:02 pm 27170506_QmZZ.png
    True, that's why I want to modify the bytecode stream right after loading
    it. Class loading happens just once, but execution could be thousands of
    times.

    -Yao
    - Show quoted text -
  • Tez Tez at Mar 14, 2012 at 7:02 pm 27170506_QmZZ.png
    I am interested in how this turns out.
    If you manage to do it, can you post about it here?

    -Earlence
    - Show quoted text -
  • 邓尧 邓尧 at Mar 16, 2012 at 1:15 pm 27170506_QmZZ.png
    Sure, but I'm now on a different project, so it would take sometime.
    -Yao
    - Show quoted text -
  • Yuru Shao Yuru Shao at Jan 28, 2013 at 11:57 pm 27170506_QmZZ.png
    hi Yao, any updates?

    在 2012年3月16日星期五UTC+8下午1时15分25秒,Deng Yao写道:
    - Show quoted text -
  • 邓尧 邓尧 at Mar 13, 2012 at 9:49 am 27170506_QmZZ.png
    Since apk decompilers already exist, I believe the information in a
    pre-compiled library should be rich enough to identify any Java method.
    - Show quoted text -

转载于:https://my.oschina.net/zhuzihasablog/blog/140925

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值