ios逆向神器frida

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#By:AloneMonkey

import sys
import frida
import codecs
import threading
import time
import re

reload(sys)
sys.setdefaultencoding('utf-8')

global session
global UIMESSAGE
global APPINFO
global appname
global appdoc
global appurl

finished = threading.Event()

APP_JS = './js/app.js'
UI_JS = './js/ui.js'
HOOK_JS = './js/hook.js'

#系统标准输出,支持grep
def outWrite(text):
    sys.stdout.write(text.encode('utf8') + '\n');

#带颜色打印输出
def colorPrint(color, s):
    return "%s[31;%dm%s%s[0m" % (chr(27), color, s , chr(27))

#获取第一个USB连接的设备
def get_usb_iphone():
    dManager = frida.get_device_manager();
    changed = threading.Event()
    def on_changed():
        changed.set()
    dManager.on('changed',on_changed)

    device = None
    while device is None:
        devices = [dev for dev in dManager.enumerate_devices() if dev.type =='tether']
        if len(devices) == 0:
            print 'Waiting for usb device...'
            changed.wait()
        else:
            device = devices[0]

    dManager.off('changed',on_changed)

    return device

#枚举运行进程信息
def listRunningProcess():
    device = get_usb_iphone();
    processes = device.enumerate_processes();
    processes.sort(key = lambda item : item.pid)
    outWrite('%-10s\t%s' % ('pid', 'name'))
    for process in processes:
        outWrite('%-10s\t%s' % (str(process.pid),process.name))

#枚举某个进程的所有模块信息
def listModulesoOfProcess(session):
    moduels = session.enumerate_modules()
    moduels.sort(key = lambda item : item.base_address)
    for module in moduels:
        outWrite('%-40s\t%-10s\t%-10s\t%s' % (module.name, hex(module.base_address), hex(module.size), module.path))
    session.detach()

#从JS接受信息
def on_message(message, data):
    if message.has_key('payload'):
        payload = message['payload']
        if isinstance(payload, dict):
            deal_message(payload)
        else:
            print payload

#处理JS中不同的信息
def deal_message(payload):
    global UIMESSAGE
    global APPINFO
    global appname
    global appdoc
    global appurl
    appdoc=''
    appurl=''
    k=0
    #基本信息输出
    if payload.has_key('mes'):
        print payload['mes']

    #安装app信息 |grep "Snapchat"
    if payload.has_key('app'):
        app = payload['app']
        APPINFO=payload['app']
        lines = app.split('\n')
        for line in lines:
            if len(line):
                arr = line.split('\t')
                if len(arr) == 3:
                    outWrite('%-40s\t%-70s\t%-80s' % (arr[0], arr[1], arr[2]))
                    if appname==arr[0]:
                        if k==0:
                            appdoc=arr[2]
                            k=1
                        else:
                            appurl=arr[2]
                            k=0
        if appurl!='':
            xs=''
            print appurl
            result = re.findall(".*file://(.*)>.*",appurl)
            for x in result:
                xs=xs+x
                #print x
            print xs
            appdoc=''
            appurl=''

    #处理UI界面输出
    if payload.has_key('ui'):
        print colorPrint(31, payload['ui'])
        UIMESSAGE=UIMESSAGE+payload['ui']

    #处理完成事件
    if payload.has_key('finished'):
        finished.set()

#加载JS文件脚本
def loadJsFile(session, filename):
    source = ''
    with codecs.open(filename, 'r', 'utf-8') as f:
        source = source + f.read()
    script = session.create_script(source)
    script.on('message', on_message)
    #接收js脚本的消息
    script.load()
    return script

def main():
    global session
    global appname
    global UIMESSAGE
    UIMESSAGE=''

    # 1. 获取USB设备
    device = get_usb_iphone()
    if len(sys.argv)>2:
        appname=sys.argv[2]
    else:
        appname=u'有料短视频'
    print '设备信息:' + str(device)
    if sys.argv[1]=='ps':
        # 2. 枚举运行进程信息
        print 'ps'
        listRunningProcess()
    elif sys.argv[1]=='appinfo':
        # 3. 枚举安装应用程序信息 |grep Snapchat
        print 'appdoc'
        session = device.attach(u'SpringBoard')
        script = loadJsFile(session, APP_JS)
        script.post({'cmd' : 'docinstalled'})
        finished.wait() 
    elif sys.argv[1]=='mod':
        # 4. 枚举某个进程加载的模块信息
        print 'mod'
        session = device.attach(appname)
        listModulesoOfProcess(session)
    elif sys.argv[1]=='ui':
        # 5. 显示界面UI
        #之后n 0xoooooooo(某个地址),输出某个地址的响应链
        print 'ui'
        session = device.attach(appname)
        script = loadJsFile(session, UI_JS)
        #我们把消息输出到文本中
        time.sleep(3)
        file_object=open('uimess.txt','w+')
        try:
            #all_the_text = file_object.read()
            file_object.write(UIMESSAGE)
        finally:
            file_object.close()
        while True:
            line = sys.stdin.readline()
            if not line:
                break
            script.post(line[:-1])#向js发命令
    elif sys.argv[1]=='hook':
        # 6. 动态Hook
        print 'hook'
        session = device.attach(appname)
        script = loadJsFile(session, HOOK_JS)
        sys.stdin.read()

    # 2. 枚举运行进程信息
    #listRunningProcess()

    # 3. 枚举安装应用程序信息
    #session = device.attach(u'SpringBoard')
    #script = loadJsFile(session, APP_JS)
    #script.post({'cmd' : 'installed'})
    #finished.wait()

    # 4. 枚举某个进程加载的模块信息
    #session = device.attach(u'Snapchat')
    #listModulesoOfProcess(session)

    # 5. 显示界面UI
    #session = device.attach(u'Snapchat')
    #script = loadJsFile(session, UI_JS)
    #while True:
    #   line = sys.stdin.readline()
    #   if not line:
    #       break
    #   script.post(line[:-1])

    # 6. 动态Hook
    #session = device.attach(u'Snapchat')
    #script = loadJsFile(session, HOOK_JS)
    #sys.stdin.read()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        if session:
            session.detach()
        sys.exit()
    else:
        pass
    finally:
        pass
