Frida Javascript api #Memory 与 #MemoryAccessMonitor (中文版)

原文链接: https://frida.re/docs/javascript-api/#memory
欢迎加入 Frida 交流群: 1049977261

Memory

  • Memory.scan(address, size, pattern, callbacks):
    根据 NativePointer 类型的 addresssize 扫描内存, 并在满足 pattern 时触发回调.

    • pattern 必须满足 "13 37 ?? ff" 格式才能匹配 0x13 后面跟着 0x37 后面跟着任意字节后面跟着 0xff.
      您可以指定 r2 风格的掩码用于实现更高级的匹配模式.
      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.

    • callbacks 是一个包含以下方法的对象:

      • onMatch: function (address, size): address 包含回调触发时的
        NativePointer 类型的地址, size 指明了以 byte 为单位的尺寸.

        这个方法可以通过返回 stop 字符串来提前终止内存扫描.

      • onError: function (reason): 当内存扫描出现错误时伴随 reason 被调用.

      • onComplete: function (): 当指定的内存范围被完整的扫描过时被调用.

  • Memory.scanSync(address, size, pattern): scan() 的同步执行版本, 返回一个包含以下属性的数组:

    • address 包含 NativePointer 类型的绝对地址.

    • sizebyte 为单位的尺寸.

var m = Process.enumerateModules()[0];// enumerate loaded modules and take the first one
// var m = Module.load('win32u.dll'); // or load module by name
console.log(JSON.stringify(m));// print its properties
console.log(hexdump(m.base));// dump it form its base address
var pattern = '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00';// the pattern that you are interested in
Memory.scan(/*NativePointer*/ m.base, /*number*/ m.size, /*string*/ pattern, {
    onMatch: function (address, size) {// called when pattern matches
        console.log("Memory.scan() found at " + address + " with size " + size);
        return 'stop';// optional, stop scanning early
    },
    onComplete: function () {
        console.log("Memory.scan() complete");
    }
});
var results = Memory.scanSync(m.base, m.size, pattern);
console.log("Memory.scanSync() result = \n" + JSON.stringify(results));
  • Memory.alloc(size): 在堆上分配 size 个字节的内存, 或者, 如果 sizeProcess.pageSize 的倍数, 一个或多个被操作系统管理的原始内存页. 返回的值是一个 NativePointer 对象并且底层的内存将在所有的 JavaScript 脚本
    不再对其持有引用时被释放. 这意味着您需要在这个指针正在被 JavaScript 运行时外的代码使用时维持一个对它的引用.

  • Memory.copy(dst, src, n): 类似于 memcpy.

  • Memory.dup(address, size): 顺序调用 Memory.alloc(), Memory.copy() 的简写.

  • Memory.protect(address, size, protection):
    更新指定范围内存的读写权限, projection 格式与 Process.enumerateRanges() 相同.

    例如:

Memory.protect(ptr('0x1234'), 4096, 'rw-');
  • Memory.patchCode(address, size, apply):
    安全的在 NativePointer 类型的 address 处修改 size 个字节.
    您所提供的 JavaScript 方法 apply 将伴随一个可写的指针被调用, 您必须在该方法返回之前写入预期的修改. 请不要假设这个指针与 address 处于相同的位置, 因为一些系统要求内存改动需要在映射到原内存页的顶部之前先写入到临时位置 (比如在 iOS 上直接修改内存中的代码有可能造成进程丢失 CS_VALID 状态).

    例如:

var getLivesLeft = Module.getExportByName('game-engine.so', 'get_lives_left');
var maxPatchSize = 64; // Do not write out of bounds, may be a temporary buffer!
Memory.patchCode(getLivesLeft, maxPatchSize, function (code) {
  var cw = new X86Writer(code, { pc: getLivesLeft });
  cw.putMovRegU32('eax', 9000);
  cw.putRet();
  cw.flush();
});
  • Memory.allocUtf8String(str),
    Memory.allocUtf16String(str),
    Memory.allocAnsiString(str):
    分配, 编码并且将 str 在堆上写出为一个 UTF-8/UTF-16/ANSI 字符串.
    返回一个 NativePointer 对象. 与其生命周期相关的详情请参考 Memory#alloc.

MemoryAccessMonitor

  • MemoryAccessMonitor.enable(ranges, callbacks):
    监控一个或多个内存范围的访问情况, 并且在每个内存页第一次访问时触发回调.
    ranges 可以是一个范围对象, 也可以是一个由范围对象构成的数组.
    这个对象包含以下属性:

    • base: NativePointer 类型的基础地址
    • size: 以 byte 为单位的尺寸

    callbacks 对象包含以下方法:

    • onAccess: function (details):
      伴随着包含以下属性的 details 对象被同步调用:

      • operation: 触发这次访问的操作类型, 仅限于 read, write, 或 execute.
      • from: NativePointer 类型的触发这次访问的指令的地址
      • address: NativePointer 类型的被访问的地址
      • rangeIndex: 被访问的范围在 MemoryAccessMonitor.enable() 方法的 ranges 参数中的索引
      • pageIndex: 被访问的内存页在指定范围中的索引
      • pagesCompleted: 到目前为止已访问(并且不再受监控)的内存页总数
      • pagesTotal: 已被监控的内存页总数
  • MemoryAccessMonitor.disable():
    停止对传递给 MemoryAccessMonitor.enable() 的剩余的内存页的监控

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,941评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,397评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,345评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,851评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,868评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,688评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,414评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,319评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,775评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,945评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,096评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,789评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,437评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,993评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,107评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,308评论 3 372
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,037评论 2 355

推荐阅读更多精彩内容