精华内容
下载资源
问答
  • 代码插桩

    千次阅读 2019-05-19 09:33:16
    【转载】http://wiki.dzsc.com/info/5081.html 代码插桩是实现覆盖测试的关键技术之一,而高效的插桩技术对于嵌入式软件的测试 来说又是至关重要的。在对CodeTeST 中插桩技术研究的基础上,以G...

    https://blog.csdn.net/woshidujian19881029/article/details/6558260

    【转载】http://wiki.dzsc.com/info/5081.html

    •   代码插桩是实现覆盖测试的关键技术之一,而高效的插桩技术对于嵌入式软件的测试 来说又是至关重要的。在对CodeTeST 中插桩技术研究的基础上,以GCC 作为开发平台,应用并实现了新的插装器,采用增加一个词法语法分析器的方法,提高了插桩的效率。经过实验证明新的插装器具有代码膨胀率小,插桩速度块的优 点,在一定程度上做到了高效插桩。
    代码插桩

    代码插桩概述

    •   在实现覆盖测试的过程中,往往需要知道某些信息,如:程序中可执行语句 被执行(即被覆盖)的情况,程序执行的路径,变量的引用、定义等。要想获取这类信息,需要跟踪被测程序的执行过程,或者是由计算机在被测程序执行的过程中 自动记录。前者需要人工进行,效率低下且枯燥乏味;后者则需要在被测程序中插入完成相应工作的代码,即代码插桩技术。如今大多数的覆盖测试工具 均采用代码插桩技术。

        在对普通应用的软件进行测试时,由于现在电脑的配置越来越高,电脑的运行速度越来越快,代码插桩所 引起的问题还不是很明显或者说是在可以接受的范围之内。但是对于嵌入式软件来说这却是致命的问题。因为嵌入式软件的系统资源有限(内存较小、I/O 通道较少等),过大的代码膨胀率将使得程序不能在嵌入式系统中运行;同时嵌入式软件通常具有很强的实时性,程序的输出只在有限的时间内有效,迟到的“正确 的”结果是无用的甚至会变成错误的、有害的。

        代码插桩技术会破坏程序的时间特性等,导致软件执行的错误。因此我们需要更高效的代码插桩技术来完成覆盖测试,尤其是嵌入式软件的覆盖测试。

    代码插桩方式比较

    •   由于程序插桩技术是在被测程序中插入探针,然后通过探针的执行来获得程序的控制流和数据流信息,以此来实现测试的目的。因此,根据探针插入的时间可以分为目标代码插桩和源代码插桩。

        (1)目标代码插桩的前提是对目标代码进:

        行必要的分析以确定需要插桩的地点和内容。由于目标代码的格式主要和操作系统相关,和具体的编程语 言及版本无关,所以得到了广泛的应用,尤其是在需要对内存进行监控的软件中。但是由于目标代码中语法、语义信息不完整,而插桩技术需要对代码词法语法的分 析有较高的要求,故在覆盖测试工具中多采用源代码插桩。

        (2)源代码插桩是在对源文件进行完整的:

        词法分析和语法分析的基础上进行的,这就保证对源文件的插桩能够达到很高的准确度和针对性。但是源代码插桩需要接触到源代码,使得工作量较大,而且随着编码语言和版本的不同需要做一定的修改。在后面我们所提到的程序插桩均指源代码插桩。

    代码插桩设计

    •   (1)插桩位置:

        探针的植入要做到紧凑精干,才能保证在做到收集的信息全面而无冗余,减少代码的膨胀率。因此,在确定插桩位置时,要将程序划分,基本的划分方法是基于“块”结构。

        按照块结构的划分,探针的植入位置有以下几种情况:

        a. 程序的第一条语句;b. 分支语句的开始;c. 循环语句的开始;d. 下一个入口语句之前的语句;e. 程序的结束语句;f. 分支语句的结束;g. 循环语句的结束;除此之外,根据覆盖测试要求的不同,插桩的位置除了上面所说的几种情况外,也会随着覆盖测试要求的不同有所变化。

        (2)插桩策略:

        插桩策略是解决“如何插”的问题。传统的插桩策略是在所有需要插桩的位置插入探针,在程序运行过程 收集所有可能用到得程序信息,将其写入数据库进行分析和处理。这种方法对于大型的程序来说,将会造成相当大的工作量,效率很低,且会造成很大的代码膨胀 率。而我们会根据不同的测试要求,每次插入不同的探针,采用相应的插桩策略,这样就减少了代码的膨胀率,保证了程序执行的效率。下面简单介绍几种探针的插 桩策略。

        语句覆盖探针(基本块探针):在基本块的入口和出口处,分别植入相应的探针,以确定程序执行时该基本块是否被覆盖。

        分支覆盖探针:C/C++语言中,分支由分支点确定。对于每个分支,在其开始处植入一个相应的探针,以确定程序执行时该分支是否被覆盖。

        条件覆盖探针:C/C++语言中,if, swich,while, do-while, for 几种语法结构都支持条件判定,在每个条件表达式的布尔表达式处植入探针,进行变量跟踪取值,以确定其被覆盖情况。

        根据不同测试要求采用不用的插桩策略 ,每次在不同的位置植入相应的探针,使得每次只是植入有限的探针,这就更大大减少了代码的膨胀率和插桩的速度。

    展开全文
  • 代码插桩是实现覆盖测试的关键技术之一,而高效的插桩技术对于嵌入式软件的测试来说又是至关重要的。文章在对CodeTeST 中插桩技术研究的基础上,以GCC 作为开发平台,应用并实现了新的插装器,采用增加一个词法语法...
  • 摘要:代码插桩是实现覆盖测试的关键技术之一,而高效的插桩技术对于嵌入式软件的测试来说又是至关重要的。文章在对CodeTest 中插桩技术研究的基础上,以GCC 作为开发平台,应用并实现了新的插装器,采用增加一个词...
  • java插桩-Jacoco java代码覆盖率可视化

    千次阅读 2020-08-27 17:50:43
    参数 选项 描述 --help 显示帮助 --quiet 抑制stdout上的所有输出 使用举例(OpenDaylight) javaagent java代理jar包路径: /home/llvm/apps/jacoco/lib/jacocoagent.jar 待插桩jar包路径:/usr/lib/opendaylight/...

    目录

    工具

    目录结构

    使用

    javaagent

    何时转储

    设置代理

    参数

    jacococli

    dump命令

    instrument命令

    merge命令

    report命令

    classinfo命令

    execinfo命令

    version命令

    使用举例(OpenDaylight)

    javaagent

    javacli

    参考


    工具

    工具对比(网图,侵删)

    博主使用的是jacoco-0.8.5版本

    目录结构

    .
    ├── coverage
    │   ├── index.html
    │   ├── jacoco.csv
    │   ├── jacoco-maven-plugin
    │   ├── jacoco-resources
    │   ├── jacoco-sessions.html
    │   ├── jacoco.xml
    │   ├── org.jacoco.agent
    │   ├── org.jacoco.agent.rt
    │   ├── org.jacoco.ant
    │   ├── org.jacoco.cli
    │   ├── org.jacoco.core
    │   ├── org.jacoco.examples
    │   ├── org.jacoco.report
    │   └── report.dtd
    ├── doc
    │   ├── agent.html
    │   ├── ant.html
    │   ├── api
    │   ├── api.html
    │   ├── build.html
    │   ├── changes.html
    │   ├── check-mojo.html
    │   ├── classids.html
    │   ├── cli.html
    │   ├── conventions.html
    │   ├── counters.html
    │   ├── dump-mojo.html
    │   ├── empty.html
    │   ├── environment.html
    │   ├── epl-2.0.html
    │   ├── examples
    │   ├── faq.html
    │   ├── flow.html
    │   ├── help-mojo.html
    │   ├── implementation.html
    │   ├── index.html
    │   ├── instrument-mojo.html
    │   ├── integrations.html
    │   ├── license.html
    │   ├── maven.html
    │   ├── merge-mojo.html
    │   ├── mission.html
    │   ├── offline.html
    │   ├── prepare-agent-integration-mojo.html
    │   ├── prepare-agent-mojo.html
    │   ├── repo.html
    │   ├── report-aggregate-mojo.html
    │   ├── report-integration-mojo.html
    │   ├── report-mojo.html
    │   ├── resources
    │   ├── restore-instrumented-classes-mojo.html
    │   ├── support.html
    │   └── team.html
    ├── index.html
    ├── lib
    │   ├── jacocoagent.jar
    │   ├── jacocoant.jar
    │   ├── jacococli.jar
    │   ├── org.jacoco.agent-0.8.5.201910111838.jar
    │   ├── org.jacoco.ant-0.8.5.201910111838.jar
    │   ├── org.jacoco.core-0.8.5.201910111838.jar
    │   └── org.jacoco.report-0.8.5.201910111838.jar
    └── test
        ├── index.html
        └── TESTS-TestSuites.xml

    •  coverage 覆盖率
    • doc 文档
    • lib 库,一些jar包  本文使用了jacocoagent.jar和jacococli.jar
    • test 测试
    • index.html 主页

    使用

    javaagent

    何时转储

    • 文件系统:在JVM终止时,执行数据被写入本地文件。
    • TCP套接字服务器:外部工具可以连接到VM,并通过套接字连接检索执行数据。可以在JVM退出时进行可选的执行数据重置和执行数据转储。
    • TCP套接字客户端:启动时,JaCoCo代理连接到给定的TCP端点。执行数据根据请求写入套接字连接。可以在VM退出时进行可选的执行数据重置和执行数据转储。

    设置代理

    -javaagent:[yourpath/]jacocoagent.jar=[option1]=[value1],[option2]=[value2]

    参数

    选项默认值说明
    destfilejacoco.exec执行数据输出文件的路径。
    outputfile用于写入coverage数据的输出方法。有效选项包括:
    • file:注意,在VM终止时,执行数据将写入destfile属性中指定的文件中。
    • tcpserver:代理在address和port属性指定的TCP端口上侦听传入连接。执行数据将写入此TCP连接
    • tcpclient:在启动时,代理连接到addressport 属性指定的TCP端口。执行数据将写入此TCP连接。
    • none:不产生任何输出。
    请参阅下面的安全注意事项。
    address回送接口IP地址或主机名,结合output为 tcpservertcpclient。在tcpserver模式下,值“ *”使代理接受任何本地地址上的连接。
    port6300当output参数为tcpservertcpclient时绑定到的端口。在 tcpserver模式下,端口必须可用,这意味着如果多个JaCoCo代理在同一台机器上运行,则必须指定不同的端口
    appendtrue如果设置为true,并且执行数据文件已经存在,那么coverage数据将附加到现有文件中。如果设置为 false,将替换现有的执行数据文件。
    includes* (所有类)执行分析中应包括的类名列表。列表条目用冒号(:)分隔,并且可以使用通配符(*?)。除性能优化或技术特殊情况外,通常不需要此选项
    excludesempty(无排除类)应该从执行分析中排除的类名称的列表。列表条目用冒号(:)分隔,并且可以使用通配符(*?)。除性能优化或技术特殊情况外,通常不需要此选项。如果要从报告中排除类别,请相应地配置相应的报告生成工具。
    exclclassloadersun.reflect.DelegatingClassLoader应该从执行分析中排除的类加载器名称的列表。列表条目用冒号(:)分隔,并且可以使用通配符(*和 ?)。在与JaCoCo代码规范冲突的特殊框架的情况下,尤其是无法访问Java运行时类的类加载器时,可能需要此选项
    inclbootstrapclassesfalse指定是否还应该检测引导类加载器中的类。谨慎使用此功能,它需要大量的包含/排除调整。
    inclnolocationclassesfalse指定是否还应检测没有源位置的类。通常,此类在运行时(例如,通过模拟框架)生成,因此默认情况下将其排除在外。
    sessionid自动产生与执行数据一起写入的会话标识符。没有此参数,代理将创建一个随机标识符。
    dumponexittrue如果设置为true,覆盖率数据将在VM关闭时写入。仅当file指定了其中一个或输出为tcpservertcpclient 并且在VM终止时打开了连接时,才能写入转储。
    classdumpdir没有转储相对于工作目录的位置,代理看到的所有类文件都将转储到该目录。这对于调试目的或在动态创建类的情况下(例如在使用脚本引擎时)很有用。
    jmxfalse如果设置为true,该代理由于功能原因通过JMX下的公开属性org.jacoco:type=Runtime暴露出来。请查看下面的安全注意事项。

    安全注意事项:在tcpserver和 tcpclient模式下打开的端口和连接以及JMX接口不提供任何身份验证机制。如果在生产系统上运行JaCoCo,请确保没有不受信任的源可以访问TCP服务器端口,或者JaCoCo TCP客户端仅连接到受信任的目标。否则,可能会泄露应用程序的内部信息,或者可能发生DOS攻击。

    jacococli

    dump命令

    格式

    java -jar jacococli.jar dump [--address <address>] --destfile <path> [--help] [--port <port>] [--quiet] [--reset] [--retry <count>]

     向以“ tcpserver”输出模式运行的JaCoCo代理请求执行数据。

    参数
    选项描述
    --address <address>主机名或ip,默认本机
    <execfiles>要读取的JaCoCo * .exec文件列表
    --classfiles <path>Java类文件的位置(必填项)
    --csv <file>CSV报告的输出文件(处理数据方便)
    --html <dir>HTML报告的输出目录(可视化)
    --encoding <charset>源文件编码(默认情况下使用平台编码)
    --help显示帮助
    --name <name>此报告使用的名称
    --quiet抑制stdout上的所有输出
    --sourcefiles <path>源文件的位置
    --tabwith <n>源页面的制表位停止宽度(默认为4)
    --resetdump后重置测试目标上的执行数据
    --retry <count>重试次数(默认10)

    instrument命令

    格式

    java -jar jacococli.jar instrument [<sourcefiles> ...] --dest <dir> [--help] [--quiet]

    Java类文件和JAR文件的离线检测。 

    参数
    选项描述
    <sourcefiles>要回避检测的文件夹或文件列表
    --dest <dir>将检测的Java类写入的路径
    --help显示帮助
    --quiet抑制stdout上的所有输出

    merge命令

    格式

    java -jar jacococli.jar merge [<execfiles> ...] --destfile <path> [--help] [--quiet]

    将多个exec文件合并到一个新的文件中。

    参数
    选项描述
    <execfiles>要读取的JaCoCo * .exec文件列表
    --destfile <path>将合并的执行数据写入的文件
    --help显示帮助
    --quiet抑制stdout上的所有输出

    report命令

    格式

    java -jar jacococli.jar report [<execfiles>...] --classfiles <path> [--csv <file>] [--encoding <charset>] [--help] [--html <dir>] [--name <name>] [--quiet] [--sourcefiles <path>] [--tabwith <n>] [--xml <file>]

    通过读取exec和Java类文件生成不同格式的报告。 

    参数
    选项描述
    <execfiles>要读取的JaCoCo * .exec文件列表
    --classfiles <path>Java类文件的位置(必填项)
    --csv <file>CSV报告的输出文件(处理数据方便)
    --html <dir>HTML报告的输出目录(可视化)
    --xml <file>XML报告的输出文件
    --encoding <charset>源文件编码(默认情况下使用平台编码)
    --help显示帮助
    --name <name>此报告使用的名称
    --quiet抑制stdout上的所有输出
    --sourcefiles <path>源文件的位置
    --tabwith <n>源页面的制表位停止宽度(默认为4)

    一般情况下填写--classfiles参数,--csv、--html、--xml中选一个,具体情况看读者要求。

    classinfo命令

    格式

    java -jar jacococli.jar classinfo [<classlocations>...] [--help] [--quiet] [--verbose]

     在提供的位置打印有关Java类文件的信息。

    参数
    选项描述
    <classlocations>Java类文件的位置
    --help显示帮助
    --quiet抑制stdout上的所有输出
    --verbose显示方法和行号详细信息

    execinfo命令

    格式

    java -jar jacococli.jar execinfo [<execfiles>...] [--help] [--quiet]

     以人类可读的格式打印exec文件内容。

    version命令

    格式

    java -jar jacococli.jar version [--help] [--quiet]

    打印JaCoCo版本信息。

    参数
    选项描述
    --help显示帮助
    --quiet抑制stdout上的所有输出

    使用举例(OpenDaylight)

    javaagent

    java代理jar包路径: /home/llvm/apps/jacoco/lib/jacocoagent.jar

    待插桩jar包路径:/usr/lib/opendaylight/karaf-0.7.3/system/org/opendaylight/openflowplugin/openflowjava/openflow-protocol-api/0.5.3/openflow-protocol-api-0.5.3.jar

    1.启动时带上Javacoco的agent

    sudo vim /usr/lib/opendaylight/karaf-0.7.3/bin/karaf

    JAVA_OPTS="$JAVA_OPTS -javaagent:/home/llvm/apps/jacoco/lib/jacocoagent.jar=destfile=jacoco.exec,output=tcpserver"
    添加JAVA_OPTS

    javacli

    version命令

     classinfo命令

    显示类名等信息

    使用一下你要测试的jar包。

    dump命令

    获取执行情况数据,在jacococli.jar所在目录(与jacocoagent.jar目录一致)执行命令: 

    java -jar jacococli.jar dump  --port 6300 --destfile data/jacoco-it.exec

    生成.exec文件

    生成.exec文件

    execinfo命令 

    java -jar jacococli.jar execinfo data/jacoco-it.exec

     .exec中包含了包名等信息

    report命令

    执行如下命令生成html报告。--classfiles指定应用程序的class文件所在目录,--html指定html报告所在目录。 

    java -jar jacococli.jar report data/jacoco-it.exec --classfiles /usr/lib/opendaylight/karaf-0.7.3/system/org/opendaylight/openflowplugin/openflowjava/openflow-protocol-api/0.5.3/ --html html
    生成html

    目录

     点击html目录中的index.html查看代码覆盖率

    包的覆盖率

    类、方法、分支等覆盖率
    具体包中类的覆盖率

    具体类中方法的覆盖率

    执行以下命令,生成csv文件

    java -jar jacococli.jar report data/jacoco-it.exec --classfiles /usr/lib/opendaylight/karaf-0.7.3/system/org/opendaylight/openflowplugin/openflowjava/openflow-protocol-api/0.5.3/ --csv openflow-protocol-api.csv

     只有MISSED和COVERED,需要自己计算下覆盖率。

    xml及其他参数没有尝试,留给读者自行探索吧。

    merge命令、instrument命令以及针对Ant、Maven框架如何使用jacoco,Eclipse、IDEA等IDE如何集成jacoco等内容也留给读者去探索吧,锻炼自己阅读官方文档的能力,学会Google、stackoverflow,加油哦!!!

    参考

    jacoco 官网

    jacoco github

    jacocoagent

    jacococli

    更多内容查看:网络安全-自学笔记

    喜欢本文的请动动小手点个赞,收藏一下,有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。如果您感觉有所收获,自愿打赏,可选择支付宝18833895206(小于),您的支持是我不断更新的动力。

    展开全文
  • 通过安卓修改大师可以很轻松的在任何apk中添加新的代码逻辑,实现额外添加的功能,本次教程通过对一款名为“VMware Horizon”的软件进行反编译,实现在登录界面添加自动登录功能(该登录界面之前已经有自动登录功能...

    通过安卓修改大师可以很轻松的在任何apk中添加新的代码逻辑,实现额外添加的功能,本次教程通过对一款名为“VMware Horizon”的软件进行反编译,实现在登录界面添加自动登录功能(该登录界面之前已经有自动登录功能,但是未实现相应的逻辑,且自动登录功能按钮在代码中自动隐藏掉了)。

     

    为了方便大家学习,文中用到的apk和java代码请点击后面的连接下载:点击这里下载

     

    1、 反编译安装包,将要反编译的安装包拖拽到安卓修改大师界面上,弹出的界面中选择反编译。系统将自动进行反编译打包。首次修改的时候,建议什么都不改,直接打包,看看有什么问题,并进行修复,确保可以打包运行才进行后续的操作。

     

    2、 修复打包过程错误,在打包的过程中会遇到图示的错误,尝试按照提示的自动修复进行打包,发现并不能进行自动修复。然后看底部的日志,按照日志的要求,按照文件路径打开文件,删除提示的不存在的属性,然后重新编译。

     

    3、 定位要修改的布局和Activity类。重新编译后,项目可以正常在手机上面运行,将手机浏览到登录界面,在安卓修改大师的左侧点击“代码/布局定位”,并点击打开界面的抓取界面布局按钮,就可以获得当前界面的Activity类名和布局文件。请记住上面的类名:

    com.vmware.view.client.android.WindowsPasswordPrompt,后续修改都是在这个文件。

    4、 点击上图右下角红框圈中的“定位布局和代码”按钮,将自动定位和搜索引用这个按钮的布局和代码文件,可以双击布局或者代码进入看布局逻辑或者代码的逻辑。

    5、 找到界面元素对应的在类里面映射的变量的方法,以找到上述的“保存密码”复选框对应的变量为例,按照同样的方法,需要自行找到界面上面的用户名、密码和登录按钮对应的变量。按照上面的步骤抓取界面后,做抓取界面左侧的预览窗口点击相应的元素,然后右侧就会显示这个元素相应的一些属性,如果这个元素有id,就会在右下角的列表中显示“查看布局”的按钮,点击后就是上面步骤看到的搜索界面。然后点击smali结尾的文件(就是程序处理源代码文件),看到的代码如下:

    最好把映射的变量记下来,同样找到用户名和密码的输入框,登录按钮对应的变量,记录下来。

     

    6、 上面是准备工作,下面切入正题。本教程的主要工作是实现自动登录,按照这个逻辑,需要实现两个方法,一个是点击登录后的保存登录信息的功能(保存用户名,密码和保存密码选择框的状态),一个是页面加载的时候读取保存的用户名、密码和保存密码的状态,并自动点击登录按钮进行登录。

    7、 要实现上述功能,需要额外添加代码来实现。一般的做法是先写好一个demo的Android studio项目,把要实现的功能写成一个类,然后确保实现功能并完成功能测试。下面就是实现该逻辑的代码,该代码也在附带的压缩包中。

     

    package com.kongyu.project;

    import android.app.Activity;
    import android.content.SharedPreferences;
    import android.widget.Button;
    import android.widget.CheckBox;
    import android.widget.EditText;

    public class AutoLogin {
        
    //实现自动登录
        public static void autoclick(final Activity context, CheckBox cbRemmber, EditText etUser, EditText etPwd, Button btnSave) {
            SharedPreferences shareData = context.getSharedPreferences(
    "Data", Activity.MODE_PRIVATE);//创建一个给全局使用
            etUser.setText(shareData.getString("UserName"""));
            etPwd.setText(shareData.getString(
    "Password"""));
            cbRemmber.setChecked(shareData.getString(
    "CheckedUser""").toLowerCase().equals("true"));
            
    if(cbRemmber.isChecked())btnSave.performClick();
        }

        
    //保存登录信息
        public static void saveinfo(final Activity context, CheckBox cbRemmber, EditText etUser, EditText etPwd) {
            SharedPreferences shareData = context.getSharedPreferences(
    "Data", Activity.MODE_PRIVATE);//创建一个给全局使用
            SharedPreferences.Editor editor = shareData.edit();//绑定sharePreferences对象
            editor.putString("UserName", etUser.getText().toString());
            editor.putString(
    "Password", etPwd.getText().toString());
            editor.putString(
    "CheckedUser""" + cbRemmber.isChecked());
            editor.commit();
    //注意保存数据
        }
    }

    下面是调用的java代码

    
    
    AutoLogin.saveinfo(this,checkBox,etuser,etpwd);
    
    AutoLogin.autoclick(this,checkBox,etuser,etpwd,btn);

     

     

    同时也要在代码里面写好这两个方法的调用方法,会利用下一步生成上述类和改调用方法对应的smali文件,这是插桩方式插入代码的关键地方。

     

    8、 然后将上述demo项目打包成apk,再用安装修改大师反编译,反编译后即可获得对应的smali代码。

     

     

    反编译后点击该项目后面的“打开目录”按钮,即打开上图显示的反编译后的文件目录,然后浏览smali目录下面,按照类路径依次找到上述的类文件对应的smali类文件(路径不一定 跟我的截图一样,按照实际的你自己定义的类路径来)。

    同时在调用这两个方法的地方,找到反编译后的对应的调用的smali调用方法,后面备用。

       保存信息的smali方式调用方法:

        invoke-static {p0, p1, v0, v1}, Lcom/kongyu/project/AutoLogin;->saveinfo(Landroid/app/Activity;Landroid/widget/CheckBox;Landroid/widget/EditText;Landroid/widget/EditText;)V

     

      自动登录的smali方式调用方法:

        invoke-static {p0, p1, v0, v1, v2}, Lcom/kongyu/project/AutoLogin;->autoclick(Landroid/app/Activity;Landroid/widget/CheckBox;Landroid/widget/EditText;Landroid/widget/EditText;Landroid/widget/Button;)V

     

    9、 下面就进行最核心的代码整合阶段了。代码整合的过程一般是先将写好的代码转变成的smali文件拷贝到目标项目的smali目录下面(只要放到smali下面就可以,具体在哪一个目录无所谓,你为了方便,也可以放到自定义目录例如plugin这样名称的目录下面),如果有资源文件,也照样拷贝到对应的res资源文件目录即可。如果你要整合的代码有依赖包,依赖包的相关反编译出来的smali文件也一并拷贝到新的项目即可,重点要强调的是,如果目标项目已经有了相关的类包,一定不要重复拷贝,会导致编译失败。

    按照上述方法,将上述获得的类smali文件拷贝到目标项目的smali目录下。到目前为止,类文件已经移植完毕。

    10、         下面进行核心的插桩操作。按照上面的分析,需要在登录按钮点击的时候插入保存信息的代码,在页面oncreate加载的地方插入自动登录的方法。大家还记得开头通过界面抓取获得类名吗,可以在那个界面直接点击转到smali,跳转到要处理的smali文件。

    跳转后的代码编辑界面,通过顶部的下拉,找到oncreate方法,并点击进入

    11、         然后在oncreate的末尾插入自动点击的方法

    自动登录的方法需要传入5个参数,分别是当前类p0,保存密码的复选框v0,用户名输入框v1,密码输入框v2,登录按钮v3,这几个界面元素对应的类里面的变量如何获取,请参考前面获取复选框的方法。

     

    12、         在登录按钮点击后,插入自动保存登录信息的调用方法。需要获得点击事件对应的代码位置,下面重点演示如何通过界面抓取来获得按钮对应的点击事件代码对应的位置。

    在界面抓取页面,点击左面的预览窗口的登录按钮,然后右侧会显示该按钮可以查看界面布局和代码,点击“查看页面布局和代码”按钮,跳转到搜索界面。

    搜索结果里面找到上述类名对应的文件,找到sswitch_0这一行,一般情况下,sswitch语句就是用来做判断跳转的,所以这个搜索结果对应的基本上就是该按钮对应的处理方法代码。

    然后双击这一行,并自动打开代码编辑页面,在代码编辑器搜索上述截图的sswitch_0,即可找到这个按钮的处理入口。下面的截图已经将保存登录信息的方法调用添加进去了。

    保存信息的方法需要四个参数,分别是当前的activity的p0,保存密码的复选框v0,保存密码的复选框v0,用户名输入框v1,密码输入框v2。

    到此为止,已经通过代码插桩的方式,将当初在android studio里面开发的java代码逻辑,转变为smali代码,并且在相应的位置插入了smali代码的调用,重新编译打包,在手机上面即可看到运行的效果。

    顺便说一句,原始的apk的保存密码选择框在布局里面有,但是运行后在界面上面看不到,通过分析代码,发现是代码中通过代码隐藏掉了,需要搜索复选框对应的变量,找到处理显示的方法setVisibility方法,然后删除或者注释掉这一行即可。Smali注释某一行的方法是在这一行的前面写#号。注释后,这句代码就不起作用了。

     

    到此为止,已经完整讲述了如何通过插桩的方式,在没有源代码的基础上,在apk里面添加新的功能。大家可以触类旁通,实现更多更复杂的功能。通过安卓修改大师,只要apk可以反编译打包运行,就可以额外添加任意逻辑。

    展开全文
  • 程序插桩-实例

    万次阅读 2017-06-06 20:31:14
    本文主要介绍插装的实例,在测试分类下已经简单介绍了程序插装的基本概念以及插装的位置,更多知识可以查看程序插装相关文献,现将整个插装的流程通过一段C语言程序进行实例说明。 注:还处于学习阶段,实例较简单,...

    本文主要介绍插装的实例,在测试分类下已经简单介绍了程序插装的基本概念以及插装的位置,更多知识可以查看程序插装相关文献,现将整个插装的流程通过一段C语言程序进行实例说明。

    • 注:还处于学习阶段,实例较简单,内容尚待改进,错误之处请指出。

    步骤一: Visual studio 编辑代码

    1.file->new->project,弹出的窗口中选择第一项W32 console application,如下图所示:

    这里写图片描述

    2.对窗口下方的项目名称及存储位置进行编辑后,点击OK,对弹出的窗口点击next,对empty project选项进行勾选,如下图所示:

    这里写图片描述

    3.在右侧窗口下方的源文件处鼠标右键,选择add->new item,如下图所示:

    这里写图片描述

    4.在弹出的窗口中选择C++ File,对文件进行命名,选择存储位置,点击add,如下图所示:

    这里写图片描述

    步骤二:插装说明

    采用网上一个说明,图片出处请点击链接,图片具体说明请点击链接,代码请看上一篇博文:控制流图、圈复杂度

    这里写图片描述

    该图片中的虚线内容是在源程序的基础上新添加计数语句,用于说明程序的执行情况。

    步骤三:插装实例

    * 以计算分支覆盖率为例
    * 在有关插装的博文中,可以了解到插装主要是在程序的入口处、分支处添加计数语句,我理解的就是添加打印语句,打印语句中包含分支的计数、程序所经历的分支说明,通过多个测试用例,检测代码是否将所有的分支都走了一遍,全部走完即为分支覆盖率百分之百。

    下面是我作业中所使用的一部分代码内容:

    void menu()
    {
        int choice;
        printf("\n\t\t******************** 主菜单 ********************");
        printf("\n\t\t*********** 1-添加纪录 2-查询纪录 ************");
        printf("\n\t\t*********** 3-删除纪录 4-修改记录 ************");
        printf("\n\t\t*********** 5-显示纪录 6-退出系统 ************");
        printf("\n\t\t************************************************");
        printf("\n\t\t请选择:");
        scanf("%d", &choice);
        rewind(stdin);
        printf("\n");
        switch (choice)
        {
        case 1:
            head = insert(head);
            rewind(stdin);
            menu();
            break;
        case 2:
            search(head);
            rewind(stdin);
            menu();
            break;
        case 3:
            head = delet(head);
            rewind(stdin);
            menu();
            break;
        case 4:
            head = alter(head);
            rewind(stdin);
            menu();
            break;
        case 5:
            show(head);
            rewind(stdin);
            menu();
            break;
        default:
            printf("\n\t\t谢谢使用!!");
            break;
        }
    }

    在上述分支处添加计数语句:

    void menu()
    {
        int choice;
        printf("\n\t\t******************** 主菜单 ********************");
        printf("\n\t\t*********** 1-添加纪录 2-查询纪录 ************");
        printf("\n\t\t*********** 3-删除纪录 4-修改记录 ************");
        printf("\n\t\t*********** 5-显示纪录 6-退出系统 ************");
        printf("\n\t\t************************************************");
        printf("\n\t\t分支数为:%d\n", i); /*插装探针*/
        printf("\n\t\t请选择:");
        scanf("%d", &choice);
        rewind(stdin);
        printf("\n");
        switch (choice)
        {
        case 1:
            printf("\n\t\t分支:%d\n", ++i); /*插装探针*/
            head = insert(head);
            rewind(stdin);
            menu();
            break;
        case 2:
            printf("\n\t\t分支:%d\n", ++i); /*插装探针*/
            search(head);
            rewind(stdin);
            menu();
            break;
        case 3:
            printf("\n\t\t分支:%d\n", ++i); /*插装探针*/
            head = delet(head);
            rewind(stdin);
            menu();
            break;
        case 4:
            printf("\n\t\t分支:%d\n", ++i); /*插装探针*/
            head = alter(head);
            rewind(stdin);
            menu();
            break;
        case 5:
            printf("\n\t\t分支:%d\n", ++i); /*插装探针*/
            show(head);
            rewind(stdin);
            menu();
            break;
        default:
            printf("\n\t\t分支:%d\n", ++i); /*插装探针*/
            printf("\n\t\t谢谢使用!!");
            break;
        }
    }
    
    • 计算语句覆盖率做法与之相同,为了节省探针的个数,需要将代码分块,在每一块的入口处或出口处添加计数语句或打印语句,对执行情况进行说明。
    展开全文
  • AFL模糊测试学习(一)源码插桩

    千次阅读 2020-04-09 21:15:23
    刚接触模糊测试肯定是要从现在最为流行的AFL开始,现在很多关于AFL的改进都是针对AFL的,而且AFL本身因为其遗传算法、高吞吐量而得到很好的应用,在一些AFL变异版本(如AFLGO、PFuzz、CollAFL、ENFuzz等)、混合模糊...
  • 内核中的插桩调试

    千次阅读 2020-05-15 18:02:25
    插桩法是内核常用的一种调试手段,利用代码插桩,执行到此时执行对应的钩子函数(hook)来达到调试的目的,从实现来说,它不可避免的会带来一些性能上的开销,不过随着实现的不断优化,这部分的开销已经越来越小了...
  • 由于go语言自带多线程处理,所以性能测试的目标如果是中间件的话,可以使用此测试桩模拟Server   package main import ( "encoding/json" "fmt" "net/http" "time"...
  • 在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况,比如,代码覆盖率必须达到80%或 90%。下面我们就来详细学习下java单元测试
  • 软件测试-二进制插桩

    千次阅读 2014-09-08 16:10:59
    关键词:插桩,软件测试     二进制插桩作用 1. 程序运行时拦截,在运行时向程序注入我们自己的代码。 2. 调试程序 3. Tracing and logging, 分析函数调用关系图,api覆盖数据。 4. 提取数据,从程序中...
  • 而对于功能测试测试覆盖率,肯定是需要进行代码插桩然后统计代码执行的密度,进行覆盖率统计,而插桩的库主流的就是istanbul 一,对于node项目 可以使用istanbul-middleware来进行插桩以及覆盖率统计,可以参考...
  • 白盒测试

    千次阅读 2020-07-03 13:35:36
    1. 逻辑覆盖法 语句覆盖(弱覆盖/最常见): 判定覆盖(弱覆盖): 条件覆盖(弱覆盖): 判定-条件覆盖: 条件组合覆盖: 2. 基本路径测试法 (1) 程序控制流图: ...目标代码插桩法 源代码插桩法 黑盒测试和白盒测试比较
  • 研发效能是一个涉及面很广的话题,它涵盖了软件交付的整个生命周期,涉及产品、架构、开发、测试、运维,每个环节都可能影响顺畅、高质量地持续有效交付。在腾讯安全平台部实际研发与测试工作中我们发现...
  • 插入代码测试

    2009-05-31 11:12:00
  • 代码插桩【转载】

    千次阅读 2011-06-21 11:59:00
    【转载】http://wiki.dzsc.com/info/5081.html   代码插桩是实现覆盖测试的关键技术之一,而高效的插桩技术对于嵌入式软件的测试来说又是至关重要的。在对CodeTeST 中插桩技术研究的基础上,以GCC ...
  • LLVM的核心思想是将各种语言解析成LLVM的中间表示语言(LLVM IR),然后LLVM通过各种pass在IR上进行优化,最后通过各种代码生成后端生成目标机器上的机器代码,这样就可以最大程度重用前端解析、中端优化以及后端代码...
  • 程序插桩

    千次阅读 2017-04-24 13:36:17
     一种基本的动态测试方法,向源程序中添加一些语句实现对程序代码的执行、变量的变化等情况的检查。如果我们想要了解一个程序在某次运行中可执行语句被覆盖的情况,或是每个语句的实际执行次数,最好的办法
  • 测试中的插桩技术

    千次阅读 2011-03-05 23:04:00
    插桩的概念:插桩就是在代码中插入一段我们自定义的代码。   插桩的目的:由于我们插入的代码会一起被编译到可执行文件中,所以可执行文件在运行过程中必然会执行我们插入的自定义代码,这样我们...
  • 参考: Android字节码插桩采坑笔记 通过自定义 Gradle 插件修改编译后的 class 文件 ASM官方文档
  • 构件集成测试离不开交互代码(粘贴代码),文中提出了一种面向粘贴代码的构件合约化测试方法。分析了基于粘贴代码的构件测试中的四种故障类型;针对这四种故障类型,依据合约的适应性,阐述了基于XML的粘贴代码合约的构造...
  • 插桩

    千次阅读 2016-10-15 22:37:49
    因此,根据探针插入的时间可以分为目标代码插桩和源代码插桩。 目标代码插桩 目标代码插桩的前提是对目标代码进行必要的分析以确定需要插桩的地点和内容。由于目标代码的格式主要和操作系统相关,和具体的编程...
  • 插桩”在农业中确实指的就是在田地里插木桩,但是在我们的安卓逆向技术范畴内,它有一个高端的定义——定位关键代码技巧。 五种定位技巧 1.信息反馈法 通过搜索它的资源id字符串来进行定位 2.特征函数法 通过搜索...
  • 前言 近些年,编译期插桩技术在Android圈越来越普遍。...另外,我们通过这种技术可以抽离出复杂、重复的代码,降低程序耦合性,提高代码的可复用性,提高开发效率。因此,了解编译期插桩技术十分必要。在...
  • 插桩工具

    千次阅读 2019-08-22 21:56:13
    DynamoRIO: 设计架构: 组件运转流程: ...在DynamoRIO框架下运行着的程序都会使用这份模拟出来的运行时上下文,同时通过DynamoRIO中的上下文切换模块代码即被投入运行之前在真实的宿主...
  • 来源 | 腾讯技术工程研发效能是一个涉及面很广的话题,它涵盖了软件交付的整个生命周期,涉及产品、架构、开发、测试、运维,每个环节都可能影响顺畅、高质量地持续有效交付。在腾讯安全平台部实际研...
  • emma 与 cobertura 是为单元测试而设计的覆盖率统计,jacoco 与 emma 同属于一家公司,但是是为了更广泛的覆盖率统计而设计的工具。 Jacoco jacoco 的文档中有个 mission 章节,里面对 jacoco 的定位描述的很好。...
  • 针对容易产生缺陷的危险代码区域,依据控制流和数据流属性,采用回溯的方式推导出静态可达路径信息和必要的符号变量,实现仅针对危险代码区域的覆盖测试。实证研究结果表明,通过规避对不关心路径和符号变量的分析,...
  • (1)辗转相除法

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,907
精华内容 1,162
关键字:

代码插桩测试