You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Frida调用Swift实例方法:Swift String构建与签名验证问题

Swift方法Hook与调用问题解答

原始Swift代码

@objc
public class Write: NSObject {
    public let db: Database

    init(db: Database) {
        self.db = db
    }
}

public extension Write {
    func execute(sql: String) {
        db.execute(sql);
    }
}

尝试的Frida脚本

const writeBlock = new ObjC.Block({
    retType: 'void',
    argTypes: ['object'],
    implementation: function(write) {
    // We get the write instance from the transaction block

    var executeAddressByName = Module.findExportByName("MyModule","$s23MyModule10WriteC7execute3sqlWlE");

    // Build swift structs
    var StringStruct = Swift.structs.String;

    var executeSQL = Swift.NativeFunction(executeAddressByName, 'void', ['pointer', StringStruct]);

    const sqlCommand = `DROP TABLE 'tableName';`;

    // Allocate memory for the SQL string and encode it as UTF-8.
    var sqlStringPointer = Memory.allocUtf8String(sqlCommand);
    var NSString = ObjC.classes.NSString;

    // Convert the SQL command to an NSString.
    var sqlString = NSString["+ stringWithUTF8String:"] (sqlStringPointer);

    executeSQL(write.handle, sqlString);
}

问题

  1. 显然NSString无法满足要求,请问如何构建Swift String?
  2. 由于execute是实例方法,当前的NativeFunction签名是否正确?

解答

1. 构建Swift String的正确方式

直接使用Frida提供的Swift.fromString()API即可将JavaScript字符串转换为符合要求的Swift String结构体,无需手动处理NSString的转换逻辑,这是最简便且可靠的方式:

const sqlCommand = `DROP TABLE 'tableName';`;
const swiftSqlString = Swift.fromString(sqlCommand);

如果要手动构造(不推荐,易出错),需要注意Swift String是包含指针、长度等字段的结构体,需分配内存并严格按照Swift的字符串布局填充,但Swift.fromString()已经封装了这些细节,优先使用即可。

2. 实例方法的NativeFunction签名修正

当前签名存在问题,正确的处理方式如下:

  • Swift实例方法的第一个参数默认是self(即实例本身),对应到NativeFunction的第一个参数应为实例的指针(通过write.handle获取);
  • 必须使用Swift.NativeFunction而非普通NativeFunction,它会自动处理Swift的调用约定,避免因调用规则不匹配导致的崩溃;
  • 第二个参数类型是Swift.structs.String,返回值void是正确的。

修正后的调用代码片段:

const executeAddressByName = Module.findExportByName("MyModule","$s23MyModule10WriteC7execute3sqlWlE");
const executeSQL = Swift.NativeFunction(executeAddressByName, 'void', ['pointer', Swift.structs.String]);

// 构建Swift String
const sqlCommand = `DROP TABLE 'tableName';`;
const swiftSqlString = Swift.fromString(sqlCommand);

// 调用实例方法
executeSQL(write.handle, swiftSqlString);

内容的提问来源于stack exchange,提问作者Hans Daigle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 11:08:13