欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

FRIDA脚本系列(四)更新篇:几个主要机制的大更新

来源:本站整理 作者:佚名 时间:2019-05-05 TAG: 我要投稿

最近沉迷学习,无法自拔,还是有一些问题百思不得骑姐,把官网文档又翻了一遍,发现其实最近的几个主要版本,更新还是挺大的,遂花了点时间和功夫,消化吸收下,在这里跟大家分享。
 
进程创建机制大更新
存在的问题:无法为新进程准备参数和环境
当我们使用Frida Python的binding的时候,一般会这么写:
pid = device.spawn(["/bin/cat", "/etc/passwd"])
或者在iOS平台上,会这样写:
pid = device.spawn(["com.apple.mobilesafari"])
目前来看貌似用这个API只能这么写,这么写其实是存在很多问题的,比如说没有考虑完整参数列表的问题,或者说新进程的环境是继承自绑定的host机环境还是设备client环境?再比如想要实现定制功能,比如以关闭ASLR模式打开safari,这些都没有考虑进去。
问题产生的原因(一):当初源码中就没有实现
我们先来看看这个API在frida-core里是如何实现的:
namespace Frida {
    …
    public class Device : GLib.Object {
        …
        public async uint spawn (string path,
            string[] argv, string[] envp)
            throws Frida.Error;
        public uint spawn_sync (string path,
            string[] argv, string[] envp)
            throws Frida.Error;
    }
    …
}
这段代码是用vala语言写的,frida-core都是用vala写的,vala看起来跟C#很像,并且最终会被编译成C代码。从代码可以看出,第一个方法——spawan是异步的,调用者调用一遍就可以去干其他事情了,不用等待调用完成,而第二个方法——spawn_sync则需要等到调用完全结束并返回。
这两个方法会被编译成如下的C代码:
void frida_device_spawn (FridaDevice * self,
    const gchar * path,
    gchar ** argv, int argv_length,
    gchar ** envp, int envp_length,
    GAsyncReadyCallback callback, gpointer user_data);
guint frida_device_spawn_finish (FridaDevice * self,
    GAsyncResult * result, GError ** error);
guint frida_device_spawn_sync (FridaDevice * self,
    const gchar * path,
    gchar ** argv, int argv_length,
    gchar ** envp, int envp_length,
    GError ** error);
前两个函数组成了spawn()的过程,首先调用第一个获得一个回调,当获得回调之后就会调用第二个函数——spawn_finish(),将回调的返回值将会作为GAsyncResult的参数。最终的返回值就是PID,当然如果有error的话就会返回error no。
第三个函数——spawn_sync()上面也解释了,是完全同步的,Frida Python用的其实就是这个。Frida nodejs用的其实是前两个,因为nodejs里的绑定默认就是异步的。当然以后其实应该也考虑将Frida Python的绑定迁移到异步的模式中来,利用Python 3.5版本引入的async/await机制。
回到上一小节那两个例子,可以发现其实调用的格式跟我们写的API并不完全一致,仔细看源码就会发现,像envp字符串列表并没有暴露给上层API,如果查看Frida Python的绑定过程的话,就可以发现其实后来在绑定里是这样写的:
envp = g_get_environ ();
envp_length = g_strv_length (envp);
也就是说最终我们传递给spawn()函数的是调用者的Python环境,这明显是不对的,host的Python环境跟client的Python肯定是不一样的,比如像client是iOS或Android的情况。
当然我们在frida-server里做了设定,在spawn()安卓或者iOS的进程的时候,envp会被默认忽略掉,这或多或少减少了问题的产生。
问题产生的原因(二):spawn()的历史遗留问题
还有一个问题就是spawn()这个古老的API的定义——string[] envp,这个定义意味着不能为空(如果写成string[]? envp的话其实就可以为空了),也就是说其实无法从根本上区别“用默认的环境配置”和“不使用任何环境配置”。
进程创建机制更新(一):参数、目录、环境均可设置
既然决定要修这个API,那就干脆顺便把跟这个API相关的问题都来看下:
如何给命令提供一些额外的环境参数
设置工作目录
自定义标准输入流
传入平台特定的参数
修正完以上bug之后,最终代码会变成下面这样:
namespace Frida {
    …
    public class Device : GLib.Object {
        …
        public async uint spawn (string program,
            Frida.SpawnOptions? options = null)
            throws Frida.Error;
        public uint spawn_sync (string program,
            Frida.SpawnOptions? options = null)
            throws Frida.Error;
    }
    …
    public class SpawnOptions : GLib.Object {

[1] [2] [3] [4]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载