使用ASM在Android中进行字节码注入

这篇具有很好参考价值的文章主要介绍了使用ASM在Android中进行字节码注入。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

使用ASM在Android中进行字节码注入

使用方法

1.编译使用插件

这里自定义了一个插件用来对字节码进行操作
使用ASM在Android中进行字节码注入首先我们需要找到这个Gradle任务,双击进行编译打包
使用ASM在Android中进行字节码注入打包成功后会生成如下目录
使用ASM在Android中进行字节码注入然后我们需要在项目的gradle文件中进行引用
使用ASM在Android中进行字节码注入
然后在application的model下的gradle中应用插件
使用ASM在Android中进行字节码注入

2.使用ASM清空特定方法体

这里在Activity中加了一个点击事件,这次是将点击事件的方法体进行清除
使用ASM在Android中进行字节码注入这里我们在插件的MethodEmptyBodyVisitor中修改
首先在visitMethod函数中找到OnClickListener的onClick方法(通过判断函数签名,函数名等找到特定函数)

 @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
        String mInterfaceStr = "";
        if(mInterface != null && mInterface.length > 0){
            for(int i = 0 ; i < mInterface.length ; i++){
                mInterfaceStr += mInterface[i];
            }
        }
        if (mv != null && name.contains("onClick") && mInterfaceStr.contains("android/view/View$OnClickListener") && descriptor.contains("(Landroid/view/View;)V")) {
            boolean isAbstractMethod = (access & ACC_ABSTRACT) != 0;
            boolean isNativeMethod = (access & ACC_NATIVE) != 0;
            if (!isAbstractMethod && !isNativeMethod) {
                generateNewBody(mv, owner, access, name, descriptor,signature,exceptions);
                return null;
            }
        }
        return mv;
    }

然后我们在generateNewBody中进行处理

protected void generateNewBody(MethodVisitor mv, String owner, int methodAccess, String methodName, String methodDesc,String signature, String[] exceptions) {
        // (1) method argument types and return type
        Type t = Type.getType(methodDesc);
        Type[] argumentTypes = t.getArgumentTypes();
        Type returnType = t.getReturnType();


        // (2) compute the size of local variable and operand stack
        boolean isStaticMethod = ((methodAccess & Opcodes.ACC_STATIC) != 0);
        int localSize = isStaticMethod ? 0 : 1;
        for (Type argType : argumentTypes) {
            localSize += argType.getSize();
        }
        int stackSize = returnType.getSize();

        // (3) method body
        mv.visitCode();
        if (returnType.getSort() == Type.VOID) {
            mv.visitInsn(RETURN);
        }
        else if (returnType.getSort() >= Type.BOOLEAN && returnType.getSort() <= Type.INT) {
            mv.visitInsn(ICONST_1);
            mv.visitInsn(IRETURN);
        }
        else if (returnType.getSort() == Type.LONG) {
            mv.visitInsn(LCONST_0);
            mv.visitInsn(LRETURN);
        }
        else if (returnType.getSort() == Type.FLOAT) {
            mv.visitInsn(FCONST_0);
            mv.visitInsn(FRETURN);
        }
        else if (returnType.getSort() == Type.DOUBLE) {
            mv.visitInsn(DCONST_0);
            mv.visitInsn(DRETURN);
        }
        else {
            mv.visitInsn(ACONST_NULL);
            mv.visitInsn(ARETURN);
        }
        mv.visitMaxs(stackSize, localSize);
        mv.visitEnd();
    }

可以看到编译后的class文件中方法体已经清除了
使用ASM在Android中进行字节码注入

3.使用ASM替换特定方法体

我们修改generateNewBody方法为

protected void generateNewBody(MethodVisitor mv, String owner, int methodAccess, String methodName, String methodDesc,String signature, String[] exceptions) {
        // (1) method argument types and return type
        Type t = Type.getType(methodDesc);
        Type[] argumentTypes = t.getArgumentTypes();
        Type returnType = t.getReturnType();


        // (2) compute the size of local variable and operand stack
        boolean isStaticMethod = ((methodAccess & Opcodes.ACC_STATIC) != 0);
        int localSize = isStaticMethod ? 0 : 1;
        for (Type argType : argumentTypes) {
            localSize += argType.getSize();
        }
        int stackSize = returnType.getSize();

        // (3) method body
        mv.visitCode();
        String mInterfaceStr = owner;
        if(exceptions != null && exceptions.length > 0){
            for(int i = 0 ; i < exceptions.length ; i++){
                mInterfaceStr += exceptions[i];
            }
        }

        //插入替换代码
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, "com/yxhuang/asm/MainActivity$1", "this$0", "Lcom/yxhuang/asm/MainActivity;");
        mv.visitMethodInsn(INVOKESTATIC, "com/yxhuang/asm/TTT", "test", "(Landroid/content/Context;)V", false);

        if (returnType.getSort() == Type.VOID) {
            mv.visitInsn(RETURN);
        }
        else if (returnType.getSort() >= Type.BOOLEAN && returnType.getSort() <= Type.INT) {
            mv.visitInsn(ICONST_1);
            mv.visitInsn(IRETURN);
        }
        else if (returnType.getSort() == Type.LONG) {
            mv.visitInsn(LCONST_0);
            mv.visitInsn(LRETURN);
        }
        else if (returnType.getSort() == Type.FLOAT) {
            mv.visitInsn(FCONST_0);
            mv.visitInsn(FRETURN);
        }
        else if (returnType.getSort() == Type.DOUBLE) {
            mv.visitInsn(DCONST_0);
            mv.visitInsn(DRETURN);
        }
        else {
            mv.visitInsn(ACONST_NULL);
            mv.visitInsn(ARETURN);
        }
        mv.visitMaxs(stackSize, localSize);
        mv.visitEnd();
    }

