• frida的简单实用


    一.环境

      1.环境

    1.手机运行服务端
    2. 电脑端运行客户端
    3.进行端口转发
      adb forward tcp:27042 tcp:27042
      adb forward tcp:27043 tcp:27043

      2. 测试

    λ frida-ps -R

    成功的标志:

    PID Name
    ---- ------------------------
    717 android.process.acore
    9080 cat
    1301 com.android.defcontainer
    882 com.android.download
    557 com.android.ime
    647 com.android.launcher2
    941 com.android.market
    597 com.android.phone
    523 com.android.systemui
    823 com.android.tools

    二.使用

      得到android手机当前最前端Activity所在的进程

    λ python37 C:Users1003441Desktopget_front_app.py.py
    Application(identifier="com.microvirt.launcher2", name="逍遥桌面", pid=647)

      get_front_app.py.py

    import frida
    rdev = frida.get_remote_device()
    front_app = rdev.get_frontmost_application()
    print (front_app)

      枚举android手机所有的进程

    λ python37 C:Users1003441Desktopenum_process.py      
    Process(pid=1, name="init")                              
    Process(pid=62, name="ueventd")                          
    Process(pid=72, name="flush-8:2")                        
    Process(pid=73, name="flush-8:3")                        
    Process(pid=74, name="logd")                             
    Process(pid=75, name="healthd")                          
    Process(pid=76, name="lmkd")                             
    Process(pid=77, name="servicemanager")                   
    Process(pid=78, name="vold")                             
    Process(pid=79, name="surfaceflinger")                   
    Process(pid=80, name="flush-8:0")                        
    Process(pid=81, name="flush-8:4")                        
    Process(pid=82, name="netd")                             
    Process(pid=83, name="debuggerd")                        
    Process(pid=84, name="rild")                             
    Process(pid=85, name="drmserver")                        
    Process(pid=86, name="mediaserver")                      
    Process(pid=87, name="installd")                         
    Process(pid=88, name="keystore")                         

      enum_process.py内容如下:

    import frida
    rdev = frida.get_remote_device()
    processes = rdev.enumerate_processes()
    for process in processes:
        print (process)

      枚举某个进程加载的所有模块以及模块中的导出函数

    import frida
    rdev = frida.get_remote_device()
    session = rdev.attach("com.tencent.mm")  #如果存在两个一样的进程名可以采用rdev.attach(pid)的方式
    modules = session.enumerate_modules()
    for module in modules:
        print (module)
        export_funcs = module.enumerate_exports()
        print ("	func_name	RVA")
        for export_func in export_funcs:
            print ("	%s	%s"%(export_func.name,hex(export_func.relative_address)))

        这边的这个版本不知道为啥调用不了enumerate_modules,所以换了js的接口

    from __future__ import print_function
    import frida, sys
    
    def on_message(message, data):
        print(message)
    
    jscode = """
        Process.enumerateModules({
              onMatch:function(exp){
            send(exp.name);
          },
              onComplete:function(){
            send("stop");
          }
    })
    """
    
    process = frida.get_usb_device().attach('com.yinghuan.aiyou')
    script = process.create_script(jscode)
    script.on('message', on_message)
    script.load()
    sys.stdin.read()

       这边更好的做法是把js代码写成一个js文件,js文件可以利用编辑器写,然后读取

      

      

    from __future__ import print_function
    import frida, sys
    
    def on_message(message, data):
        print(message)
    
    jscode = """
        Process.enumerateModules({
              onMatch:function(exp){
            send(exp.name);
          },
              onComplete:function(){
            send("stop");
          }
    })
    """
    
    process = frida.get_usb_device().attach('com.yinghuan.aiyou')
    file=open('test.js')
    jscode=file.read() script
    = process.create_script(jscode) script.on('message', on_message) script.load() sys.stdin.read()

       hook android的native函数

    import frida
    import sys
    rdev = frida.get_remote_device()
    session = rdev.attach("com.tencent.mm")
    scr = """
    Interceptor.attach(Module.findExportByName("libc.so" , "open"), {
        onEnter: function(args) {
            send("open("+Memory.readCString(args[0])+","+args[1]+")");
        },
        onLeave:function(retval){
        
        }
    });
    """
    script = session.create_script(scr)
    def on_message(message ,data):
        print (message)
    script.on("message" , on_message)
    script.load()
    sys.stdin.read()

      hook android的java层函数

      如下代码为hook微信(测试版本为6.3.13,不同版本由于混淆名字的随机生成的原因或者代码改动导致类名不一样)
      com.tencent.mm.sdk.platformtools.ay类的随机数生成函数,让微信猜拳随机(type=2),而摇色子总是为6点(type=5)

    import frida
    import sys
    rdev = frida.get_remote_device()
    session = rdev.attach("com.tencent.mm")
    
    scr = """
    Java.perform(function () {
    var ay = Java.use("com.tencent.mm.sdk.platformtools.ay");
    ay.pu.implementation = function(){
        var type = arguments[0];
        send("type="+type);
        if (type == 2)
        {
        return this.pu(type);
        }
        else
        {
        return 5;
        }
    };
    
    });
    """
    
    script = session.create_script(scr)
    def on_message(message ,data):
        print message
    script.on("message" , on_message)
    script.load()
    sys.stdin.read()

      通过frida向android进程注入dex

    import frida, sys, optparse, re
    def on_message(message, data):
        if message['type'] == 'send':
            print("[*] {0}".format(message['payload']))
        else:
            print(message)
    
    jscode = """
    Java.perform(function () {
        var currentApplication = Java.use("android.app.ActivityThread").currentApplication();
        var context = currentApplication.getApplicationContext();
        var pkgName = context.getPackageName();
        var dexPath = "%s";
        var entryClass = "%s";
        Java.openClassFile(dexPath).load();
        console.log("inject " + dexPath +" to " + pkgName + " successfully!")
        Java.use(entryClass).%s("%s");
        console.log("call entry successfully!")
    });
    """
    
    def checkRequiredArguments(opts, parser):
        missing_options = []
        for option in parser.option_list:
            if re.match(r'^[REQUIRED]', option.help) and eval('opts.' + option.dest) == None:
                missing_options.extend(option._long_opts)
        if len(missing_options) > 0:
            parser.error('Missing REQUIRED parameters: ' + str(missing_options))
    
    if __name__ == "__main__":
        usage = "usage: python %prog [options] arg
    
    " 
                "example: python %prog -p com.android.launcher " 
                "-f /data/local/tmp/test.apk " 
                "-e com.parker.test.DexMain/main " 
                ""hello fridex!""
        parser = optparse.OptionParser(usage)
        parser.add_option("-p", "--package", dest="pkg", type="string",
                          help="[REQUIRED]package name of the app to be injected.")
        parser.add_option("-f", "--file", dest="dexPath", type="string",
                          help="[REQUIRED]path of the dex")
        parser.add_option("-e", "--entry", dest="entry", type="string",
                          help="[REQUIRED]the entry function Name.")
    
        (options, args) = parser.parse_args()
        checkRequiredArguments(options, parser)
        if len(args) == 0:
            arg = ""
        else:
            arg = args[0]
    
        pkgName = options.pkg
        dexPath = options.dexPath
        entry = options.entry.split("/")
        if len(entry) > 1:
            entryClass = entry[0]
            entryFunction = entry[1]
        else:
            entryClass = entry[0]
            entryFunction = "main"
    
        process = frida.get_usb_device(1).attach(pkgName)
        jscode = jscode%(dexPath, entryClass, entryFunction, arg)
        script = process.create_script(jscode)
        script.on('message', on_message)
        print('[*] Running fridex')
        script.load()
        sys.stdin.read()

      通过注入抛出异常代码实现跟踪程序调用栈

      在<<Android 软件安全与逆向分析>>这本书中第八章有介绍通过重打包写入异常代码进行栈跟踪,但是这样比较麻烦,使用frida注入更方便。

      frida的相关资源

  • 相关阅读:
    什么是同源策略,什么是跨域,如何跨域,Jsonp/CORS跨域
    Scrapy
    爬虫
    Falsk-信号
    python函数中把列表(list)当参数时的"入坑"与"出坑"
    SQLAlchemy基本使用(Flask中)
    列表生成式&生成器表达式
    javascript数据结构——队列
    javascript数据结构——栈
    js数组去重的几种方法
  • 原文地址:https://www.cnblogs.com/tjp40922/p/11357660.html
Copyright © 2020-2023  润新知