RetroScope工具:下载,编译,启动:
http://blog.csdn.net/rzwinters/article/details/77003230
RetroScope工具:Android设备内存取证:
http://blog.csdn.net/rzwinters/article/details/76999398
1. 概述
RetroScope工具运行在一个修改过的Android模拟器中,与其具体实现相关的文件分布在该Android模拟器源代码的多个目录下,因此分析该工具的执行流程相比于分析普通的Android程序要复杂许多,故在此记录对于该工具执行流程的详细分析。
2. 重要文件或目录
RetroScope工具主要功能实现代码目录(C++)
目录:/dalvik/vm/zombie/RetroScope App源代码目录(Java)
目录:/packages/apps/RetroScope/src/com/forensix/retroscope/ZmbSurface类定义,Native方法定义—ZmbSurface.java(Java)
目录:/home/richard/RetroScope/frameworks/base/core/java/android/view/JNI函数定义,Native方法注册函数定义—android_view_ZmbSurface.cpp(C++)
目录:/frameworks/base/core/jni/Native方法注册函数调用—AndroidRuntime.cpp(C++)
目录:/frameworks/base/core/jni/
3. 执行流程
首先,在Andorid模拟器的启动过程中,模拟器执行AndroidRuntime.cpp
文件中的代码以构建Android运行环境,其中,模拟器通过调用位于android_view_ZmbSurface.cpp
文件中的Native方法注册函数完成同一文件中定义的JNI函数与ZmbSurface.java
文件中定义的Native函数的链接注册。
public class ZmbSurface{
public boolean more_dls; // !
public native boolean initImage(WindowManager wm, int bitmap_width, int bitmap_height); // native method
public native GLES20DisplayList getDL(); // native method
public ZmbSurface(WindowManager wm, int bitmap_width, int bitmap_height){ // constructor
more_dls = initImage(wm, bitmap_width, bitmap_height); // call the native method to init images
}
}
/* Define the JNINativeMethod struct to describe the native methods in Java */
static JNINativeMethod gZmbSurfaceMethods[] = {
{"initImage", "(Landroid/view/WindowManager;II)Z",
(void*)nativeInitImage },
{"getDL", "()Landroid/view/GLES20DisplayList;",
(void *)nativeGetDL }
};
int register_android_view_ZmbSurface(JNIEnv* env)
{
/* Register the native methods */
int err = AndroidRuntime::registerNativeMethods(env, "android/view/ZmbSurface",
gZmbSurfaceMethods, NELEM(gZmbSurfaceMethods));
return err;
}
随后,在Android模拟器启动完成之后,RetroScopoe App中的MyReceiver类接收到模拟器启动完成的Intent广播,解锁屏幕,保持屏幕常亮,并启动MyActivity类,即启动RetroScope App。
@Override
public void onReceive(Context context, Intent intent) { // called when receiving an Intent broadcast
......
Intent myIntent = new Intent(context, MyActivity.class); // create an Intent instance
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // add flags to start a new task
context.startActivity(myIntent); // launch new activity according to the Intent instance
}
接着,RetroScope App在完成一系列初始化及显示工作之后,创建ZmbSurface类实例,并调用其Native成员方法以实现RetroScope工具的内存取证主体功能,该Native方法由之前与其链接注册的JNI函数实现,而该JNI函数的主体功能代码位于RetroScope工具主要功能实现代码目录中,该目录中的代码均被编译至libdvm.so共享库中。
zmbSurface = new ZmbSurface(wm, bitmap_width, bitmap_height); // create an instance of ZmbSurface
if (!zmbSurface.more_dls) return;
currDL = zmbSurface.getDL(); // get the display list of the ZmbSurface instance
最后,在执行完ZmbSurface类实例的Native成员方法,完成内存分析,并获得Display List之后,模拟器回到RetroScopoe App中的MyActivity类,绘制Display List中的所有屏幕图像并保存,以最终完成RetroScope工具的内存取证功能。
while (currDL != null) {
......
GLES20Layer layer = new GLES20RenderLayer(bitmap_width, bitmap_height, true);
HardwareCanvas hwCanvas = layer.start(null);
dlView.draw(hwCanvas);
layer.end(null);
......
layer.copyInto(bitmap);
......
if (!bitmap.sameAs(emptyBitmap)) {
try {
String path = Environment.getExternalStorageDirectory().getPath() + "/generatedImages/" + i + ".png";
boolean streamFlushed = false;
while (!streamFlushed) {
FileOutputStream out = new FileOutputStream(path);
streamFlushed = bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.close();
}
......
} catch (Exception e) {
e.printStackTrace();
}
}
......
currDL = zmbSurface.getDL();
}