这是一段跳转其他Activity的代码,原代码如下

public class TTT {
    //跳转A页面
    public static void test(Context context){
        context.startActivity(new Intent(context,A.class));
    }
}

未被替换的代码如下

mTvHello.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this,"aaa",Toast.LENGTH_SHORT).show();
            }
        });

替换后的class如下
使用ASM在Android中进行字节码注入

辅助工具

由于字节码的插桩具有一定难度,因此我们可以通过ASM Bytecode Viewer Support Kotlin这款插件来辅助
使用ASM在Android中进行字节码注入生成的代码如下所示
使用ASM在Android中进行字节码注入然后我们可以通过选择ASMified来查看ASM插桩的代码
使用ASM在Android中进行字节码注入文章来源地址https://www.toymoban.com/news/detail-488491.html

到了这里,关于使用ASM在Android中进行字节码注入的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 从零开发基于ASM字节码的Java代码混淆插件XHood

    因在公司负责基础框架的开发设计,所以针对框架源代码的保护工作比较重视,之前也加入了一系列保护措施 例如自定义classloader加密保护,授权license保护等,但都是防君子不防小人,安全等级还比较低 经过调研各类加密混淆措施后,决定自研混淆插件,自主可控,能够贴

    2024年02月06日
    浏览(15)
  • 一、认识 JVM 规范(JVM 概述、字节码指令集、Class文件解析、ASM)

    JVM : Java Virtual Machine ,也就是 Java 虚拟机 所谓虚拟机是指:通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的计算机系统。 即:虚拟机是一个计算机系统。这种计算机系统运行在完全隔离的环境中,且它的硬件系统功能是通过软件模拟出来的。 JVM 通

    2024年01月23日
    浏览(28)
  • Android Binder机制浅谈以及使用Binder进行跨进程通信的俩种方式(AIDL以及直接利用Binder的transact方法实现)

    Binder机制学习 ·为何新增Binder来作为主要的IPC方式 Android也是基于Linux内核,Linux现有的进程通信手段有管道/消息队列/共享内存/套接字/信号量。 既然有现有的IPC方式,为什么重新设计一套Binder机制呢? 主要是出于以上三个方面的考量: 2. binder是什么? 从进程间通信的角度

    2024年02月16日
    浏览(17)
  • Linux-0.11 kernel目录进程管理asm.s详解

    该模块和CPU异常处理相关,在代码结构上asm.s和traps.c强相关。 CPU探测到异常时,主要分为两种处理方式,一种是有错误码,另一种是没有错误码,对应的方法就是 error_code 和 no_error_code 。在下面的函数详解中,将主要以两个函数展开。 no_error_code 对于一些异常而言,CPU在出现

    2024年02月07日
    浏览(40)
  • 1分钟了解C语言正确使用字节对齐及#pragma pack的方法

    ​ C/C++编译器的缺省字节对齐方式为自然对界。即在缺省情况下,编译器为每一个变量或是数据单元按其自然对界条件分配空间。 在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储(成员之间可能有

    2024年02月02日
    浏览(38)
  • Git注册、登录和使用方法(2),字节跳动历年Linux运维中高级面试题全收录

    5.输入用户名 Enter a username*——输入用户名* Username **** is not available ——用户名 **** 不可用(用户名已经被注册) **** is available. —— **** 可用(用户名还没有被注册) 用户名 **** 不可用 输入您需要的用户名 如果您需要的用户名已经被注册,则重新输入一个; 如果您需要的

    2024年04月12日
    浏览(21)
  • 自动化测试工具Selenium的基本使用方法,面试字节跳动的前端工程师该怎么准备

    8.小结 上述均可以改写成find_element(By.ID,‘kw’)的形式 find_elements_by_xxx的形式是查找到多个元素,结果为列表 import time from selenium import webdriver#驱动浏览器 from selenium.webdriver import ActionChains #滑动 from selenium.webdriver.common.by import By #选择器 from selenium.webdriver.common.by import By #按照什

    2024年04月16日
    浏览(23)
  • 使用nginx代理https网站,并注入自己js的方法

    最近遇到一个变态的问题,客户要我们做的网站收集到的数据直接上传到他们上级的一个数据汇总系统,但是上级系统已经运行了很多年,貌似没有再进行二次开发的可能了,并且别人的系统也不一定给我们对接,那么有什么办法能把我们的数据直接在用户提交表单的时候直

    2024年02月16日
    浏览(16)
  • 帝国cms高危SQL注入漏洞(盲注)系统自带RepPIntvar过滤函数使用方法

    帝国cms源码开发的时候很多时候要用到$_GET过来的参数,在处理的时候如果不严谨容易被发现利用,给系统整体安全带来影响。 帝国cms系统本身有自带了过滤函数RepPIntvar,传递过来的字段加上过滤可以给安全加分。 错误的写法: $title = $_GET[\\\'id\\\'] ; 未经过滤存在SQL注入漏洞风

    2024年02月04日
    浏览(35)
  • SQL注入实战:宽字节注入

    一、宽字节概率 1、单字节字符集:所有的字符都使用一个字节来表示,比如 ASCII编码(0-127) 2、多字节字符集:在多字节字符集中,一部分字符用多个字节来表示,另一部分字符(可能没有)用 单个字节来表示。 3、宽字节注入是利用mysql的一个特性,使用GBK编码的时候,会认为两

    2024年01月22日
    浏览(16)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包