Chinaunix首页 | 论坛 | 博客
  • 博客访问: 365913
  • 博文数量: 160
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 250
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-18 01:16
文章分类

全部博文(160)

文章存档

2016年(4)

2015年(13)

2014年(29)

2013年(114)

我的朋友

分类: LINUX

2013-08-03 10:50:11

原文地址:Dalvik虚拟机技术 作者:hunterzy416

【1】Dalvik 分析之准备篇
   

前言:dalvik  Android 的重要组成部分 ,掌握其运行机制对理解整个Android系统有着相当之大的帮助。本文将介绍GDB单步调试和Dexdump工具的使用,期望为探索dalvik打下一定的基础

 

1. Dalvik 之编译

为了能够更方便的调试dalvik,我们需要编译一个在X86上运行的dalvik和相关工具。编译步骤如下:

  1. 首先进入到Android 源码根目录
  2. source build/envsetup.sh (不是网上有些文章写的只输入 build/envsetup.sh)
  3. lunch 2  在此之后可以看到TARGET_PRODUCT simTARGET_ARCHx86
  4. make  或者 make dalvikvm  make dexdump   (make 为编译所有程序,比较耗时,有时甚至某些模块编译不过,如为节省时间,可使用make dalvikvm直接编译dalvik, make dexdump直接编译dexdump)

 

2. Gdb调试dalvik之准备工作

在用gdb启动dalvik时,需要设置一些环境,比较繁琐,这里创建一个脚本来简化这些过程,脚本名为grund.sh,放于Android源码根目录。下面为脚本内容。

 

#!/bin/sh

base=`pwd`

root=$base/out/debug/host/linux-x86/pr/sim/system

export ANDROID_ROOT=$root

bootpath=$root/framework

export BOOTCLASSPATH=$bootpath/core.jar:$bootpath/ext.jar:$bootpath/framework.jar:$bootpath/android.police.jar

export ANDROID_DATA=/tmp/dalvik_test

mkdir -p $ANDROID_DATA/dalvik-cache

exec gdb $root/bin/dalvikvm 

 

3. Gdb 调试 dalvik

  1. 准备一个简单的java 程序,如hello.java,编译后将hello.jar拷贝至Android 源码根目录。 hello.javamakefile见附录)
  2. 进入到Android 源码根目录
  3. ./grund.sh  (执行上述脚本,之后会看到gdb提示符)
  4. gdb提示符后输入 “set args –cp hello.jar hello”
  5. 这个时候就可以设置断点,单步跟踪了!如有对gdb不熟的同学,请google之。 main()函数为入口函数,先在main.c 212行设置断点(在gdb提示符后输入 “b 212”
  6. gdb提示符后输入”r” OK,我们会看到dalvikgdb启动执行,然后停于212行,执行JNI_CreateJavaVM函数前先看看gDvm的内容(输入p gDvm)。 然后执行JNI_CreateJavaVM函数(输入“n”),再看看gDvm的内容。对比执行前后的变化,可大概知道JNI_CreateJavaVM函数所做的事情。
  7. main.c 249 行代码用于加载hello.class,在249行设置断点。在此中断后,看下slashClass的内容(输入“p slashClass)slashClass正是”hello”字符串。接下来单步进入执行之(输入”s”),然后查看下函数调用栈(输入”bt”)。可知现在正在执行的是jni.c 中的FindClass函数。通过此方法,可知函数指针指向的是何函数。
  8. main.c 255行代码用于取得hello.java main函数编译后的字节码。类似于g步骤,可知此时执行的函数为jni.c中的GetStaticMethodID函数
  9. main.c 273行代码执行main函数编译后的字节码,类似于g步骤,可知此时执行的函数为jni.c 中的2681行。此处为宏定义,不容易找到。但通过gdb调试,可以准确的定位。如此时继续运行程序,”hello world” 就会出现在我们的眼前!

 

此处只做简单分析,为抛砖引玉用,各位同学可以藉此探究自己感兴趣的内容。在接下来的文章中会详细分析class加载与字节码的执行。

 

4.  dexdump查看jar文件

 

Dexdump 可执行文件放于out目录下, 可使用”find out/ -name dexdump”命令来找到dexdump

“dexdump –f  hello.jar” 命令可打印jar文件的头部信息。

“dexdump –d hello.jar” 可打印所编译的字节码。

 

头部信息如下:

Opened 'hello.jar', DEX version '035'

DEX file header:

magic               : 'dex

035'

checksum            : f2f85a9c

signature           : 0404...7831

file_size           : 740

header_size         : 112

link_size           : 0

link_off            : 0 (0x000000)

string_ids_size     : 14

string_ids_off      : 112 (0x000070)

type_ids_size       : 7

type_ids_off        : 168 (0x0000a8)

field_ids_size      : 1

field_ids_off       : 232 (0x0000e8)

method_ids_size     : 4

method_ids_off      : 240 (0x0000f0)

class_defs_size     : 1

class_defs_off      : 272 (0x000110)

data_size           : 436

data_off            : 304 (0x000130)

 

 

阅读(510) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~