### 如何使用Frida进行iOS应用的逆向工程并实现自定义Hook代码 Frida 是一种强大的动态分析工具,能够用于 Hook iOS 应用程序中的函数并实时修改其行为。以下是关于如何在 iOS 环境中使用 Frida 进行逆向工程,并实现自定义 Hook 的详细说明。 #### 1. 环境准备 为了使用 FridaiOS 应用进行逆向工程,需要以下环境和工具: - **Mac电脑**:作为开发主机。 - **Xcode**:用于调试和安装应用程序到越狱设备[^1]。 - **越狱设备**:支持 Frida 的安装和运行。 - **Frida 工具链**:包括 Frida Server 和 Frida Client。 - **分析工具**:如 class-dump 或 Hopper,用于提取目标应用的头文件或方法签名[^1]。 #### 2. 安装 Frida 在 Mac 上安装 Frida 可以通过 Python 包管理器完成: ```bash pip install frida-tools ``` 将 Frida Server 部署到越狱设备上,并确保它与 Mac 主机在同一网络中运行。 #### 3. 使用 Frida Hook 方法 Frida 提供了 JavaScript 脚本接口来实现动态 Hook。以下是一个典型的 Hook 流程: ##### (1) 导入 Frida API 创建一个 JavaScript 文件(例如 `hook.js`),并在其中导入 Frida 的核心模块: ```javascript // hook.js Interceptor.attach(Module.findExportByName(null, "target_function"), { onEnter: function(args) { console.log("Function called with arguments:", args); }, onLeave: function(retval) { console.log("Return value:", retval); } }); ``` ##### (2) 替换目标函数的行为 可以通过 `Interceptor.replace` 修改目标函数的行为。例如,替换某个函数的返回值: ```javascript // Replace the return value of a function Interceptor.replace(Module.findExportByName(null, "target_function"), new NativeCallback(function() { console.log("Function replaced!"); return 0; // Return a custom value }, 'int', [])); ``` ##### (3) 动态注入脚本 使用 Frida CLI 将上述脚本注入到目标进程: ```bash frida -U -n target_app_name -l hook.js ``` 其中: - `-U` 表示连接到 USB 设备。 - `-n` 指定目标应用的名称。 - `-l` 加载指定的 JavaScript 脚本文件。 #### 4. 示例:Hook 一个简单的函数 假设目标应用中有一个名为 `authenticateUser` 的函数,我们希望 Hook 它以打印调用参数并修改其返回值。 ##### (1) 分析目标函数 使用 class-dump 或 Hopper 提取目标函数的签名。例如: ```c BOOL authenticateUser(const char *username, const char *password); ``` ##### (2) 编写 Hook 脚本 根据函数签名编写对应的 Frida 脚本: ```javascript // hook_authenticate.js Interceptor.attach(Module.findExportByName(null, "authenticateUser"), { onEnter: function(args) { console.log("authenticateUser called with username:", Memory.readUtf8String(args[0])); console.log("authenticateUser called with password:", Memory.readUtf8String(args[1])); }, onLeave: function(retval) { console.log("authenticateUser returned:", retval ? "true" : "false"); retval.replace(1); // Modify the return value to true } }); ``` ##### (3) 注入脚本 将脚本注入到目标应用中: ```bash frida -U -n MyApp -l hook_authenticate.js ``` #### 5. 注意事项 - **权限问题**:确保 Frida Server 在越狱设备上具有足够的权限运行[^1]。 - **动态符号解析**:如果目标函数未导出,可以使用 `Process.enumerateModules()` 和 `Module.enumerateExports()` 动态查找符号。 - **稳定性**:Hook 操作可能影响应用的正常运行,建议在测试环境中操作。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值