[安卓逆向]frida api文档JavaScript API 中文翻译 双语对照 带csdn目录

JavaScript API
Getting started 开始
我手动编写了csdn的目录,方便大家翻阅,可以看文章右侧

Runtime information 运行时信息


Frida 弗里达
Frida.version: property containing the current Frida version, as a string.
Frida.version:包含当前 Frida 版本的属性,以字符串形式出现。

Frida.heapSize: dynamic property containing the current size of Frida’s private heap, shared by all scripts and Frida’s own runtime. This is useful for keeping an eye on how much memory your instrumentation is using out of the total consumed by the hosting process.
Frida.heapSize:包含 Frida 私有堆的当前大小的动态属性,由所有脚本和 Frida 自己的运行时共享。这对于密切关注检测在托管进程消耗的总内存中消耗的内存量非常有用。

Script 脚本

Script.runtime: string property containing the runtime being used. Either QJS or V8.
Script.runtime:包含正在使用的运行时的字符串属性。QJS 或 V8。

Script.pin(): temporarily prevents the current script from being unloaded. This is reference-counted, so there must be one matching unpin() happening at a later point. Typically used in the callback of bindWeak() when you need to schedule cleanup on another thread.
Script.pin():暂时阻止当前脚本被卸载。这是引用计数的,因此稍后必须有一个匹配的 unpin()。通常用于 bindWeak() 的回调,当您需要在另一个线程上安排清理时。

Script.unpin(): reverses a previous pin() so the current script may be unloaded.
Script.unpin():反转之前的 pin(),以便可以卸载当前脚本。

Script.bindWeak(value, fn): monitors value and calls the fn callback as soon as value has been garbage-collected, or the script is about to get unloaded. Returns an ID that you can pass to Script.unbindWeak() for explicit cleanup.
Script.bindWeak(value, fn):监控 value 并在 value 被垃圾回收或脚本即将卸载时立即调用 fn 回调。返回一个 ID,您可以将该 ID 传递给 Script.unbindWeak() 以进行显式清理。

This API is useful if you’re building a language-binding, where you need to free native resources when a JS value is no longer needed.
如果要构建语言绑定,则此 API 非常有用,在该语言绑定中,当不再需要 JS 值时,需要释放本机资源。

Script.unbindWeak(id): stops monitoring the value passed to Script.bindWeak(value, fn), and call the fn callback immediately.
Script.unbindWeak(id):停止监控传递给 Script.bindWeak(value, fn) 的值,并立即调用 fn 回调。

Script.setGlobalAccessHandler(handler | null): installs or uninstalls a handler that is used to resolve attempts to access non-existent global variables. Useful for implementing a REPL where unknown identifiers may be fetched lazily from a database.
Script.setGlobalAccessHandler(handler | null):安装或卸载处理程序,该处理程序用于解决访问不存在的全局变量的尝试。对于实现 REPL 很有用,其中未知标识符可以从数据库中延迟获取。

The handler is an object containing two properties:
handler 是包含两个属性的对象:
    enumerate(): queries which additional globals exist. Must return an array of strings.
    enumerate():查询存在哪些其他全局变量。必须返回字符串数组。
    get(property): retrieves the value for the given property.
    get(property):检索给定属性的值。

Process, Thread, Module and Memory

进程、线程、模块和内存


Process 过程

Process.id: property containing the PID as a number
Process.id:包含 PID 作为数字的属性

Process.arch: property containing the string ia32, x64, arm or arm64
Process.arch:包含字符串 ia32、x64、arm 或 arm64 的属性

Process.platform: property containing the string windows, darwin, linux or qnx
Process.platform:包含字符串 windows、darwin、linux 或 qnx 的属性

Process.pageSize: property containing the size of a virtual memory page (in bytes) as a number. This is used to make your scripts more portable.
Process.pageSize:包含虚拟内存页的大小(以字节为单位)的属性。这用于使脚本更具可移植性。

Process.pointerSize: property containing the size of a pointer (in bytes) as a number. This is used to make your scripts more portable.
Process.pointerSize:包含指针大小(以字节为单位)作为数字的属性。这用于使脚本更具可移植性。

Process.codeSigningPolicy: property containing the string optional or required, where the latter means Frida will avoid modifying existing code in memory and will not try to run unsigned code. Currently this property will always be set to optional unless you are using Gadget and have configured it to assume that code-signing is required. This property allows you to determine whether the Interceptor API is off limits, and whether it is safe to modify code or run unsigned code.
Process.codeSigningPolicy:包含字符串 optional 或 required 的属性,其中后者表示 Frida 将避免修改内存中的现有代码,并且不会尝试运行未签名的代码。目前,此属性将始终设置为 optional,除非您使用的是 Gadget 并将其配置为假定需要代码签名。此属性允许您确定拦截器 API 是否禁止,以及修改代码或运行未签名的代码是否安全。

Process.mainModule: property containing a Module representing the main executable of the process
Process.mainModule:包含表示进程主可执行文件的模块的属性

Process.getCurrentDir(): returns a string specifying the filesystem path to the current working directory
Process.getCurrentDir():返回一个字符串,指定当前工作目录的文件系统路径

Process.getHomeDir(): returns a string specifying the filesystem path to the current user’s home directory
Process.getHomeDir():返回一个字符串,指定当前用户主目录的文件系统路径

Process.getTmpDir(): returns a string specifying the filesystem path to the directory to use for temporary files
Process.getTmpDir():返回一个字符串,指定用于临时文件的目录的文件系统路径

Process.isDebuggerAttached(): returns a boolean indicating whether a debugger is currently attached
Process.isDebuggerAttached():返回一个布尔值,指示当前是否附加了调试器

Process.getCurrentThreadId(): get this thread’s OS-specific id as a number
Process.getCurrentThreadId():以数字形式获取此线程的操作系统特定 ID

Process.enumerateThreads(): enumerates all threads, returning an array of objects containing the following properties:
Process.enumerateThreads():枚举所有线程,返回包含以下属性的对象数组:
    id: OS-specific id id:特定于操作系统的 ID
    state: string specifying either running, stopped, waiting, uninterruptible or halted
    state:指定 running、stopped、waiting、uninterruptible 或 halted 的字符串
    context: object with the keys pc and sp, which are NativePointer objects specifying EIP/RIP/PC and ESP/RSP/SP, respectively, for ia32/x64/arm. Other processor-specific keys are also available, e.g. eax, rax, r0, x0, etc.
    context:键为 pc 和 sp 的对象,它们是 NativePointer 对象,分别为 ia32/x64/arm 指定 EIP/RIP/PC 和 ESP/RSP/SP。其他特定于处理器的键也可用,例如 eax、rax、r0、x0 等。

Process.findModuleByAddress(address), Process.getModuleByAddress(address), Process.findModuleByName(name), Process.getModuleByName(name): returns a Module whose address or name matches the one specified. In the event that no such module could be found, the find-prefixed functions return null whilst the get-prefixed functions throw an exception.
Process.findModuleByAddress(address)、Process.getModuleByAddress(address)、Process.findModuleByName(name)、Process.getModuleByName(name):返回地址或名称与指定模块匹配的模块。如果找不到此类模块,则 find 前缀函数返回 null,而 get 前缀函数将引发异常。

Process.enumerateModules(): enumerates modules loaded right now, returning an array of Module objects.
Process.enumerateModules():枚举当前加载的模块,返回 Module 对象数组。

Process.findRangeByAddress(address), getRangeByAddress(address): return an object with details about the range containing address. In the event that no such range could be found, findRangeByAddress() returns null whilst getRangeByAddress() throws an exception. See Process.enumerateRanges() for details about which fields are included.
Process.findRangeByAddress(address), getRangeByAddress(address):返回一个对象,其中包含有关包含地址的范围的详细信息。如果找不到这样的范围,findRangeByAddress() 返回 null,而 getRangeByAddress() 会引发异常。 请参阅 Process.enumerateRanges() 以获取有关包含哪些字段的详细信息。

Process.enumerateRanges(protection|specifier): enumerates memory ranges satisfying protection given as a string of the form: rwx, where rw- means “must be at least readable and writable”. Alternatively you may provide a specifier object with a protection key whose value is as aforementioned, and a coalesce key set to true if you’d like neighboring ranges with the same protection to be coalesced (the default is false; i.e. keeping the ranges separate). Returns an array of objects containing the following properties:
Process.enumerateRanges(protection|specifier):枚举满足 protection 的内存范围,以以下格式的字符串给出:rwx,其中 rw- 表示“必须至少是可读和可写的”。或者,您可以为 specifier 对象提供一个 protection 键,其值如上所述,如果您希望合并具有相同保护的相邻范围(默认值为 false,则将 coalesce 键设置为 true(默认值为 false;即保持范围分开)。返回包含以下属性的对象数组:
    base: base address as a NativePointer
    base:作为 NativePointer 的基址
    size: size in bytes size:大小(以字节为单位)
    protection: protection string (see above)
    protection:保护字符串(见上文)

    file: (when available) file mapping details as an object containing:
    file:(如果可用)文件映射详细信息作为包含以下内容的对象:
        path: full filesystem path as a string
        path:字符串格式的完整文件系统路径
        offset: offset in the mapped file on disk, in bytes
        offset:磁盘上映射文件中的偏移量(以字节为单位)
        size: size in the mapped file on disk, in bytes
        size:磁盘上映射文件的大小(以字节为单位)

Process.enumerateMallocRanges(): just like enumerateRanges(), but for individual memory allocations known to the system heap.
Process.enumerateMallocRanges():与 enumerateRanges() 类似,但用于系统堆已知的单个内存分配。

Process.setExceptionHandler(callback): install a process-wide exception handler callback that gets a chance to handle native exceptions before the hosting process itself does. Called with a single argument, details, that is an object containing:
Process.setExceptionHandler(callback):安装进程范围的异常处理程序回调,该回调有机会在托管进程本身之前处理本机异常。使用单个参数 details 调用,该参数是一个包含以下内容的对象:
    type: string specifying one of:
        abort 流产
        access-violation 访问冲突
        guard-page 防护页
        illegal-instruction 非法指令
        stack-overflow 堆栈溢出
        arithmetic 算术
        breakpoint 断点
        single-step 单步法
        system 系统
    address: address where the exception occurred, as a NativePointer
    address:发生异常的地址,作为 NativePointer
    memory: if present, is an object containing:
        operation: the kind of operation that triggered the exception, as a string specifying either read, write, or execute
        operation:触发异常的操作类型,作为指定 read、write 或 execute 的字符串
        address: address that was accessed when the exception occurred, as a NativePointer
        address:发生异常时访问的地址,作为 NativePointer
    context: object with the keys pc and sp, which are NativePointer objects specifying EIP/RIP/PC and ESP/RSP/SP, respectively, for ia32/x64/arm. Other processor-specific keys are also available, e.g. eax, rax, r0, x0, etc. You may also update register values by assigning to these keys.
    context:键为 pc 和 sp 的对象,它们是 NativePointer 对象,分别为 ia32/x64/arm 指定 EIP/RIP/PC 和 ESP/RSP/SP。其他特定于处理器的键也可用,例如 eax、rax、r0、x0 等。您还可以通过分配给这些键来更新寄存器值。
    nativeContext: address of the OS and architecture-specific CPU context struct, as a NativePointer. This is only exposed as a last resort for edge-cases where context isn’t providing enough details. We would however discourage using this and rather submit a pull-request to add the missing bits needed for your use-case.
    nativeContext:操作系统和特定于体系结构的 CPU 上下文结构的地址,作为 NativePointer。这仅作为 context 未提供足够细节的边缘情况的最后手段而公开。但是,我们不鼓励使用它,而是提交拉取请求以添加您的用例所需的缺失位。

It is up to your callback to decide what to do with the exception. It could log the issue, notify your application through a send() followed by a blocking recv() for acknowledgement of the sent data being received, or it can modify registers and memory to recover from the exception. You should return true if you did handle the exception, in which case Frida will resume the thread immediately. If you do not return true, Frida will forward the exception to the hosting process’ exception handler, if it has one, or let the OS terminate the process.
由您的回调决定如何处理异常。它可以记录问题,通过 send() 后跟阻塞 recv() 来通知您的应用程序,以确认正在接收的已发送数据,或者它可以修改寄存器和内存以从异常中恢复。如果您确实处理了异常,则应返回 true,在这种情况下,Frida 将立即恢复线程。如果您不返回 true,Frida 会将异常转发给托管进程的异常处理程序(如果有),或者让操作系统终止该进程。

Thread 线

Thread.backtrace([context, backtracer]): generate a backtrace for the current thread, returned as an array of NativePointer objects.
Thread.backtrace([context, backtracer]):为当前线程生成回溯跟踪,作为 NativePointer 对象数组返回。

If you call this from Interceptor’s onEnter or onLeave callbacks you should provide this.context for the optional context argument, as it will give you a more accurate backtrace. Omitting context means the backtrace will be generated from the current stack location, which may not give you a very good backtrace due to the JavaScript VM’s stack frames. The optional backtracer argument specifies the kind of backtracer to use, and must be either Backtracer.FUZZY or Backtracer.ACCURATE, where the latter is the default if not specified. The accurate kind of backtracers rely on debugger-friendly binaries or presence of debug information to do a good job, whereas the fuzzy backtracers perform forensics on the stack in order to guess the return addresses, which means you will get false positives, but it will work on any binary. The generated backtrace is currently limited to 16 frames and is not adjustable without recompiling Frida.
如果从 Interceptor 的 onEnter 或 onLeave 回调调用此参数,则应为可选的 context 参数提供 this.context,因为它会为您提供更准确的回溯。省略 context 意味着回溯将从当前堆栈位置生成,由于 JavaScript VM 的堆栈帧,这可能不会给你一个很好的回溯。可选的 backtracer 参数指定要使用的回溯跟踪器的类型,并且必须是 Backtracer.FUZZY 或 Backtracer.ACCURATE,如果未指定,则后者是默认值。准确的回溯程序依赖于调试器友好的二进制文件或调试信息的存在来做好工作,而模糊回溯程序则对堆栈执行取证以猜测返回地址,这意味着你会得到误报,但它适用于任何二进制文件。生成的回溯目前限制为 16 帧,如果不重新编译 Frida,则无法调整。

const f = Module.getExportByName(‘libcommonCrypto.dylib’,
‘CCCryptorCreate’);
Interceptor.attach(f, {
onEnter(args) {
console.log(‘CCCryptorCreate called from:\n’ +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join(‘\n’) + ‘\n’);
}
});

Thread.sleep(delay): suspend execution of the current thread for delay seconds specified as a number. For example 0.05 to sleep for 50 ms.
Thread.sleep(delay):暂停当前线程的执行 delay 秒,指定为数字。例如,0.05 休眠 50 毫秒。

Module 模块

Objects returned by e.g. Module.load() and Process.enumerateModules().

例如 Module.load() 和 Process.enumerateModules() 返回的对象。

name: canonical module name as a string
name:字符串形式的规范模块名称

base: base address as a NativePointer
base:作为 NativePointer 的基址

size: size in bytes size:大小(以字节为单位)

path: full filesystem path as a string
path:字符串格式的完整文件系统路径

enumerateImports(): enumerates imports of module, returning an array of objects containing the following properties:
enumerateImports():枚举模块的导入,返回包含以下属性的对象数组:
    type: string specifying either function or variable
    type:指定 function 或 variable 的字符串
    name: import name as a string
    name:将名称导入为字符串
    module: module name as a string
    module:字符串形式的模块名称
    address: absolute address as a NativePointer
    address:作为 NativePointer 的绝对地址
    slot: memory location where the import is stored, as a NativePointer
    slot:存储导入的内存位置,作为 NativePointer

Only the name field is guaranteed to be present for all imports. The platform-specific backend will do its best to resolve the other fields even beyond what the native metadata provides, but there is no guarantee that it will succeed.
只有 name 字段保证所有导入都存在。特定于平台的后端将尽最大努力解析其他字段,甚至超出本机元数据提供的内容,但不能保证它会成功。

enumerateExports(): enumerates exports of module, returning an array of objects containing the following properties:
enumerateExports():枚举模块的导出,返回包含以下属性的对象数组:
    type: string specifying either function or variable
    type:指定 function 或 variable 的字符串
    name: export name as a string
    name:将名称导出为字符串
    address: absolute address as a NativePointer
    address:作为 NativePointer 的绝对地址

enumerateSymbols(): enumerates symbols of module, returning an array of objects containing the following properties:
enumerateSymbols():枚举模块的符号,返回包含以下属性的对象数组:
    isGlobal: boolean specifying whether symbol is globally visible
    isGlobal:指定符号是否全局可见的布尔值
    type: string specifying one of:
        unknown 未知
        section 部分
        undefined (Mach-O) 未定义 (Mach-O)
        absolute (Mach-O) 绝对值 (Mach-O)
        prebound-undefined (Mach-O)
        prebound-undefined (马赫-O)
        indirect (Mach-O) 间接 (Mach-O)
        object (ELF) 对象 (ELF)
        function (ELF) 功能 (ELF)
        file (ELF) 文件 (ELF)
        common (ELF) 普通 (ELF)
        tls (ELF) tls (ELF)
    section: if present, is an object containing:
        id: string containing section index, segment name (if applicable) and section name – same format as r2’s section IDs
        id:包含节索引、节名称(如果适用)和节名称的字符串 – 与 r2 的节 ID 格式相同
        protection: protection like in Process.enumerateRanges()
        protection:像 Process.enumerateRanges() 一样的保护
    name: symbol name as a string
    name:字符串形式的符号名称
    address: absolute address as a NativePointer
    address:作为 NativePointer 的绝对地址
    size: if present, a number specifying the symbol’s size in bytes
    size:如果存在,则指定符号大小(以字节为单位)的数字

enumerateSymbols() is only available on i/macOS and Linux-based OSes
enumerateSymbols() 仅在 i/macOS 和基于 Linux 的操作系统上可用

We would love to support this on the other platforms too, so if you find this useful and would like to help out, please get in touch. You may also find the DebugSymbol API adequate, depending on your use-case.
我们也很乐意在其他平台上支持这一点,所以如果你觉得这很有用并想提供帮助,请与我们联系。您可能还会发现 DebugSymbol API 足够了,具体取决于您的用例。

enumerateRanges(protection): just like Process.enumerateRanges, except it’s scoped to the module.
enumerateRanges(protection):与 Process.enumerateRanges 类似,只是它的范围限定为模块。

enumerateSections(): enumerates sections of module, returning an array of objects containing the following properties:
enumerateSections():枚举模块的各个部分,返回包含以下属性的对象数组:
    id: string containing section index, segment name (if applicable) and section name – same format as r2’s section IDs
    id:包含节索引、节名称(如果适用)和节名称的字符串 – 与 r2 的节 ID 格式相同
    name: section name as a string
    name:字符串形式的节名
    address: absolute address as a NativePointer
    address:作为 NativePointer 的绝对地址
    size: size in bytes size:大小(以字节为单位)

enumerateDependencies(): enumerates dependencies of module, returning an array of objects containing the following properties:
enumerateDependencies():枚举模块的依赖关系,返回包含以下属性的对象数组:
    name: module name as a string
    name:字符串形式的模块名称
    type: string specifying one of:
        regular 定期
        weak
        reexport 再输出
        upward 向上

findExportByName(exportName), getExportByName(exportName): returns the absolute address of the export named exportName. In the event that no such export could be found, the find-prefixed function returns null whilst the get-prefixed function throws an exception.
findExportByName(exportName), getExportByName(exportName):返回名为 exportName 的导出的绝对地址。如果找不到此类导出,则 find-prefixed 函数返回 null,而 get prefixed 函数将引发异常。

Module.load(path): loads the specified module from the filesystem path and returns a Module object. Throws an exception if the specified module cannot be loaded.
Module.load(path):从文件系统路径加载指定的模块并返回一个 Module 对象。如果无法加载指定的模块,则引发异常。

Module.ensureInitialized(name): ensures that initializers of the specified module have been run. This is important during early instrumentation, i.e. code run early in the process lifetime, to be able to safely interact with APIs. One such use-case is interacting with ObjC classes provided by a given module.
Module.ensureInitialized(name):确保已运行指定模块的初始值设定项。这在早期检测期间非常重要,即在进程生命周期的早期运行代码,以便能够安全地与 API 交互。其中一个用例是与给定模块提供的 ObjC 类进行交互。

Module.findBaseAddress(name), Module.getBaseAddress(name): returns the base address of the name module. In the event that no such module could be found, the find-prefixed function returns null whilst the get-prefixed function throws an exception.
Module.findBaseAddress(name), Module.getBaseAddress(name):返回 name 模块的基址。如果找不到此类模块,则 find-prefixed 函数返回 null,而 get-prefixed 函数将引发异常。

Module.findExportByName(moduleName|null, exportName), Module.getExportByName(moduleName|null, exportName): returns the absolute address of the export named exportName in moduleName. If the module isn’t known you may pass null instead of its name, but this can be a costly search and should be avoided. In the event that no such module or export could be found, the find-prefixed function returns null whilst the get-prefixed function throws an exception.
Module.findExportByName(moduleName|null, exportName), Module.getExportByName(moduleName|null, exportName):返回 moduleName 中名为 exportName 的导出的绝对地址。如果模块未知,您可以传递 null 而不是它的名称,但这可能是一个昂贵的搜索,应该避免。如果找不到此类模块或导出,则 find-prefixed 函数返回 null,而 get-prefixed 函数将引发异常。

ModuleMap 模块地图

new ModuleMap([filter]): create a new module map optimized for determining which module a given memory address belongs to, if any. Takes a snapshot of the currently loaded modules when created, which may be refreshed by calling update(). The filter argument is optional and allows you to pass a function used for filtering the list of modules. This is useful if you e.g. only care about modules owned by the application itself, and allows you to quickly check if an address belongs to one of its modules. The filter function is passed a Module object and must return true for each module that should be kept in the map. It is called for each loaded module every time the map is updated.
new ModuleMap([filter]):创建一个新的模块映射,该映射经过优化,用于确定给定内存地址属于哪个模块(如果有)。创建时获取当前加载的模块的快照,可以通过调用 update() 来刷新。filter 参数是可选的,允许您传递用于筛选模块列表的函数。例如,如果您只关心应用程序本身拥有的模块,这将非常有用,并且允许您快速检查地址是否属于其模块之一。函数 filter 传递一个 Module 对象,并且必须为应保留在映射中的每个模块返回 true。每次更新地图时,都会为每个加载的模块调用它。

has(address): check if address belongs to any of the contained modules, and returns the result as a boolean
has(address):检查 address 是否属于任何包含的模块,并以布尔值的形式返回结果

find(address), get(address): returns a Module with details about the module that address belongs to. In the event that no such module could be found, find() returns null whilst get() throws an exception.
find(address), get(address):返回一个模块,其中包含有关 address 所属模块的详细信息。如果找不到这样的模块,find() 返回 null,而 get() 抛出异常。

findName(address), getName(address), findPath(address), getPath(address): just like find() and get(), but only returns the name or path field, which means less overhead when you don’t need the other details.
findName(address)、getName(address)、findPath(address)、getPath(address):就像 find() 和 get() 一样,但只返回 name 或 path 字段,这意味着当您不需要其他详细信息时开销更少。

update(): update the map. You should call this after a module has been loaded or unloaded to avoid operating on stale data.
update():更新地图。您应该在加载或卸载模块后调用它,以避免对过时的数据进行操作。

values(): returns an array with the Module objects currently in the map. The returned array is a deep copy and will not mutate after a call to update().
values():返回一个数组,其中包含当前在映射中的 Module 对象。返回的数组是深层拷贝,在调用 update() 后不会发生变异。

Memory 记忆

Memory.scan(address, size, pattern, callbacks): scan memory for occurrences of pattern in the memory range given by address and size.
Memory.scan(address, size, pattern, callbacks):扫描内存中 address 和 size 给出的内存范围内是否出现 pattern。

    pattern must be of the form “13 37 ?? ff” to match 0x13 followed by 0x37 followed by any byte followed by 0xff. For more advanced matching it is also possible to specify an r2-style mask. The mask is bitwise AND-ed against both the needle and the haystack. To specify the mask append a : character after the needle, followed by the mask using the same syntax. For example: “13 37 13 37 : 1f ff ff f1”. For convenience it is also possible to specify nibble-level wildcards, like “?3 37 13 ?7”, which gets translated into masks behind the scenes.
    pattern 必须采用“13 37 ??ff“匹配 0x13 后跟 0x37 后跟任意字节,后跟 0xff。对于更高级的匹配,还可以指定 r2 样式的掩码。掩码是针对针头和大海捞针的位 AND-ed。若要指定掩码,请在针后附加一个 : 字符,后跟使用相同语法的掩码。例如:“13 37 13 37 : 1f ff ff f1”。为方便起见,还可以指定半字节级别的通配符,例如“?3 37 13 ?7”,它会在幕后转换为掩码。

    callbacks is an object with:
    callbacks 是具有以下条件的对象:

        onMatch(address, size): called with address containing the address of the occurence as a NativePointer and size specifying the size as a number.
        onMatch(address, size):使用 address 调用,其中包含作为 NativePointer 的出现地址,并使用 size 将大小指定为数字。

        This function may return the string stop to cancel the memory scanning early.
        此函数可能会返回字符串 stop 以提前取消内存扫描。

        onError(reason): called with reason when there was a memory access error while scanning
        onError(reason):扫描时出现内存访问错误时使用 reason 调用

        onComplete(): called when the memory range has been fully scanned
        onComplete():完全扫描内存范围时调用

Memory.scanSync(address, size, pattern): synchronous version of scan() that returns an array of objects containing the following properties:
Memory.scanSync(address, size, pattern):scan() 的同步版本,返回包含以下属性的对象数组:
    address: absolute address as a NativePointer.
    address:作为 NativePointer 的绝对地址。
    size: size in bytes size:大小(以字节为单位)

For example: 例如:

// Find the module for the program itself, always at index 0:
const m = Process.enumerateModules()[0];

// Or load a module by name:
//const m = Module.load(‘win32u.dll’);

// Print its properties:
console.log(JSON.stringify(m));

// Dump it from its base address:
console.log(hexdump(m.base));

// The pattern that you are interested in:
const pattern = ‘00 00 00 00 ?? 13 37 ?? 42’;

Memory.scan(m.base, m.size, pattern, {
onMatch(address, size) {
console.log(‘Memory.scan() found match at’, address,
‘with size’, size);

// Optionally stop scanning early:
return 'stop';

},
onComplete() {
console.log(‘Memory.scan() complete’);
}
});

const results = Memory.scanSync(m.base, m.size, pattern);
console.log(‘Memory.scanSync() result:\n’ +
JSON.stringify(results));

Memory.alloc(size[, options]): allocate size bytes of memory on the heap, or, if size is a multiple of Process.pageSize, one or more raw memory pages managed by the OS. When using page granularity you may also specify an options object if you need the memory allocated close to a given address, by specifying { near: address, maxDistance: distanceInBytes }. The returned value is a NativePointer and the underlying memory will be released when all JavaScript handles to it are gone. This means you need to keep a reference to it while the pointer is being used by code outside the JavaScript runtime.
Memory.alloc(size[, options]):在堆上分配 size 字节的内存,或者,如果 size 是 Process.pageSize 的倍数,则分配由操作系统管理的一个或多个原始内存页。使用页面粒度时,如果需要在给定地址附近分配内存,也可以通过指定 { near: address, maxDistance: distanceInBytes } 来指定 options 对象。返回的值是 NativePointer,当它的所有 JavaScript 句柄都消失时,将释放基础内存。这意味着,当 JavaScript 运行时外部的代码使用指针时,您需要保留对指针的引用。

Memory.copy(dst, src, n): just like memcpy(). Returns nothing.
Memory.copy(dst, src, n):就像 memcpy() 一样。不返回任何内容。
    dst: a NativePointer specifying the destination base address.
    dst:指定目标基址的 NativePointer。
    src: a NativePointer specifying the source base address.
    src:指定源基址的 NativePointer。
    n: size in bytes to be copied.
    n:要复制的大小(以字节为单位)。

Memory.dup(address, size): short-hand for Memory.alloc() followed by Memory.copy(). Returns a NativePointer containing the base address of the freshly allocated memory. See Memory.copy() for details on the memory allocation’s lifetime.
Memory.dup(address, size):Memory.alloc() 后跟 Memory.copy() 的简写。返回一个 NativePointer,其中包含新分配的内存的基址。请参阅 Memory.copy() 以获取有关内存分配生存期的详细信息。

Memory.protect(address, size, protection): update protection on a region of memory, where protection is a string of the same format as Process.enumerateRanges().
Memory.protect(address, size, protection):更新内存区域上的保护,其中 protection 是与 Process.enumerateRanges() 格式相同的字符串。

Returns a boolean indicating whether the operation completed successfully.
返回一个布尔值,指示操作是否成功完成。

For example: 例如:

Memory.protect(ptr(‘0x1234’), 4096, ‘rw-’);

Memory.patchCode(address, size, apply): safely modify size bytes at address, specified as a NativePointer. The supplied JavaScript function apply gets called with a writable pointer where you must write the desired modifications before returning. Do not make any assumptions about this being the same location as address, as some systems require modifications to be written to a temporary location before being mapped into memory on top of the original memory page (e.g. on iOS, where directly modifying in-memory code may result in the process losing its CS_VALID status).
Memory.patchCode(address, size, apply):安全修改 address 处的 size 字节,指定为 NativePointer。提供的 JavaScript 函数 apply 使用可写指针调用,您必须在返回之前编写所需的修改。不要假设这与 address 的位置相同,因为某些系统需要在映射到原始内存页面顶部的内存之前将修改写入临时位置(例如,在 iOS 上,直接修改内存中的代码可能会导致进程失去其CS_VALID状态)。

For example: 例如:

const getLivesLeft = Module.getExportByName(‘game-engine.so’, ‘get_lives_left’);
const maxPatchSize = 64; // Do not write out of bounds, may be a temporary buffer!
Memory.patchCode(getLivesLeft, maxPatchSize, code => {
const cw = new X86Writer(code, { pc: getLivesLeft });
cw.putMovRegU32(‘eax’, 9000);
cw.putRet();
cw.flush();
});

Memory.allocUtf8String(str), Memory.allocUtf16String(str), Memory.allocAnsiString(str): allocate, encode and write out str as a UTF-8/UTF-16/ANSI string on the heap. The returned object is a NativePointer. See Memory.alloc() for details about its lifetime.
Memory.allocUtf8String(str)、Memory.allocUtf16String(str)、Memory.allocAnsiString(str):将 str 分配、编码并写出 str 作为堆上的 UTF-8/UTF-16/ANSI 字符串。返回的对象是 NativePointer。有关其生存期的详细信息,请参见 Memory.alloc()。

MemoryAccessMonitor 内存访问监视器

MemoryAccessMonitor.enable(ranges, callbacks): monitor one or more memory ranges for access, and notify on the first access of each contained memory page. ranges is either a single range object or an array of such objects, each of which contains:
MemoryAccessMonitor.enable(ranges, callbacks):监视一个或多个内存范围的访问,并在首次访问每个包含的内存页时通知。ranges 是单个范围对象或此类对象的数组,每个对象包含:
    base: base address as a NativePointer
    base:作为 NativePointer 的基址
    size: size in bytes size:大小(以字节为单位)

callbacks is an object specifying:
callbacks 是一个对象,指定:
    onAccess(details): called synchronously with details object containing:
        operation: the kind of operation that triggered the access, as a string specifying either read, write, or execute
        operation:触发访问的操作类型,作为指定 read、write 或 execute 的字符串
        from: address of instruction performing the access as a NativePointer
        from:作为 NativePointer 执行访问的指令地址
        address: address being accessed as a NativePointer
        address:作为 NativePointer 访问的地址
        rangeIndex: index of the accessed range in the ranges provided to MemoryAccessMonitor.enable()
        rangeIndex:提供给 MemoryAccessMonitor.enable() 的范围内访问范围的索引
        pageIndex: index of the accessed memory page inside the specified range
        pageIndex:指定范围内访问的内存页的索引
        pagesCompleted: overall number of pages which have been accessed so far (and are no longer being monitored)
        pagesCompleted:到目前为止已访问的页面总数(并且不再受到监控)
        pagesTotal: overall number of pages that were initially monitored
        pagesTotal:最初监控的页面总数

MemoryAccessMonitor.disable(): stop monitoring the remaining memory ranges passed to MemoryAccessMonitor.enable().
MemoryAccessMonitor.disable():停止监视传递给 MemoryAccessMonitor.enable() 的剩余内存范围。

CModule

new CModule(code[, symbols, options]): creates a new C module from the provided code, either a string containing the C source code to compile, or an ArrayBuffer containing a precompiled shared library. The C module gets mapped into memory and becomes fully accessible to JavaScript.
new CModule(code[, symbols, options]):从提供的 code 创建一个新的 C 模块,可以是包含要编译的 C 源代码的字符串,也可以是包含预编译共享库的 ArrayBuffer。C 模块被映射到内存中,并完全可供 JavaScript 访问。

Useful for implementing hot callbacks, e.g. for Interceptor and Stalker, but also useful when needing to start new threads in order to call functions in a tight loop, e.g. for fuzzing purposes.
对于实现热回调很有用,例如用于 Interceptor 和 Stalker,但在需要启动新线程以在紧密循环中调用函数时也很有用,例如用于模糊测试目的。

Global functions are automatically exported as NativePointer properties named exactly like in the C source code. This means you can pass them to Interceptor and Stalker, or call them using NativePointer.
全局函数会自动导出为 NativePointer 属性,其命名方式与 C 源代码中的名称完全相同。这意味着您可以将它们传递给 Interceptor 和 Stalker,或者使用 NativePointer 调用它们。

In addition to accessing a curated subset of Gum, GLib, and standard C APIs, the code being mapped in can also communicate with JavaScript through the symbols exposed to it. This is the optional second argument, an object specifying additional symbol names and their NativePointer values, each of which will be plugged in at creation. This may for example be one or more memory blocks allocated using Memory.alloc(), and/or NativeCallback values for receiving callbacks from the C module.
除了访问 Gum、GLib 和标准 C API 的精选子集外,映射的代码还可以通过向 JavaScript 公开的 symbols 与 JavaScript 进行通信。这是可选的第二个参数,该对象指定其他符号名称及其 NativePointer 值,每个值都将在创建时插入。例如,这可能是使用 Memory.alloc() 和/或 NativeCallback 值分配的一个或多个内存块,用于接收来自 C 模块的回调。

To perform initialization and cleanup, you may define functions with the following names and signatures:
若要执行初始化和清理,可以使用以下名称和签名定义函数:
    void init (void)
    void finalize (void)

Note that all data is read-only, so writable globals should be declared extern, allocated using e.g. Memory.alloc(), and passed in as symbols through the constructor’s second argument.
请注意,所有数据都是只读的,因此应将可写全局变量声明为 extern,使用 Memory.alloc() 等方式进行分配,并通过构造函数的第二个参数作为符号传入。

The optional third argument, options, is an object that may be used to specify which toolchain to use, e.g.: { toolchain: 'external' }. Supported values are:
可选的第三个参数 options 是一个对象,可用于指定要使用的工具链,例如:{ toolchain: 'external' }。 支持的值包括:
    internal: use TinyCC, which is statically linked into the runtime. Never touches the filesystem and works even in sandboxed processes. The generated code is however not optimized, as TinyCC optimizes for small compiler footprint and short compilation times.
    internal:使用静态链接到运行时的 TinyCC。从不接触文件系统,即使在沙盒进程中也能工作。然而,生成的代码并未进行优化,因为 TinyCC 针对较小的编译器占用空间和较短的编译时间进行了优化。
    external: use toolchain provided by the target system, assuming it is accessible to the process we’re executing inside.
    external:使用目标系统提供的工具链,假设我们在其中执行的进程可以访问它。
    any: same as internal if Process.arch is supported by TinyCC, and external otherwise. This is the default behavior if left unspecified.
    any:如果 TinyCC 支持 Process.arch,则与 internal 相同,否则为 external。如果未指定,这是默认行为。

dispose(): eagerly unmaps the module from memory. Useful for short-lived modules when waiting for a future garbage collection isn’t desirable.
dispose():急切地从内存中取消模块映射。对于短期模块,在等待将来的垃圾回收是不可取的时很有用。

builtins: an object specifying builtins present when constructing a CModule from C source code. This is typically used by a scaffolding tool such as frida-create in order to set up a build environment that matches what CModule uses. The exact contents depends on the Process.arch and Frida version, but may look something like the following:
builtins:一个对象,用于指定从 C 源代码构造 CModule 时存在的内置项。这通常由脚手架工具(如 frida-create)使用,以便设置与 CModule 使用的构建环境相匹配。确切的内容取决于 Process.arch 和 Frida 版本,但可能如下所示:

{
  defines: {
    'GLIB_SIZEOF_VOID_P': '8',
    'G_GINT16_MODIFIER': '"h"',
    'G_GINT32_MODIFIER': '""',
    'G_GINT64_MODIFIER': '"ll"',
    'G_GSIZE_MODIFIER': '"l"',
    'G_GSSIZE_MODIFIER': '"l"',
    'HAVE_I386': true
  },
  headers: {
    'gum/arch-x86/gumx86writer.h': '…',
    'gum/gumdefs.h': '…',
    'gum/guminterceptor.h': '…',
    'gum/gummemory.h': '…',
    'gum/gummetalarray.h': '…',
    'gum/gummetalhash.h': '…',
    'gum/gummodulemap.h': '…',
    'gum/gumprocess.h': '…',
    'gum/gumspinlock.h': '…',
    'gum/gumstalker.h': '…',
    'glib.h': '…',
    'json-glib/json-glib.h': '…',
    'capstone.h': '…'
  }
}

Examples 例子

const cm = new CModule(`
#include <stdio.h>

void hello(void) {
printf(“Hello World from CModule\n”);
}
`);

console.log(JSON.stringify(cm));

const hello = new NativeFunction(cm.hello, ‘void’, []);
hello();

Which you might load using Frida’s REPL:
您可以使用 Frida 的 REPL 加载:

$ frida -p 0 -l example.js

(The REPL monitors the file on disk and reloads the script on change.)
(REPL 监视磁盘上的文件,并在更改时重新加载脚本。

You can then type hello() in the REPL to call the C function.
然后,您可以在 REPL 中键入 hello() 来调用 C 函数。

For prototyping we recommend using the Frida REPL’s built-in CModule support:
对于原型设计,我们建议使用 Frida REPL 的内置 CModule 支持:

$ frida -p 0 -C example.c

You may also add -l example.js to load some JavaScript next to it. The JavaScript code may use the global variable named cm to access the CModule object, but only after rpc.exports.init() has been called, so perform any initialization depending on the CModule there. You may also inject symbols by assigning to the global object named cs, but this must be done before rpc.exports.init() gets called.
您也可以添加 -l example.js 以在它旁边加载一些 JavaScript。JavaScript 代码可以使用名为 cm 的全局变量来访问 CModule 对象,但只有在调用 rpc.exports.init() 之后,因此请根据那里的 CModule 执行任何初始化。您也可以通过赋值给名为 cs 的全局对象来注入符号,但这必须在调用 rpc.exports.init() 之前完成。

Here’s an example: 下面是一个示例:

CModule REPL example

More details on CModule can be found in the Frida 12.7 release notes.
有关 CModule 的更多详细信息,请参阅 Frida 12.7 发行说明。
ApiResolver

new ApiResolver(type): create a new resolver of the given type, allowing you to quickly find APIs by name, with globs permitted. Precisely which resolvers are available depends on the current platform and runtimes loaded in the current process. As of the time of writing, the available resolvers are:
new ApiResolver(type):创建给定 type 的新解析器,允许您按名称快速查找 API,并允许使用 glob。确切地说,哪些解析器可用取决于当前平台和当前进程中加载的运行时。截至撰写本文时,可用的解析器包括:
    module: Resolves module exports, imports, and sections. Always available.
    module:解析模块导出、导入和分区。 随时可用。
    swift: Resolves Swift functions. Available in processes that have a Swift runtime loaded. Use Swift.available to check at runtime, or wrap your new ApiResolver('swift') call in a try-catch.
    swift:解析 Swift 函数。 在加载了 Swift 运行时的进程中可用。使用 Swift.available 在运行时进行检查,或将 new ApiResolver('swift') 调用包装在 try-catch 中。
    objc: Resolves Objective-C methods. Available on macOS and iOS in processes that have the Objective-C runtime loaded. Use ObjC.available to check at runtime, or wrap your new ApiResolver('objc') call in a try-catch.
    objc:解析 Objective-C 方法。 在加载了 Objective-C 运行时的进程中的 macOS 和 iOS 上可用。使用 ObjC.available 在运行时进行检查,或将 new ApiResolver('objc') 调用包装在 try-catch 中。

The resolver will load the minimum amount of data required on creation, and lazy-load the rest depending on the queries it receives. It is thus recommended to use the same instance for a batch of queries, but recreate it for future batches to avoid looking at stale data.
解析程序将加载创建时所需的最小数据量,并根据收到的查询延迟加载其余数据。因此,建议对一批查询使用相同的实例,但为将来的批次重新创建该实例,以避免查看过时的数据。

enumerateMatches(query): performs the resolver-specific query string, optionally suffixed with /i to perform case-insensitive matching, returning an array of objects containing the following properties:
enumerateMatches(query):执行特定于解析程序的 query 字符串,可选后缀为 /i 以执行不区分大小写的匹配,返回包含以下属性的对象数组:
    name: name of the API that was found
    name:找到的 API 的名称
    address: address as a NativePointer
    address:地址作为 NativePointer
    size: if present, a number specifying the size in bytes
    size:如果存在,则指定大小(以字节为单位)的数字

const resolver = new ApiResolver(‘module’);
const matches = resolver.enumerateMatches(‘exports:!open’);
const first = matches[0];
/*

  • Where first is an object similar to:
  • {
  • name: ‘/usr/lib/libSystem.B.dylib!opendir$INODE64’,
  • address: ptr(‘0x7fff870135c9’)
  • }
    */

const resolver = new ApiResolver(‘module’);
const matches = resolver.enumerateMatches('sections:!text’);
const first = matches[0];
/

  • Where first is an object similar to:
  • {
  • name: ‘/usr/lib/libSystem.B.dylib!0.__TEXT.__text’,
  • address: ptr(‘0x191c1e504’),
  • size: 1528
  • }
    */

const resolver = new ApiResolver(‘swift’);
const matches = resolver.enumerateMatches('functions:CoreDevice!RemoteDevice’);
const first = matches[0];
/

  • Where first is an object similar to:
  • {
  • name: ‘/Library/Developer/PrivateFrameworks/CoreDevice.framework/Versions/A/CoreDevice!dispatch thunk of CoreDevice.RemoteDevice.addDeviceInfoChanged(on: __C.OS_dispatch_queue?, handler: (Foundation.UUID, CoreDeviceProtocols.DeviceInfo) -> ()) -> CoreDevice.Invalidatable’,
  • address: ptr(‘0x1078c3570’)
  • }
    */

const resolver = new ApiResolver(‘objc’);
const matches = resolver.enumerateMatches(‘-[NSURL* HTTP]’);
const first = matches[0];
/*

  • Where first is an object similar to:
  • {
  • name: ‘-[NSURLRequest valueForHTTPHeaderField:]’,
  • address: ptr(‘0x7fff94183e22’)
  • }
    */

DebugSymbol 调试符号

DebugSymbol.fromAddress(address), DebugSymbol.fromName(name): look up debug information for address/name and return it as an object containing:
DebugSymbol.fromAddress(address), DebugSymbol.fromName(name):查找 address/name 的调试信息,并将其作为包含以下内容的对象返回:
    address: Address that this symbol is for, as a NativePointer.
    address:此符号用于的地址,作为 NativePointer。
    name: Name of the symbol, as a string, or null if unknown.
    name:符号的名称,以字符串形式表示,如果未知,则为 null。
    moduleName: Module name owning this symbol, as a string, or null if unknown.
    moduleName:拥有此符号的模块名称,为字符串,如果未知,则为 null。
    fileName: File name owning this symbol, as a string, or null if unknown.
    fileName:拥有此符号的文件名,为字符串,如果未知,则为 null。
    lineNumber: Line number in fileName, as a number, or null if unknown.
    lineNumber:fileName 中的行号,为数字,如果未知,则为 null。

You may also call toString() on it, which is very useful when combined with Thread.backtrace():
您也可以在它上面调用 toString(),这在与 Thread.backtrace() 结合使用时非常有用:

const f = Module.getExportByName(‘libcommonCrypto.dylib’,
‘CCCryptorCreate’);
Interceptor.attach(f, {
onEnter(args) {
console.log(‘CCCryptorCreate called from:\n’ +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join(‘\n’) + ‘\n’);
}
});

DebugSymbol.getFunctionByName(name): resolves a function name and returns its address as a NativePointer. Returns the first if more than one function is found. Throws an exception if the name cannot be resolved.
DebugSymbol.getFunctionByName(name):解析函数名称并将其地址作为 NativePointer 返回。如果找到多个函数,则返回第一个函数。如果无法解析名称,则引发异常。

DebugSymbol.findFunctionsNamed(name): resolves a function name and returns its addresses as an array of NativePointer objects.
DebugSymbol.findFunctionsNamed(name):解析函数名称并将其地址作为 NativePointer 对象数组返回。

DebugSymbol.findFunctionsMatching(glob): resolves function names matching glob and returns their addresses as an array of NativePointer objects.
DebugSymbol.findFunctionsMatching(glob):解析与 glob 匹配的函数名称,并将其地址作为 NativePointer 对象数组返回。

DebugSymbol.load(path): loads debug symbols for a specific module.
DebugSymbol.load(path):加载特定模块的调试符号。

Kernel 内核

Kernel.available: a boolean specifying whether the Kernel API is available. Do not invoke any other Kernel properties or methods unless this is the case.
Kernel.available:指定内核 API 是否可用的布尔值。除非是这种情况,否则不要调用任何其他 Kernel 属性或方法。

Kernel.base: base address of the kernel, as a UInt64.
Kernel.base:内核的基址,作为 UInt64。

Kernel.pageSize: size of a kernel page in bytes, as a number.
Kernel.pageSize:内核页的大小(以字节为单位),以数字表示。

Kernel.enumerateModules(): enumerates kernel modules loaded right now, returning an array of objects containing the following properties:
Kernel.enumerateModules():枚举当前加载的内核模块,返回包含以下属性的对象数组:
    name: canonical module name as a string
    name:字符串形式的规范模块名称
    base: base address as a NativePointer
    base:作为 NativePointer 的基址
    size: size in bytes size:大小(以字节为单位)

Kernel.enumerateRanges(protection|specifier): enumerate kernel memory ranges satisfying protection given as a string of the form: rwx, where rw- means “must be at least readable and writable”. Alternatively you may provide a specifier object with a protection key whose value is as aforementioned, and a coalesce key set to true if you’d like neighboring ranges with the same protection to be coalesced (the default is false; i.e. keeping the ranges separate). Returns an array of objects containing the following properties:
Kernel.enumerateRanges(protection|specifier):枚举满足 protection 的内核内存范围,以以下格式的字符串给出:rwx,其中 rw- 表示“必须至少是可读和可写的”。或者,您可以为 specifier 对象提供一个 protection 键,其值如上所述,如果您希望合并具有相同保护的相邻范围(默认值为 false,则将 coalesce 键设置为 true(默认值为 false;即保持范围分开)。返回包含以下属性的对象数组:
    base: base address as a NativePointer
    base:作为 NativePointer 的基址
    size: size in bytes size:大小(以字节为单位)
    protection: protection string (see above)
    protection:保护字符串(见上文)

Kernel.enumerateModuleRanges(name, protection): just like Kernel.enumerateRanges, except it’s scoped to the specified module name – which may be null for the module of the kernel itself. Each range also has a name field containing a unique identifier as a string.
Kernel.enumerateModuleRanges(name, protection):就像 Kernel.enumerateRanges 一样,只是它的范围限定为指定的模块 name——对于内核本身的模块,它可能是 null。每个范围还有一个 name 字段,其中包含字符串形式的唯一标识符。

Kernel.alloc(size): allocate size bytes of kernel memory, rounded up to a multiple of the kernel’s page size. The returned value is a UInt64 specifying the base address of the allocation.
Kernel.alloc(size):分配 size 字节的内核内存,四舍五入为内核页面大小的倍数。返回的值是指定分配基址的 UInt64。

Kernel.protect(address, size, protection): update protection on a region of kernel memory, where protection is a string of the same format as Kernel.enumerateRanges().
Kernel.protect(address, size, protection):更新内核内存区域上的保护,其中 protection 是与 Kernel.enumerateRanges() 格式相同的字符串。

For example: 例如:

Kernel.protect(UInt64(‘0x1234’), 4096, ‘rw-’);

Kernel.readByteArray(address, length): just like NativePointer#readByteArray, but reading from kernel memory.
Kernel.readByteArray(address, length):就像 NativePointer#readByteArray 一样,但从内核内存中读取。

Kernel.writeByteArray(address, bytes): just like NativePointer#writeByteArray, but writing to kernel memory.
Kernel.writeByteArray(address, bytes):就像 NativePointer#writeByteArray 一样,但写入内核内存。

Kernel.scan(address, size, pattern, callbacks): just like Memory.scan, but scanning kernel memory.
Kernel.scan(address, size, pattern, callbacks):就像 Memory.scan,但扫描内核内存。

Kernel.scanSync(address, size, pattern): synchronous version of scan() that returns the matches in an array.
Kernel.scanSync(address, size, pattern):scan() 的同步版本,返回数组中的匹配项。

Data Types, Function and Callback

数据类型、函数和回调


Int64 国际64

new Int64(v): create a new Int64 from v, which is either a number or a string containing a value in decimal, or hexadecimal if prefixed with “0x”. You may use the int64(v) short-hand for brevity.
new Int64(v):从 v 创建一个新的 Int64,该 Int64 是一个数字或字符串,其中包含十进制值,如果前缀为“0x”,则为十六进制。为简洁起见,您可以使用 int64(v) 简写。

add(rhs), sub(rhs), and(rhs), or(rhs), xor(rhs): make a new Int64 with this Int64 plus/minus/and/or/xor rhs, which may either be a number or another Int64
add(rhs)、sub(rhs)、and(rhs)、or(rhs)、xor(rhs):使用此 Int64 加/减/和/或/xor rhs 创建一个新的 Int64,它可以是一个数字,也可以是另一个 Int64

shr(n), shl(n): make a new Int64 with this Int64 shifted right/left by n bits
shr(n), shl(n):创建一个新的 Int64,将此 Int64 向右/向左移动 n 位

compare(rhs): returns an integer comparison result just like String#localeCompare()
compare(rhs):返回整数比较结果,就像 String#localeCompare() 一样

toNumber(): cast this Int64 to a number
toNumber():将此 Int64 转换为一个数字

toString([radix = 10]): convert to a string of optional radix (defaults to 10)
toString([radix = 10]):转换为可选基数的字符串(默认为 10)

UInt64

new UInt64(v): create a new UInt64 from v, which is either a number or a string containing a value in decimal, or hexadecimal if prefixed with “0x”. You may use the uint64(v) short-hand for brevity.
new UInt64(v):从 v 创建一个新的 UInt64,该 UInt64 是一个数字或字符串,其中包含十进制值,如果前缀为“0x”,则为十六进制。为简洁起见,您可以使用 uint64(v) 简写。

add(rhs), sub(rhs), and(rhs), or(rhs), xor(rhs): make a new UInt64 with this UInt64 plus/minus/and/or/xor rhs, which may either be a number or another UInt64
add(rhs)、sub(rhs)、and(rhs)、or(rhs)、xor(rhs):使用此 UInt64 加/减/和/或/x或 rhs 创建一个新的 UInt64,它可以是数字或另一个 UInt64

shr(n), shl(n): make a new UInt64 with this UInt64 shifted right/left by n bits
shr(n), shl(n):使用此 UInt64 向右/向左移动 n 位创建一个新的 UInt64

compare(rhs): returns an integer comparison result just like String#localeCompare()
compare(rhs):返回整数比较结果,就像 String#localeCompare() 一样

toNumber(): cast this UInt64 to a number
toNumber():将此 UInt64 转换为一个数字

toString([radix = 10]): convert to a string of optional radix (defaults to 10)
toString([radix = 10]):转换为可选基数的字符串(默认为 10)

NativePointer 本机指针

new NativePointer(s): creates a new NativePointer from the string s containing a memory address in either decimal, or hexadecimal if prefixed with ‘0x’. You may use the ptr(s) short-hand for brevity.
new NativePointer(s):从字符串 s 创建一个新的 NativePointer,其中包含十进制或十六进制的内存地址(如果前缀为“0x”)。为简洁起见,您可以使用 ptr(s) 简写。

isNull(): returns a boolean allowing you to conveniently check if a pointer is NULL
isNull():返回一个布尔值,以便方便地检查指针是否为 NULL

add(rhs), sub(rhs), and(rhs), or(rhs), xor(rhs): makes a new NativePointer with this NativePointer plus/minus/and/or/xor rhs, which may either be a number or another NativePointer
add(rhs)、sub(rhs)、and(rhs)、or(rhs)、xor(rhs):使用此 NativePointer 加/减/和/或/或 rhs 创建一个新的 NativePointer,它可以是数字,也可以是另一个 NativePointer

shr(n), shl(n): makes a new NativePointer with this NativePointer shifted right/left by n bits
shr(n), shl(n):使用此 NativePointer 向右/向左移动 n 位创建一个新的 NativePointer

not(): makes a new NativePointer with this NativePointer’s bits inverted
not():使用此 NativePointer 的位反转创建一个新的 NativePointer

sign([key, data]): makes a new NativePointer by taking this NativePointer’s bits and adding pointer authentication bits, creating a signed pointer. This is a no-op if the current process does not support pointer authentication, returning this NativePointer instead of a new value.
sign([key, data]):通过获取此 NativePointer 的位并添加指针身份验证位来创建新的 NativePointer,从而创建签名指针。如果当前进程不支持指针身份验证,则此操作将返回此 NativePointer 而不是新值。

Optionally, key may be specified as a string. Supported values are:
(可选)可以将 key 指定为字符串。支持的值为:
    ia: The IA key, for signing code pointers. This is the default.
    ia:IA 密钥,用于对代码指针进行签名。这是默认设置。
    ib: The IB key, for signing code pointers.
    ib:IB 密钥,用于对代码指针进行签名。
    da: The DA key, for signing data pointers.
    da:DA 键,用于对数据指针进行签名。
    db: The DB key, for signing data pointers.
    db:DB 键,用于对数据指针进行签名。

The data argument may also be specified as a NativePointer/number-like value to provide extra data used for the signing, and defaults to 0.
还可以将 data 参数指定为 NativePointer/类似数字的值,以提供用于签名的额外数据,默认为 0。

strip([key]): makes a new NativePointer by taking this NativePointer’s bits and removing its pointer authentication bits, creating a raw pointer. This is a no-op if the current process does not support pointer authentication, returning this NativePointer instead of a new value.
strip([key]):通过获取此 NativePointer 的位并删除其指针身份验证位,创建原始指针来创建新的 NativePointer。如果当前进程不支持指针身份验证,则此操作将返回此 NativePointer 而不是新值。

Optionally, key may be passed to specify which key was used to sign the pointer being stripped. Defaults to ia. (See sign() for supported values.)
(可选)可以传递 key 以指定使用哪个键对被剥离的指针进行签名。默认值为 ia。(有关支持的值,请参见 sign()。

blend(smallInteger): makes a new NativePointer by taking this NativePointer’s bits and blending them with a constant, which may in turn be passed to sign() as data.
blend(smallInteger):通过获取此 NativePointer 的位并将它们与常量混合来创建一个新的 NativePointer,该常量又可以作为 data 传递给 sign()。

equals(rhs): returns a boolean indicating whether rhs is equal to this one; i.e. it has the same pointer value
equals(rhs):返回一个布尔值,指示 rhs 是否等于此值;即它具有相同的指针值

compare(rhs): returns an integer comparison result just like String#localeCompare()
compare(rhs):返回整数比较结果,就像 String#localeCompare() 一样

toInt32(): casts this NativePointer to a signed 32-bit integer
toInt32():将此 NativePointer 强制转换为有符号的 32 位整数

toString([radix = 16]): converts to a string of optional radix (defaults to 16)
toString([radix = 16]):转换为可选基数的字符串(默认为 16)

toMatchPattern(): returns a string containing a Memory.scan()-compatible match pattern for this pointer’s raw value
toMatchPattern():返回一个字符串,其中包含此指针的原始值的 Memory.scan() 兼容匹配模式

readPointer(): reads a NativePointer from this memory location.
readPointer():从此内存位置读取 NativePointer。

A JavaScript exception will be thrown if the address isn’t readable.
如果地址不可读,则会引发 JavaScript 异常。

writePointer(ptr): writes ptr to this memory location.
writePointer(ptr):将 ptr 写入此内存位置。

A JavaScript exception will be thrown if the address isn’t writable.
如果地址不可写,则会引发 JavaScript 异常。

readS8(), readU8(), readS16(), readU16(), readS32(), readU32(), readShort(), readUShort(), readInt(), readUInt(), readFloat(), readDouble(): reads a signed or unsigned 8/16/32/etc. or float/double value from this memory location and returns it as a number.
readS8()、readU8()、readS16()、readU16()、readS32()、readU32()、readShort()、readUShort()、readInt()、readUInt()、readFloat()、readDouble():从此内存位置读取有符号或无符号的 8/16/32/etc. 或浮点数/双精度值,并将其作为数字返回。

A JavaScript exception will be thrown if the address isn’t readable.
如果地址不可读,则会引发 JavaScript 异常。

writeS8(value), writeU8(value), writeS16(value), writeU16(value), writeS32(value), writeU32(value), writeShort(value), writeUShort(value), writeInt(value), writeUInt(value), writeFloat(value), writeDouble(value): writes a signed or unsigned 8/16/32/etc. or float/double value to this memory location.
writeS8(value)、writeU8(value)、writeS16(value)、writeU16(value)、writeS32(value)、writeU32(value)、writeShort(value)、writeUShort(value)、writeInt(value)、writeUInt(value)、writeFloat(value)、writeDouble(value):将有符号或无符号的 8/16/32/etc. 或浮点数/双精度 value 写入此内存位置。

A JavaScript exception will be thrown if the address isn’t writable.
如果地址不可写,则会引发 JavaScript 异常。

readS64(), readU64(), readLong(), readULong(): reads a signed or unsigned 64-bit, or long-sized, value from this memory location and returns it as an Int64/UInt64 value.
readS64()、readU64()、readLong()、readULong():从此内存位置读取有符号或无符号的 64 位或长大小值,并将其作为 Int64/UInt64 值返回。

A JavaScript exception will be thrown if the address isn’t readable.
如果地址不可读,则会引发 JavaScript 异常。

writeS64(value), writeU64(value), writeLong(value), writeULong(value): writes the Int64/UInt64 value to this memory location.
writeS64(value)、writeU64(value)、writeLong(value)、writeULong(value):将 Int64/UInt64 value 写入此内存位置。

A JavaScript exception will be thrown if the address isn’t writable.
如果地址不可写,则会引发 JavaScript 异常。

readByteArray(length): reads length bytes from this memory location, and returns it as an ArrayBuffer. This buffer may be efficiently transferred to your Frida-based application by passing it as the second argument to send().
readByteArray(length):从此内存位置读取 length 字节,并将其作为 ArrayBuffer 返回。通过将此缓冲区作为 send() 的第二个参数传递,可以有效地将其传输到基于 Frida 的应用程序。

A JavaScript exception will be thrown if any of the length bytes read from the address isn’t readable.
如果从地址读取的任何 length 字节不可读,则会引发 JavaScript 异常。

writeByteArray(bytes): writes bytes to this memory location, where bytes is either an ArrayBuffer, typically returned from readByteArray(), or an array of integers between 0 and 255. For example: [ 0x13, 0x37, 0x42 ].
writeByteArray(bytes):将 bytes 写入此内存位置,其中 bytes 是通常从 readByteArray() 返回的 ArrayBuffer,或者是介于 0 和 255 之间的整数数组。例如:[ 0x13, 0x37, 0x42 ]。

A JavaScript exception will be thrown if any of the bytes written to the address isn’t writable.
如果写入地址的任何字节不可写,则会引发 JavaScript 异常。

readCString([size = -1]), readUtf8String([size = -1]), readUtf16String([length = -1]), readAnsiString([size = -1]): reads the bytes at this memory location as an ASCII, UTF-8, UTF-16, or ANSI string. Supply the optional size argument if you know the size of the string in bytes, or omit it or specify -1 if the string is NUL-terminated. Likewise you may supply the optional length argument if you know the length of the string in characters.
readCString([size = -1])、readUtf8String([size = -1])、readUtf16String([length = -1])、readAnsiString([size = -1]):将此内存位置的字节读取为 ASCII、UTF-8、UTF-16 或 ANSI 字符串。如果您知道字符串的大小(以字节为单位),请提供可选的 size 参数,如果字符串以 NUL 结尾,则省略它或指定 -1。同样,如果您知道字符串的长度(以字符为单位),则可以提供可选的 length 参数。

A JavaScript exception will be thrown if any of the size / length bytes read from the address isn’t readable.
如果从地址读取的任何 size / length 字节不可读,则会引发 JavaScript 异常。

Note that readAnsiString() is only available (and relevant) on Windows.
请注意,readAnsiString() 仅在 Windows 上可用(且相关)。

writeUtf8String(str), writeUtf16String(str), writeAnsiString(str): encodes and writes the JavaScript string to this memory location (with NUL-terminator).
writeUtf8String(str)、writeUtf16String(str)、writeAnsiString(str):对 JavaScript 字符串进行编码并将其写入此内存位置(使用 NUL-terminator)。

A JavaScript exception will be thrown if any of the bytes written to the address isn’t writable.
如果写入地址的任何字节不可写,则会引发 JavaScript 异常。

Note that writeAnsiString() is only available (and relevant) on Windows.
请注意,writeAnsiString() 仅在 Windows 上可用(且相关)。

ArrayBuffer 数组缓冲区

wrap(address, size): creates an ArrayBuffer backed by an existing memory region, where address is a NativePointer specifying the base address of the region, and size is a number specifying its size. Unlike the NativePointer read/write APIs, no validation is performed on access, meaning a bad pointer will crash the process.
wrap(address, size):创建由现有内存区域支持的 ArrayBuffer,其中 address 是指定区域基址的 NativePointer,size 是指定其大小的数字。与 NativePointer 读/写 API 不同,访问时不执行任何验证,这意味着错误的指针会使进程崩溃。

unwrap(): returns a NativePointer specifying the base address of the ArrayBuffer’s backing store. It is the caller’s responsibility to keep the buffer alive while the backing store is still being used.
unwrap():返回一个 NativePointer,指定 ArrayBuffer 后备存储的基址。调用方有责任在后备存储仍在使用时保持缓冲区处于活动状态。

NativeFunction 本机函数

new NativeFunction(address, returnType, argTypes[, abi]): create a new NativeFunction to call the function at address (specified with a NativePointer), where returnType specifies the return type, and the argTypes array specifies the argument types. You may optionally also specify abi if not system default. For variadic functions, add a '...' entry to argTypes between the fixed arguments and the variadic ones.
new NativeFunction(address, returnType, argTypes[, abi]):创建一个新的 NativeFunction 以在 address(使用 NativePointer 指定)处调用函数,其中 returnType 指定返回类型,argTypes 数组指定参数类型。如果不是系统默认值,您也可以选择指定 abi。对于可变参数,在固定参数和可变参数之间向 argTypes 添加一个 '...' 条目。
    Structs & Classes by Value
    按值划分的结构和类

    As for structs or classes passed by value, instead of a string provide an array containing the struct’s field types following each other. You may nest these as deep as desired for representing structs inside structs. Note that the returned object is also a NativePointer, and can thus be passed to Interceptor#attach.
    对于按值传递的结构或类,请提供一个数组,而不是字符串,其中包含结构的字段类型,这些字段类型彼此跟随。您可以根据需要将它们嵌套到尽可能深的深度,以便在结构中表示结构。请注意,返回的对象也是 NativePointer,因此可以传递给 Interceptor#attach。

    This must match the struct/class exactly, so if you have a struct with three ints, you must pass ['int', 'int', 'int'].
    这必须与 struct/class 完全匹配,因此如果您有一个具有三个 int 的结构,则必须传递 ['int', 'int', 'int']。

    For a class that has virtual methods, the first field will be a pointer to the vtable.
    对于具有虚拟方法的类,第一个字段将是指向 vtable 的指针。

    For C++ scenarios involving a return value that is larger than Process.pointerSize, a typical ABI may expect that a NativePointer to preallocated space must be passed in as the first parameter. (This scenario is common in WebKit, for example.)
    对于涉及大于 Process.pointerSize 的返回值的 C++ 方案,典型的 ABI 可能期望必须将预分配空间的 NativePointer 作为第一个参数传入。(例如,此方案在 WebKit 中很常见。
    Supported Types 支持的类型
        void
        pointer 指针
        int
        uint
        long
        ulong 乌龙
        char
        uchar 苍蝇
        size_t
        ssize_t
        float 浮
        double 双
        int8
        uint8
        int16 国际16
        uint16
        int32
        uint32
        int64
        uint64
        bool
    Supported ABIs 支持的 ABIS
        default 违约
        Windows 32-bit:
            sysv
            stdcall 标准电话
            thiscall 这个电话
            fastcall 快速呼叫
            mscdecl MSCDECL系列
        Windows 64-bit:
            win64 win64的
        UNIX x86:
            sysv
            unix64 UNIX64的
        UNIX ARM:
            sysv
            vfp

new NativeFunction(address, returnType, argTypes[, options]): just like the previous constructor, but where the fourth argument, options, is an object that may contain one or more of the following keys:
new NativeFunction(address, returnType, argTypes[, options]):与前面的构造函数类似,但第四个参数 options 是一个对象,可以包含以下一个或多个键:
    abi: same enum as above.
    abi:与上面相同的枚举。
    scheduling: scheduling behavior as a string. Supported values are:
        cooperative: Allow other threads to execute JavaScript code while calling the native function, i.e. let go of the lock before the call, and re-acquire it afterwards. This is the default behavior.
        cooperative:允许其他线程在调用原生函数时执行 JavaScript 代码,即在调用前放开锁,之后重新获取。这是默认行为。
        exclusive: Do not allow other threads to execute JavaScript code while calling the native function, i.e. keep holding the JavaScript lock. This is faster but may result in deadlocks.
        独占:在调用本机函数时不允许其他线程执行 JavaScript 代码,即保持 JavaScript 锁。这速度更快,但可能会导致死锁。
    exceptions: exception behavior as a string. Supported values are:
        steal: If the called function generates a native exception, e.g. by dereferencing an invalid pointer, Frida will unwind the stack and steal the exception, turning it into a JavaScript exception that can be handled. This may leave the application in an undefined state, but is useful to avoid crashing the process while experimenting. This is the default behavior.
        steal:如果被调用的函数生成本机异常,例如通过取消引用无效指针,Frida 将展开堆栈并窃取异常,将其转换为可以处理的 JavaScript 异常。这可能会使应用程序处于未定义状态,但对于避免在试验时使进程崩溃很有用。这是默认行为。
        propagate: Let the application deal with any native exceptions that occur during the function call. (Or, the handler installed through Process.setExceptionHandler().)
        propagate:让应用程序处理函数调用期间发生的任何本机异常。(或者,通过 Process.setExceptionHandler() 安装的处理程序。
    traps: code traps to be enabled, as a string. Supported values are:
        default: Interceptor.attach() callbacks will be called if any hooks are triggered by a function call.
        default:如果函数调用触发了任何钩子,将调用 Interceptor.attach() 回调。
        all: In addition to Interceptor callbacks, Stalker may also be temporarily reactivated for the duration of each function call. This is useful for e.g. measuring code coverage while guiding a fuzzer, implementing “step into” in a debugger, etc. Note that this is also possible when using the Java and ObjC APIs, as method wrappers also provide a clone(options) API to create a new method wrapper with custom NativeFunction options.
        all:除了 Interceptor 回调之外,Stalker 也可能在每次函数调用期间暂时重新激活。例如,这对于在引导模糊器时测量代码覆盖率、在调试器中实现“单步执行”等非常有用。 请注意,在使用 Java 和 ObjC API 时,这也是可能的,因为方法包装器还提供了一个 clone(options) API 来创建具有自定义 NativeFunction 选项的新方法包装器。

NativeCallback 我不是一个好人。

new NativeCallback(func, returnType, argTypes[, abi]): create a new NativeCallback implemented by the JavaScript function func, where returnType specifies the return type, and the argTypes array specifies the argument types. You may also specify the abi if not system default. See NativeFunction for details about supported types and abis. Note that the returned object is also a NativePointer, and can thus be passed to Interceptor#replace. When using the resulting callback with Interceptor.replace(), func will be invoked with this bound to an object with some useful properties, just like the one in Interceptor.attach().
new NativeCallback(func, returnType, argTypes[, abi]):创建一个由 JavaScript 函数 func 实现的新 NativeCallback,其中 returnType 指定返回类型,argTypes 数组指定参数类型。如果不是系统默认值,您也可以指定 abi。有关支持的类型和 abis 的详细信息,请参阅 NativeFunction。请注意,返回的对象也是一个 NativePointer,因此可以传递给 Interceptor#replace。当将生成的回调与 Interceptor.replace() 一起使用时,func 将被调用,并将 this 绑定到具有一些有用属性的对象,就像 Interceptor.attach() 中的对象一样。

SystemFunction 系统功能

new SystemFunction(address, returnType, argTypes[, abi]): just like NativeFunction, but also provides a snapshot of the thread’s last error status. The return value is an object wrapping the actual return value as value, with one additional platform-specific field named either errno (UNIX) or lastError (Windows).
new SystemFunction(address, returnType, argTypes[, abi]):就像 NativeFunction 一样,但也提供线程上次错误状态的快照。返回值是一个将实际返回值包装为 value 的对象,其中包含一个名为 errno (UNIX) 或 lastError (Windows) 的附加特定于平台的字段。

new SystemFunction(address, returnType, argTypes[, options]): same as above but accepting an options object like NativeFunction’s corresponding constructor.
new SystemFunction(address, returnType, argTypes[, options]):与上述相同,但接受 options 对象,如 NativeFunction 的相应构造函数。

Network 网络


Network 网络

Socket.listen([options]): open a TCP or UNIX listening socket. Returns a Promise that receives a SocketListener.
Socket.listen([options]):打开 TCP 或 UNIX 侦听套接字。返回接收 SocketListener 的 Promise。

Defaults to listening on both IPv4 and IPv6, if supported, and binding on all interfaces on a randomly selected TCP port.
默认侦听 IPv4 和 IPv6(如果支持),并绑定随机选择的 TCP 端口上的所有接口。

The optional options argument is an object that may contain some of the following keys:
可选的 options 参数是一个对象,它可能包含以下一些键:
    family: address family as a string. Supported values are:
        unix
        ipv4
        ipv6 Defaults to listening on both ipv4 and ipv6 if supported.
        ipv6 默认侦听 ipv4 和 ipv6(如果支持)。
    host: (IP family) IP address as a string. Defaults to all interfaces.
    host:(IP 系列)字符串形式的 IP 地址。默认为所有接口。
    port: (IP family) IP port as a number. Defaults to any available.
    port:(IP 系列)IP 端口作为数字。默认为任何可用。
    type: (UNIX family) UNIX socket type as a string. Supported types are:
        anonymous 匿名
        path
        abstract 抽象
        abstract-padded Defaults to path.
        abstract-padded 默认值为 path。
    path: (UNIX family) UNIX socket path as a string.
    path:(UNIX 系列)字符串形式的 UNIX 套接字路径。
    backlog: Listen backlog as a number. Defaults to 10.
    backlog:将积压工作作为数字进行侦听。默认值为 10。

Socket.connect(options): connect to a TCP or UNIX server. Returns a Promise that receives a SocketConnection.
Socket.connect(options):连接到 TCP 或 UNIX 服务器。返回接收 SocketConnection 的 Promise。

The options argument is an object that should contain some of the following keys:
options 参数是一个对象,它应该包含以下一些键:
    family: address family as a string. Supported values are:
        unix
        ipv4
        ipv6 Defaults to an IP family depending on the host specified.
        ipv6 默认为 IP 系列,具体取决于指定的 host。
    host: (IP family) IP address as a string. Defaults to localhost.
    host:(IP 系列)字符串形式的 IP 地址。默认值为 localhost。
    port: (IP family) IP port as a number.
    port:(IP 系列)IP 端口作为数字。
    type: (UNIX family) UNIX socket type as a string. Supported types are:
        anonymous 匿名
        path
        abstract 抽象
        abstract-padded Defaults to path.
        abstract-padded 默认值为 path。
    path: (UNIX family) UNIX socket path as a string.
    path:(UNIX 系列)字符串形式的 UNIX 套接字路径。

Socket.type(handle): inspect the OS socket handle and return its type as a string which is either tcp, udp, tcp6, udp6, unix:stream, unix:dgram, or null if invalid or unknown.
Socket.type(handle):检查操作系统套接字 handle,并将其类型返回为字符串,如果无效或未知,则为 tcp、udp、tcp6、udp6、unix:stream、unix:dgram 或 null。

Socket.localAddress(handle), Socket.peerAddress(handle): inspect the OS socket handle and return its local or peer address, or null if invalid or unknown.
Socket.localAddress(handle), Socket.peerAddress(handle):检查操作系统套接字 handle 并返回其本地或对等地址,如果无效或未知,则返回 null。

The object returned has the fields:
返回的对象包含以下字段:
    ip: (IP sockets) IP address as a string.
    ip:(IP 套接字)字符串形式的 IP 地址。
    port: (IP sockets) IP port as a number.
    port:(IP 套接字)IP 端口作为数字。
    path: (UNIX sockets) UNIX path as a string.
    path:(UNIX 套接字)字符串形式的 UNIX 路径。

SocketListener 套接字侦听器

All methods are fully asynchronous and return Promise objects.

所有方法都是完全异步的,并返回 Promise 对象。

path: (UNIX family) path being listened on.
path:正在侦听的(UNIX 系列)路径。

port: (IP family) IP port being listened on.
port:(IP 系列)正在侦听的 IP 端口。

close(): close the listener, releasing resources related to it. Once the listener is closed, all other operations will fail. Closing a listener multiple times is allowed and will not result in an error.
close():关闭侦听器,释放与之相关的资源。关闭侦听器后,所有其他操作都将失败。允许多次关闭侦听器,并且不会导致错误。

accept(): wait for the next client to connect. The returned Promise receives a SocketConnection.
accept():等待下一个客户端连接。返回的 Promise 接收 SocketConnection。

SocketConnection 套接字连接

Inherits from IOStream. All methods are fully asynchronous and return Promise objects.

继承自 IOStream。所有方法都是完全异步的,并返回 Promise 对象。

setNoDelay(noDelay): disable the Nagle algorithm if noDelay is true, otherwise enable it. The Nagle algorithm is enabled by default, so it is only necessary to call this method if you wish to optimize for low delay instead of high throughput.
setNoDelay(noDelay):如果 noDelay 为 true,则禁用 Nagle 算法,否则启用它。默认情况下,Nagle 算法处于启用状态,因此,仅当您希望针对低延迟而不是高吞吐量进行优化时,才需要调用此方法。

File and Stream 文件和流


File and Stream 文件和流

File.readAllBytes(path): synchronously read all bytes from the file specified by path and return them as an ArrayBuffer.
File.readAllBytes(path):从 path 指定的文件中同步读取所有字节,并将其作为 ArrayBuffer 返回。

File.readAllText(path): synchronously read all text from the file specified by path and return it as a string. The file must be UTF-8 encoded, and an exception will be thrown if this is not the case.
File.readAllText(path):同步读取 path 指定的文件中的所有文本,并以字符串形式返回。该文件必须是 UTF-8 编码的,如果不是这种情况,将引发异常。

File.writeAllBytes(path, data): synchronously write data to the file specified by path, where data is an ArrayBuffer.
File.writeAllBytes(path, data):将 data 同步写入 path 指定的文件,其中 data 是 ArrayBuffer。

File.writeAllText(path, text): synchronously write text to the file specified by path, where text is a string. The file will be UTF-8 encoded.
File.writeAllText(path, text):将 text 同步写入 path 指定的文件,其中 text 是字符串。该文件将采用 UTF-8 编码。

new File(filePath, mode): open or create the file at filePath with the mode string specifying how it should be opened. For example "wb" to open the file for writing in binary mode (this is the same format as fopen() from the C standard library).
new File(filePath, mode):在 filePath 处打开或创建文件,并使用 mode 字符串指定应如何打开文件。例如,"wb" 打开文件以二进制模式进行写入(这与 C 标准库中的 fopen() 格式相同)。

tell(): return the current position of the file pointer within the file.
tell():返回文件指针在文件中的当前位置。

seek(offset[, whence]): move the file pointer to a new location. offset is the position to move to, and whence is the starting point for the offset (File.SEEK_SET for the beginning of the file, File.SEEK_CUR for the current file position, or File.SEEK_END for the end of the file).
seek(offset[, whence]):将文件指针移动到新位置。offset 是要移动到的位置,whence 是偏移量的起点(File.SEEK_SET 表示文件的开头,File.SEEK_CUR 表示当前文件位置,或 File.SEEK_END 表示文件的末尾)。

readBytes([size]): read and return size bytes from the file starting from the current file pointer position as an ArrayBuffer. If size is not specified, reads until the end of the file from the current position.
readBytes([size]):从当前文件指针位置开始读取并返回 size 字节,作为 ArrayBuffer。如果未指定 size,则从当前位置读取文件末尾。

readText([size]): read and return size characters from the file starting from the current file pointer position as a string. If size is not specified, reads text until the end of the file from the current position. The bytes being read must be UTF-8 encoded, and an exception will be thrown if this is not the case.
readText([size]):从当前文件指针位置开始,以字符串形式从文件中读取并返回 size 个字符。如果未指定 size,则从当前位置读取文本,直到文件末尾。读取的字节必须是 UTF-8 编码的,如果不是这种情况,将引发异常。

readLine(): read and return the next line as a string. Starts reading from the current file pointer position. The returned line does not include the newline character.
readLine():读取并返回下一行作为字符串。从当前文件指针位置开始读取。返回的行不包含换行符。

write(data): synchronously write data to the file, where data is either a string or a buffer as returned by NativePointer#readByteArray
write(data):将 data 同步写入文件,其中 data 是 NativePointer#readByteArray 返回的字符串或缓冲区

flush(): flush any buffered data to the underlying file.
flush():将所有缓冲数据刷新到基础文件。

close(): close the file. You should call this function when you’re done with the file unless you are fine with this happening when the object is garbage-collected or the script is unloaded.
close():关闭文件。在完成文件处理后,应调用此函数,除非在垃圾回收对象或卸载脚本时可以正常执行此操作。

IOStream IOStream的

All methods are fully asynchronous and return Promise objects.

所有方法都是完全异步的,并返回 Promise 对象。

input: the InputStream to read from.
input:要从中读取的 InputStream。

output: the OutputStream to write to.
output:要写入的 OutputStream。

close(): close the stream, releasing resources related to it. This will also close the individual input and output streams. Once the stream is closed, all other operations will fail. Closing a stream multiple times is allowed and will not result in an error.
close():关闭流,释放与之相关的资源。这也将关闭单个输入和输出流。流关闭后,所有其他操作都将失败。允许多次关闭流,并且不会导致错误。

InputStream 输入流

All methods are fully asynchronous and return Promise objects.

所有方法都是完全异步的,并返回 Promise 对象。

close(): close the stream, releasing resources related to it. Once the stream is closed, all other operations will fail. Closing a stream multiple times is allowed and will not result in an error.
close():关闭流,释放与之相关的资源。流关闭后,所有其他操作都将失败。允许多次关闭流,并且不会导致错误。

read(size): read up to size bytes from the stream. The returned Promise receives an ArrayBuffer up to size bytes long. End of stream is signalled through an empty buffer.
read(size):从流中读取最多 size 个字节。返回的 Promise 接收长达 size 字节的 ArrayBuffer。流的结束通过一个空的缓冲区发出信号。

readAll(size): keep reading from the stream until exactly size bytes have been consumed. The returned Promise receives an ArrayBuffer that is exactly size bytes long. Premature error or end of stream results in the Promise getting rejected with an error, where the Error object has a partialData property containing the incomplete data.
readAll(size):继续读取流,直到正好消耗 size 个字节。返回的 Promise 接收长度正好为 size 字节的 ArrayBuffer。过早的错误或流的结束会导致 Promise 被拒绝并出现错误,其中 Error 对象具有包含不完整数据的 partialData 属性。

OutputStream 输出流

All methods are fully asynchronous and return Promise objects.

所有方法都是完全异步的,并返回 Promise 对象。

close(): close the stream, releasing resources related to it. Once the stream is closed, all other operations will fail. Closing a stream multiple times is allowed and will not result in an error.
close():关闭流,释放与之相关的资源。流关闭后,所有其他操作都将失败。允许多次关闭流,并且不会导致错误。

write(data): try to write data to the stream. The data value is either an ArrayBuffer or an array of integers between 0 and 255. The returned Promise receives a Number specifying how many bytes of data were written to the stream.
write(data):尝试将 data 写入流。data 值是 ArrayBuffer 或介于 0 和 255 之间的整数数组。返回的 Promise 接收一个 Number,该数字指定将 data 的字节数写入流。

writeAll(data): keep writing to the stream until all of data has been written. The data value is either an ArrayBuffer or an array of integers between 0 and 255. Premature error or end of stream results in an error, where the Error object has a partialSize property specifying how many bytes of data were written to the stream before the error occurred.
writeAll(data):继续写入流,直到写入所有 data。data 值是 ArrayBuffer 或介于 0 和 255 之间的整数数组。过早错误或流结束会导致错误,其中 Error 对象具有 partialSize 属性,该属性指定在错误发生之前将 data 的字节数写入流。

writeMemoryRegion(address, size): try to write size bytes to the stream, reading them from address, which is a NativePointer. The returned Promise receives a Number specifying how many bytes of data were written to the stream.
writeMemoryRegion(address, size):尝试将 size 个字节写入流,从 address 读取它们,这是一个 NativePointer。返回的 Promise 接收一个 Number,该数字指定将 data 的字节数写入流。

UnixInputStream

(Only available on UNIX-like OSes.)

(仅在类 UNIX 操作系统上可用。

new UnixInputStream(fd[, options]): create a new InputStream from the specified file descriptor fd.
new UnixInputStream(fd[, options]):从指定的文件描述符 fd 创建新的 InputStream。

You may also supply an options object with autoClose set to true to make the stream close the underlying file descriptor when the stream is released, either through close() or future garbage-collection.
您还可以提供一个 autoClose 设置为 true 的 options 对象,以使流在发布流时关闭基础文件描述符,无论是通过 close() 还是将来的垃圾回收。

UnixOutputStream

(Only available on UNIX-like OSes.)

(仅在类 UNIX 操作系统上可用。

new UnixOutputStream(fd[, options]): create a new OutputStream from the specified file descriptor fd.
new UnixOutputStream(fd[, options]):从指定的文件描述符 fd 创建新的 OutputStream。

You may also supply an options object with autoClose set to true to make the stream close the underlying file descriptor when the stream is released, either through close() or future garbage-collection.
您还可以提供一个 autoClose 设置为 true 的 options 对象,以使流在发布流时关闭基础文件描述符,无论是通过 close() 还是将来的垃圾回收。

Win32InputStream

(Only available on Windows.)

(仅在 Windows 上可用。

new Win32InputStream(handle[, options]): create a new InputStream from the specified handle, which is a Windows HANDLE value.
new Win32InputStream(handle[, options]):从指定的 handle 创建新的 InputStream,该值是 Windows HANDLE 值。

You may also supply an options object with autoClose set to true to make the stream close the underlying handle when the stream is released, either through close() or future garbage-collection.
您还可以提供一个 options 对象,并将 autoClose 设置为 true,以使流在释放流时关闭基础句柄,无论是通过 close() 还是将来的垃圾回收。

Win32OutputStream

(Only available on Windows.)

(仅在 Windows 上可用。

new Win32OutputStream(handle[, options]): create a new OutputStream from the specified handle, which is a Windows HANDLE value.
new Win32OutputStream(handle[, options]):从指定的 handle 创建新的 OutputStream,该值是 Windows HANDLE 值。

You may also supply an options object with autoClose set to true to make the stream close the underlying handle when the stream is released, either through close() or future garbage-collection.
您还可以提供一个 options 对象,并将 autoClose 设置为 true,以使流在释放流时关闭基础句柄,无论是通过 close() 还是将来的垃圾回收。

Database 数据库


SqliteDatabase Sqlite数据库

SqliteDatabase.open(path[, options]): opens the SQLite v3 database specified by path, a string containing the filesystem path to the database. By default the database will be opened read-write, but you may customize this behavior by providing an options object with a property named flags, specifying an array of strings containing one or more of the following values: readonly, readwrite, create. The returned SqliteDatabase object will allow you to perform queries on the database.
SqliteDatabase.open(path[, options]):打开由 path 指定的 SQLite v3 数据库,该字符串包含数据库的文件系统路径。默认情况下,数据库将处于读写状态,但您可以通过提供具有名为 flags 的属性的 options 对象来自定义此行为,该对象指定包含以下一个或多个值的字符串数组:readonly、readwrite、create。 返回的 SqliteDatabase 对象将允许您对数据库执行查询。

SqliteDatabase.openInline(encodedContents): just like open() but the contents of the database is provided as a string containing its data, Base64-encoded. We recommend gzipping the database before Base64-encoding it, but this is optional and detected by looking for a gzip magic marker. The database is opened read-write, but is 100% in-memory and never touches the filesystem. This is useful for agents that need to bundle a cache of precomputed data, e.g. static analysis data used to guide dynamic analysis.
SqliteDatabase.openInline(encodedContents):与 open() 类似,但数据库的内容以包含其数据的字符串形式提供,Base64 编码。我们建议在对数据库进行 Base64 编码之前对其进行 gzip 压缩,但这是可选的,可以通过查找 gzip 魔术标记来检测。数据库是打开读写的,但 100% 在内存中,从不接触文件系统。这对于需要捆绑预计算数据缓存的代理非常有用,例如用于指导动态分析的静态分析数据。

close(): close the database. You should call this function when you’re done with the database, unless you are fine with this happening when the object is garbage-collected or the script is unloaded.
close():关闭数据库。使用完数据库后,应调用此函数,除非在垃圾回收对象或卸载脚本时可以正常执行此操作。

exec(sql): execute a raw SQL query, where sql is a string containing the text-representation of the query. The query’s result is ignored, so this should only be used for queries for setting up the database, e.g. table creation.
exec(sql):执行原始 SQL 查询,其中 sql 是包含查询的文本表示形式的字符串。查询的结果将被忽略,因此这应该仅用于设置数据库的查询,例如表创建。

prepare(sql): compile the provided SQL into a SqliteStatement object, where sql is a string containing the text-representation of the query.
prepare(sql):将提供的 SQL 编译为 SqliteStatement 对象,其中 sql 是包含查询的文本表示形式的字符串。

For example: 例如:

const db = SqliteDatabase.open(‘/path/to/people.db’);

const smt = db.prepare(‘SELECT name, bio FROM people WHERE age = ?’);

console.log(‘People whose age is 42:’);
smt.bindInteger(1, 42);
let row;
while ((row = smt.step()) !== null) {
const [name, bio] = row;
console.log(‘Name:’, name);
console.log(‘Bio:’, bio);
}
smt.reset();

dump(): dump the database to a gzip-compressed blob encoded as Base64, where the result is returned as a string. This is useful for inlining a cache in your agent’s code, loaded by calling SqliteDatabase.openInline().
dump():将数据库转储到编码为 Base64 的 gzip 压缩 Blob,其中结果以字符串形式返回。这对于在代理代码中内联缓存非常有用,该缓存通过调用 SqliteDatabase.openInline() 加载。

SqliteStatement

bindInteger(index, value): bind the integer value to index
bindInteger(index, value):将整数 value 绑定到 index
bindFloat(index, value): bind the floating point value to index
bindFloat(index, value):将浮点数 value 绑定到 index
bindText(index, value): bind the text value to index
bindText(index, value):将文本 value 绑定到 index
bindBlob(index, bytes): bind the blob bytes to index, where bytes is an ArrayBuffer, array of byte values, or a string
bindBlob(index, bytes):将 blob bytes 绑定到 index,其中 bytes 是 ArrayBuffer、字节值数组或字符串
bindNull(index): bind a null value to index
bindNull(index):将 null 值绑定到 index
step(): either start a new query and get the first result, or move to the next one. Returns an array containing the values in the order specified by the query, or null when the last result is reached. You should call reset() at that point if you intend to use this object again.
step():启动新查询并获取第一个结果,或移动到下一个查询。返回一个数组,其中包含按查询指定的顺序排列的值,或者在到达最后一个结果时返回 null。如果您打算再次使用此对象,则应在此时调用 reset()。
reset(): reset internal state to allow subsequent queries
reset():重置内部状态以允许后续查询

Instrumentation 仪表
Interceptor 拦截 器

Interceptor.attach(target, callbacks[, data]): intercept calls to function at target. This is a NativePointer specifying the address of the function you would like to intercept calls to. Note that on 32-bit ARM this address must have its least significant bit set to 0 for ARM functions, and 1 for Thumb functions. Frida takes care of this detail for you if you get the address from a Frida API (for example Module.getExportByName()).
Interceptor.attach(target, callbacks[, data]):截获对 target 处函数的调用。这是一个 NativePointer,用于指定要拦截调用的函数的地址。请注意,在 32 位 ARM 上,对于 ARM 函数,此地址的最低有效位必须设置为 0,对于 Thumb 函数,必须将其最低有效位设置为 1。如果您从 Frida API 获取地址(例如 Module.getExportByName()),Frida 会为您处理此详细信息。

The callbacks argument is an object containing one or more of:
callbacks 参数是包含以下一个或多个项的对象:

    onEnter(args): callback function given one argument args that can be used to read or write arguments as an array of NativePointer objects. {: #interceptor-onenter}
    onEnter(args):给定一个参数 args 的回调函数,可用于将参数作为 NativePointer 对象数组读取或写入。{: #interceptor-onenter}

    onLeave(retval): callback function given one argument retval that is a NativePointer-derived object containing the raw return value. You may call retval.replace(1337) to replace the return value with the integer 1337, or retval.replace(ptr("0x1234")) to replace with a pointer. Note that this object is recycled across onLeave calls, so do not store and use it outside your callback. Make a deep copy if you need to store the contained value, e.g.: ptr(retval.toString()).
    onLeave(retval):给定一个参数 retval 的回调函数,该参数是包含原始返回值的 NativePointer 派生对象。您可以调用 retval.replace(1337) 将返回值替换为整数 1337,或调用 retval.replace(ptr("0x1234")) 以替换为指针。请注意,此对象在 onLeave 调用中循环使用,因此请勿在回调之外存储和使用它。如果需要存储包含的值,请进行深层复制,例如:ptr(retval.toString())。

In case the hooked function is very hot, onEnter and onLeave may be NativePointer values pointing at native C functions compiled using CModule. Their signatures are:
如果挂钩函数非常热,则 onEnter 和 onLeave 可能是指向使用 CModule 编译的本机 C 函数的 NativePointer 值。他们的签名是:

    void onEnter (GumInvocationContext * ic)

    void onLeave (GumInvocationContext * ic)

In such cases, the third optional argument data may be a NativePointer accessible through gum_invocation_context_get_listener_function_data().
在这种情况下,第三个可选参数 data 可能是可通过 gum_invocation_context_get_listener_function_data() 访问的 NativePointer。

You may also intercept arbitrary instructions by passing a function instead of the callbacks object. This function has the same signature as onEnter, but the args argument passed to it will only give you sensible values if the intercepted instruction is at the beginning of a function or at a point where registers/stack have not yet deviated from that point.
您还可以通过传递函数而不是 callbacks 对象来拦截任意指令。此函数具有与 onEnter 相同的签名,但传递给它的 args 参数只有在截获的指令位于函数的开头或寄存器/堆栈尚未偏离该点时才会为您提供合理的值。

Just like above, this function may also be implemented in C by specifying a NativePointer instead of a function.
就像上面一样,这个函数也可以通过指定一个 NativePointer 而不是一个函数来实现 C。

Returns a listener object that you can call detach() on.
返回一个侦听器对象,您可以在其上调用 detach()。

Note that these functions will be invoked with this bound to a per-invocation (thread-local) object where you can store arbitrary data, which is useful if you want to read an argument in onEnter and act on it in onLeave.
请注意,这些函数将在 this 绑定到每个调用(线程本地)对象的情况下调用,您可以在其中存储任意数据,如果您想读取 onEnter 中的参数并在 onLeave 中对其进行操作,这将非常有用。

For example: 例如:

Interceptor.attach(Module.getExportByName(‘libc.so’, ‘read’), {
onEnter(args) {
this.fileDescriptor = args[0].toInt32();
},
onLeave(retval) {
if (retval.toInt32() > 0) {
/* do something with this.fileDescriptor */
}
}
});

Additionally, the object contains some useful properties:
此外,该对象还包含一些有用的属性:

    returnAddress: return address as a NativePointer
    returnAddress:以 NativePointer 形式返回地址

    context: object with the keys pc and sp, which are NativePointer objects specifying EIP/RIP/PC and ESP/RSP/SP, respectively, for ia32/x64/arm. Other processor-specific keys are also available, e.g. eax, rax, r0, x0, etc. You may also update register values by assigning to these keys.
    context:键为 pc 和 sp 的对象,它们是 NativePointer 对象,分别为 ia32/x64/arm 指定 EIP/RIP/PC 和 ESP/RSP/SP。其他特定于处理器的键也可用,例如 eax、rax、r0、x0 等。您还可以通过分配给这些键来更新寄存器值。

    errno: (UNIX) current errno value (you may replace it)
    errno: (UNIX) 当前 errno 值(您可以替换它)

    lastError: (Windows) current OS error value (you may replace it)
    lastError:(Windows)当前操作系统错误值(您可以替换它)

    threadId: OS thread ID threadId:操作系统线程 ID

    depth: call depth of relative to other invocations
    depth:相对于其他调用的调用深度

For example: 例如:

Interceptor.attach(Module.getExportByName(null, ‘read’), {
onEnter(args) {
console.log(‘Context information:’);
console.log('Context : ’ + JSON.stringify(this.context));
console.log('Return : ’ + this.returnAddress);
console.log('ThreadId : ’ + this.threadId);
console.log('Depth : ’ + this.depth);
console.log('Errornr : ’ + this.err);

// Save arguments for processing in onLeave.
this.fd = args[0].toInt32();
this.buf = args[1];
this.count = args[2].toInt32();

},
onLeave(result) {
console.log(‘----------’)
// Show argument 1 (buf), saved during onEnter.
const numBytes = result.toInt32();
if (numBytes > 0) {
console.log(hexdump(this.buf, { length: numBytes, ansi: true }));
}
console.log('Result : ’ + numBytes);
}
})

Performance considerations 性能注意事项


性能注意事项)

The callbacks provided have a significant impact on performance. If you only need to inspect arguments but do not care about the return value, or the other way around, make sure you omit the callback that you don’t need; i.e. avoid putting your logic in onEnter and leaving onLeave in there as an empty callback.
提供的回调对性能有重大影响。如果你只需要检查参数,而不关心返回值,或者相反,请确保省略不需要的回调;即避免将逻辑放在 onEnter 中并将 onLeave 作为空回调留在那里。

On an iPhone 5S the base overhead when providing just onEnter might be something like 6 microseconds, and 11 microseconds with both onEnter and onLeave provided.
在 iPhone 5S 上,仅提供 onEnter 时的基本开销可能约为 6 微秒,同时提供 onEnter 和 onLeave 时为 11 微秒。

Also be careful about intercepting calls to functions that are called a bazillion times per second; while send() is asynchronous, the total overhead of sending a single message is not optimized for high frequencies, so that means Frida leaves it up to you to batch multiple values into a single send()-call, based on whether low delay or high throughput is desired.
还要小心截获对称为每秒数亿次的函数的调用;虽然 send() 是异步的,但发送单条消息的总开销并未针对高频进行优化,因此这意味着 Frida 将多个值批处理到单个 send() 调用中,具体取决于是需要低延迟还是高吞吐量。

However when hooking hot functions you may use Interceptor in conjunction with CModule to implement the callbacks in C.
但是,在挂钩热函数时,可以将 Interceptor 与 CModule 结合使用,以实现 C 中的回调。

Interceptor.detachAll(): detach all previously attached callbacks.
Interceptor.detachAll():分离所有先前附加的回调。

Interceptor.replace(target, replacement[, data]): replace function at target with implementation at replacement. This is typically used if you want to fully or partially replace an existing function’s implementation.
Interceptor.replace(target, replacement[, data]):将 target 中的函数替换为 replacement 中的实现。如果要完全或部分替换现有函数的实现,通常使用此方法。

Use NativeCallback to implement a replacement in JavaScript.
使用 NativeCallback 在 JavaScript 中实现 replacement。

In case the replaced function is very hot, you may implement replacement in C using CModule. You may then also specify the third optional argument data, which is a NativePointer accessible through gum_invocation_context_get_listener_function_data(). Use gum_interceptor_get_current_invocation() to get hold of the GumInvocationContext *.
如果替换的函数非常热,您可以使用 CModule 在 C 中实现 replacement。然后,您还可以指定第三个可选参数 data,该参数是通过 gum_invocation_context_get_listener_function_data() 访问的 NativePointer。使用 gum_interceptor_get_current_invocation() 获取 GumInvocationContext *。

Note that replacement will be kept alive until Interceptor#revert is called.
请注意,在调用 Interceptor#revert 之前,replacement 将保持活动状态。

If you want to chain to the original implementation you can synchronously call target through a NativeFunction inside your implementation, which will bypass and go directly to the original implementation.
如果要链接到原始实现,可以通过实现中的 NativeFunction 同步调用 target,这将绕过并直接转到原始实现。

Here’s an example: 下面是一个示例:

const openPtr = Module.getExportByName(‘libc.so’, ‘open’);
const open = new NativeFunction(openPtr, ‘int’, [‘pointer’, ‘int’]);
Interceptor.replace(openPtr, new NativeCallback((pathPtr, flags) => {
const path = pathPtr.readUtf8String();
log(‘Opening "’ + path + ‘"’);
const fd = open(pathPtr, flags);
log('Got fd: ’ + fd);
return fd;
}, ‘int’, [‘pointer’, ‘int’]));

Interceptor.revert(target): revert function at target to the previous implementation.
Interceptor.revert(target):将 target 处的函数恢复到之前的实现。

Interceptor.flush(): ensure any pending changes have been committed to memory. This is should only be done in the few cases where this is necessary, e.g. if you just attach()ed to or replace()d a function that you are about to call using NativeFunction. Pending changes are flushed automatically whenever the current thread is about to leave the JavaScript runtime or calls send(). This includes any API built on top of send(), like when returning from an RPC method, and calling any method on the console API.
Interceptor.flush():确保任何挂起的更改都已提交到内存中。只有在少数必要的情况下才应该这样做,例如,如果您只是将 attach()ed 或替换 ()d 您将要使用 NativeFunction 调用的函数。每当当前线程即将离开 JavaScript 运行时或调用 send() 时,挂起的更改都会自动刷新。这包括基于 send() 构建的任何 API,例如从 RPC 方法返回时,以及在控制台 API 上调用任何方法时。

Interceptor.breakpointKind: a string specifying the kind of breakpoints to use for non-inline hooks. Only available in the Barebone backend.
Interceptor.breakpointKind:指定用于非内联挂钩的断点类型的字符串。仅在准系统后端可用。

Defaults to ‘soft’, i.e. software breakpoints. Set it to ‘hard’ to use hardware breakpoints.
默认为“软”,即软件断点。将其设置为“硬”以使用硬件断点。

Stalker 跟踪

Stalker.exclude(range): marks the specified memory range as excluded, which is an object with base and size properties – like the properties in an object returned by e.g. Process.getModuleByName().
Stalker.exclude(range):将指定的内存 range 标记为 excluded,这是一个具有 base 和 size 属性的对象——类似于 Process.getModuleByName() 返回的对象中的属性。

This means Stalker will not follow execution when encountering a call to an instruction in such a range. You will thus be able to observe/modify the arguments going in, and the return value coming back, but won’t see the instructions that happened between.
这意味着 Stalker 在遇到对此类范围内指令的调用时不会遵循执行。因此,您将能够观察/修改输入的参数,以及返回的返回值,但不会看到两者之间发生的指令。

Useful to improve performance and reduce noise.
有助于提高性能和降低噪音。

Stalker.follow([threadId, options]): start stalking threadId (or the current thread if omitted), optionally with options for enabling events.
Stalker.follow([threadId, options]):开始跟踪 threadId(如果省略,则跟踪当前线程),可选使用 options 启用事件。

For example: 例如:

const mainThread = Process.enumerateThreads()[0];

Stalker.follow(mainThread.id, {
events: {
call: true, // CALL instructions: yes please

// Other events:
ret: false, // RET instructions
exec: false, // all instructions: not recommended as it's
             //                   a lot of data
block: false, // block executed: coarse execution trace
compile: false // block compiled: useful for coverage

},

//
// Only specify one of the two following callbacks.
// (See note below.)
//

//
// onReceive: Called with events containing a binary blob
// comprised of one or more GumEvent structs.
// See gumevent.h for details about the
// format. Use Stalker.parse() to examine the
// data.
//
//onReceive(events) {
//},
//

//
// onCallSummary: Called with summary being a key-value
// mapping of call target to number of
// calls, in the current time window. You
// would typically implement this instead of
// onReceive() for efficiency, i.e. when
// you only want to know which targets were
// called and how many times, but don’t care
// about the order that the calls happened
// in.
//
onCallSummary(summary) {
},

//
// Advanced users: This is how you can plug in your own
// StalkerTransformer, where the provided
// function is called synchronously
// whenever Stalker wants to recompile
// a basic block of the code that’s about
// to be executed by the stalked thread.
//
//transform(iterator) {
// let instruction = iterator.next();
//
// const startAddress = instruction.address;
// const isAppCode = startAddress.compare(appStart) >= 0 &&
// startAddress.compare(appEnd) === -1;
//
// /*
// * Need to be careful on ARM/ARM64 as we may disturb instruction sequences
// * that deal with exclusive stores.
// */
// const canEmitNoisyCode = iterator.memoryAccess === ‘open’;
//
// do {
// if (isAppCode && canEmitNoisyCode && instruction.mnemonic === ‘ret’) {
// iterator.putCmpRegI32(‘eax’, 60);
// iterator.putJccShortLabel(‘jb’, ‘nope’, ‘no-hint’);
//
// iterator.putCmpRegI32(‘eax’, 90);
// iterator.putJccShortLabel(‘ja’, ‘nope’, ‘no-hint’);
//
// iterator.putCallout(onMatch);
//
// iterator.putLabel(‘nope’);
// }
//
// iterator.keep();
// } while ((instruction = iterator.next()) !== null);
//},
//
// The default implementation is just:
//
// while (iterator.next() !== null)
// iterator.keep();
//
// The example above shows how you can insert your own code
// just before every ret instruction across any code
// executed by the stalked thread inside the app’s own
// memory range. It inserts code that checks if the eax
// register contains a value between 60 and 90, and inserts
// a synchronous callout back into JavaScript whenever that
// is the case. The callback receives a single argument
// that gives it access to the CPU registers, and it is
// also able to modify them.
//
// function onMatch (context) {
// console.log(‘Match! pc=’ + context.pc +
// ’ rax=’ + context.rax.toInt32());
// }
//
// Note that not calling keep() will result in the
// instruction getting dropped, which makes it possible
// for your transform to fully replace certain instructions
// when this is desirable.
//

//
// Want better performance? Write the callbacks in C:
//
// /*
// * const cm = new CModule(`
// *
// * #include <gum/gumstalker.h>
// *
// * static void on_ret (GumCpuContext * cpu_context,
// * gpointer user_data);
// *
// * void
// * transform (GumStalkerIterator * iterator,
// * GumStalkerOutput * output,
// * gpointer user_data)
// * {
// * cs_insn * insn;
// *
// * while (gum_stalker_iterator_next (iterator, &insn))
// * {
// * if (insn->id == X86_INS_RET)
// * {
// * gum_x86_writer_put_nop (output->writer.x86);
// * gum_stalker_iterator_put_callout (iterator,
// * on_ret, NULL, NULL);
// * }
// *
// * gum_stalker_iterator_keep (iterator);
// * }
// * }
// *
// * static void
// * on_ret (GumCpuContext * cpu_context,
// * gpointer user_data)
// * {
// * printf (“on_ret!\n”);
// * }
// *
// * void
// * process (const GumEvent * event,
// * GumCpuContext * cpu_context,
// * gpointer user_data)
// * {
// * switch (event->type)
// * {
// * case GUM_CALL:
// * break;
// * case GUM_RET:
// * break;
// * case GUM_EXEC:
// * break;
// * case GUM_BLOCK:
// * break;
// * case GUM_COMPILE:
// * break;
// * default:
// * break;
// * }
// * }
// * `);
// /
//
//transform: cm.transform,
//onEvent: cm.process,
//data: ptr(1337) /
user_data */
//
// You may also use a hybrid approach and only write
// some of the callouts in C.
//
});

Performance considerations
性能注意事项

The callbacks provided have a significant impact on performance. If you only need periodic call summaries but do not care about the raw events, or the other way around, make sure you omit the callback that you don’t need; i.e. avoid putting your logic in onCallSummary and leaving onReceive in there as an empty callback.
提供的回调对性能有重大影响。如果您只需要定期调用摘要,但不关心原始事件,或者相反,请确保省略不需要的回调;即避免将逻辑放在 onCallSummary 中并将 onReceive 作为空回调留在那里。

Also note that Stalker may be used in conjunction with CModule, which means the callbacks may be implemented in C.
另请注意,Stalker 可以与 CModule 结合使用,这意味着回调可以在 C 中实现。

Stalker.unfollow([threadId]): stop stalking threadId (or the current thread if omitted).
Stalker.unfollow([threadId]):停止跟踪 threadId(如果省略,则停止跟踪当前线程)。

Stalker.parse(events[, options]): parse GumEvent binary blob, optionally with options for customizing the output.
Stalker.parse(events[, options]):解析 GumEvent 二进制 blob,可选使用 options 来自定义输出。

For example: 例如:

onReceive(events) {
console.log(Stalker.parse(events, {
annotate: true, // to display the type of event
stringify: true
// to format pointer values as strings instead of NativePointer
// values, i.e. less overhead if you’re just going to send() the
// thing not actually parse the data agent-side
}));
},

Stalker.flush(): flush out any buffered events. Useful when you don’t want to wait until the next Stalker.queueDrainInterval tick.
Stalker.flush():清除所有缓冲事件。当您不想等到下一个 Stalker.queueDrainInterval 勾选时很有用。

Stalker.garbageCollect(): free accumulated memory at a safe point after Stalker#unfollow. This is needed to avoid race-conditions where the thread just unfollowed is executing its last instructions.
Stalker.garbageCollect():在Stalker#unfollow之后的安全点释放累积的内存。这是为了避免刚刚取消关注的线程正在执行其最后一条指令的争用条件。

Stalker.invalidate(address): invalidates the current thread’s translated code for a given basic block. Useful when providing a transform callback and wanting to dynamically adapt the instrumentation for a given basic block. This is much more efficient than unfollowing and re-following the thread, which would discard all cached translations and require all encountered basic blocks to be compiled from scratch.
Stalker.invalidate(address):使给定基本块的当前线程的转换代码无效。在提供转换回调并希望针对给定的基本块动态调整检测时非常有用。这比取消关注和重新关注线程要有效得多,后者将丢弃所有缓存的翻译,并要求从头开始编译所有遇到的基本块。

Stalker.invalidate(threadId, address): invalidates a specific thread’s translated code for a given basic block. Useful when providing a transform callback and wanting to dynamically adapt the instrumentation for a given basic block. This is much more efficient than unfollowing and re-following the thread, which would discard all cached translations and require all encountered basic blocks to be compiled from scratch.
Stalker.invalidate(threadId, address):使给定基本块的特定线程的翻译代码无效。在提供转换回调并希望针对给定的基本块动态调整检测时非常有用。这比取消关注和重新关注线程要有效得多,后者将丢弃所有缓存的翻译,并要求从头开始编译所有遇到的基本块。

Stalker.addCallProbe(address, callback[, data]): call callback (see Interceptor#attach#onEnter for signature) synchronously when a call is made to address. Returns an id that can be passed to Stalker#removeCallProbe later.
Stalker.addCallProbe(address, callback[, data]):当调用 address 时同步调用 callback(参见 Interceptor#attach#onEnter 进行签名)。返回一个 id,稍后可以传递给 Stalker#removeCallProbe。

It is also possible to implement callback in C using CModule, by specifying a NativePointer instead of a function. Signature:
也可以使用 CModule 在 C 语言中通过指定 NativePointer 而不是函数来实现 callback。签名:
    void onCall (GumCallSite * site, gpointer user_data)

In such cases, the third optional argument data may be a NativePointer whose value is passed to the callback as user_data.
在这种情况下,第三个可选参数 data 可能是 NativePointer,其值作为 user_data 传递给回调。

Stalker.removeCallProbe: remove a call probe added by Stalker#addCallProbe.
Stalker.removeCallProbe:删除 Stalker#addCallProbe 添加的呼叫探测。

Stalker.trustThreshold: an integer specifying how many times a piece of code needs to be executed before it is assumed it can be trusted to not mutate. Specify -1 for no trust (slow), 0 to trust code from the get-go, and N to trust code after it has been executed N times. Defaults to 1.
Stalker.trustThreshold:一个整数,指定一段代码需要执行多少次才能假定它可以被信任为不会变异。指定 -1 表示不信任(慢速),0 表示从一开始就信任代码,N 表示执行 N 次后的信任代码。默认值为 1。

Stalker.queueCapacity: an integer specifying the capacity of the event queue in number of events. Defaults to 16384 events.
Stalker.queueCapacity:一个整数,指定事件队列的容量(以事件数为单位)。默认为 16384 个事件。

Stalker.queueDrainInterval: an integer specifying the time in milliseconds between each time the event queue is drained. Defaults to 250 ms, which means that the event queue is drained four times per second. You may also set this property to zero to disable periodic draining, and instead call Stalker.flush() when you would like the queue to be drained.
Stalker.queueDrainInterval:一个整数,指定每次耗尽事件队列之间的时间(以毫秒为单位)。默认值为 250 毫秒,这意味着事件队列每秒耗尽四次。您也可以将此属性设置为零以禁用定期排空,并在希望排空队列时调用 Stalker.flush()。

ObjC

ObjC.available: a boolean specifying whether the current process has an Objective-C runtime loaded. Do not invoke any other ObjC properties or methods unless this is the case.
ObjC.available:一个布尔值,指定当前进程是否加载了 Objective-C 运行时。除非是这种情况,否则不要调用任何其他 ObjC 属性或方法。

ObjC.api: an object mapping function names to NativeFunction instances for direct access to a big portion of the Objective-C runtime API.
ObjC.api:将函数名称映射到 NativeFunction 实例的对象,用于直接访问 Objective-C 运行时 API 的大部分内容。

ObjC.classes: an object mapping class names to ObjC.Object JavaScript bindings for each of the currently registered classes. You can interact with objects by using dot notation and replacing colons with underscores, i.e.: [NSString stringWithString:@"Hello World"] becomes const { NSString } = ObjC.classes; NSString.stringWithString_("Hello World");. Note the underscore after the method name. Refer to iOS Examples section for more details.
ObjC.classes:将类名映射到每个当前注册的类的 ObjC.Object JavaScript 绑定的对象。您可以通过使用点表示法并将冒号替换为下划线来与对象进行交互,即:[NSString stringWithString:@"Hello World"] 变为 const { NSString } = ObjC.classes; NSString.stringWithString_("Hello World");。请注意方法名称后面的下划线。有关详细信息,请参阅 iOS 示例部分。

ObjC.protocols: an object mapping protocol names to ObjC.Protocol JavaScript bindings for each of the currently registered protocols.
ObjC.protocols:将协议名称映射到每个当前注册协议的 ObjC.Protocol JavaScript 绑定的对象。

ObjC.mainQueue: the GCD queue of the main thread
ObjC.mainQueue:主线程的 GCD 队列

ObjC.schedule(queue, work): schedule the JavaScript function work on the GCD queue specified by queue. An NSAutoreleasePool is created just before calling work, and cleaned up on return.
ObjC.schedule(queue, work):在 queue 指定的 GCD 队列上调度 JavaScript 函数 work。在调用 work 之前创建一个 NSAutoreleasePool,并在返回时进行清理。

const { NSSound } = ObjC.classes; /* macOS */
ObjC.schedule(ObjC.mainQueue, () => {
const sound = NSSound.alloc().initWithContentsOfFile_byReference_(“/Users/oleavr/.Trash/test.mp3”, true);
sound.play();
});

new ObjC.Object(handle[, protocol]): create a JavaScript binding given the existing object at handle (a NativePointer). You may also specify the protocol argument if you’d like to treat handle as an object implementing a certain protocol only.
new ObjC.Object(handle[, protocol]):在给定 handle 处的现有对象(NativePointer)创建 JavaScript 绑定。如果要将 handle 视为仅实现特定协议的对象,也可以指定 protocol 参数。

Interceptor.attach(myFunction.implementation, {
onEnter(args) {
// ObjC: args[0] = self, args[1] = selector, args[2-n] = arguments
const myString = new ObjC.Object(args[2]);
console.log("String argument: " + myString.toString());
}
});

This object has some special properties:
此对象具有一些特殊属性:

    $kind: string specifying either instance, class or meta-class
    $kind:指定 instance、class 或 meta-class 的字符串
    $super: an ObjC.Object instance used for chaining up to super-class method implementations
    $super:用于链接到超类方法实现的 ObjC.Object 实例
    $superClass: super-class as an ObjC.Object instance
    $superClass:作为 ObjC.Object 实例的超类
    $class: class of this object as an ObjC.Object instance
    $class:此对象作为 ObjC.Object 实例的类
    $className: string containing the class name of this object
    $className:包含此对象的类名的字符串
    $moduleName: string containing the module path of this object
    $moduleName:包含此对象的模块路径的字符串
    $protocols: object mapping protocol name to ObjC.Protocol instance for each of the protocols that this object conforms to
    $protocols:将对象映射协议名称映射到此对象符合的每个协议的 ObjC.Protocol 实例
    $methods: array containing native method names exposed by this object’s class and parent classes
    $methods:包含此对象的类和父类公开的本机方法名称的数组
    $ownMethods: array containing native method names exposed by this object’s class, not including parent classes
    $ownMethods:包含此对象的类公开的本机方法名称的数组,不包括父类
    $ivars: object mapping each instance variable name to its current value, allowing you to read and write each through access and assignment
    $ivars:对象将每个实例变量名称映射到其当前值,允许您通过访问和分配来读取和写入每个实例

There is also an equals(other) method for checking whether two instances refer to the same underlying object.
还有一个 equals(other) 方法用于检查两个实例是否引用相同的底层对象。

Note that all method wrappers provide a clone(options) API to create a new method wrapper with custom NativeFunction options.
请注意,所有方法包装器都提供 clone(options) API 来创建具有自定义 NativeFunction 选项的新方法包装器。

new ObjC.Protocol(handle): create a JavaScript binding given the existing protocol at handle (a NativePointer).
new ObjC.Protocol(handle):在 handle 处给定现有协议(NativePointer)创建一个 JavaScript 绑定。

new ObjC.Block(target[, options]): create a JavaScript binding given the existing block at target (a NativePointer), or, to define a new block, target should be an object specifying the type signature and JavaScript function to call whenever the block is invoked. The function is specified with an implementation key, and the signature is specified either through a types key, or through the retType and argTypes keys. See ObjC.registerClass() for details.
new ObjC.Block(target[, options]):在 target 处给定现有块(NativePointer)创建一个 JavaScript 绑定,或者,要定义新块,target 应该是一个对象,指定在调用块时要调用的类型签名和 JavaScript 函数。该函数使用 implementation 键指定,签名通过 types 键或通过 retType 和 argTypes 键指定。有关详细信息,请参见 ObjC.registerClass()。

Note that if an existing block lacks signature metadata, you may call declare(signature), where signature is an object with either a types key, or retType and argTypes keys, as described above.
请注意,如果现有块缺少签名元数据,则可以调用 declare(signature),其中 signature 是具有 types 键或 retType 和 argTypes 键的对象,如上所述。

You may also provide an options object with the same options as supported by NativeFunction, e.g. to pass traps: 'all' in order to Stalker.follow() the execution when calling the block.
您还可以提供一个 options 对象,其中包含与 NativeFunction 支持的相同选项,例如,在调用块时将执行传递 traps: 'all' 以便执行 Stalker.follow()。

The most common use-case is hooking an existing block, which for a block expecting two arguments would look something like:
最常见的用例是挂钩现有块,对于需要两个参数的块,它看起来像这样:

const pendingBlocks = new Set();

Interceptor.attach(…, {
onEnter(args) {
const block = new ObjC.Block(args[4]);
pendingBlocks.add(block); // Keep it alive
const appCallback = block.implementation;
block.implementation = (error, value) => {
// Do your logging here
const result = appCallback(error, value);
pendingBlocks.delete(block);
return result;
};
}
});

ObjC.implement(method, fn): create a JavaScript implementation compatible with the signature of method, where the JavaScript function fn is used as the implementation. Returns a NativeCallback that you may assign to an ObjC method’s implementation property.
ObjC.implement(method, fn):创建一个与 method 签名兼容的 JavaScript 实现,其中使用 JavaScript 函数 fn 作为实现。返回一个 NativeCallback,您可以将其分配给 ObjC 方法的 implementation 属性。

const NSSound = ObjC.classes.NSSound; /* macOS */
const oldImpl = NSSound.play.implementation;
NSSound.play.implementation = ObjC.implement(NSSound.play, (handle, selector) => {
return oldImpl(handle, selector);
});

const NSView = ObjC.classes.NSView; /* macOS */
const drawRect = NSView[‘- drawRect:’];
const oldImpl = drawRect.implementation;
drawRect.implementation = ObjC.implement(drawRect, (handle, selector) => {
oldImpl(handle, selector);
});

As the implementation property is a NativeFunction and thus also a NativePointer, you may also use Interceptor to hook functions:
由于 implementation 属性是 NativeFunction,因此也是 NativePointer,因此也可以使用 Interceptor 来挂钩函数:

const { NSSound } = ObjC.classes; /* macOS */
Interceptor.attach(NSSound.play.implementation, {
onEnter() {
send(“[NSSound play]”);
}
});

ObjC.registerProxy(properties): create a new class designed to act as a proxy for a target object, where properties is an object specifying:
ObjC.registerProxy(properties):创建一个新类,旨在充当目标对象的代理,其中 properties 是一个指定:
    protocols: (optional) Array of protocols this class conforms to.
    protocols:(可选)此类符合的协议数组。
    methods: (optional) Object specifying methods to implement.
    methods:(可选)指定要实现的方法的对象。
    events: (optional) Object specifying callbacks for getting notified about events:
        dealloc(): Called right after the object has been deallocated. This is where you might clean up any associated state.
        dealloc():在解除分配对象后立即调用。您可以在此处清理任何关联的状态。
        forward(name): Called with name specifying the method name that we’re about to forward a call to. This might be where you’d start out with a temporary callback that just logs the names to help you decide which methods to override.
        forward(name):使用 name 调用,指定我们将要转发调用的方法名称。这可能是你从临时回调开始的地方,该回调只记录名称,以帮助你决定重写哪些方法。

const MyConnectionDelegateProxy = ObjC.registerProxy({
protocols: [ObjC.protocols.NSURLConnectionDataDelegate],
methods: {
‘- connection:didReceiveResponse:’: function (conn, resp) {
/* fancy logging code here /
/
this.data.foo === 1234 /
this.data.target
.connection_didReceiveResponse_(conn, resp);
},
‘- connection:didReceiveData:’: function (conn, data) {
/
other logging code here /
this.data.target
.connection_didReceiveData_(conn, data);
}
},
events: {
forward(name) {
console.log('
** forwarding: ’ + name);
}
}
});

const method = ObjC.classes.NSURLConnection[
‘- initWithRequest:delegate:startImmediately:’];
Interceptor.attach(method.implementation, {
onEnter(args) {
args[3] = new MyConnectionDelegateProxy(args[3], {
foo: 1234
});
}
});

ObjC.registerClass(properties): create a new Objective-C class, where properties is an object specifying:
ObjC.registerClass(properties):创建一个新的 Objective-C 类,其中 properties 是一个对象,指定:
    name: (optional) String specifying the name of the class; omit this if you don’t care about the globally visible name and would like the runtime to auto-generate one for you.
    name:(可选)指定类名的字符串;如果您不关心全局可见的名称,并希望运行时为您自动生成一个名称,请省略此名称。
    super: (optional) Super-class, or null to create a new root class; omit to inherit from NSObject.
    super:(可选)Super-class,或 null 创建新的根类;省略从 NSObject 继承。
    protocols: (optional) Array of protocols this class conforms to.
    protocols:(可选)此类符合的协议数组。
    methods: (optional) Object specifying methods to implement.
    methods:(可选)指定要实现的方法的对象。

const MyConnectionDelegateProxy = ObjC.registerClass({
name: ‘MyConnectionDelegateProxy’,
super: ObjC.classes.NSObject,
protocols: [ObjC.protocols.NSURLConnectionDataDelegate],
methods: {
‘- init’: function () {
const self = this.super.init();
if (self !== null) {
ObjC.bind(self, {
foo: 1234
});
}
return self;
},
‘- dealloc’: function () {
ObjC.unbind(this.self);
this.super.dealloc();
},
‘- connection:didReceiveResponse:’: function (conn, resp) {
/* this.data.foo === 1234 /
},
/

* But those previous methods are declared assuming that
* either the super-class or a protocol we conform to has
* the same method so we can grab its type information.
* However, if that’s not the case, you would write it
* like this:
/
‘- connection:didReceiveResponse:’: {
retType: ‘void’,
argTypes: [‘object’, ‘object’],
implementation(conn, resp) {
}
},
/
Or grab it from an existing class: /
‘- connection:didReceiveResponse:’: {
types: ObjC.classes
.Foo[‘- connection:didReceiveResponse:’].types,
implementation(conn, resp) {
}
},
/
Or from an existing protocol: /
‘- connection:didReceiveResponse:’: {
types: ObjC.protocols.NSURLConnectionDataDelegate
.methods[‘- connection:didReceiveResponse:’].types,
implementation(conn, resp) {
}
},
/
Or write the signature by hand if you really want to: */
‘- connection:didReceiveResponse:’: {
types: ‘v32@0:8@16@24’,
implementation(conn, resp) {
}
}
}
});

const proxy = MyConnectionDelegateProxy.alloc().init();
/* use proxy, and later: */
proxy.release();

ObjC.registerProtocol(properties): create a new Objective-C protocol, where properties is an object specifying:
ObjC.registerProtocol(properties):创建一个新的 Objective-C 协议,其中 properties 是一个对象,指定:
    name: (optional) String specifying the name of the protocol; omit this if you don’t care about the globally visible name and would like the runtime to auto-generate one for you.
    name:(可选)指定协议名称的字符串;如果您不关心全局可见的名称,并希望运行时为您自动生成一个名称,请省略此名称。
    protocols: (optional) Array of protocols this protocol incorporates.
    protocols:(可选)此协议包含的协议数组。
    methods: (optional) Object specifying methods to declare.
    methods:(可选)指定要声明的方法的对象。

const MyDataDelegate = ObjC.registerProtocol({
name: ‘MyDataDelegate’,
protocols: [ObjC.protocols.NSURLConnectionDataDelegate],
methods: {
/* You must specify the signature: /
‘- connection:didStuff:’: {
retType: ‘void’,
argTypes: [‘object’, ‘object’]
},
/
Or grab it from a method of an existing class: /
‘- connection:didStuff:’: {
types: ObjC.classes
.Foo[‘- connection:didReceiveResponse:’].types
},
/
Or from an existing protocol method: /
‘- connection:didStuff:’: {
types: ObjC.protocols.NSURLConnectionDataDelegate
.methods[‘- connection:didReceiveResponse:’].types
},
/
Or write the signature by hand if you really want to: /
‘- connection:didStuff:’: {
types: ‘v32@0:8@16@24’
},
/
You can also make a method optional (default is required): */
‘- connection:didStuff:’: {
retType: ‘void’,
argTypes: [‘object’, ‘object’],
optional: true
}
}
});

ObjC.bind(obj, data): bind some JavaScript data to an Objective-C instance; see ObjC.registerClass() for an example.
ObjC.bind(obj, data):将一些 JavaScript 数据绑定到 Objective-C 实例;有关示例,请参阅 ObjC.registerClass()。

ObjC.unbind(obj): unbind previous associated JavaScript data from an Objective-C instance; see ObjC.registerClass() for an example.
ObjC.unbind(obj):从 Objective-C 实例中解绑先前关联的 JavaScript 数据;有关示例,请参阅 ObjC.registerClass()。

ObjC.getBoundData(obj): look up previously bound data from an Objective-C object.
ObjC.getBoundData(obj):从 Objective-C 对象中查找以前绑定的数据。

ObjC.enumerateLoadedClasses([options, ]callbacks): enumerate classes loaded right now, where callbacks is an object specifying:
ObjC.enumerateLoadedClasses([options, ]callbacks):枚举当前加载的类,其中 callbacks 是一个对象,指定:

    onMatch(name, owner): called for each loaded class with the name of the class as a string, and owner specifying the path to the module where the class was loaded from. To obtain a JavaScript wrapper for a given class, do: ObjC.classes[name].
    onMatch(name, owner):使用类的 name 作为字符串为每个加载的类调用,owner 指定从中加载类的模块的路径。要获取给定类的 JavaScript 包装器,请执行以下操作:ObjC.classes[name]。

    onComplete(): called when all classes have been enumerated.
    onComplete():枚举所有类时调用。

For example: 例如:

ObjC.enumerateLoadedClasses({
onMatch(name, owner) {
console.log(‘onMatch:’, name, owner);
},
onComplete() {
}
});

The optional options argument is an object where you may specify the ownedBy property to limit enumeration to modules in a given ModuleMap.
可选的 options 参数是一个对象,您可以在其中指定 ownedBy 属性以将枚举限制为给定 ModuleMap 中的模块。

For example: 例如:

const appModules = new ModuleMap(isAppModule);
ObjC.enumerateLoadedClasses({ ownedBy: appModules }, {
onMatch(name, owner) {
console.log(‘onMatch:’, name, owner);
},
onComplete() {
}
});

function isAppModule(m) {
return !/^/(usr/lib|System|Developer)//.test(m.path);
}

ObjC.enumerateLoadedClassesSync([options]): synchronous version of enumerateLoadedClasses() that returns an object mapping owner module to an array of class names.
ObjC.enumerateLoadedClassesSync([options]):enumerateLoadedClasses() 的同步版本,用于将对象映射所有者模块返回到类名数组。

For example: 例如:

const appModules = new ModuleMap(isAppModule);
const appClasses = ObjC.enumerateLoadedClassesSync({ ownedBy: appModules });
console.log(‘appClasses:’, JSON.stringify(appClasses));

function isAppModule(m) {
return !/^/(usr/lib|System|Developer)//.test(m.path);
}

ObjC.choose(specifier, callbacks): enumerate live instances of classes matching specifier by scanning the heap. specifier is either a class selector or an object specifying a class selector and desired options. The class selector is an ObjC.Object of a class, e.g. ObjC.classes.UIButton. When passing an object as the specifier you should provide the class field with your class selector, and the subclasses field with a boolean indicating whether you’re also interested in subclasses matching the given class selector. The default is to also include subclasses. The callbacks argument is an object specifying:
ObjC.choose(specifier, callbacks):通过扫描堆来枚举与 specifier 匹配的类的实时实例。specifier 是类选择器或指定类选择器和所需选项的对象。类选择器是类的 ObjC.Object,例如 ObjC.classes.UIButton。将对象作为说明符传递时,应提供 class 字段和类选择器,以及 subclasses 字段,该布尔值指示您是否也对与给定类选择器匹配的子类感兴趣。默认设置是还包括子类。callbacks 参数是一个对象,用于指定:

    onMatch(instance): called once for each live instance found with a ready-to-use instance just as if you would have called new ObjC.Object(ptr("0x1234")) knowing that this particular Objective-C instance lives at 0x1234.
    onMatch(instance):为使用现成的 instance 找到的每个实时实例调用一次,就像您知道这个特定的 Objective-C 实例位于 0x1234 时调用新的 ObjC.Object(“0x1234”)一样。

    This function may return the string stop to cancel the enumeration early.
    此函数可能会返回字符串 stop 以提前取消枚举。

    onComplete(): called when all instances have been enumerated
    onComplete():枚举所有实例时调用

ObjC.chooseSync(specifier): synchronous version of choose() that returns the instances in an array.
ObjC.chooseSync(specifier):返回数组中实例的 choose() 的同步版本。

ObjC.selector(name): convert the JavaScript string name to a selector
ObjC.selector(name):将 JavaScript 字符串 name 转换为选择器

ObjC.selectorAsString(sel): convert the selector sel to a JavaScript string
ObjC.selectorAsString(sel):将选择器 sel 转换为 JavaScript 字符串

Java

Java.available: a boolean specifying whether the current process has the a Java VM loaded, i.e. Dalvik or ART. Do not invoke any other Java properties or methods unless this is the case.
Java.available:一个布尔值,指定当前进程是否加载了 Java VM,即 Dalvik 或 ART。除非是这种情况,否则不要调用任何其他 Java 属性或方法。

Java.androidVersion: a string specifying which version of Android we’re running on.
Java.androidVersion:一个字符串,指定我们运行的是哪个版本的 Android。

Java.enumerateLoadedClasses(callbacks): enumerate classes loaded right now, where callbacks is an object specifying:
Java.enumerateLoadedClasses(callbacks):枚举当前加载的类,其中 callbacks 是一个对象,指定:

    onMatch(name, handle): called for each loaded class with name that may be passed to use() to get a JavaScript wrapper. You may also Java.cast() the handle to java.lang.Class.
    onMatch(name, handle):用 name 为每个加载的类调用,可以传递给 use() 来获取 JavaScript 包装器。您也可以将 Java.cast() 的 handle 改为 java.lang.Class。

    onComplete(): called when all classes have been enumerated.

Java.enumerateLoadedClassesSync(): synchronous version of enumerateLoadedClasses() that returns the class names in an array.

Java.enumerateClassLoaders(callbacks): enumerate class loaders present in the Java VM, where callbacks is an object specifying:

    onMatch(loader): called for each class loader with loader, a wrapper for the specific java.lang.ClassLoader.

    onComplete(): called when all class loaders have been enumerated.

You may pass such a loader to Java.ClassFactory.get() to be able to .use() classes on the specified class loader.

Java.enumerateClassLoadersSync(): synchronous version of enumerateClassLoaders() that returns the class loaders in an array.

Java.enumerateMethods(query): enumerate methods matching query, specified as "class!method", with globs permitted. May also be suffixed with / and one or more modifiers:
Java.enumerateMethods(query):枚举匹配 query 的方法,指定为 "class!method",允许使用 glob。也可以用 / 和一个或多个修饰符作为后缀:
    i: Case-insensitive matching.
    i:不区分大小写的匹配。
    s: Include method signatures, so e.g. "putInt" becomes "putInt(java.lang.String, int): void".
    s:包括方法签名,例如 "putInt" 变为 "putInt(java.lang.String, int): void"。
    u: User-defined classes only, ignoring system classes.
    u:仅用户定义的类,忽略系统类。

Java.perform(() => {
const groups = Java.enumerateMethods(‘youtube!on*’)
console.log(JSON.stringify(groups, null, 2));
});

[
{
“loader”: “<instance: java.lang.ClassLoader, $className: dalvik.system.PathClassLoader>”,
“classes”: [
{
“name”: “com.google.android.apps.youtube.app.watch.nextgenwatch.ui.NextGenWatchLayout”,
“methods”: [
“onAttachedToWindow”,
“onDetachedFromWindow”,
“onFinishInflate”,
“onInterceptTouchEvent”,
“onLayout”,
“onMeasure”,
“onSizeChanged”,
“onTouchEvent”,
“onViewRemoved”
]
},
{
“name”: “com.google.android.apps.youtube.app.search.suggest.YouTubeSuggestionProvider”,
“methods”: [
“onCreate”
]
},
{
“name”: “com.google.android.libraries.youtube.common.ui.YouTubeButton”,
“methods”: [
“onInitializeAccessibilityNodeInfo”
]
},

]
}
]

Java.scheduleOnMainThread(fn): run fn on the main thread of the VM.
Java.scheduleOnMainThread(fn):在 VM 的主线程上运行 fn。

Java.perform(fn): ensure that the current thread is attached to the VM and call fn. (This isn’t necessary in callbacks from Java.) Will defer calling fn if the app’s class loader is not available yet. Use Java.performNow() if access to the app’s classes is not needed.
Java.perform(fn):确保当前线程已附加到 VM 并调用 fn。(这在来自 Java 的回调中不是必需的。如果应用的类加载器尚不可用,将延迟调用 fn。如果不需要访问应用程序的类,请使用 Java.performNow()。

Java.perform(() => {
const Activity = Java.use(‘android.app.Activity’);
Activity.onResume.implementation = function () {
send(‘onResume() got called! Let’s call the original implementation’);
this.onResume();
};
});

Java.performNow(fn): ensure that the current thread is attached to the VM and call fn. (This isn’t necessary in callbacks from Java.)
Java.performNow(fn):确保当前线程已附加到 VM 并调用 fn。(这在来自 Java 的回调中不是必需的。

Java.use(className): dynamically get a JavaScript wrapper for className that you can instantiate objects from by calling $new() on it to invoke a constructor. Call $dispose() on an instance to clean it up explicitly (or wait for the JavaScript object to get garbage-collected, or script to get unloaded). Static and non-static methods are available, and you can even replace a method implementation and throw an exception from it:
Java.use(className):动态获取 className 的 JavaScript 包装器,您可以通过在它上调用 $new() 来调用构造函数来实例化对象。在实例上调用 $dispose() 以显式清理它(或等待 JavaScript 对象被垃圾回收,或脚本被卸载)。静态和非静态方法可用,您甚至可以替换方法实现并从中引发异常:

Java.perform(() => {
const Activity = Java.use(‘android.app.Activity’);
const Exception = Java.use(‘java.lang.Exception’);
Activity.onResume.implementation = function () {
throw Exception.$new(‘Oh noes!’);
};
});

Uses the app’s class loader by default, but you may customize this by assigning a different loader instance to Java.classFactory.loader.
默认情况下使用应用的类加载器,但你可以通过将不同的加载器实例分配给 Java.classFactory.loader 来自定义。

Note that all method wrappers provide a clone(options) API to create a new method wrapper with custom NativeFunction options.
请注意,所有方法包装器都提供 clone(options) API 来创建具有自定义 NativeFunction 选项的新方法包装器。

Java.openClassFile(filePath): open the .dex file at filePath, returning an object with the following methods:
Java.openClassFile(filePath):打开 filePath 处的 .dex 文件,使用以下方法返回一个对象:

    load(): load the contained classes into the VM.
    load():将包含的类加载到 VM 中。

    getClassNames(): obtain an array of available class names.
    getClassNames():获取可用类名的数组。

Java.choose(className, callbacks): enumerate live instances of the className class by scanning the Java heap, where callbacks is an object specifying:
Java.choose(className, callbacks):通过扫描 Java 堆来枚举 className 类的实时实例,其中 callbacks 是一个对象,指定:

    onMatch(instance): called with each live instance found with a ready-to-use instance just as if you would have called Java.cast() with a raw handle to this particular instance.
    onMatch(instance):使用现成的 instance 找到的每个实时实例进行调用,就像使用此特定实例的原始句柄调用 Java.cast() 一样。

    This function may return the string stop to cancel the enumeration early.
    此函数可能会返回字符串 stop 以提前取消枚举。

    onComplete(): called when all instances have been enumerated
    onComplete():枚举所有实例时调用

Java.retain(obj): duplicates the JavaScript wrapper obj for later use outside replacement method.
Java.retain(obj):复制 JavaScript 包装器 obj,以便以后在替换方法之外使用。

Java.perform(() => {
const Activity = Java.use(‘android.app.Activity’);
let lastActivity = null;
Activity.onResume.implementation = function () {
lastActivity = Java.retain(this);
this.onResume();
};
});

Java.cast(handle, klass): create a JavaScript wrapper given the existing instance at handle of given class klass as returned from Java.use(). Such a wrapper also has a class property for getting a wrapper for its class, and a $className property for getting a string representation of its class-name.
Java.cast(handle, klass):在给定类 klass 的 handle 处创建一个 JavaScript 包装器,从 Java.use() 返回。这样的包装器还具有一个 class 属性,用于获取其类的包装器,以及一个 $className 属性,用于获取其类名的字符串表示形式。

const Activity = Java.use(‘android.app.Activity’);
const activity = Java.cast(ptr(‘0x1234’), Activity);

Java.array(type, elements): creates a Java array with elements of the specified type, from a JavaScript array elements. The resulting Java array behaves like a JS array, but can be passed by reference to Java APIs in order to allow them to modify its contents.
Java.array(type, elements):从 JavaScript 数组 elements 创建具有指定 type 元素的 Java 数组。生成的 Java 数组的行为类似于 JS 数组,但可以通过引用 Java API 来传递,以允许它们修改其内容。

const values = Java.array(‘int’, [ 1003, 1005, 1007 ]);

const JString = Java.use(‘java.lang.String’);
const str = JString.$new(Java.array(‘byte’, [ 0x48, 0x65, 0x69 ]));

Java.isMainThread(): determine whether the caller is running on the main thread.
Java.isMainThread():确定调用方是否在主线程上运行。

Java.registerClass(spec): create a new Java class and return a wrapper for it, where spec is an object containing:
Java.registerClass(spec):创建一个新的 Java 类并为其返回一个包装器,其中 spec 是一个包含以下内容的对象:
    name: String specifying the name of the class.
    name:指定类名称的字符串。
    superClass: (optional) Super-class. Omit to inherit from java.lang.Object.
    superClass:(可选)超级类。省略继承自 java.lang.Object。
    implements: (optional) Array of interfaces implemented by this class.
    fields: (optional) Object specifying the name and type of each field to expose.
    methods: (optional) Object specifying methods to implement.

const SomeBaseClass = Java.use(‘com.example.SomeBaseClass’);
const X509TrustManager = Java.use(‘javax.net.ssl.X509TrustManager’);

const MyTrustManager = Java.registerClass({
name: ‘com.example.MyTrustManager’,
implements: [X509TrustManager],
methods: {
checkClientTrusted(chain, authType) {
},
checkServerTrusted(chain, authType) {
},
getAcceptedIssuers() {
return [];
},
}
});

const MyWeirdTrustManager = Java.registerClass({
name: ‘com.example.MyWeirdTrustManager’,
superClass: SomeBaseClass,
implements: [X509TrustManager],
fields: {
description: ‘java.lang.String’,
limit: ‘int’,
},
methods: {
$init() {
console.log(‘Constructor called’);
},
checkClientTrusted(chain, authType) {
console.log(‘checkClientTrusted’);
},
checkServerTrusted: [{
returnType: ‘void’,
argumentTypes: [‘[Ljava.security.cert.X509Certificate;’, ‘java.lang.String’],
implementation(chain, authType) {
console.log(‘checkServerTrusted A’);
}
}, {
returnType: ‘java.util.List’,
argumentTypes: [‘[Ljava.security.cert.X509Certificate;’, ‘java.lang.String’, ‘java.lang.String’],
implementation(chain, authType, host) {
console.log(‘checkServerTrusted B’);
return null;
}
}],
getAcceptedIssuers() {
console.log(‘getAcceptedIssuers’);
return [];
},
}
});

Java.deoptimizeEverything(): forces the VM to execute everything with its interpreter. Necessary to prevent optimizations from bypassing method hooks in some cases, and allows ART’s Instrumentation APIs to be used for tracing the runtime.
Java.deoptimizeEverything():强制 VM 使用其解释器执行所有操作。在某些情况下,这是防止优化绕过方法钩子所必需的,并允许使用 ART 的 Instrumentation API 来跟踪运行时。

Java.deoptimizeBootImage(): similar to Java.deoptimizeEverything() but only deoptimizes boot image code. Use with dalvik.vm.dex2oat-flags --inline-max-code-units=0 for best results.
Java.deoptimizeBootImage():类似于 Java.deoptimizeEverything(),但只取消优化启动映像代码。与 dalvik.vm.dex2oat-flags --inline-max-code-units=0 一起使用以获得最佳效果。

Java.vm: object with the following methods:
Java.vm:对象,方法如下:

    perform(fn): ensures that the current thread is attached to the VM and calls fn. (This isn’t necessary in callbacks from Java.)
    perform(fn):确保当前线程附加到 VM 并调用 fn。(这在来自 Java 的回调中不是必需的。

    getEnv(): gets a wrapper for the current thread’s JNIEnv. Throws an exception if the current thread is not attached to the VM.
    getEnv():获取当前线程 JNIEnv 的包装器。如果当前线程未附加到 VM,则引发异常。

    tryGetEnv(): tries to get a wrapper for the current thread’s JNIEnv. Returns null if the current thread is not attached to the VM.
    tryGetEnv():尝试获取当前线程 JNIEnv 的包装器。如果当前线程未连接到 VM,则返回 null。

Java.classFactory: the default class factory used to implement e.g. Java.use(). Uses the application’s main class loader.
Java.classFactory:用于实现的默认类工厂,例如 Java.use()。使用应用程序的主类加载器。

Java.ClassFactory: class with the following properties:
Java.ClassFactory:具有以下属性的类:

    get(classLoader): Gets the class factory instance for a given class loader. The default class factory used behind the scenes only interacts with the application’s main class loader. Other class loaders can be discovered through Java.enumerateClassLoaders() and interacted with through this API.
    get(classLoader):获取给定类装入器的类工厂实例。在后台使用的默认类工厂仅与应用程序的主类加载器交互。其他类加载器可以通过 Java.enumerateClassLoaders() 发现,并通过此 API 进行交互。

    loader: read-only property providing a wrapper for the class loader currently being used. For the default class factory this is updated by the first call to Java.perform().
    loader:只读属性,为当前使用的类装入器提供包装。对于缺省类工厂,这是通过第一次调用 Java.perform() 来更新的。

    cacheDir: string containing path to cache directory currently being used. For the default class factory this is updated by the first call to Java.perform().
    cacheDir:包含当前正在使用的缓存目录路径的字符串。对于缺省类工厂,这是通过第一次调用 Java.perform() 来更新的。

    tempFileNaming: object specifying naming convention to use for temporary files. Defaults to { prefix: 'frida', suffix: 'dat' }.
    tempFileNaming:指定用于临时文件的命名约定的对象。默认值为 { prefix: 'frida', suffix: 'dat' }。

    use(className): like Java.use() but for a specific class loader.
    use(className):类似于 Java.use(),但用于特定的类加载器。

    openClassFile(filePath): like Java.openClassFile() but for a specific class loader.
    openClassFile(filePath):类似于 Java.openClassFile(),但用于特定的类装入器。

    choose(className, callbacks): like Java.choose() but for a specific class loader.
    choose(className, callbacks):类似于 Java.choose(),但用于特定的类加载器。

    retain(obj): like Java.retain() but for a specific class loader.
    retain(obj):类似于 Java.retain(),但用于特定的类装入器。

    cast(handle, klass): like Java.cast() but for a specific class loader.
    cast(handle, klass):类似于 Java.cast(),但用于特定的类加载器。

    array(type, elements): like Java.array() but for a specific class loader.
    array(type, elements):类似于 Java.array(),但用于特定的类装入器。

    registerClass(spec): like Java.registerClass() but for a specific class loader.
    registerClass(spec):类似于 Java.registerClass(),但用于特定的类装入器。

CPU Instruction CPU指令 Instruction 指令


Instruction 指令)

Instruction.parse(target): parse the instruction at the target address in memory, represented by a NativePointer. Note that on 32-bit ARM this address must have its least significant bit set to 0 for ARM functions, and 1 for Thumb functions. Frida takes care of this detail for you if you get the address from a Frida API (for example Module.getExportByName()).
Instruction.parse(target):解析内存中 target 地址处的指令,由 NativePointer 表示。请注意,在 32 位 ARM 上,对于 ARM 函数,此地址的最低有效位必须设置为 0,对于 Thumb 函数,必须将其最低有效位设置为 1。如果您从 Frida API 获取地址(例如 Module.getExportByName()),Frida 会为您处理此详细信息。

The object returned has the fields:
返回的对象包含以下字段:
    address: address (EIP) of this instruction, as a NativePointer
    address:此指令的地址 (EIP),作为 NativePointer
    next: pointer to the next instruction, so you can parse() it
    next:指向下一条指令的指针,因此您可以 parse() 它
    size: size of this instruction
    size:此指令的大小
    mnemonic: string representation of instruction mnemonic
    mnemonic:指令助记符的字符串表示
    opStr: string representation of instruction operands
    opStr:指令操作数的字符串表示形式
    operands: array of objects describing each operand, each specifying the type and value, at a minimum, but potentially also additional properties depending on the architecture
    operands:描述每个操作数的对象数组,每个操作数至少指定 type 和 value,但根据体系结构,可能还会有其他属性
    regsRead: array of register names implicitly read by this instruction
    regsRead:此指令隐式读取的寄存器名称数组
    regsWritten: array of register names implicitly written to by this instruction
    regsWritten:此指令隐式写入的寄存器名称数组
    groups: array of group names that this instruction belongs to
    groups:此指令所属的组名数组
    toString(): convert to a human-readable string
    toString():转换为人类可读的字符串

For details about operands and groups, please consult the Capstone documentation for your architecture.
有关 operands 和 groups 的详细信息,请参阅适用于您的体系结构的 Capstone 文档。

X86Writer X86写入器

new X86Writer(codeAddress[, { pc: ptr('0x1234') }]): create a new code writer for generating x86 machine code written directly to memory at codeAddress, specified as a NativePointer. The second argument is an optional options object where the initial program counter may be specified, which is useful when generating code to a scratch buffer. This is essential when using Memory.patchCode() on iOS, which may provide you with a temporary location that later gets mapped into memory at the intended memory location.
new X86Writer(codeAddress[, { pc: ptr('0x1234') }]):创建一个新的代码编写器,用于生成直接写入内存的 x86 机器代码,该机器代码位于 codeAddress,指定为 NativePointer。第二个参数是一个可选的 options 对象,其中可以指定初始程序计数器,这在将代码生成到暂存缓冲区时非常有用。在 iOS 上使用 Memory.patchCode() 时,这是必不可少的,它可能会为您提供一个临时位置,稍后该位置会映射到预期内存位置的内存中。

reset(codeAddress[, { pc: ptr('0x1234') }]): recycle instance
reset(codeAddress[, { pc: ptr('0x1234') }]):回收实例

dispose(): eagerly clean up memory
dispose():急切地清理记忆

flush(): resolve label references and write pending data to memory. You should always call this once you’ve finished generating code. It is usually also desirable to do this between pieces of unrelated code, e.g. when generating multiple functions in one go.
flush():解析标签引用并将挂起的数据写入内存。在完成代码生成后,应始终调用此函数。通常还希望在不相关的代码段之间执行此操作,例如,在一次生成多个函数时。

base: memory location of the first byte of output, as a NativePointer
base:输出第一个字节的内存位置,作为 NativePointer

code: memory location of the next byte of output, as a NativePointer
code:输出的下一个字节的内存位置,作为 NativePointer

pc: program counter at the next byte of output, as a NativePointer
pc:在输出的下一个字节处编程计数器,作为 NativePointer

offset: current offset as a JavaScript Number
offset:作为 JavaScript 数字的当前偏移量

putLabel(id): put a label at the current position, where id is a string that may be referenced in past and future put*Label() calls
putLabel(id):在当前位置放置一个标签,其中 id 是可以在过去和将来的 put*Label() 调用中引用的字符串

putCallAddressWithArguments(func, args): put code needed for calling a C function with the specified args, specified as a JavaScript array where each element is either a string specifying the register, or a Number or NativePointer specifying the immediate value.
putCallAddressWithArguments(func, args):使用指定的 args 放置调用 C 函数所需的代码,指定为 JavaScript 数组,其中每个元素要么是指定寄存器的字符串,要么是指定即时值的 Number 或 NativePointer。

putCallAddressWithAlignedArguments(func, args): like above, but also ensures that the argument list is aligned on a 16 byte boundary
putCallAddressWithAlignedArguments(func, args):如上所述,但也确保参数列表在 16 字节边界上对齐

putCallRegWithArguments(reg, args): put code needed for calling a C function with the specified args, specified as a JavaScript array where each element is either a string specifying the register, or a Number or NativePointer specifying the immediate value.
putCallRegWithArguments(reg, args):使用指定的 args 放置调用 C 函数所需的代码,指定为 JavaScript 数组,其中每个元素要么是指定寄存器的字符串,要么是指定即时值的 Number 或 NativePointer。

putCallRegWithAlignedArguments(reg, args): like above, but also ensures that the argument list is aligned on a 16 byte boundary
putCallRegWithAlignedArguments(reg, args):如上所述,但也确保参数列表在 16 字节边界上对齐

putCallRegOffsetPtrWithArguments(reg, offset, args): put code needed for calling a C function with the specified args, specified as a JavaScript array where each element is either a string specifying the register, or a Number or NativePointer specifying the immediate value.
putCallRegOffsetPtrWithArguments(reg, offset, args):使用指定的 args 放置调用 C 函数所需的代码,指定为 JavaScript 数组,其中每个元素要么是指定寄存器的字符串,要么是指定即时值的 Number 或 NativePointer。

putCallAddress(address): put a CALL instruction
putCallAddress(address):发出 CALL 指令

putCallReg(reg): put a CALL instruction
putCallReg(reg):发出 CALL 指令

putCallRegOffsetPtr(reg, offset): put a CALL instruction
putCallRegOffsetPtr(reg, offset):发出 CALL 指令

putCallIndirect(addr): put a CALL instruction
putCallIndirect(addr):发出 CALL 指令

putCallIndirectLabel(labelId): put a CALL instruction referencing labelId, defined by a past or future putLabel()
putCallIndirectLabel(labelId):放置引用 labelId 的 CALL 指令,由过去或将来的 putLabel() 定义

putCallNearLabel(labelId): put a CALL instruction referencing labelId, defined by a past or future putLabel()
putCallNearLabel(labelId):放置引用 labelId 的 CALL 指令,由过去或将来的 putLabel() 定义

putLeave(): put a LEAVE instruction
putLeave():发出 LEAVE 指令

putRet(): put a RET instruction
putRet():输入RET指令

putRetImm(immValue): put a RET instruction
putRetImm(immValue):输入RET指令

putJmpAddress(address): put a JMP instruction
putJmpAddress(address):输入JMP指令

putJmpShortLabel(labelId): put a JMP instruction referencing labelId, defined by a past or future putLabel()
putJmpShortLabel(labelId):放置引用 labelId 的 JMP 指令,由过去或未来的 putLabel() 定义

putJmpNearLabel(labelId): put a JMP instruction referencing labelId, defined by a past or future putLabel()
putJmpNearLabel(labelId):放置引用 labelId 的 JMP 指令,由过去或未来的 putLabel() 定义

putJmpReg(reg): put a JMP instruction
putJmpReg(reg):输入JMP指令

putJmpRegPtr(reg): put a JMP instruction
putJmpRegPtr(reg):输入JMP指令

putJmpRegOffsetPtr(reg, offset): put a JMP instruction
putJmpRegOffsetPtr(reg, offset):输入JMP指令

putJmpNearPtr(address): put a JMP instruction
putJmpNearPtr(address):输入JMP指令

putJccShort(instructionId, target, hint): put a JCC instruction
putJccShort(instructionId, target, hint):放置 JCC 指令

putJccNear(instructionId, target, hint): put a JCC instruction
putJccNear(instructionId, target, hint):放置 JCC 指令

putJccShortLabel(instructionId, labelId, hint): put a JCC instruction referencing labelId, defined by a past or future putLabel()
putJccShortLabel(instructionId, labelId, hint):放置引用 labelId 的 JCC 指令,由过去或将来的 putLabel() 定义

putJccNearLabel(instructionId, labelId, hint): put a JCC instruction referencing labelId, defined by a past or future putLabel()
putJccNearLabel(instructionId, labelId, hint):放置引用 labelId 的 JCC 指令,由过去或将来的 putLabel() 定义

putAddRegImm(reg, immValue): put an ADD instruction
putAddRegImm(reg, immValue):输入ADD指令

putAddRegReg(dstReg, srcReg): put an ADD instruction
putAddRegReg(dstReg, srcReg):输入ADD指令

putAddRegNearPtr(dstReg, srcAddress): put an ADD instruction
putAddRegNearPtr(dstReg, srcAddress):输入ADD指令

putSubRegImm(reg, immValue): put a SUB instruction
putSubRegImm(reg, immValue):输入 SUB 指令

putSubRegReg(dstReg, srcReg): put a SUB instruction
putSubRegReg(dstReg, srcReg):输入 SUB 指令

putSubRegNearPtr(dstReg, srcAddress): put a SUB instruction
putSubRegNearPtr(dstReg, srcAddress):输入 SUB 指令

putIncReg(reg): put an INC instruction
putIncReg(reg):输入INC指令

putDecReg(reg): put a DEC instruction
putDecReg(reg):放置 DEC 指令

putIncRegPtr(target, reg): put an INC instruction
putIncRegPtr(target, reg):输入INC指令

putDecRegPtr(target, reg): put a DEC instruction
putDecRegPtr(target, reg):放置 DEC 指令

putLockXaddRegPtrReg(dstReg, srcReg): put a LOCK XADD instruction
putLockXaddRegPtrReg(dstReg, srcReg):输入 LOCK XADD 指令

putLockCmpxchgRegPtrReg(dstReg, srcReg): put a LOCK CMPXCHG instruction
putLockCmpxchgRegPtrReg(dstReg, srcReg):输入 LOCK CMPXCHG 指令

putLockIncImm32Ptr(target): put a LOCK INC IMM32 instruction
putLockIncImm32Ptr(target):输入 LOCK INC IMM32 指令

putLockDecImm32Ptr(target): put a LOCK DEC IMM32 instruction
putLockDecImm32Ptr(target):放置 LOCK DEC IMM32 指令

putAndRegReg(dstReg, srcReg): put an AND instruction
putAndRegReg(dstReg, srcReg):输入 AND 指令

putAndRegU32(reg, immValue): put an AND instruction
putAndRegU32(reg, immValue):输入 AND 指令

putShlRegU8(reg, immValue): put a SHL instruction
putShlRegU8(reg, immValue):输入 SHL 指令

putShrRegU8(reg, immValue): put a SHR instruction
putShrRegU8(reg, immValue):放置 SHR 指令

putXorRegReg(dstReg, srcReg): put an XOR instruction
putXorRegReg(dstReg, srcReg):输入 XOR 指令

putMovRegReg(dstReg, srcReg): put a MOV instruction
putMovRegReg(dstReg, srcReg):放置 MOV 指令

putMovRegU32(dstReg, immValue): put a MOV instruction
putMovRegU32(dstReg, immValue):放置 MOV 指令

putMovRegU64(dstReg, immValue): put a MOV instruction
putMovRegU64(dstReg, immValue):放置 MOV 指令

putMovRegAddress(dstReg, address): put a MOV instruction
putMovRegAddress(dstReg, address):放置 MOV 指令

putMovRegPtrU32(dstReg, immValue): put a MOV instruction
putMovRegPtrU32(dstReg, immValue):放置 MOV 指令

putMovRegOffsetPtrU32(dstReg, dstOffset, immValue): put a MOV instruction
putMovRegOffsetPtrU32(dstReg, dstOffset, immValue):放置 MOV 指令

putMovRegPtrReg(dstReg, srcReg): put a MOV instruction
putMovRegPtrReg(dstReg, srcReg):放置 MOV 指令

putMovRegOffsetPtrReg(dstReg, dstOffset, srcReg): put a MOV instruction
putMovRegOffsetPtrReg(dstReg, dstOffset, srcReg):放置 MOV 指令

putMovRegRegPtr(dstReg, srcReg): put a MOV instruction
putMovRegRegPtr(dstReg, srcReg):放置 MOV 指令

putMovRegRegOffsetPtr(dstReg, srcReg, srcOffset): put a MOV instruction
putMovRegRegOffsetPtr(dstReg, srcReg, srcOffset):放置 MOV 指令

putMovRegBaseIndexScaleOffsetPtr(dstReg, baseReg, indexReg, scale, offset): put a MOV instruction
putMovRegBaseIndexScaleOffsetPtr(dstReg, baseReg, indexReg, scale, offset):放置 MOV 指令

putMovRegNearPtr(dstReg, srcAddress): put a MOV instruction
putMovRegNearPtr(dstReg, srcAddress):放置 MOV 指令

putMovNearPtrReg(dstAddress, srcReg): put a MOV instruction
putMovNearPtrReg(dstAddress, srcReg):放置 MOV 指令

putMovFsU32PtrReg(fsOffset, srcReg): put a MOV FS instruction
putMovFsU32PtrReg(fsOffset, srcReg):放置 MOV FS 指令

putMovRegFsU32Ptr(dstReg, fsOffset): put a MOV FS instruction
putMovRegFsU32Ptr(dstReg, fsOffset):放置 MOV FS 指令

putMovFsRegPtrReg(fsOffset, srcReg): put a MOV FS instruction
putMovFsRegPtrReg(fsOffset, srcReg):放置 MOV FS 指令

putMovRegFsRegPtr(dstReg, fsOffset): put a MOV FS instruction
putMovRegFsRegPtr(dstReg, fsOffset):放置 MOV FS 指令

putMovGsU32PtrReg(fsOffset, srcReg): put a MOV GS instruction
putMovGsU32PtrReg(fsOffset, srcReg):放置 MOV GS 指令

putMovRegGsU32Ptr(dstReg, fsOffset): put a MOV GS instruction
putMovRegGsU32Ptr(dstReg, fsOffset):放置 MOV GS 指令

putMovGsRegPtrReg(gsOffset, srcReg): put a MOV GS instruction
putMovGsRegPtrReg(gsOffset, srcReg):放置 MOV GS 指令

putMovRegGsRegPtr(dstReg, gsOffset): put a MOV GS instruction
putMovRegGsRegPtr(dstReg, gsOffset):放置 MOV GS 指令

putMovqXmm0EspOffsetPtr(offset): put a MOVQ XMM0 ESP instruction
putMovqXmm0EspOffsetPtr(offset):输入 MOVQ XMM0 ESP 指令

putMovqEaxOffsetPtrXmm0(offset): put a MOVQ EAX XMM0 instruction
putMovqEaxOffsetPtrXmm0(offset):输入 MOVQ EAX XMM0 指令

putMovdquXmm0EspOffsetPtr(offset): put a MOVDQU XMM0 ESP instruction
putMovdquXmm0EspOffsetPtr(offset):输入 MOVDQU XMM0 ESP 指令

putMovdquEaxOffsetPtrXmm0(offset): put a MOVDQU EAX XMM0 instruction
putMovdquEaxOffsetPtrXmm0(offset):输入 MOVDQU EAX XMM0 指令

putLeaRegRegOffset(dstReg, srcReg, srcOffset): put a LEA instruction
putLeaRegRegOffset(dstReg, srcReg, srcOffset):放置 LEA 指令

putXchgRegRegPtr(leftReg, rightReg): put an XCHG instruction
putXchgRegRegPtr(leftReg, rightReg):输入 XCHG 指令

putPushU32(immValue): put a PUSH instruction
putPushU32(immValue):输入 PUSH 指令

putPushNearPtr(address): put a PUSH instruction
putPushNearPtr(address):输入 PUSH 指令

putPushReg(reg): put a PUSH instruction
putPushReg(reg):输入 PUSH 指令

putPopReg(reg): put a POP instruction
putPopReg(reg):输入 POP 指令

putPushImmPtr(immPtr): put a PUSH instruction
putPushImmPtr(immPtr):输入 PUSH 指令

putPushax(): put a PUSHAX instruction
putPushax():输入 PUSHAX 指令

putPopax(): put a POPAX instruction
putPopax():输入 POPAX 指令

putPushfx(): put a PUSHFX instruction
putPushfx():输入 PUSHFX 指令

putPopfx(): put a POPFX instruction
putPopfx():放置 POPFX 指令

putSahf(): put a SAHF instruction
putSahf():发出 SAHF 指令

putLahf(): put a LAHF instruction
putLahf():放置 LAHF 指令

putTestRegReg(regA, regB): put a TEST instruction
putTestRegReg(regA, regB):输入 TEST 指令

putTestRegU32(reg, immValue): put a TEST instruction
putTestRegU32(reg, immValue):输入 TEST 指令

putCmpRegI32(reg, immValue): put a CMP instruction
putCmpRegI32(reg, immValue):放置 CMP 指令

putCmpRegOffsetPtrReg(regA, offset, regB): put a CMP instruction
putCmpRegOffsetPtrReg(regA, offset, regB):放置 CMP 指令

putCmpImmPtrImmU32(immPtr, immValue): put a CMP instruction
putCmpImmPtrImmU32(immPtr, immValue):放置 CMP 指令

putCmpRegReg(regA, regB): put a CMP instruction
putCmpRegReg(regA, regB):放置 CMP 指令

putClc(): put a CLC instruction
putClc():放置 CLC 指令

putStc(): put a STC instruction
putStc():放置 STC 指令

putCld(): put a CLD instruction
putCld():输入 CLD 指令

putStd(): put a STD instruction
putStd():放置 STD 指令

putCpuid(): put a CPUID instruction
putCpuid():输入 CPUID 指令

putLfence(): put an LFENCE instruction
putLfence():放置 LFENCE 指令

putRdtsc(): put an RDTSC instruction
putRdtsc():输入 RDTSC 指令

putPause(): put a PAUSE instruction
putPause():发出暂停指令

putNop(): put a NOP instruction
putNop():输入NOP指令

putBreakpoint(): put an OS/architecture-specific breakpoint instruction
putBreakpoint():放置特定于操作系统/体系结构的断点指令

putPadding(n): put n guard instruction
putPadding(n):把n守卫指令

putNopPadding(n): put n NOP instructions
putNopPadding(n):把nNOP指令

putFxsaveRegPtr(reg): put a FXSAVE instruction
putFxsaveRegPtr(reg):输入FXSAVE指令

putFxrstorRegPtr(reg): put a FXRSTOR instruction
putFxrstorRegPtr(reg):输入 FXRSTOR 指令

putU8(value): put a uint8 putU8(value):放一个uint8

putS8(value): put an int8 putS8(value):把一个 int8

putBytes(data): put raw data from the provided ArrayBuffer
putBytes(data):从提供的 ArrayBuffer 中放置原始数据

X86Relocator X86重定位器

new X86Relocator(inputCode, output): create a new code relocator for copying x86 instructions from one memory location to another, taking care to adjust position-dependent instructions accordingly. The source address is specified by inputCode, a NativePointer. The destination is given by output, an X86Writer pointed at the desired target memory address.
new X86Relocator(inputCode, output):创建一个新的代码重定位器,用于将 x86 指令从一个内存位置复制到另一个内存位置,注意相应地调整与位置相关的指令。源地址由 inputCode 指定,即 NativePointer。目标由 output 给出,X86Writer 指向所需的目标内存地址。

reset(inputCode, output): recycle instance
reset(inputCode, output):回收实例

dispose(): eagerly clean up memory
dispose():急切地清理记忆

input: latest Instruction read so far. Starts out null and changes on every call to readOne().
input:到目前为止阅读的最新指令。从 null 开始,并在每次调用 readOne() 时发生变化。

eob: boolean indicating whether end-of-block has been reached, i.e. we’ve reached a branch of any kind, like CALL, JMP, BL, RET.
eob:布尔值,表示是否已到达区块末尾,即我们已到达任何类型的分支,如 CALL、JMP、BL、RET。

eoi: boolean indicating whether end-of-input has been reached, e.g. we’ve reached JMP/B/RET, an instruction after which there may or may not be valid code.
eoi:布尔值,表示是否已达到输入结束,例如,我们已达到 JMP/B/RET,该指令之后可能有也可能没有有效代码。

readOne(): read the next instruction into the relocator’s internal buffer and return the number of bytes read so far, including previous calls. You may keep calling this method to keep buffering, or immediately call either writeOne() or skipOne(). Or, you can buffer up until the desired point and then call writeAll(). Returns zero when end-of-input is reached, which means the eoi property is now true.
readOne():将下一条指令读取到重定位器的内部缓冲区中,并返回到目前为止读取的字节数,包括之前的调用。您可以继续调用此方法以保持缓冲,也可以立即调用 writeOne() 或 skipOne()。或者,您可以缓冲到所需的点,然后调用 writeAll()。当达到输入结束时返回零,这意味着 eoi 属性现在为 true。

peekNextWriteInsn(): peek at the next Instruction to be written or skipped
peekNextWriteInsn():查看要编写或跳过的下一条指令

peekNextWriteSource(): peek at the address of the next instruction to be written or skipped
peekNextWriteSource():查看要编写或跳过的下一条指令的地址

skipOne(): skip the instruction that would have been written next
skipOne():跳过接下来要写的指令

skipOneNoLabel(): skip the instruction that would have been written next, but without a label for internal use. This breaks relocation of branches to locations inside the relocated range, and is an optimization for use-cases where all branches are rewritten (e.g. Frida’s Stalker).
skipOneNoLabel():跳过接下来要编写的指令,但没有内部使用的标签。这会破坏分支到重新定位范围内的位置,并且是针对重写所有分支的用例(例如 Frida's Stalker)的优化。

writeOne(): write the next buffered instruction
writeOne():写入下一个缓冲指令

writeOneNoLabel(): write the next buffered instruction, but without a label for internal use. This breaks relocation of branches to locations inside the relocated range, and is an optimization for use-cases where all branches are rewritten (e.g. Frida’s Stalker).
writeOneNoLabel():编写下一个缓冲指令,但没有供内部使用的标签。这会破坏分支到重新定位范围内的位置,并且是针对重写所有分支的用例(例如 Frida's Stalker)的优化。

writeAll(): write all buffered instructions
writeAll():写入所有缓冲指令

x86 enum types x86 枚举类型

Register: xax xcx xdx xbx xsp xbp xsi xdi eax ecx edx ebx esp ebp esi edi rax rcx rdx rbx rsp rbp rsi rdi r8 r9 r10 r11 r12 r13 r14 r15 r8d r9d r10d r11d r12d r13d r14d r15d xip eip rip
寄存器: xax xcx xdx xbx xsp xbp xsi xdi eax ecx edx ebx esp ebp esi edi rax rcx rdx rbx rsp rbp rsi rdi r8 r9 r10 r11 r12 r13 r14 r15 r8d r9d r10d r11d r12d r13d r14d r15d xip eip rip
InstructionId: jo jno jb jae je jne jbe ja js jns jp jnp jl jge jle jg jcxz jecxz jrcxz
指令 ID: jo jno jb jae je jne jbe ja js jns jp jnp jl jge jle jg jcxz jecxz jrcxz
BranchHint: no-hint likely unlikely
分支提示:no-hint likely unlikely
PointerTarget: byte dword qword
指针目标:byte dword qword

ArmWriter ArmWriter 的

new ArmWriter(codeAddress[, { pc: ptr('0x1234') }]): create a new code writer for generating ARM machine code written directly to memory at codeAddress, specified as a NativePointer. The second argument is an optional options object where the initial program counter may be specified, which is useful when generating code to a scratch buffer. This is essential when using Memory.patchCode() on iOS, which may provide you with a temporary location that later gets mapped into memory at the intended memory location.
new ArmWriter(codeAddress[, { pc: ptr('0x1234') }]):创建一个新的代码编写器,用于生成直接写入内存的 ARM 机器代码 codeAddress,指定为 NativePointer。第二个参数是一个可选的 options 对象,其中可以指定初始程序计数器,这在将代码生成到暂存缓冲区时非常有用。在 iOS 上使用 Memory.patchCode() 时,这是必不可少的,它可能会为您提供一个临时位置,稍后该位置会映射到预期内存位置的内存中。

reset(codeAddress[, { pc: ptr('0x1234') }]): recycle instance
reset(codeAddress[, { pc: ptr('0x1234') }]):回收实例

dispose(): eagerly clean up memory
dispose():急切地清理记忆

flush(): resolve label references and write pending data to memory. You should always call this once you’ve finished generating code. It is usually also desirable to do this between pieces of unrelated code, e.g. when generating multiple functions in one go.
flush():解析标签引用并将挂起的数据写入内存。在完成代码生成后,应始终调用此函数。通常还希望在不相关的代码段之间执行此操作,例如,在一次生成多个函数时。

base: memory location of the first byte of output, as a NativePointer
base:输出第一个字节的内存位置,作为 NativePointer

code: memory location of the next byte of output, as a NativePointer
code:输出的下一个字节的内存位置,作为 NativePointer

pc: program counter at the next byte of output, as a NativePointer
pc:在输出的下一个字节处编程计数器,作为 NativePointer

offset: current offset as a JavaScript Number
offset:作为 JavaScript 数字的当前偏移量

skip(nBytes): skip nBytes skip(nBytes):跳过 nBytes

putLabel(id): put a label at the current position, where id is a string that may be referenced in past and future put*Label() calls
putLabel(id):在当前位置放置一个标签,其中 id 是可以在过去和将来的 put*Label() 调用中引用的字符串

putCallAddressWithArguments(func, args): put code needed for calling a C function with the specified args, specified as a JavaScript array where each element is either a string specifying the register, or a Number or NativePointer specifying the immediate value.
putCallAddressWithArguments(func, args):使用指定的 args 放置调用 C 函数所需的代码,指定为 JavaScript 数组,其中每个元素要么是指定寄存器的字符串,要么是指定即时值的 Number 或 NativePointer。

putCallReg(reg): put a CALL instruction
putCallReg(reg):发出 CALL 指令

putCallRegWithArguments(reg, args): put code needed for calling a C function with the specified args, specified as a JavaScript array where each element is either a string specifying the register, or a Number or NativePointer specifying the immediate value.
putCallRegWithArguments(reg, args):使用指定的 args 放置调用 C 函数所需的代码,指定为 JavaScript 数组,其中每个元素要么是指定寄存器的字符串,要么是指定即时值的 Number 或 NativePointer。

putBranchAddress(address): put code needed for branching/jumping to the given address
putBranchAddress(address):将分支/跳转到给定地址所需的代码

canBranchDirectlyBetween(from, to): determine whether a direct branch is possible between the two given memory locations
canBranchDirectlyBetween(from, to):确定两个给定内存位置之间是否可能存在直接分支

putBImm(target): put a B instruction
putBImm(target):输入 B 指令

putBCondImm(cc, target): put a B COND instruction
putBCondImm(cc, target):输入 B COND 指令

putBLabel(labelId): put a B instruction referencing labelId, defined by a past or future putLabel()
putBLabel(labelId):放置一个引用 labelId 的 B 指令,由过去或未来的 putLabel() 定义

putBCondLabel(cc, labelId): put a B COND instruction referencing labelId, defined by a past or future putLabel()
putBCondLabel(cc, labelId):放置一个引用 labelId 的 B COND 指令,由过去或未来的 putLabel() 定义

putBlImm(target): put a BL instruction
putBlImm(target):放置 BL 指令

putBlxImm(target): put a BLX instruction
putBlxImm(target):输入 BLX 指令

putBlLabel(labelId): put a BL instruction referencing labelId, defined by a past or future putLabel()
putBlLabel(labelId):放置一个引用 labelId 的 BL 指令,由过去或将来的 putLabel() 定义

putBxReg(reg): put a BX instruction
putBxReg(reg):输入BX指令

putBlReg(reg): put a BL instruction
putBlReg(reg):放置 BL 指令

putBlxReg(reg): put a BLX instruction
putBlxReg(reg):输入 BLX 指令

putRet(): put a RET instruction
putRet():输入RET指令

putVpushRange(firstReg, lastReg): put a VPUSH RANGE instruction
putVpushRange(firstReg, lastReg):输入 VPUSH RANGE 指令

putVpopRange(firstReg, lastReg): put a VPOP RANGE instruction
putVpopRange(firstReg, lastReg):输入 VPOP RANGE 指令

putLdrRegAddress(reg, address): put an LDR instruction
putLdrRegAddress(reg, address):输入 LDR 指令

putLdrRegU32(reg, val): put an LDR instruction
putLdrRegU32(reg, val):输入 LDR 指令

putLdrRegReg(dstReg, srcReg): put an LDR instruction
putLdrRegReg(dstReg, srcReg):输入 LDR 指令

putLdrRegRegOffset(dstReg, srcReg, srcOffset): put an LDR instruction
putLdrRegRegOffset(dstReg, srcReg, srcOffset):输入 LDR 指令

putLdrCondRegRegOffset(cc, dstReg, srcReg, srcOffset): put an LDR COND instruction
putLdrCondRegRegOffset(cc, dstReg, srcReg, srcOffset):输入LDR COND指令

putLdmiaRegMask(reg, mask): put an LDMIA MASK instruction
putLdmiaRegMask(reg, mask):放置LDMIA MASK指令

putLdmiaRegMaskWb(reg, mask): put an LDMIA MASK WB instruction
putLdmiaRegMaskWb(reg, mask):放置 LDMIA MASK WB 指令

putStrRegReg(srcReg, dstReg): put a STR instruction
putStrRegReg(srcReg, dstReg):放置 STR 指令

putStrRegRegOffset(srcReg, dstReg, dstOffset): put a STR instruction
putStrRegRegOffset(srcReg, dstReg, dstOffset):放置 STR 指令

putStrCondRegRegOffset(cc, srcReg, dstReg, dstOffset): put a STR COND instruction
putStrCondRegRegOffset(cc, srcReg, dstReg, dstOffset):输入 STR COND 指令

putMovRegReg(dstReg, srcReg): put a MOV instruction
putMovRegReg(dstReg, srcReg):放置 MOV 指令

putMovRegRegShift(dstReg, srcReg, shift, shiftValue): put a MOV SHIFT instruction
putMovRegRegShift(dstReg, srcReg, shift, shiftValue):输入 MOV SHIFT 指令

putMovRegCpsr(reg): put a MOV CPSR instruction
putMovRegCpsr(reg):放置 MOV CPSR 指令

putMovCpsrReg(reg): put a MOV CPSR instruction
putMovCpsrReg(reg):放置 MOV CPSR 指令

putAddRegU16(dstReg, val): put an ADD U16 instruction
putAddRegU16(dstReg, val):输入 ADD U16 指令

putAddRegU32(dstReg, val): put an ADD instruction
putAddRegU32(dstReg, val):输入ADD指令

putAddRegRegImm(dstReg, srcReg, immVal): put an ADD instruction
putAddRegRegImm(dstReg, srcReg, immVal):输入ADD指令

putAddRegRegReg(dstReg, srcReg1, srcReg2): put an ADD instruction
putAddRegRegReg(dstReg, srcReg1, srcReg2):输入ADD指令

putAddRegRegRegShift(dstReg, srcReg1, srcReg2, shift, shiftValue): put an ADD SHIFT instruction
putAddRegRegRegShift(dstReg, srcReg1, srcReg2, shift, shiftValue):输入 ADD SHIFT 指令

putSubRegU16(dstReg, val): put a SUB U16 instruction
putSubRegU16(dstReg, val):输入 SUB U16 指令

putSubRegU32(dstReg, val): put a SUB instruction
putSubRegU32(dstReg, val):输入 SUB 指令

putSubRegRegImm(dstReg, srcReg, immVal): put a SUB instruction
putSubRegRegImm(dstReg, srcReg, immVal):输入 SUB 指令

putSubRegRegReg(dstReg, srcReg1, srcReg2): put a SUB instruction
putSubRegRegReg(dstReg, srcReg1, srcReg2):输入 SUB 指令

putRsbRegRegImm(dstReg, srcReg, immVal): put a RSB instruction
putRsbRegRegImm(dstReg, srcReg, immVal):输入 RSB 指令

putAndsRegRegImm(dstReg, srcReg, immVal): put an ANDS instruction
putAndsRegRegImm(dstReg, srcReg, immVal):输入 ANDS 指令

putCmpRegImm(dstReg, immVal): put a CMP instruction
putCmpRegImm(dstReg, immVal):放置 CMP 指令

putNop(): put a NOP instruction
putNop():输入NOP指令

putBreakpoint(): put an OS/architecture-specific breakpoint instruction
putBreakpoint():放置特定于操作系统/体系结构的断点指令

putBrkImm(imm): put a BRK instruction
putBrkImm(imm):输入 BRK 指令

putInstruction(insn): put a raw instruction as a JavaScript Number
putInstruction(insn):将原始指令作为 JavaScript 编号

putBytes(data): put raw data from the provided ArrayBuffer
putBytes(data):从提供的 ArrayBuffer 中放置原始数据

ArmRelocator ArmRelocator(手臂搬迁器)

new ArmRelocator(inputCode, output): create a new code relocator for copying ARM instructions from one memory location to another, taking care to adjust position-dependent instructions accordingly. The source address is specified by inputCode, a NativePointer. The destination is given by output, an ArmWriter pointed at the desired target memory address.
new ArmRelocator(inputCode, output):创建一个新的代码重定位器,用于将 ARM 指令从一个内存位置复制到另一个内存位置,并注意相应地调整与位置相关的指令。源地址由 inputCode 指定,即 NativePointer。目标由 output 给出,ArmWriter 指向所需的目标内存地址。

reset(inputCode, output): recycle instance
reset(inputCode, output):回收实例

dispose(): eagerly clean up memory
dispose():急切地清理记忆

input: latest Instruction read so far. Starts out null and changes on every call to readOne().
input:到目前为止阅读的最新指令。从 null 开始,并在每次调用 readOne() 时发生变化。

eob: boolean indicating whether end-of-block has been reached, i.e. we’ve reached a branch of any kind, like CALL, JMP, BL, RET.
eob:布尔值,表示是否已到达区块末尾,即我们已到达任何类型的分支,如 CALL、JMP、BL、RET。

eoi: boolean indicating whether end-of-input has been reached, e.g. we’ve reached JMP/B/RET, an instruction after which there may or may not be valid code.
eoi:布尔值,表示是否已达到输入结束,例如,我们已达到 JMP/B/RET,该指令之后可能有也可能没有有效代码。

readOne(): read the next instruction into the relocator’s internal buffer and return the number of bytes read so far, including previous calls. You may keep calling this method to keep buffering, or immediately call either writeOne() or skipOne(). Or, you can buffer up until the desired point and then call writeAll(). Returns zero when end-of-input is reached, which means the eoi property is now true.
readOne():将下一条指令读取到重定位器的内部缓冲区中,并返回到目前为止读取的字节数,包括之前的调用。您可以继续调用此方法以保持缓冲,也可以立即调用 writeOne() 或 skipOne()。或者,您可以缓冲到所需的点,然后调用 writeAll()。当达到输入结束时返回零,这意味着 eoi 属性现在为 true。

peekNextWriteInsn(): peek at the next Instruction to be written or skipped
peekNextWriteInsn():查看要编写或跳过的下一条指令

peekNextWriteSource(): peek at the address of the next instruction to be written or skipped
peekNextWriteSource():查看要编写或跳过的下一条指令的地址

skipOne(): skip the instruction that would have been written next
skipOne():跳过接下来要写的指令

writeOne(): write the next buffered instruction
writeOne():写入下一个缓冲指令

writeAll(): write all buffered instructions
writeAll():写入所有缓冲指令

ThumbWriter 拇指编写器

new ThumbWriter(codeAddress[, { pc: ptr('0x1234') }]): create a new code writer for generating ARM machine code written directly to memory at codeAddress, specified as a NativePointer. The second argument is an optional options object where the initial program counter may be specified, which is useful when generating code to a scratch buffer. This is essential when using Memory.patchCode() on iOS, which may provide you with a temporary location that later gets mapped into memory at the intended memory location.
new ThumbWriter(codeAddress[, { pc: ptr('0x1234') }]):创建一个新的代码编写器,用于生成直接写入内存的 ARM 机器代码 codeAddress,指定为 NativePointer。第二个参数是一个可选的 options 对象,其中可以指定初始程序计数器,这在将代码生成到暂存缓冲区时非常有用。在 iOS 上使用 Memory.patchCode() 时,这是必不可少的,它可能会为您提供一个临时位置,稍后该位置会映射到预期内存位置的内存中。

reset(codeAddress[, { pc: ptr('0x1234') }]): recycle instance
reset(codeAddress[, { pc: ptr('0x1234') }]):回收实例

dispose(): eagerly clean up memory
dispose():急切地清理记忆

flush(): resolve label references and write pending data to memory. You should always call this once you’ve finished generating code. It is usually also desirable to do this between pieces of unrelated code, e.g. when generating multiple functions in one go.
flush():解析标签引用并将挂起的数据写入内存。在完成代码生成后,应始终调用此函数。通常还希望在不相关的代码段之间执行此操作,例如,在一次生成多个函数时。

base: memory location of the first byte of output, as a NativePointer
base:输出第一个字节的内存位置,作为 NativePointer

code: memory location of the next byte of output, as a NativePointer
code:输出的下一个字节的内存位置,作为 NativePointer

pc: program counter at the next byte of output, as a NativePointer
pc:在输出的下一个字节处编程计数器,作为 NativePointer

offset: current offset as a JavaScript Number
offset:作为 JavaScript 数字的当前偏移量

skip(nBytes): skip nBytes skip(nBytes):跳过 nBytes

putLabel(id): put a label at the current position, where id is a string that may be referenced in past and future put*Label() calls
putLabel(id):在当前位置放置一个标签,其中 id 是可以在过去和将来的 put*Label() 调用中引用的字符串

commitLabel(id): commit the first pending reference to the given label, returning true on success. Returns false if the given label hasn’t been defined yet, or there are no more pending references to it.
commitLabel(id):提交对给定标签的第一个挂起引用,成功后返回 true。如果给定标签尚未定义,或者没有更多待处理的引用,则返回 false。

putCallAddressWithArguments(func, args): put code needed for calling a C function with the specified args, specified as a JavaScript array where each element is either a string specifying the register, or a Number or NativePointer specifying the immediate value.
putCallAddressWithArguments(func, args):使用指定的 args 放置调用 C 函数所需的代码,指定为 JavaScript 数组,其中每个元素要么是指定寄存器的字符串,要么是指定即时值的 Number 或 NativePointer。

putCallRegWithArguments(reg, args): put code needed for calling a C function with the specified args, specified as a JavaScript array where each element is either a string specifying the register, or a Number or NativePointer specifying the immediate value.
putCallRegWithArguments(reg, args):使用指定的 args 放置调用 C 函数所需的代码,指定为 JavaScript 数组,其中每个元素要么是指定寄存器的字符串,要么是指定即时值的 Number 或 NativePointer。

putBranchAddress(address): put code needed for branching/jumping to the given address
putBranchAddress(address):将分支/跳转到给定地址所需的代码

canBranchDirectlyBetween(from, to): determine whether a direct branch is possible between the two given memory locations
canBranchDirectlyBetween(from, to):确定两个给定内存位置之间是否可能存在直接分支

putBImm(target): put a B instruction
putBImm(target):输入 B 指令

putBLabel(labelId): put a B instruction referencing labelId, defined by a past or future putLabel()
putBLabel(labelId):放置一个引用 labelId 的 B 指令,由过去或未来的 putLabel() 定义

putBLabelWide(labelId): put a B WIDE instruction
putBLabelWide(labelId):输入 B WIDE 指令

putBxReg(reg): put a BX instruction
putBxReg(reg):输入BX指令

putBlImm(target): put a BL instruction
putBlImm(target):放置 BL 指令

putBlLabel(labelId): put a BL instruction referencing labelId, defined by a past or future putLabel()
putBlLabel(labelId):放置一个引用 labelId 的 BL 指令,由过去或将来的 putLabel() 定义

putBlxImm(target): put a BLX instruction
putBlxImm(target):输入 BLX 指令

putBlxReg(reg): put a BLX instruction
putBlxReg(reg):输入 BLX 指令

putCmpRegImm(reg, immValue): put a CMP instruction
putCmpRegImm(reg, immValue):放置 CMP 指令

putBeqLabel(labelId): put a BEQ instruction referencing labelId, defined by a past or future putLabel()
putBeqLabel(labelId):放置引用 labelId 的 BEQ 指令,由过去或将来的 putLabel() 定义

putBneLabel(labelId): put a BNE instruction referencing labelId, defined by a past or future putLabel()
putBneLabel(labelId):放置一个引用 labelId 的 BNE 指令,由过去或未来的 putLabel() 定义

putBCondLabel(cc, labelId): put a B COND instruction referencing labelId, defined by a past or future putLabel()
putBCondLabel(cc, labelId):放置一个引用 labelId 的 B COND 指令,由过去或未来的 putLabel() 定义

putBCondLabelWide(cc, labelId): put a B COND WIDE instruction
putBCondLabelWide(cc, labelId):输入 B COND WIDE 指令

putCbzRegLabel(reg, labelId): put a CBZ instruction referencing labelId, defined by a past or future putLabel()
putCbzRegLabel(reg, labelId):放置引用 labelId 的 CBZ 指令,由过去或将来的 putLabel() 定义

putCbnzRegLabel(reg, labelId): put a CBNZ instruction referencing labelId, defined by a past or future putLabel()
putCbnzRegLabel(reg, labelId):放置引用 labelId 的 CBNZ 指令,由过去或将来的 putLabel() 定义

putPushRegs(regs): put a PUSH instruction with the specified registers, specified as a JavaScript array where each element is a string specifying the register name.
putPushRegs(regs):将 PUSH 指令与指定的寄存器一起放置,指定为 JavaScript 数组,其中每个元素都是指定寄存器名称的字符串。

putPopRegs(regs): put a POP instruction with the specified registers, specified as a JavaScript array where each element is a string specifying the register name.
putPopRegs(regs):将 POP 指令与指定的寄存器一起放置,指定为 JavaScript 数组,其中每个元素都是指定寄存器名称的字符串。

putVpushRange(firstReg, lastReg): put a VPUSH RANGE instruction
putVpushRange(firstReg, lastReg):输入 VPUSH RANGE 指令

putVpopRange(firstReg, lastReg): put a VPOP RANGE instruction
putVpopRange(firstReg, lastReg):输入 VPOP RANGE 指令

putLdrRegAddress(reg, address): put an LDR instruction
putLdrRegAddress(reg, address):输入 LDR 指令

putLdrRegU32(reg, val): put an LDR instruction
putLdrRegU32(reg, val):输入 LDR 指令

putLdrRegReg(dstReg, srcReg): put an LDR instruction
putLdrRegReg(dstReg, srcReg):输入 LDR 指令

putLdrRegRegOffset(dstReg, srcReg, srcOffset): put an LDR instruction
putLdrRegRegOffset(dstReg, srcReg, srcOffset):输入 LDR 指令

putLdrbRegReg(dstReg, srcReg): put an LDRB instruction
putLdrbRegReg(dstReg, srcReg):发出LDRB指令

putVldrRegRegOffset(dstReg, srcReg, srcOffset): put a VLDR instruction
putVldrRegRegOffset(dstReg, srcReg, srcOffset):输入 VLDR 指令

putLdmiaRegMask(reg, mask): put an LDMIA MASK instruction
putLdmiaRegMask(reg, mask):放置LDMIA MASK指令

putStrRegReg(srcReg, dstReg): put a STR instruction
putStrRegReg(srcReg, dstReg):放置 STR 指令

putStrRegRegOffset(srcReg, dstReg, dstOffset): put a STR instruction
putStrRegRegOffset(srcReg, dstReg, dstOffset):放置 STR 指令

putMovRegReg(dstReg, srcReg): put a MOV instruction
putMovRegReg(dstReg, srcReg):放置 MOV 指令

putMovRegU8(dstReg, immValue): put a MOV instruction
putMovRegU8(dstReg, immValue):放置 MOV 指令

putMovRegCpsr(reg): put a MOV CPSR instruction
putMovRegCpsr(reg):放置 MOV CPSR 指令

putMovCpsrReg(reg): put a MOV CPSR instruction
putMovCpsrReg(reg):放置 MOV CPSR 指令

putAddRegImm(dstReg, immValue): put an ADD instruction
putAddRegImm(dstReg, immValue):输入ADD指令

putAddRegReg(dstReg, srcReg): put an ADD instruction
putAddRegReg(dstReg, srcReg):输入ADD指令

putAddRegRegReg(dstReg, leftReg, rightReg): put an ADD instruction
putAddRegRegReg(dstReg, leftReg, rightReg):输入ADD指令

putAddRegRegImm(dstReg, leftReg, rightValue): put an ADD instruction
putAddRegRegImm(dstReg, leftReg, rightValue):输入ADD指令

putSubRegImm(dstReg, immValue): put a SUB instruction
putSubRegImm(dstReg, immValue):输入 SUB 指令

putSubRegReg(dstReg, srcReg): put a SUB instruction
putSubRegReg(dstReg, srcReg):输入 SUB 指令

putSubRegRegReg(dstReg, leftReg, rightReg): put a SUB instruction
putSubRegRegReg(dstReg, leftReg, rightReg):输入 SUB 指令

putSubRegRegImm(dstReg, leftReg, rightValue): put a SUB instruction
putSubRegRegImm(dstReg, leftReg, rightValue):输入 SUB 指令

putAndRegRegImm(dstReg, leftReg, rightValue): put an AND instruction
putAndRegRegImm(dstReg, leftReg, rightValue):输入 AND 指令

putOrRegRegImm(dstReg, leftReg, rightValue): put an OR instruction
putOrRegRegImm(dstReg, leftReg, rightValue):输入 OR 指令

putLslRegRegImm(dstReg, leftReg, rightValue): put a LSL instruction
putLslRegRegImm(dstReg, leftReg, rightValue):输入LSL指令

putLslsRegRegImm(dstReg, leftReg, rightValue): put a LSLS instruction
putLslsRegRegImm(dstReg, leftReg, rightValue):输入 LSLS 指令

putLsrsRegRegImm(dstReg, leftReg, rightValue): put a LSRS instruction
putLsrsRegRegImm(dstReg, leftReg, rightValue):放置 LSRS 指令

putMrsRegReg(dstReg, srcReg): put a MRS instruction
putMrsRegReg(dstReg, srcReg):放置 MRS 指令

putMsrRegReg(dstReg, srcReg): put a MSR instruction
putMsrRegReg(dstReg, srcReg):放置 MSR 指令

putNop(): put a NOP instruction
putNop():输入NOP指令

putBkptImm(imm): put a BKPT instruction
putBkptImm(imm):输入BKPT指令

putBreakpoint(): put an OS/architecture-specific breakpoint instruction
putBreakpoint():放置特定于操作系统/体系结构的断点指令

putInstruction(insn): put a raw instruction as a JavaScript Number
putInstruction(insn):将原始指令作为 JavaScript 编号

putInstructionWide(upper, lower): put a raw Thumb-2 instruction from two JavaScript Number values
putInstructionWide(upper, lower):从两个 JavaScript Number 值中放入一个原始的 Thumb-2 指令

putBytes(data): put raw data from the provided ArrayBuffer
putBytes(data):从提供的 ArrayBuffer 中放置原始数据

ThumbRelocator 拇指定位器

new ThumbRelocator(inputCode, output): create a new code relocator for copying ARM instructions from one memory location to another, taking care to adjust position-dependent instructions accordingly. The source address is specified by inputCode, a NativePointer. The destination is given by output, a ThumbWriter pointed at the desired target memory address.
new ThumbRelocator(inputCode, output):创建一个新的代码重定位器,用于将 ARM 指令从一个内存位置复制到另一个内存位置,并注意相应地调整与位置相关的指令。源地址由 inputCode 指定,即 NativePointer。目标由 output 给出,ThumbWriter 指向所需的目标内存地址。

reset(inputCode, output): recycle instance
reset(inputCode, output):回收实例

dispose(): eagerly clean up memory
dispose():急切地清理记忆

input: latest Instruction read so far. Starts out null and changes on every call to readOne().
input:到目前为止阅读的最新指令。从 null 开始,并在每次调用 readOne() 时发生变化。

eob: boolean indicating whether end-of-block has been reached, i.e. we’ve reached a branch of any kind, like CALL, JMP, BL, RET.
eob:布尔值,表示是否已到达区块末尾,即我们已到达任何类型的分支,如 CALL、JMP、BL、RET。

eoi: boolean indicating whether end-of-input has been reached, e.g. we’ve reached JMP/B/RET, an instruction after which there may or may not be valid code.
eoi:布尔值,表示是否已达到输入结束,例如,我们已达到 JMP/B/RET,该指令之后可能有也可能没有有效代码。

readOne(): read the next instruction into the relocator’s internal buffer and return the number of bytes read so far, including previous calls. You may keep calling this method to keep buffering, or immediately call either writeOne() or skipOne(). Or, you can buffer up until the desired point and then call writeAll(). Returns zero when end-of-input is reached, which means the eoi property is now true.
readOne():将下一条指令读取到重定位器的内部缓冲区中,并返回到目前为止读取的字节数,包括之前的调用。您可以继续调用此方法以保持缓冲,也可以立即调用 writeOne() 或 skipOne()。或者,您可以缓冲到所需的点,然后调用 writeAll()。当达到输入结束时返回零,这意味着 eoi 属性现在为 true。

peekNextWriteInsn(): peek at the next Instruction to be written or skipped
peekNextWriteInsn():查看要编写或跳过的下一条指令

peekNextWriteSource(): peek at the address of the next instruction to be written or skipped
peekNextWriteSource():查看要编写或跳过的下一条指令的地址

skipOne(): skip the instruction that would have been written next
skipOne():跳过接下来要写的指令

writeOne(): write the next buffered instruction
writeOne():写入下一个缓冲指令

copyOne(): copy out the next buffered instruction without advancing the output cursor, allowing the same instruction to be written out multiple times
copyOne():在不前进输出光标的情况下复制出下一个缓冲指令,允许多次写出同一指令

writeAll(): write all buffered instructions
writeAll():写入所有缓冲指令

ARM enum types ARM 枚举类型

Register: r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 sp lr sb sl fp ip pc s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15
寄存器: r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 sp lr sb sl fp ip pc s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s14 s8 s9 s10 s11 s12 s13 s14 s14 s9 s10 s11 s12 s13 s14 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15
SystemRegister: apsr-nzcvq 系统注册表:apsr-nzcvq
ConditionCode: eq ne hs lo mi pl vs vc hi ls ge lt gt le al
条件码: eq ne hs lo mi pl vs vc hi ls ge lt gt le al
Shifter: asr lsl lsr ror rrx asr-reg lsl-reg lsr-reg ror-reg rrx-reg
变速杆: asr lsl lsr ror rrx asr-reg lsl-reg lsr-reg ror-reg rrx-reg

Arm64Writer Arm64写入器

new Arm64Writer(codeAddress[, { pc: ptr('0x1234') }]): create a new code writer for generating AArch64 machine code written directly to memory at codeAddress, specified as a NativePointer. The second argument is an optional options object where the initial program counter may be specified, which is useful when generating code to a scratch buffer. This is essential when using Memory.patchCode() on iOS, which may provide you with a temporary location that later gets mapped into memory at the intended memory location.
new Arm64Writer(codeAddress[, { pc: ptr('0x1234') }]):创建一个新的代码编写器,用于生成直接写入内存的 AArch64 机器代码 codeAddress,指定为 NativePointer。第二个参数是一个可选的 options 对象,其中可以指定初始程序计数器,这在将代码生成到暂存缓冲区时非常有用。在 iOS 上使用 Memory.patchCode() 时,这是必不可少的,它可能会为您提供一个临时位置,稍后该位置会映射到预期内存位置的内存中。

reset(codeAddress[, { pc: ptr('0x1234') }]): recycle instance
reset(codeAddress[, { pc: ptr('0x1234') }]):回收实例

dispose(): eagerly clean up memory
dispose():急切地清理记忆

flush(): resolve label references and write pending data to memory. You should always call this once you’ve finished generating code. It is usually also desirable to do this between pieces of unrelated code, e.g. when generating multiple functions in one go.
flush():解析标签引用并将挂起的数据写入内存。在完成代码生成后,应始终调用此函数。通常还希望在不相关的代码段之间执行此操作,例如,在一次生成多个函数时。

base: memory location of the first byte of output, as a NativePointer
base:输出第一个字节的内存位置,作为 NativePointer

code: memory location of the next byte of output, as a NativePointer
code:输出的下一个字节的内存位置,作为 NativePointer

pc: program counter at the next byte of output, as a NativePointer
pc:在输出的下一个字节处编程计数器,作为 NativePointer

offset: current offset as a JavaScript Number
offset:作为 JavaScript 数字的当前偏移量

skip(nBytes): skip nBytes skip(nBytes):跳过 nBytes

putLabel(id): put a label at the current position, where id is a string that may be referenced in past and future put*Label() calls
putLabel(id):在当前位置放置一个标签,其中 id 是可以在过去和将来的 put*Label() 调用中引用的字符串

putCallAddressWithArguments(func, args): put code needed for calling a C function with the specified args, specified as a JavaScript array where each element is either a string specifying the register, or a Number or NativePointer specifying the immediate value.
putCallAddressWithArguments(func, args):使用指定的 args 放置调用 C 函数所需的代码,指定为 JavaScript 数组,其中每个元素要么是指定寄存器的字符串,要么是指定即时值的 Number 或 NativePointer。

putCallRegWithArguments(reg, args): put code needed for calling a C function with the specified args, specified as a JavaScript array where each element is either a string specifying the register, or a Number or NativePointer specifying the immediate value.
putCallRegWithArguments(reg, args):使用指定的 args 放置调用 C 函数所需的代码,指定为 JavaScript 数组,其中每个元素要么是指定寄存器的字符串,要么是指定即时值的 Number 或 NativePointer。

putBranchAddress(address): put code needed for branching/jumping to the given address
putBranchAddress(address):将分支/跳转到给定地址所需的代码

canBranchDirectlyBetween(from, to): determine whether a direct branch is possible between the two given memory locations
canBranchDirectlyBetween(from, to):确定两个给定内存位置之间是否可能存在直接分支

putBImm(address): put a B instruction
putBImm(address):输入 B 指令

putBLabel(labelId): put a B instruction referencing labelId, defined by a past or future putLabel()
putBLabel(labelId):放置一个引用 labelId 的 B 指令,由过去或未来的 putLabel() 定义

putBCondLabel(cc, labelId): put a B COND instruction referencing labelId, defined by a past or future putLabel()
putBCondLabel(cc, labelId):放置一个引用 labelId 的 B COND 指令,由过去或未来的 putLabel() 定义

putBlImm(address): put a BL instruction
putBlImm(address):放置 BL 指令

putBlLabel(labelId): put a BL instruction referencing labelId, defined by a past or future putLabel()
putBlLabel(labelId):放置一个引用 labelId 的 BL 指令,由过去或将来的 putLabel() 定义

putBrReg(reg): put a BR instruction
putBrReg(reg):放置 BR 指令

putBrRegNoAuth(reg): put a BR instruction expecting a raw pointer without any authentication bits
putBrRegNoAuth(reg):放置一个 BR 指令,该指令需要没有任何身份验证位的原始指针

putBlrReg(reg): put a BLR instruction
putBlrReg(reg):放置 BLR 指令

putBlrRegNoAuth(reg): put a BLR instruction expecting a raw pointer without any authentication bits
putBlrRegNoAuth(reg):放置一个 BLR 指令,该指令需要没有任何身份验证位的原始指针

putRet(): put a RET instruction
putRet():输入RET指令

putRetReg(reg): put a RET instruction
putRetReg(reg):输入RET指令

putCbzRegImm(reg, target): put a CBZ instruction
putCbzRegImm(reg, target):放置 CBZ 指令

putCbnzRegImm(reg, target): put a CBNZ instruction
putCbnzRegImm(reg, target):输入CBNZ指令

putCbzRegLabel(reg, labelId): put a CBZ instruction referencing labelId, defined by a past or future putLabel()
putCbzRegLabel(reg, labelId):放置引用 labelId 的 CBZ 指令,由过去或将来的 putLabel() 定义

putCbnzRegLabel(reg, labelId): put a CBNZ instruction referencing labelId, defined by a past or future putLabel()
putCbnzRegLabel(reg, labelId):放置引用 labelId 的 CBNZ 指令,由过去或将来的 putLabel() 定义

putTbzRegImmImm(reg, bit, target): put a TBZ instruction
putTbzRegImmImm(reg, bit, target):放置 TBZ 指令

putTbnzRegImmImm(reg, bit, target): put a TBNZ instruction
putTbnzRegImmImm(reg, bit, target):输入 TBNZ 指令

putTbzRegImmLabel(reg, bit, labelId): put a TBZ instruction referencing labelId, defined by a past or future putLabel()
putTbzRegImmLabel(reg, bit, labelId):放置引用 labelId 的 TBZ 指令,由过去或将来的 putLabel() 定义

putTbnzRegImmLabel(reg, bit, labelId): put a TBNZ instruction referencing labelId, defined by a past or future putLabel()
putTbnzRegImmLabel(reg, bit, labelId):放置一个引用 labelId 的 TBNZ 指令,由过去或未来的 putLabel() 定义

putPushRegReg(regA, regB): put a PUSH instruction
putPushRegReg(regA, regB):输入 PUSH 指令

putPopRegReg(regA, regB): put a POP instruction
putPopRegReg(regA, regB):输入 POP 指令

putPushAllXRegisters(): put code needed for pushing all X registers on the stack
putPushAllXRegisters():将所有 X 寄存器推送到堆栈上所需的代码

putPopAllXRegisters(): put code needed for popping all X registers off the stack
putPopAllXRegisters():将所有 X 寄存器从堆栈中弹出所需的代码

putPushAllQRegisters(): put code needed for pushing all Q registers on the stack
putPushAllQRegisters():将所有 Q 寄存器推送到堆栈上所需的代码

putPopAllQRegisters(): put code needed for popping all Q registers off the stack
putPopAllQRegisters():将所有 Q 寄存器从堆栈中弹出所需的代码

putLdrRegAddress(reg, address): put an LDR instruction
putLdrRegAddress(reg, address):输入 LDR 指令

putLdrRegU32(reg, val): put an LDR instruction
putLdrRegU32(reg, val):输入 LDR 指令

putLdrRegU64(reg, val): put an LDR instruction
putLdrRegU64(reg, val):输入 LDR 指令

putLdrRegU32Ptr(reg, srcAddress): put an LDR instruction
putLdrRegU32Ptr(reg, srcAddress):输入 LDR 指令

putLdrRegU64Ptr(reg, srcAddress): put an LDR instruction
putLdrRegU64Ptr(reg, srcAddress):输入 LDR 指令

putLdrRegRef(reg): put an LDR instruction with a dangling data reference, returning an opaque ref value that should be passed to putLdrRegValue() at the desired location
putLdrRegRef(reg):放置一个带有悬空数据引用的 LDR 指令,返回一个不透明的 ref 值,该值应传递给所需位置的 putLdrRegValue()

putLdrRegValue(ref, value): put the value and update the LDR instruction from a previous putLdrRegRef()
putLdrRegValue(ref, value):输入值并更新之前 putLdrRegRef() 的 LDR 指令

putLdrRegReg(dstReg, srcReg): put an LDR instruction
putLdrRegReg(dstReg, srcReg):输入 LDR 指令

putLdrRegRegOffset(dstReg, srcReg, srcOffset): put an LDR instruction
putLdrRegRegOffset(dstReg, srcReg, srcOffset):输入 LDR 指令

putLdrRegRegOffsetMode(dstReg, srcReg, srcOffset, mode): put an LDR MODE instruction
putLdrRegRegOffsetMode(dstReg, srcReg, srcOffset, mode):输入 LDR MODE 指令

putLdrswRegRegOffset(dstReg, srcReg, srcOffset): put an LDRSW instruction
putLdrswRegRegOffset(dstReg, srcReg, srcOffset):输入 LDRSW 指令

putAdrpRegAddress(reg, address): put an ADRP instruction
putAdrpRegAddress(reg, address):输入ADRP指令

putStrRegReg(srcReg, dstReg): put a STR instruction
putStrRegReg(srcReg, dstReg):放置 STR 指令

putStrRegRegOffset(srcReg, dstReg, dstOffset): put a STR instruction
putStrRegRegOffset(srcReg, dstReg, dstOffset):放置 STR 指令

putStrRegRegOffsetMode(srcReg, dstReg, dstOffset, mode): put a STR MODE instruction
putStrRegRegOffsetMode(srcReg, dstReg, dstOffset, mode):输入 STR MODE 指令

putLdpRegRegRegOffset(regA, regB, regSrc, srcOffset, mode): put an LDP instruction
putLdpRegRegRegOffset(regA, regB, regSrc, srcOffset, mode):输入LDP指令

putStpRegRegRegOffset(regA, regB, regDst, dstOffset, mode): put a STP instruction
putStpRegRegRegOffset(regA, regB, regDst, dstOffset, mode):放置 STP 指令

putMovRegReg(dstReg, srcReg): put a MOV instruction
putMovRegReg(dstReg, srcReg):放置 MOV 指令

putMovRegNzcv(reg): put a MOV NZCV instruction
putMovRegNzcv(reg):放置 MOV NZCV 指令

putMovNzcvReg(reg): put a MOV NZCV instruction
putMovNzcvReg(reg):放置 MOV NZCV 指令

putUxtwRegReg(dstReg, srcReg): put an UXTW instruction
putUxtwRegReg(dstReg, srcReg):放置 UXTW 指令

putAddRegRegImm(dstReg, leftReg, rightValue): put an ADD instruction
putAddRegRegImm(dstReg, leftReg, rightValue):输入ADD指令

putAddRegRegReg(dstReg, leftReg, rightReg): put an ADD instruction
putAddRegRegReg(dstReg, leftReg, rightReg):输入ADD指令

putSubRegRegImm(dstReg, leftReg, rightValue): put a SUB instruction
putSubRegRegImm(dstReg, leftReg, rightValue):输入 SUB 指令

putSubRegRegReg(dstReg, leftReg, rightReg): put a SUB instruction
putSubRegRegReg(dstReg, leftReg, rightReg):输入 SUB 指令

putAndRegRegImm(dstReg, leftReg, rightValue): put an AND instruction
putAndRegRegImm(dstReg, leftReg, rightValue):输入 AND 指令

putEorRegRegReg(dstReg, leftReg, rightReg): put an EOR instruction
putEorRegRegReg(dstReg, leftReg, rightReg):输入 EOR 指令

putUbfm(dstReg, srcReg, imms, immr): put an UBFM instruction
putUbfm(dstReg, srcReg, imms, immr):输入 UBFM 指令

putLslRegImm(dstReg, srcReg, shift): put a LSL instruction
putLslRegImm(dstReg, srcReg, shift):输入LSL指令

putLsrRegImm(dstReg, srcReg, shift): put a LSR instruction
putLsrRegImm(dstReg, srcReg, shift):放置 LSR 指令

putTstRegImm(reg, immValue): put a TST instruction
putTstRegImm(reg, immValue):输入 TST 指令

putCmpRegReg(regA, regB): put a CMP instruction
putCmpRegReg(regA, regB):放置 CMP 指令

putXpaciReg(reg): put an XPACI instruction
putXpaciReg(reg):输入 XPACI 指令

putNop(): put a NOP instruction
putNop():输入NOP指令

putBrkImm(imm): put a BRK instruction
putBrkImm(imm):输入 BRK 指令

putMrs(dstReg, systemReg): put a MRS instruction
putMrs(dstReg, systemReg):放置 MRS 指令

putInstruction(insn): put a raw instruction as a JavaScript Number
putInstruction(insn):将原始指令作为 JavaScript 编号

putBytes(data): put raw data from the provided ArrayBuffer
putBytes(data):从提供的 ArrayBuffer 中放置原始数据

sign(value): sign the given pointer value
sign(value):对给定的指针值进行签名

Arm64Relocator Arm64搬迁器

new Arm64Relocator(inputCode, output): create a new code relocator for copying AArch64 instructions from one memory location to another, taking care to adjust position-dependent instructions accordingly. The source address is specified by inputCode, a NativePointer. The destination is given by output, an Arm64Writer pointed at the desired target memory address.
new Arm64Relocator(inputCode, output):创建一个新的代码重定位器,用于将 AArch64 指令从一个内存位置复制到另一个内存位置,并注意相应地调整与位置相关的指令。源地址由 inputCode 指定,即 NativePointer。目标由 output 给出,Arm64Writer 指向所需的目标内存地址。

reset(inputCode, output): recycle instance
reset(inputCode, output):回收实例

dispose(): eagerly clean up memory
dispose():急切地清理记忆

input: latest Instruction read so far. Starts out null and changes on every call to readOne().
input:到目前为止阅读的最新指令。从 null 开始,并在每次调用 readOne() 时发生变化。

eob: boolean indicating whether end-of-block has been reached, i.e. we’ve reached a branch of any kind, like CALL, JMP, BL, RET.
eob:布尔值,表示是否已到达区块末尾,即我们已到达任何类型的分支,如 CALL、JMP、BL、RET。

eoi: boolean indicating whether end-of-input has been reached, e.g. we’ve reached JMP/B/RET, an instruction after which there may or may not be valid code.
eoi:布尔值,表示是否已达到输入结束,例如,我们已达到 JMP/B/RET,该指令之后可能有也可能没有有效代码。

readOne(): read the next instruction into the relocator’s internal buffer and return the number of bytes read so far, including previous calls. You may keep calling this method to keep buffering, or immediately call either writeOne() or skipOne(). Or, you can buffer up until the desired point and then call writeAll(). Returns zero when end-of-input is reached, which means the eoi property is now true.
readOne():将下一条指令读取到重定位器的内部缓冲区中,并返回到目前为止读取的字节数,包括之前的调用。您可以继续调用此方法以保持缓冲,也可以立即调用 writeOne() 或 skipOne()。或者,您可以缓冲到所需的点,然后调用 writeAll()。当达到输入结束时返回零,这意味着 eoi 属性现在为 true。

peekNextWriteInsn(): peek at the next Instruction to be written or skipped
peekNextWriteInsn():查看要编写或跳过的下一条指令

peekNextWriteSource(): peek at the address of the next instruction to be written or skipped
peekNextWriteSource():查看要编写或跳过的下一条指令的地址

skipOne(): skip the instruction that would have been written next
skipOne():跳过接下来要写的指令

writeOne(): write the next buffered instruction
writeOne():写入下一个缓冲指令

writeAll(): write all buffered instructions
writeAll():写入所有缓冲指令

AArch64 enum types AArch64 枚举类型

Register: x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 w0 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 w30 sp lr fp wsp wzr xzr nzcv ip0 ip1 s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 q16 q17 q18 q19 q20 q21 q22 q23 q24 q25 q26 q27 q28 q29 q30 q31
寄存器: x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 w0 w1 w2 w3 w4 w5 w6 w6 w0 w1 w2 w3 w4 w5 w6 w6 w1 w2 w3 w4 w5 w6 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 w30 sp lr fp wsp wzr xzr nzcv ip0 ip1 s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 q16 q17 q18 q19 q20 q21 q22 q23 q24 q25 q26 q27 q28 q29 q30 q31
ConditionCode: eq ne hs lo mi pl vs vc hi ls ge lt gt le al nv
条件代码: eq ne hs lo mi pl vs vc hi ls ge lt gt le al nv
IndexMode: post-adjust signed-offset pre-adjust
索引模式: post-adjust signed-offset pre-adjust

MipsWriter

new MipsWriter(codeAddress[, { pc: ptr('0x1234') }]): create a new code writer for generating MIPS machine code written directly to memory at codeAddress, specified as a NativePointer. The second argument is an optional options object where the initial program counter may be specified, which is useful when generating code to a scratch buffer. This is essential when using Memory.patchCode() on iOS, which may provide you with a temporary location that later gets mapped into memory at the intended memory location.
new MipsWriter(codeAddress[, { pc: ptr('0x1234') }]):创建一个新的代码编写器,用于生成直接写入内存的 MIPS 机器代码 codeAddress,指定为 NativePointer。第二个参数是一个可选的 options 对象,其中可以指定初始程序计数器,这在将代码生成到暂存缓冲区时非常有用。在 iOS 上使用 Memory.patchCode() 时,这是必不可少的,它可能会为您提供一个临时位置,稍后该位置会映射到预期内存位置的内存中。

reset(codeAddress[, { pc: ptr('0x1234') }]): recycle instance
reset(codeAddress[, { pc: ptr('0x1234') }]):回收实例

dispose(): eagerly clean up memory
dispose():急切地清理记忆

flush(): resolve label references and write pending data to memory. You should always call this once you’ve finished generating code. It is usually also desirable to do this between pieces of unrelated code, e.g. when generating multiple functions in one go.
flush():解析标签引用并将挂起的数据写入内存。在完成代码生成后,应始终调用此函数。通常还希望在不相关的代码段之间执行此操作,例如,在一次生成多个函数时。

base: memory location of the first byte of output, as a NativePointer
base:输出第一个字节的内存位置,作为 NativePointer

code: memory location of the next byte of output, as a NativePointer
code:输出的下一个字节的内存位置,作为 NativePointer

pc: program counter at the next byte of output, as a NativePointer
pc:在输出的下一个字节处编程计数器,作为 NativePointer

offset: current offset as a JavaScript Number
offset:作为 JavaScript 数字的当前偏移量

skip(nBytes): skip nBytes skip(nBytes):跳过 nBytes

putLabel(id): put a label at the current position, where id is a string that may be referenced in past and future put*Label() calls
putLabel(id):在当前位置放置一个标签,其中 id 是可以在过去和将来的 put*Label() 调用中引用的字符串

putCallAddressWithArguments(func, args): put code needed for calling a C function with the specified args, specified as a JavaScript array where each element is either a string specifying the register, or a Number or NativePointer specifying the immediate value.
putCallAddressWithArguments(func, args):使用指定的 args 放置调用 C 函数所需的代码,指定为 JavaScript 数组,其中每个元素要么是指定寄存器的字符串,要么是指定即时值的 Number 或 NativePointer。

putCallRegWithArguments(reg, args): put code needed for calling a C function with the specified args, specified as a JavaScript array where each element is either a string specifying the register, or a Number or NativePointer specifying the immediate value.
putCallRegWithArguments(reg, args):使用指定的 args 放置调用 C 函数所需的代码,指定为 JavaScript 数组,其中每个元素要么是指定寄存器的字符串,要么是指定即时值的 Number 或 NativePointer。

putJAddress(address): put a J instruction
putJAddress(address):输入 J 指令

putJAddressWithoutNop(address): put a J WITHOUT NOP instruction
putJAddressWithoutNop(address):放置一个没有 NOP 指令的 J

putJLabel(labelId): put a J instruction referencing labelId, defined by a past or future putLabel()
putJLabel(labelId):放置一个引用 labelId 的 J 指令,由过去或未来的 putLabel() 定义

putJrReg(reg): put a JR instruction
putJrReg(reg):输入JR指令

putJalAddress(address): put a JAL instruction
putJalAddress(address):输入 JAL 指令

putJalrReg(reg): put a JALR instruction
putJalrReg(reg):输入 JALR 指令

putBOffset(offset): put a B instruction
putBOffset(offset):输入 B 指令

putBeqRegRegLabel(rightReg, leftReg, labelId): put a BEQ instruction referencing labelId, defined by a past or future putLabel()
putBeqRegRegLabel(rightReg, leftReg, labelId):放置引用 labelId 的 BEQ 指令,由过去或将来的 putLabel() 定义

putRet(): put a RET instruction
putRet():输入RET指令

putLaRegAddress(reg, address): put a LA instruction
putLaRegAddress(reg, address):放置 LA 指令

putLuiRegImm(reg, imm): put a LUI instruction
putLuiRegImm(reg, imm):放置 LUI 指令

putDsllRegReg(dstReg, srcReg, amount): put a DSLL instruction
putDsllRegReg(dstReg, srcReg, amount):输入 DSLL 指令

putOriRegRegImm(rt, rs, imm): put an ORI instruction
putOriRegRegImm(rt, rs, imm):输入 ORI 指令

putLdRegRegOffset(dstReg, srcReg, srcOffset): put an LD instruction
putLdRegRegOffset(dstReg, srcReg, srcOffset):输入LD指令

putLwRegRegOffset(dstReg, srcReg, srcOffset): put a LW instruction
putLwRegRegOffset(dstReg, srcReg, srcOffset):输入 LW 指令

putSwRegRegOffset(srcReg, dstReg, dstOffset): put a SW instruction
putSwRegRegOffset(srcReg, dstReg, dstOffset):输入软件指令

putMoveRegReg(dstReg, srcReg): put a MOVE instruction
putMoveRegReg(dstReg, srcReg):输入 MOVE 指令

putAdduRegRegReg(dstReg, leftReg, rightReg): put an ADDU instruction
putAdduRegRegReg(dstReg, leftReg, rightReg):输入 ADDU 指令

putAddiRegRegImm(dstReg, leftReg, imm): put an ADDI instruction
putAddiRegRegImm(dstReg, leftReg, imm):输入ADDI指令

putAddiRegImm(dstReg, imm): put an ADDI instruction
putAddiRegImm(dstReg, imm):输入ADDI指令

putSubRegRegImm(dstReg, leftReg, imm): put a SUB instruction
putSubRegRegImm(dstReg, leftReg, imm):输入 SUB 指令

putPushReg(reg): put a PUSH instruction
putPushReg(reg):输入 PUSH 指令

putPopReg(reg): put a POP instruction
putPopReg(reg):输入 POP 指令

putMfhiReg(reg): put a MFHI instruction
putMfhiReg(reg):输入 MFHI 指令

putMfloReg(reg): put a MFLO instruction
putMfloReg(reg):输入 MFLO 指令

putMthiReg(reg): put a MTHI instruction
putMthiReg(reg):放置 MTHI 指令

putMtloReg(reg): put a MTLO instruction
putMtloReg(reg):放置 MTLO 指令

putNop(): put a NOP instruction
putNop():输入NOP指令

putBreak(): put a BREAK instruction
putBreak():输入 BREAK 指令

putPrologueTrampoline(reg, address): put a minimal sized trampoline for vectoring to the given address
putPrologueTrampoline(reg, address):放置一个最小尺寸的蹦床,用于向给定地址进行矢量化

putInstruction(insn): put a raw instruction as a JavaScript Number
putInstruction(insn):将原始指令作为 JavaScript 编号

putBytes(data): put raw data from the provided ArrayBuffer
putBytes(data):从提供的 ArrayBuffer 中放置原始数据

MipsRelocator MipsRelocator(米普斯搬迁器)

new MipsRelocator(inputCode, output): create a new code relocator for copying MIPS instructions from one memory location to another, taking care to adjust position-dependent instructions accordingly. The source address is specified by inputCode, a NativePointer. The destination is given by output, a MipsWriter pointed at the desired target memory address.
new MipsRelocator(inputCode, output):创建一个新的代码重定位器,用于将MIPS指令从一个存储器位置复制到另一个存储器位置,并注意相应地调整与位置相关的指令。源地址由 inputCode 指定,即 NativePointer。目标由 output 给出,MipsWriter 指向所需的目标内存地址。

reset(inputCode, output): recycle instance
reset(inputCode, output):回收实例

dispose(): eagerly clean up memory
dispose():急切地清理记忆

input: latest Instruction read so far. Starts out null and changes on every call to readOne().
input:到目前为止阅读的最新指令。从 null 开始,并在每次调用 readOne() 时发生变化。

eob: boolean indicating whether end-of-block has been reached, i.e. we’ve reached a branch of any kind, like CALL, JMP, BL, RET.
eob:布尔值,表示是否已到达区块末尾,即我们已到达任何类型的分支,如 CALL、JMP、BL、RET。

eoi: boolean indicating whether end-of-input has been reached, e.g. we’ve reached JMP/B/RET, an instruction after which there may or may not be valid code.
eoi:布尔值,表示是否已达到输入结束,例如,我们已达到 JMP/B/RET,该指令之后可能有也可能没有有效代码。

readOne(): read the next instruction into the relocator’s internal buffer and return the number of bytes read so far, including previous calls. You may keep calling this method to keep buffering, or immediately call either writeOne() or skipOne(). Or, you can buffer up until the desired point and then call writeAll(). Returns zero when end-of-input is reached, which means the eoi property is now true.
readOne():将下一条指令读取到重定位器的内部缓冲区中,并返回到目前为止读取的字节数,包括之前的调用。您可以继续调用此方法以保持缓冲,也可以立即调用 writeOne() 或 skipOne()。或者,您可以缓冲到所需的点,然后调用 writeAll()。当达到输入结束时返回零,这意味着 eoi 属性现在为 true。

peekNextWriteInsn(): peek at the next Instruction to be written or skipped
peekNextWriteInsn():查看要编写或跳过的下一条指令

peekNextWriteSource(): peek at the address of the next instruction to be written or skipped
peekNextWriteSource():查看要编写或跳过的下一条指令的地址

skipOne(): skip the instruction that would have been written next
skipOne():跳过接下来要写的指令

writeOne(): write the next buffered instruction
writeOne():写入下一个缓冲指令

writeAll(): write all buffered instructions
writeAll():写入所有缓冲指令

MIPS enum types MIPS 枚举类型

Register: v0 v1 a0 a1 a2 a3 t0 t1 t2 t3 t4 t5 t6 t7 s0 s1 s2 s3 s4 s5 s6 s7 t8 t9 k0 k1 gp sp fp s8 ra hi lo zero at 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
寄存器: v0 v1 a0 a1 a2 a3 t0 t1 t2 t3 t4 t5 t6 t7 s0 s1 s2 s3 s4 s5 s6 s7 t8 t9 k0 k1 gp sp fp s8 ra hi lo zero zero hi 4] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

Others 别人
Console 安慰

console.log(line), console.warn(line), console.error(line): write line to the console of your Frida-based application. The exact behavior depends on where frida-core is integrated. For example, this output goes to stdout or stderr when using Frida through frida-python, qDebug when using frida-qml, etc.
console.log(line)、console.warn(line)、console.error(line):将 line 写入基于 Frida 的应用程序的控制台。确切的行为取决于 frida-core 的集成位置。例如,当通过 frida-python 使用 Frida 时,此输出将转到 stdout 或 stderr,使用 frida-qml 时,此输出将转到 qDebug,等等。

Arguments that are ArrayBuffer objects will be substituted by the result of hexdump() with default options.
作为 ArrayBuffer 对象的参数将被 hexdump() 的结果替换为默认选项。

Hexdump 十六进制转储

hexdump(target[, options]): generate a hexdump from the provided ArrayBuffer or NativePointer target, optionally with options for customizing the output.
hexdump(target[, options]):从提供的 ArrayBuffer 或 NativePointer target 生成十六进制转储,可以选择使用 options 自定义输出。

For example: 例如:

const libc = Module.findBaseAddress(‘libc.so’);
console.log(hexdump(libc, {
offset: 0,
length: 64,
header: true,
ansi: true
}));

       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF

00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 .ELF…
00000010 03 00 28 00 01 00 00 00 00 00 00 00 34 00 00 00 …(…4…
00000020 34 a8 04 00 00 00 00 05 34 00 20 00 08 00 28 00 4…4. …(.
00000030 1e 00 1d 00 06 00 00 00 34 00 00 00 34 00 00 00 …4…4…

Shorthand 速记

int64(v): short-hand for new Int64(v)
int64(v):新 Int64(v) 的简写

uint64(v): short-hand for new UInt64(v)
uint64(v):新 UInt64(v) 的简写

ptr(s): short-hand for new NativePointer(s)
ptr(s):新 NativePointer 的简写

NULL: short-hand for ptr("0")
NULL:ptr("0") 的简写

Communication between host and injected process
主机与注入进程之间的通信

recv([type, ]callback): request callback to be called on the next message received from your Frida-based application. Optionally type may be specified to only receive a message where the type field is set to type.
recv([type, ]callback):请求在从基于 Frida 的应用程序收到的下一条消息时调用 callback。(可选)可以将 type 指定为仅接收 type 字段设置为 type 的消息。

The message is passed in the first argument, and in case binary data was passed along with it, the second argument is an ArrayBuffer, otherwise null.
消息在第一个参数中传递,如果二进制数据随它一起传递,则第二个参数是 ArrayBuffer,否则为 null。

This will only give you one message, so you need to call recv() again to receive the next one.
这只会给你一条消息,所以你需要再次调用recv()才能接收下一条消息。

send(message[, data]): send the JavaScript object message to your Frida-based application (it must be serializable to JSON). If you also have some raw binary data that you’d like to send along with it, e.g. you dumped some memory using NativePointer#readByteArray, then you may pass this through the optional data argument. This requires it to either be an ArrayBuffer or an array of integers between 0 and 255.
send(message[, data]):将 JavaScript 对象 message 发送到基于 Frida 的应用程序(它必须可序列化为 JSON)。如果您还想发送一些原始二进制数据,例如,您使用 NativePointer#readByteArray 转储了一些内存,那么您可以通过可选的 data 参数传递它。这要求它要么是 ArrayBuffer,要么是介于 0 和 255 之间的整数数组。
Performance considerations
性能注意事项

While send() is asynchronous, the total overhead of sending a single message is not optimized for high frequencies, so that means Frida leaves it up to you to batch multiple values into a single send()-call, based on whether low delay or high throughput is desired.
虽然 send() 是异步的,但发送单条消息的总开销并未针对高频进行优化,因此这意味着 Frida 会根据是需要低延迟还是高吞吐量,将多个值批处理到单个 send() 调用中。

rpc.exports: empty object that you can either replace or insert into to expose an RPC-style API to your application. The key specifies the method name and the value is your exported function. This function may either return a plain value for returning that to the caller immediately, or a Promise for returning asynchronously.
rpc.exports:可以替换或插入的空对象,以向应用程序公开 RPC 样式的 API。该键指定方法名称,值为导出的函数。此函数可以返回一个普通值,以便立即将其返回给调用方,也可以返回一个 Promise 用于异步返回。

For example: 例如:

rpc.exports = {
add(a, b) {
return a + b;
},
sub(a, b) {
return new Promise(resolve => {
setTimeout(() => {
resolve(a - b);
}, 100);
});
}
};

From an application using the Node.js bindings this API would be consumed like this:
在使用 Node.js 绑定的应用程序中,此 API 将按如下方式使用:

const frida = require(‘frida’);
const fs = require(‘fs’);
const path = require(‘path’);
const util = require(‘util’);

const readFile = util.promisify(fs.readFile);

let session, script;
async function run() {
const source = await readFile(path.join(__dirname, ‘_agent.js’), ‘utf8’);
session = await frida.attach(‘iTunes’);
script = await session.createScript(source);
script.message.connect(onMessage);
await script.load();
console.log(await script.exports.add(2, 3));
console.log(await script.exports.sub(5, 3));
}

run().catch(onError);

function onError(error) {
console.error(error.stack);
}

function onMessage(message, data) {
if (message.type === ‘send’) {
console.log(message.payload);
} else if (message.type === ‘error’) {
console.error(message.stack);
}
}

The Python version would be very similar:
Python 版本将非常相似:

import codecs
import frida

def on_message(message, data):
if message[‘type’] == ‘send’:
print(message[‘payload’])
elif message[‘type’] == ‘error’:
print(message[‘stack’])

session = frida.attach(‘iTunes’)
with codecs.open(‘./agent.js’, ‘r’, ‘utf-8’) as f:
source = f.read()
script = session.create_script(source)
script.on(‘message’, on_message)
script.load()
print(script.exports.add(2, 3))
print(script.exports.sub(5, 3))
session.detach()

In the example above we used script.on(‘message’, on_message) to monitor for any messages from the injected process, JavaScript side. There are other notifications that you can watch for as well on both the script and session. If you want to be notified when the target process exits, use session.on(‘detached’, your_function).
在上面的示例中,我们使用 script.on(‘message’, on_message) 来监视来自注入进程(JavaScript 端)的任何消息。 您还可以在 script 和 session 上关注其他通知。如果希望在目标进程退出时收到通知,请使用 session.on(‘detached’, your_function)。
Timing events 计时事件

setTimeout(func, delay[, ...parameters]): call func after delay milliseconds, optionally passing it one or more parameters. Returns an id that can be passed to clearTimeout to cancel it.
setTimeout(func, delay[, ...parameters]):在 delay 毫秒后调用 func,可以选择传递一个或多个 parameters。返回一个 id,该 ID 可以传递给 clearTimeout 以取消它。

clearTimeout(id): cancel id returned by call to setTimeout.
clearTimeout(id):取消调用 setTimeout 返回的 ID。

setInterval(func, delay[, ...parameters]): call func every delay milliseconds, optionally passing it one or more parameters. Returns an id that can be passed to clearInterval to cancel it.
setInterval(func, delay[, ...parameters]):每 delay 毫秒调用 func,可选择传递一个或多个 parameters。返回一个 id,该 ID 可以传递给 clearInterval 以取消它。

clearInterval(id): cancel id returned by call to setInterval.
clearInterval(id):取消调用 setInterval 返回的 ID。

setImmediate(func[, ...parameters]): schedules func to be called on Frida’s JavaScript thread as soon as possible, optionally passing it one or more parameters. Returns an id that can be passed to clearImmediate to cancel it.
setImmediate(func[, ...parameters]):计划尽快在 Frida 的 JavaScript 线程上调用 func,可以选择向它传递一个或多个 parameters。返回一个 id,该 ID 可以传递给 clearImmediate 以取消它。

clearImmediate(id): cancel id returned by call to setImmediate.
clearImmediate(id):取消调用 setImmediate 返回的 ID。

Garbage collection 垃圾回收

gc(): force garbage collection. Useful for testing, especially logic involving Script.bindWeak().
gc():强制垃圾回收。对于测试很有用,尤其是涉及 Script.bindWeak() 的逻辑。

Worker 工人

Worker script with its own JavaScript heap, lock, etc.
具有自己的 JavaScript 堆、锁等的 worker 脚本。

This is useful to move heavy processing to a background thread, allowing hooks to be handled in a timely manner.
这对于将繁重的处理移动到后台线程非常有用,从而可以及时处理钩子。

new Worker(url[, options]): creates a new worker, executing the script at the specified url.
new Worker(url[, options]):创建一个新的工作线程,在指定的 url 处执行脚本。

The URL is typically retrieved by having the module export its import.meta.url, and importing that from the module that creates the worker.
通常通过让模块导出其 import.meta.url 并从创建工作线程的模块导入该 URL 来检索 URL。

If specified, options is an object that may contain one or more of the following keys:
如果指定,则 options 是可能包含以下一个或多个键的对象:
    onMessage: function to call when the worker emits a message using send(). Callback signature is the same as recv().
    onMessage:当 worker 使用 send() 发出消息时调用的函数。回调签名与 recv() 相同。

terminate(): terminates the worker.
terminate():终止工作线程。

post(message[, data]): posts a message to the worker. Signature is identical to send(). Use recv() to receive it inside the worker.
post(message[, data]):向工作人员发布消息。签名与 send() 相同。使用 recv() 在 worker 内部接收它。

exports: magic proxy object for calling rpc.exports defined by the worker. Each function returns a Promise, which you may await inside an async function.
exports:用于调用 worker 定义的 rpc.exports 的魔术代理对象。每个函数都返回一个 Promise,您可以在异步函数中等待它。
  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值