frida-mem-scan 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/process/darwin.d.ts +10 -0
- package/dist/process/darwin.js +126 -0
- package/dist/process/index.d.ts +2 -0
- package/dist/process/index.js +12 -0
- package/dist/process/linux.d.ts +9 -0
- package/dist/process/linux.js +19 -0
- package/dist/process/types.d.ts +23 -0
- package/dist/process/types.js +1 -0
- package/dist/process/windows.d.ts +9 -0
- package/dist/process/windows.js +19 -0
- package/dist/scanner/bytes-arm64.d.ts +2 -0
- package/dist/scanner/bytes-arm64.js +106 -0
- package/dist/scanner/bytes-x86_64.d.ts +2 -0
- package/dist/scanner/bytes-x86_64.js +104 -0
- package/dist/scanner/index.d.ts +11 -0
- package/dist/scanner/index.js +140 -0
- package/dist/symbols.d.ts +1 -0
- package/dist/symbols.js +16 -0
- package/dist/target.d.ts +26 -0
- package/dist/target.js +78 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frida-mem-scan
|
|
2
|
+
|
|
3
|
+
Fast SIMD-accelerated memory scanner for Frida. Targets either the
|
|
4
|
+
current process or any other process by PID, with the same API.
|
|
5
|
+
|
|
6
|
+
The scanner core is a self-contained, relocation-free assembly blob
|
|
7
|
+
(SSE4.1 on x86_64, NEON on arm64) that's copied into a JIT page at
|
|
8
|
+
load time. On modern hardware it saturates memory bandwidth on the
|
|
9
|
+
parallel path; see `src/README.md` for measurements on a specific
|
|
10
|
+
machine. The cross-process path uses the platform's native VM API
|
|
11
|
+
(mach\_vm\_\* on macOS, with Windows and Linux backends stubbed for
|
|
12
|
+
future contributions).
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
frida-pm install frida-mem-scan
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { Target } from "frida-mem-scan";
|
|
24
|
+
|
|
25
|
+
// In-process scan: find every Hv::Vm vtable pointer.
|
|
26
|
+
const me = Target.self();
|
|
27
|
+
const hits = me.find(["Hypervisor!_ZTVN2Hv2VmE+16"]);
|
|
28
|
+
for (const h of hits) {
|
|
29
|
+
console.log(h.addr);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Cross-process scan, restricted to readable regions <= 100 MB:
|
|
33
|
+
const t = Target.pid(9549);
|
|
34
|
+
const hits = t.find(["Hypervisor!_ZTVN2Hv2VmE+16"], {
|
|
35
|
+
filter: { readable: true, maxBytes: 100 * 1024 * 1024 },
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Raw memory read (works for both self and cross-process):
|
|
39
|
+
const bytes = t.read(ptr("0x104dbd560"), 128);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Targets are either raw addresses (`NativePointer`, `UInt64`, or
|
|
43
|
+
`number`) or `<module>!<symbol>[+<offset>]` strings that resolve
|
|
44
|
+
against the loaded image set. The `+16` convention matches the
|
|
45
|
+
Itanium C++ ABI vtable address-point so you can scan for object
|
|
46
|
+
instances by their class name.
|
|
47
|
+
|
|
48
|
+
By default a mask of `0x00007ffffffffff8` is applied to each candidate
|
|
49
|
+
slot before equality comparison; that strips arm64e PAC and the
|
|
50
|
+
non-pointer-isa flag bits in one go. Pass your own `mask` to opt out
|
|
51
|
+
or scan for something else (e.g. `~0` for raw equality).
|
|
52
|
+
|
|
53
|
+
## API
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
class Target {
|
|
57
|
+
static self(): Target
|
|
58
|
+
static pid(pid: number): Target
|
|
59
|
+
|
|
60
|
+
find(targets: TargetSpec[], opts?: FindOpts): ScanHit[]
|
|
61
|
+
read(addr: NativePointer, size: number): ArrayBuffer
|
|
62
|
+
regions(filter?: RegionFilter): Iterable<Region>
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface FindOpts {
|
|
66
|
+
mask?: UInt64
|
|
67
|
+
filter?: RegionFilter
|
|
68
|
+
capPerThread?: number
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface RegionFilter {
|
|
72
|
+
readable?: boolean
|
|
73
|
+
writable?: boolean
|
|
74
|
+
executable?: boolean
|
|
75
|
+
tags?: number[] | Set<number>
|
|
76
|
+
minBytes?: number
|
|
77
|
+
maxBytes?: number
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The lower-level `Scanner` class is also exported for callers that
|
|
82
|
+
want to feed in already-prepared buffers without going through the
|
|
83
|
+
`Target` abstraction.
|
|
84
|
+
|
|
85
|
+
## Building
|
|
86
|
+
|
|
87
|
+
The published package ships pre-built JavaScript and TypeScript
|
|
88
|
+
typings; you only need this section if you're modifying the assembly
|
|
89
|
+
core.
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
cd src
|
|
93
|
+
make # builds scan_<arch>.dylib, regenerates ../lib/scanner/bytes-*.ts
|
|
94
|
+
make test # native + Rosetta tests with perf numbers
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The assembly sources, build scripts, and test harness live in `src/`
|
|
98
|
+
and are excluded from the npm package (only `dist/` ships).
|
|
99
|
+
|
|
100
|
+
## Platform support
|
|
101
|
+
|
|
102
|
+
| platform | status |
|
|
103
|
+
| ---------------------------- | ------------------------------------------------------- |
|
|
104
|
+
| Windows | stub (planned: `ReadProcessMemory` + `VirtualQueryEx`) |
|
|
105
|
+
| macOS x86_64 (incl. Rosetta) | full — Mach backend |
|
|
106
|
+
| macOS arm64 (incl. arm64e) | full — Mach backend |
|
|
107
|
+
| Linux | stub (planned: `process_vm_readv` + `/proc/<pid>/maps`) |
|
|
108
|
+
|
|
109
|
+
The scanner SIMD blob itself is platform-neutral; only the
|
|
110
|
+
cross-process VM access needs per-OS implementation.
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ProcessMemory, Region, RegionFilter } from "./types.js";
|
|
2
|
+
export declare class DarwinProcessMemory implements ProcessMemory {
|
|
3
|
+
#private;
|
|
4
|
+
readonly pid: number;
|
|
5
|
+
readonly isSelf: boolean;
|
|
6
|
+
constructor(pid: number);
|
|
7
|
+
regions(filter?: RegionFilter): Iterable<Region>;
|
|
8
|
+
read(addr: NativePointer, size: number): ArrayBuffer | null;
|
|
9
|
+
readInto(addr: NativePointer, dst: NativePointer, size: number): boolean;
|
|
10
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const KERN_SUCCESS = 0;
|
|
2
|
+
const VM_PROT_EXEC = 0x04;
|
|
3
|
+
const VM_PROT_READ = 0x01;
|
|
4
|
+
const VM_PROT_WRITE = 0x02;
|
|
5
|
+
const VM_REGION_INFO_COUNT = 19;
|
|
6
|
+
export class DarwinProcessMemory {
|
|
7
|
+
pid;
|
|
8
|
+
isSelf;
|
|
9
|
+
#task;
|
|
10
|
+
constructor(pid) {
|
|
11
|
+
resolveNatives();
|
|
12
|
+
this.pid = pid;
|
|
13
|
+
this.isSelf = pid === Process.id;
|
|
14
|
+
this.#task = openTask(pid);
|
|
15
|
+
}
|
|
16
|
+
*regions(filter) {
|
|
17
|
+
const wantReadable = filter?.readable === true;
|
|
18
|
+
const wantWritable = filter?.writable === true;
|
|
19
|
+
const wantExecutable = filter?.executable === true;
|
|
20
|
+
const tagSet = makeTagSet(filter?.tags);
|
|
21
|
+
const minBytes = filter?.minBytes;
|
|
22
|
+
const maxBytes = filter?.maxBytes;
|
|
23
|
+
let cursor = NULL;
|
|
24
|
+
while (true) {
|
|
25
|
+
const r = nextRegion(this.#task, cursor);
|
|
26
|
+
if (r === null) {
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
cursor = r.base.add(r.size);
|
|
30
|
+
if (wantReadable && !r.readable) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (wantWritable && !r.writable) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (wantExecutable && !r.executable) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (tagSet !== null && !tagSet.has(r.tag)) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const sz = r.size.toNumber();
|
|
43
|
+
if (minBytes !== undefined && sz < minBytes) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (maxBytes !== undefined && sz > maxBytes) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
yield r;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
read(addr, size) {
|
|
53
|
+
const buf = Memory.alloc(size);
|
|
54
|
+
if (!this.readInto(addr, buf, size)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const view = new Uint8Array(buf.readByteArray(size));
|
|
58
|
+
return view.slice().buffer;
|
|
59
|
+
}
|
|
60
|
+
readInto(addr, dst, size) {
|
|
61
|
+
const outsize = Memory.alloc(8);
|
|
62
|
+
const kr = machVmReadOverwrite(this.#task, addr, uint64(size), dst, outsize);
|
|
63
|
+
return kr === KERN_SUCCESS;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function makeTagSet(tags) {
|
|
67
|
+
if (tags === undefined) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
return tags instanceof Set ? tags : new Set(tags);
|
|
71
|
+
}
|
|
72
|
+
function openTask(pid) {
|
|
73
|
+
if (pid === Process.id) {
|
|
74
|
+
return machTaskSelf;
|
|
75
|
+
}
|
|
76
|
+
const out = Memory.alloc(4);
|
|
77
|
+
const kr = taskForPid(machTaskSelf, pid, out);
|
|
78
|
+
if (kr !== KERN_SUCCESS) {
|
|
79
|
+
throw new Error(`task_for_pid(${pid}) failed: kr=${kr}`);
|
|
80
|
+
}
|
|
81
|
+
return out.readU32();
|
|
82
|
+
}
|
|
83
|
+
function nextRegion(task, startAddr) {
|
|
84
|
+
const ADDR_OFF = 0;
|
|
85
|
+
const SIZE_OFF = 8;
|
|
86
|
+
const DEPTH_OFF = 16;
|
|
87
|
+
const INFO_OFF = 24;
|
|
88
|
+
const COUNT_OFF = 152;
|
|
89
|
+
const TOTAL = 156;
|
|
90
|
+
const scratch = Memory.alloc(TOTAL);
|
|
91
|
+
const addrPtr = scratch.add(ADDR_OFF);
|
|
92
|
+
const sizePtr = scratch.add(SIZE_OFF);
|
|
93
|
+
const depthPtr = scratch.add(DEPTH_OFF);
|
|
94
|
+
const info = scratch.add(INFO_OFF);
|
|
95
|
+
const countPtr = scratch.add(COUNT_OFF);
|
|
96
|
+
addrPtr.writePointer(startAddr);
|
|
97
|
+
depthPtr.writeU32(2048);
|
|
98
|
+
countPtr.writeU32(VM_REGION_INFO_COUNT);
|
|
99
|
+
const kr = machVmRegionRecurse(task, addrPtr, sizePtr, depthPtr, info, countPtr);
|
|
100
|
+
if (kr !== KERN_SUCCESS) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const prot = info.readS32();
|
|
104
|
+
return {
|
|
105
|
+
base: addrPtr.readPointer(),
|
|
106
|
+
size: sizePtr.readU64(),
|
|
107
|
+
readable: (prot & VM_PROT_READ) !== 0,
|
|
108
|
+
writable: (prot & VM_PROT_WRITE) !== 0,
|
|
109
|
+
executable: (prot & VM_PROT_EXEC) !== 0,
|
|
110
|
+
tag: info.add(24).readU32(),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
let machTaskSelf = 0;
|
|
114
|
+
let machVmReadOverwrite = null;
|
|
115
|
+
let machVmRegionRecurse = null;
|
|
116
|
+
let taskForPid = null;
|
|
117
|
+
function resolveNatives() {
|
|
118
|
+
if (taskForPid !== null) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const libSystem = Process.getModuleByName("libSystem.B.dylib");
|
|
122
|
+
machTaskSelf = libSystem.getExportByName("mach_task_self_").readU32();
|
|
123
|
+
taskForPid = new NativeFunction(libSystem.getExportByName("task_for_pid"), "int", ["uint", "int", "pointer"]);
|
|
124
|
+
machVmRegionRecurse = new NativeFunction(libSystem.getExportByName("mach_vm_region_recurse"), "int", ["uint", "pointer", "pointer", "pointer", "pointer", "pointer"]);
|
|
125
|
+
machVmReadOverwrite = new NativeFunction(libSystem.getExportByName("mach_vm_read_overwrite"), "int", ["uint", "pointer", "uint64", "pointer", "pointer"]);
|
|
126
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DarwinProcessMemory } from "./darwin.js";
|
|
2
|
+
import { LinuxProcessMemory } from "./linux.js";
|
|
3
|
+
import { WindowsProcessMemory } from "./windows.js";
|
|
4
|
+
export function openProcessMemory(pid) {
|
|
5
|
+
switch (Process.platform) {
|
|
6
|
+
case "windows": return new WindowsProcessMemory(pid);
|
|
7
|
+
case "darwin": return new DarwinProcessMemory(pid);
|
|
8
|
+
case "linux": return new LinuxProcessMemory(pid);
|
|
9
|
+
default:
|
|
10
|
+
throw new Error(`frida-mem-scan: no backend for platform ${Process.platform}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ProcessMemory, Region, RegionFilter } from "./types.js";
|
|
2
|
+
export declare class LinuxProcessMemory implements ProcessMemory {
|
|
3
|
+
readonly pid: number;
|
|
4
|
+
readonly isSelf: boolean;
|
|
5
|
+
constructor(pid: number);
|
|
6
|
+
regions(_filter?: RegionFilter): Iterable<Region>;
|
|
7
|
+
read(_addr: NativePointer, _size: number): ArrayBuffer | null;
|
|
8
|
+
readInto(_addr: NativePointer, _dst: NativePointer, _size: number): boolean;
|
|
9
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const UNIMPLEMENTED = "frida-mem-scan: Linux backend not yet implemented";
|
|
2
|
+
export class LinuxProcessMemory {
|
|
3
|
+
pid;
|
|
4
|
+
isSelf;
|
|
5
|
+
constructor(pid) {
|
|
6
|
+
this.pid = pid;
|
|
7
|
+
this.isSelf = pid === Process.id;
|
|
8
|
+
throw new Error(UNIMPLEMENTED);
|
|
9
|
+
}
|
|
10
|
+
*regions(_filter) {
|
|
11
|
+
throw new Error(UNIMPLEMENTED);
|
|
12
|
+
}
|
|
13
|
+
read(_addr, _size) {
|
|
14
|
+
throw new Error(UNIMPLEMENTED);
|
|
15
|
+
}
|
|
16
|
+
readInto(_addr, _dst, _size) {
|
|
17
|
+
throw new Error(UNIMPLEMENTED);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface Region {
|
|
2
|
+
base: NativePointer;
|
|
3
|
+
size: UInt64;
|
|
4
|
+
readable: boolean;
|
|
5
|
+
writable: boolean;
|
|
6
|
+
executable: boolean;
|
|
7
|
+
tag: number;
|
|
8
|
+
}
|
|
9
|
+
export interface RegionFilter {
|
|
10
|
+
readable?: boolean;
|
|
11
|
+
writable?: boolean;
|
|
12
|
+
executable?: boolean;
|
|
13
|
+
tags?: number[] | Set<number>;
|
|
14
|
+
minBytes?: number;
|
|
15
|
+
maxBytes?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ProcessMemory {
|
|
18
|
+
readonly pid: number;
|
|
19
|
+
readonly isSelf: boolean;
|
|
20
|
+
regions(filter?: RegionFilter): Iterable<Region>;
|
|
21
|
+
read(addr: NativePointer, size: number): ArrayBuffer | null;
|
|
22
|
+
readInto(addr: NativePointer, dst: NativePointer, size: number): boolean;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ProcessMemory, Region, RegionFilter } from "./types.js";
|
|
2
|
+
export declare class WindowsProcessMemory implements ProcessMemory {
|
|
3
|
+
readonly pid: number;
|
|
4
|
+
readonly isSelf: boolean;
|
|
5
|
+
constructor(pid: number);
|
|
6
|
+
regions(_filter?: RegionFilter): Iterable<Region>;
|
|
7
|
+
read(_addr: NativePointer, _size: number): ArrayBuffer | null;
|
|
8
|
+
readInto(_addr: NativePointer, _dst: NativePointer, _size: number): boolean;
|
|
9
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const UNIMPLEMENTED = "frida-mem-scan: Windows backend not yet implemented";
|
|
2
|
+
export class WindowsProcessMemory {
|
|
3
|
+
pid;
|
|
4
|
+
isSelf;
|
|
5
|
+
constructor(pid) {
|
|
6
|
+
this.pid = pid;
|
|
7
|
+
this.isSelf = pid === Process.id;
|
|
8
|
+
throw new Error(UNIMPLEMENTED);
|
|
9
|
+
}
|
|
10
|
+
*regions(_filter) {
|
|
11
|
+
throw new Error(UNIMPLEMENTED);
|
|
12
|
+
}
|
|
13
|
+
read(_addr, _size) {
|
|
14
|
+
throw new Error(UNIMPLEMENTED);
|
|
15
|
+
}
|
|
16
|
+
readInto(_addr, _dst, _size) {
|
|
17
|
+
throw new Error(UNIMPLEMENTED);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Generated by extract_text.sh + emit_ts.sh from build/scan_arm64.bin
|
|
2
|
+
// Do not edit by hand; rerun `make` after editing the .S source.
|
|
3
|
+
export const SCAN_ARM64_BYTES = new Uint8Array([
|
|
4
|
+
0xff, 0x83, 0x01, 0xd1, 0xfd, 0x7b, 0x05, 0xa9, 0xfd, 0x43, 0x01, 0x91,
|
|
5
|
+
0xe9, 0x33, 0x40, 0xf9, 0xea, 0x37, 0x40, 0xf9, 0xeb, 0x3b, 0x40, 0xf9,
|
|
6
|
+
0xec, 0x3f, 0x40, 0xf9, 0x8d, 0x05, 0x00, 0xd1, 0x6d, 0x00, 0x0d, 0x8b,
|
|
7
|
+
0xad, 0x09, 0xcc, 0x9a, 0xe2, 0x37, 0x00, 0xa9, 0xe3, 0x13, 0x01, 0xa9,
|
|
8
|
+
0xe5, 0x1b, 0x02, 0xa9, 0xe7, 0x27, 0x03, 0xa9, 0xea, 0x2f, 0x04, 0xa9,
|
|
9
|
+
0xf0, 0x03, 0x00, 0xaa, 0xe0, 0x03, 0x0c, 0xaa, 0xe2, 0x03, 0x00, 0x91,
|
|
10
|
+
0xc3, 0x00, 0x00, 0x10, 0x00, 0x02, 0x3f, 0xd6, 0xfd, 0x7b, 0x45, 0xa9,
|
|
11
|
+
0xff, 0x83, 0x01, 0x91, 0xc0, 0x03, 0x5f, 0xd6, 0x1f, 0x20, 0x03, 0xd5,
|
|
12
|
+
0xfd, 0x7b, 0xbe, 0xa9, 0xfd, 0x03, 0x00, 0x91, 0xe0, 0x07, 0x01, 0xa9,
|
|
13
|
+
0x0a, 0x2c, 0x40, 0xa9, 0x0c, 0x34, 0x41, 0xa9, 0x0e, 0x3c, 0x42, 0xa9,
|
|
14
|
+
0x10, 0x44, 0x43, 0xa9, 0x09, 0x24, 0x40, 0xf9, 0x22, 0x7c, 0x0b, 0x9b,
|
|
15
|
+
0x22, 0x79, 0x21, 0xf8, 0x5f, 0x00, 0x0c, 0xeb, 0x83, 0x00, 0x00, 0x54,
|
|
16
|
+
0x09, 0x20, 0x40, 0xf9, 0x3f, 0x79, 0x21, 0xf8, 0x12, 0x00, 0x00, 0x14,
|
|
17
|
+
0x83, 0x01, 0x02, 0xcb, 0x7f, 0x00, 0x0b, 0xeb, 0x63, 0x30, 0x8b, 0x9a,
|
|
18
|
+
0x4a, 0x0d, 0x02, 0x8b, 0x24, 0x7c, 0x11, 0x9b, 0x10, 0x0a, 0x04, 0x8b,
|
|
19
|
+
0xe0, 0x03, 0x0a, 0xaa, 0xe1, 0x03, 0x03, 0xaa, 0xe2, 0x03, 0x0d, 0xaa,
|
|
20
|
+
0xe3, 0x03, 0x0e, 0xaa, 0xe4, 0x03, 0x0f, 0xaa, 0xe5, 0x03, 0x10, 0xaa,
|
|
21
|
+
0xe6, 0x03, 0x11, 0xaa, 0x44, 0x00, 0x00, 0x94, 0xe9, 0x2b, 0x41, 0xa9,
|
|
22
|
+
0x2b, 0x21, 0x40, 0xf9, 0x60, 0x79, 0x2a, 0xf8, 0xfd, 0x7b, 0xc2, 0xa8,
|
|
23
|
+
0xc0, 0x03, 0x5f, 0xd6, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
|
|
24
|
+
0xff, 0x83, 0x01, 0xd1, 0xfd, 0x7b, 0x05, 0xa9, 0xfd, 0x43, 0x01, 0x91,
|
|
25
|
+
0xe9, 0x33, 0x40, 0xf9, 0xea, 0x37, 0x40, 0xf9, 0xeb, 0x3b, 0x40, 0xf9,
|
|
26
|
+
0x6c, 0x05, 0x00, 0xd1, 0x6c, 0x00, 0x0c, 0x8b, 0x8c, 0x09, 0xcb, 0x9a,
|
|
27
|
+
0xe2, 0x33, 0x00, 0xa9, 0xe3, 0x13, 0x01, 0xa9, 0xe5, 0x13, 0x00, 0xf9,
|
|
28
|
+
0xe6, 0x1f, 0x03, 0xa9, 0xe9, 0x2b, 0x04, 0xa9, 0xf0, 0x03, 0x00, 0xaa,
|
|
29
|
+
0xe0, 0x03, 0x0b, 0xaa, 0xe2, 0x03, 0x00, 0x91, 0xe3, 0x00, 0x00, 0x10,
|
|
30
|
+
0x00, 0x02, 0x3f, 0xd6, 0xfd, 0x7b, 0x45, 0xa9, 0xff, 0x83, 0x01, 0x91,
|
|
31
|
+
0xc0, 0x03, 0x5f, 0xd6, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
|
|
32
|
+
0xfd, 0x7b, 0xbe, 0xa9, 0xfd, 0x03, 0x00, 0x91, 0xe0, 0x07, 0x01, 0xa9,
|
|
33
|
+
0x0a, 0x2c, 0x40, 0xa9, 0x0c, 0x34, 0x41, 0xa9, 0x0e, 0x10, 0x40, 0xf9,
|
|
34
|
+
0x0f, 0x40, 0x43, 0xa9, 0x09, 0x24, 0x40, 0xf9, 0x22, 0x7c, 0x0b, 0x9b,
|
|
35
|
+
0x22, 0x79, 0x21, 0xf8, 0x5f, 0x00, 0x0c, 0xeb, 0x83, 0x00, 0x00, 0x54,
|
|
36
|
+
0x09, 0x20, 0x40, 0xf9, 0x3f, 0x79, 0x21, 0xf8, 0x11, 0x00, 0x00, 0x14,
|
|
37
|
+
0x83, 0x01, 0x02, 0xcb, 0x7f, 0x00, 0x0b, 0xeb, 0x63, 0x30, 0x8b, 0x9a,
|
|
38
|
+
0x4a, 0x0d, 0x02, 0x8b, 0x24, 0x7c, 0x10, 0x9b, 0xef, 0x09, 0x04, 0x8b,
|
|
39
|
+
0xe0, 0x03, 0x0a, 0xaa, 0xe1, 0x03, 0x03, 0xaa, 0xe2, 0x03, 0x0d, 0xaa,
|
|
40
|
+
0xe3, 0x03, 0x0e, 0xaa, 0xe4, 0x03, 0x0f, 0xaa, 0xe5, 0x03, 0x10, 0xaa,
|
|
41
|
+
0x75, 0x00, 0x00, 0x94, 0xe9, 0x2b, 0x41, 0xa9, 0x2b, 0x21, 0x40, 0xf9,
|
|
42
|
+
0x60, 0x79, 0x2a, 0xf8, 0xfd, 0x7b, 0xc2, 0xa8, 0xc0, 0x03, 0x5f, 0xd6,
|
|
43
|
+
0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
|
|
44
|
+
0xfd, 0x7b, 0xbf, 0xa9, 0xfd, 0x03, 0x00, 0x91, 0xe7, 0x03, 0x1f, 0xaa,
|
|
45
|
+
0xa1, 0x0c, 0x00, 0xb4, 0x40, 0x0c, 0x08, 0x4e, 0x9f, 0x10, 0x00, 0xf1,
|
|
46
|
+
0x4c, 0x09, 0x00, 0x54, 0x62, 0x00, 0x40, 0xfd, 0x9f, 0x04, 0x00, 0xf1,
|
|
47
|
+
0x20, 0x01, 0x00, 0x54, 0x63, 0x04, 0x40, 0xfd, 0x9f, 0x08, 0x00, 0xf1,
|
|
48
|
+
0x60, 0x01, 0x00, 0x54, 0x64, 0x08, 0x40, 0xfd, 0x9f, 0x0c, 0x00, 0xf1,
|
|
49
|
+
0xa0, 0x01, 0x00, 0x54, 0x65, 0x0c, 0x40, 0xfd, 0x10, 0x00, 0x00, 0x14,
|
|
50
|
+
0x42, 0x04, 0x08, 0x4e, 0x43, 0x1c, 0xa2, 0x4e, 0x44, 0x1c, 0xa2, 0x4e,
|
|
51
|
+
0x45, 0x1c, 0xa2, 0x4e, 0x0f, 0x00, 0x00, 0x14, 0x42, 0x04, 0x08, 0x4e,
|
|
52
|
+
0x63, 0x04, 0x08, 0x4e, 0x44, 0x1c, 0xa2, 0x4e, 0x45, 0x1c, 0xa2, 0x4e,
|
|
53
|
+
0x0a, 0x00, 0x00, 0x14, 0x42, 0x04, 0x08, 0x4e, 0x63, 0x04, 0x08, 0x4e,
|
|
54
|
+
0x84, 0x04, 0x08, 0x4e, 0x45, 0x1c, 0xa2, 0x4e, 0x05, 0x00, 0x00, 0x14,
|
|
55
|
+
0x42, 0x04, 0x08, 0x4e, 0x63, 0x04, 0x08, 0x4e, 0x84, 0x04, 0x08, 0x4e,
|
|
56
|
+
0xa5, 0x04, 0x08, 0x4e, 0xe8, 0x03, 0x1f, 0xaa, 0x29, 0xf8, 0x7f, 0x92,
|
|
57
|
+
0x1f, 0x01, 0x09, 0xeb, 0x2a, 0x03, 0x00, 0x54, 0x0a, 0x0c, 0x08, 0x8b,
|
|
58
|
+
0x41, 0x01, 0xc0, 0x3d, 0x21, 0x1c, 0x20, 0x4e, 0x30, 0x8c, 0xe2, 0x6e,
|
|
59
|
+
0x31, 0x8c, 0xe3, 0x6e, 0x32, 0x8c, 0xe4, 0x6e, 0x33, 0x8c, 0xe5, 0x6e,
|
|
60
|
+
0x10, 0x1e, 0xb1, 0x4e, 0x52, 0x1e, 0xb3, 0x4e, 0x10, 0x1e, 0xb2, 0x4e,
|
|
61
|
+
0x0b, 0x3e, 0x08, 0x4e, 0x0c, 0x3e, 0x18, 0x4e, 0x6d, 0x01, 0x0c, 0xaa,
|
|
62
|
+
0x2d, 0x01, 0x00, 0xb4, 0x4b, 0x00, 0x00, 0xb4, 0x2a, 0x00, 0x00, 0x94,
|
|
63
|
+
0xcc, 0x00, 0x00, 0xb4, 0x0e, 0x05, 0x00, 0x91, 0xef, 0x03, 0x08, 0xaa,
|
|
64
|
+
0xe8, 0x03, 0x0e, 0xaa, 0x25, 0x00, 0x00, 0x94, 0xe8, 0x03, 0x0f, 0xaa,
|
|
65
|
+
0x08, 0x09, 0x00, 0x91, 0xe7, 0xff, 0xff, 0x17, 0x1f, 0x01, 0x01, 0xeb,
|
|
66
|
+
0xca, 0x04, 0x00, 0x54, 0x0a, 0x0c, 0x08, 0x8b, 0x4b, 0x01, 0x40, 0xf9,
|
|
67
|
+
0x6b, 0x01, 0x02, 0x8a, 0xec, 0x03, 0x1f, 0xaa, 0x9f, 0x01, 0x04, 0xeb,
|
|
68
|
+
0x0a, 0x04, 0x00, 0x54, 0x6d, 0x78, 0x6c, 0xf8, 0x7f, 0x01, 0x0d, 0xeb,
|
|
69
|
+
0x61, 0x00, 0x00, 0x54, 0x16, 0x00, 0x00, 0x94, 0x1b, 0x00, 0x00, 0x14,
|
|
70
|
+
0x8c, 0x05, 0x00, 0x91, 0xf8, 0xff, 0xff, 0x17, 0xe8, 0x03, 0x1f, 0xaa,
|
|
71
|
+
0x1f, 0x01, 0x01, 0xeb, 0xca, 0x02, 0x00, 0x54, 0x0a, 0x0c, 0x08, 0x8b,
|
|
72
|
+
0x4b, 0x01, 0x40, 0xf9, 0x6b, 0x01, 0x02, 0x8a, 0xec, 0x03, 0x1f, 0xaa,
|
|
73
|
+
0x9f, 0x01, 0x04, 0xeb, 0x0a, 0x01, 0x00, 0x54, 0x6d, 0x78, 0x6c, 0xf8,
|
|
74
|
+
0x7f, 0x01, 0x0d, 0xeb, 0x61, 0x00, 0x00, 0x54, 0x06, 0x00, 0x00, 0x94,
|
|
75
|
+
0x03, 0x00, 0x00, 0x14, 0x8c, 0x05, 0x00, 0x91, 0xf8, 0xff, 0xff, 0x17,
|
|
76
|
+
0x08, 0x05, 0x00, 0x91, 0xf0, 0xff, 0xff, 0x17, 0xe7, 0x04, 0x00, 0x91,
|
|
77
|
+
0xff, 0x00, 0x06, 0xeb, 0x68, 0x00, 0x00, 0x54, 0xf0, 0x04, 0x00, 0xd1,
|
|
78
|
+
0xa8, 0x78, 0x30, 0xb8, 0xc0, 0x03, 0x5f, 0xd6, 0xe0, 0x03, 0x07, 0xaa,
|
|
79
|
+
0xfd, 0x7b, 0xc1, 0xa8, 0xc0, 0x03, 0x5f, 0xd6, 0x1f, 0x20, 0x03, 0xd5,
|
|
80
|
+
0xfd, 0x7b, 0xbf, 0xa9, 0xfd, 0x03, 0x00, 0x91, 0xe6, 0x03, 0x1f, 0xaa,
|
|
81
|
+
0xc1, 0x06, 0x00, 0xb4, 0x40, 0x0c, 0x08, 0x4e, 0x62, 0x0c, 0x08, 0x4e,
|
|
82
|
+
0xe8, 0x03, 0x1f, 0xaa, 0x29, 0xf4, 0x7e, 0x92, 0x1f, 0x01, 0x09, 0xeb,
|
|
83
|
+
0x0a, 0x04, 0x00, 0x54, 0x0a, 0x0c, 0x08, 0x8b, 0x41, 0x0d, 0x40, 0xad,
|
|
84
|
+
0x21, 0x1c, 0x20, 0x4e, 0x63, 0x1c, 0x20, 0x4e, 0x21, 0x8c, 0xe2, 0x6e,
|
|
85
|
+
0x63, 0x8c, 0xe2, 0x6e, 0x24, 0x1c, 0xa3, 0x4e, 0x8b, 0x3c, 0x08, 0x4e,
|
|
86
|
+
0x8c, 0x3c, 0x18, 0x4e, 0x6d, 0x01, 0x0c, 0xaa, 0x6d, 0x02, 0x00, 0xb4,
|
|
87
|
+
0x2b, 0x3c, 0x08, 0x4e, 0x4b, 0x00, 0x00, 0xb4, 0x1c, 0x00, 0x00, 0x94,
|
|
88
|
+
0x2b, 0x3c, 0x18, 0x4e, 0x8b, 0x00, 0x00, 0xb4, 0x08, 0x05, 0x00, 0x91,
|
|
89
|
+
0x18, 0x00, 0x00, 0x94, 0x08, 0x05, 0x00, 0xd1, 0x6b, 0x3c, 0x08, 0x4e,
|
|
90
|
+
0x8b, 0x00, 0x00, 0xb4, 0x08, 0x09, 0x00, 0x91, 0x13, 0x00, 0x00, 0x94,
|
|
91
|
+
0x08, 0x09, 0x00, 0xd1, 0x6b, 0x3c, 0x18, 0x4e, 0x8b, 0x00, 0x00, 0xb4,
|
|
92
|
+
0x08, 0x0d, 0x00, 0x91, 0x0e, 0x00, 0x00, 0x94, 0x08, 0x0d, 0x00, 0xd1,
|
|
93
|
+
0x08, 0x11, 0x00, 0x91, 0xe0, 0xff, 0xff, 0x17, 0x1f, 0x01, 0x01, 0xeb,
|
|
94
|
+
0xea, 0x01, 0x00, 0x54, 0x0a, 0x0c, 0x08, 0x8b, 0x4b, 0x01, 0x40, 0xf9,
|
|
95
|
+
0x6b, 0x01, 0x02, 0x8a, 0x7f, 0x01, 0x03, 0xeb, 0x41, 0x00, 0x00, 0x54,
|
|
96
|
+
0x03, 0x00, 0x00, 0x94, 0x08, 0x05, 0x00, 0x91, 0xf7, 0xff, 0xff, 0x17,
|
|
97
|
+
0xc6, 0x04, 0x00, 0x91, 0xdf, 0x00, 0x05, 0xeb, 0x68, 0x00, 0x00, 0x54,
|
|
98
|
+
0xce, 0x04, 0x00, 0xd1, 0x88, 0x78, 0x2e, 0xb8, 0xc0, 0x03, 0x5f, 0xd6,
|
|
99
|
+
0xe0, 0x03, 0x06, 0xaa, 0xfd, 0x7b, 0xc1, 0xa8, 0xc0, 0x03, 0x5f, 0xd6
|
|
100
|
+
]);
|
|
101
|
+
export const SYMBOLS = {
|
|
102
|
+
scan: 0x1e0,
|
|
103
|
+
scan1: 0x390,
|
|
104
|
+
scan1_parallel: 0xf0,
|
|
105
|
+
scan_parallel: 0x0,
|
|
106
|
+
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Generated by extract_text.sh + emit_ts.sh from build/scan_x86_64.bin
|
|
2
|
+
// Do not edit by hand; rerun `make` after editing the .S source.
|
|
3
|
+
export const SCAN_X86_64_BYTES = new Uint8Array([
|
|
4
|
+
0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x60, 0x48, 0x89, 0x14, 0x24,
|
|
5
|
+
0x48, 0x89, 0x4c, 0x24, 0x10, 0x4c, 0x89, 0x44, 0x24, 0x18, 0x4c, 0x89,
|
|
6
|
+
0x4c, 0x24, 0x20, 0x48, 0x8b, 0x45, 0x10, 0x48, 0x89, 0x44, 0x24, 0x28,
|
|
7
|
+
0x48, 0x8b, 0x45, 0x18, 0x48, 0x89, 0x44, 0x24, 0x30, 0x48, 0x8b, 0x45,
|
|
8
|
+
0x20, 0x48, 0x89, 0x44, 0x24, 0x38, 0x48, 0x8b, 0x45, 0x28, 0x48, 0x89,
|
|
9
|
+
0x44, 0x24, 0x40, 0x48, 0x8b, 0x45, 0x30, 0x48, 0x89, 0x44, 0x24, 0x48,
|
|
10
|
+
0x48, 0x89, 0xc8, 0x4c, 0x8b, 0x55, 0x38, 0x4c, 0x01, 0xd0, 0x48, 0xff,
|
|
11
|
+
0xc8, 0x31, 0xd2, 0x49, 0xf7, 0xf2, 0x48, 0x89, 0x44, 0x24, 0x08, 0x48,
|
|
12
|
+
0x89, 0x7c, 0x24, 0x58, 0x4c, 0x89, 0xd7, 0x48, 0x89, 0xe2, 0x48, 0x8d,
|
|
13
|
+
0x0d, 0x0f, 0x00, 0x00, 0x00, 0xff, 0x54, 0x24, 0x58, 0x48, 0x83, 0xc4,
|
|
14
|
+
0x60, 0x5d, 0xc3, 0x0f, 0x1f, 0x44, 0x00, 0x00, 0x55, 0x48, 0x89, 0xe5,
|
|
15
|
+
0x48, 0x83, 0xec, 0x30, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0,
|
|
16
|
+
0x4c, 0x8b, 0x57, 0x08, 0x4c, 0x8b, 0x5f, 0x10, 0x48, 0x89, 0xf0, 0x49,
|
|
17
|
+
0x0f, 0xaf, 0xc2, 0x48, 0x8b, 0x4f, 0x48, 0x48, 0x89, 0x04, 0xf1, 0x4c,
|
|
18
|
+
0x39, 0xd8, 0x72, 0x0e, 0x48, 0x8b, 0x4f, 0x40, 0x48, 0xc7, 0x04, 0xf1,
|
|
19
|
+
0x00, 0x00, 0x00, 0x00, 0xeb, 0x4f, 0x49, 0x29, 0xc3, 0x4d, 0x39, 0xd3,
|
|
20
|
+
0x4d, 0x0f, 0x43, 0xda, 0x48, 0x8b, 0x57, 0x38, 0x48, 0x89, 0xf1, 0x48,
|
|
21
|
+
0x0f, 0xaf, 0xca, 0x48, 0xc1, 0xe1, 0x02, 0x48, 0x03, 0x4f, 0x30, 0x48,
|
|
22
|
+
0x89, 0x14, 0x24, 0x49, 0x89, 0xc9, 0x4c, 0x8b, 0x47, 0x28, 0x48, 0x8b,
|
|
23
|
+
0x57, 0x18, 0x48, 0x8b, 0x4f, 0x20, 0x4c, 0x89, 0xde, 0x4c, 0x8b, 0x17,
|
|
24
|
+
0x49, 0x8d, 0x3c, 0xc2, 0xe8, 0x27, 0x01, 0x00, 0x00, 0x48, 0x8b, 0x4d,
|
|
25
|
+
0xf8, 0x48, 0x8b, 0x75, 0xf0, 0x4c, 0x8b, 0x59, 0x40, 0x49, 0x89, 0x04,
|
|
26
|
+
0xf3, 0x48, 0x83, 0xc4, 0x30, 0x5d, 0xc3, 0x90, 0x55, 0x48, 0x89, 0xe5,
|
|
27
|
+
0x48, 0x83, 0xec, 0x60, 0x48, 0x89, 0x14, 0x24, 0x48, 0x89, 0x4c, 0x24,
|
|
28
|
+
0x10, 0x4c, 0x89, 0x44, 0x24, 0x18, 0x4c, 0x89, 0x4c, 0x24, 0x20, 0x48,
|
|
29
|
+
0x8b, 0x45, 0x10, 0x48, 0x89, 0x44, 0x24, 0x30, 0x48, 0x8b, 0x45, 0x18,
|
|
30
|
+
0x48, 0x89, 0x44, 0x24, 0x38, 0x48, 0x8b, 0x45, 0x20, 0x48, 0x89, 0x44,
|
|
31
|
+
0x24, 0x40, 0x48, 0x8b, 0x45, 0x28, 0x48, 0x89, 0x44, 0x24, 0x48, 0x48,
|
|
32
|
+
0x89, 0xc8, 0x4c, 0x8b, 0x55, 0x30, 0x4c, 0x01, 0xd0, 0x48, 0xff, 0xc8,
|
|
33
|
+
0x31, 0xd2, 0x49, 0xf7, 0xf2, 0x48, 0x89, 0x44, 0x24, 0x08, 0x48, 0x89,
|
|
34
|
+
0x7c, 0x24, 0x58, 0x4c, 0x89, 0xd7, 0x48, 0x89, 0xe2, 0x48, 0x8d, 0x0d,
|
|
35
|
+
0x18, 0x00, 0x00, 0x00, 0xff, 0x54, 0x24, 0x58, 0x48, 0x83, 0xc4, 0x60,
|
|
36
|
+
0x5d, 0xc3, 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
37
|
+
0x0f, 0x1f, 0x40, 0x00, 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x30,
|
|
38
|
+
0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x4c, 0x8b, 0x57, 0x08,
|
|
39
|
+
0x4c, 0x8b, 0x5f, 0x10, 0x48, 0x89, 0xf0, 0x49, 0x0f, 0xaf, 0xc2, 0x48,
|
|
40
|
+
0x8b, 0x4f, 0x48, 0x48, 0x89, 0x04, 0xf1, 0x4c, 0x39, 0xd8, 0x72, 0x0e,
|
|
41
|
+
0x48, 0x8b, 0x4f, 0x40, 0x48, 0xc7, 0x04, 0xf1, 0x00, 0x00, 0x00, 0x00,
|
|
42
|
+
0xeb, 0x4a, 0x49, 0x29, 0xc3, 0x4d, 0x39, 0xd3, 0x4d, 0x0f, 0x43, 0xda,
|
|
43
|
+
0x48, 0x8b, 0x57, 0x38, 0x48, 0x89, 0xf1, 0x48, 0x0f, 0xaf, 0xca, 0x48,
|
|
44
|
+
0xc1, 0xe1, 0x02, 0x48, 0x03, 0x4f, 0x30, 0x49, 0x89, 0xc8, 0x49, 0x89,
|
|
45
|
+
0xd1, 0x48, 0x8b, 0x4f, 0x20, 0x48, 0x8b, 0x57, 0x18, 0x4c, 0x89, 0xde,
|
|
46
|
+
0x4c, 0x8b, 0x17, 0x49, 0x8d, 0x3c, 0xc2, 0xe8, 0x7c, 0x01, 0x00, 0x00,
|
|
47
|
+
0x48, 0x8b, 0x4d, 0xf8, 0x48, 0x8b, 0x75, 0xf0, 0x4c, 0x8b, 0x59, 0x40,
|
|
48
|
+
0x49, 0x89, 0x04, 0xf3, 0x48, 0x83, 0xc4, 0x30, 0x5d, 0xc3, 0x66, 0x0f,
|
|
49
|
+
0x1f, 0x44, 0x00, 0x00, 0x55, 0x48, 0x89, 0xe5, 0x53, 0x41, 0x54, 0x31,
|
|
50
|
+
0xdb, 0x48, 0x85, 0xf6, 0x0f, 0x84, 0x3d, 0x01, 0x00, 0x00, 0x4c, 0x8b,
|
|
51
|
+
0x5d, 0x10, 0x49, 0x89, 0xcc, 0x66, 0x48, 0x0f, 0x6e, 0xc2, 0x66, 0x0f,
|
|
52
|
+
0x6c, 0xc0, 0x49, 0x83, 0xf8, 0x04, 0x0f, 0x87, 0xe9, 0x00, 0x00, 0x00,
|
|
53
|
+
0xf3, 0x0f, 0x7e, 0x11, 0x66, 0x0f, 0x6c, 0xd2, 0x49, 0x83, 0xf8, 0x01,
|
|
54
|
+
0x74, 0x29, 0xf3, 0x0f, 0x7e, 0x59, 0x08, 0x66, 0x0f, 0x6c, 0xdb, 0x49,
|
|
55
|
+
0x83, 0xf8, 0x02, 0x74, 0x28, 0xf3, 0x0f, 0x7e, 0x61, 0x10, 0x66, 0x0f,
|
|
56
|
+
0x6c, 0xe4, 0x49, 0x83, 0xf8, 0x03, 0x74, 0x23, 0xf3, 0x0f, 0x7e, 0x69,
|
|
57
|
+
0x18, 0x66, 0x0f, 0x6c, 0xed, 0xeb, 0x1c, 0x66, 0x0f, 0x6f, 0xda, 0x66,
|
|
58
|
+
0x0f, 0x6f, 0xe2, 0x66, 0x0f, 0x6f, 0xea, 0xeb, 0x0e, 0x66, 0x0f, 0x6f,
|
|
59
|
+
0xe2, 0x66, 0x0f, 0x6f, 0xea, 0xeb, 0x04, 0x66, 0x0f, 0x6f, 0xea, 0x4d,
|
|
60
|
+
0x31, 0xd2, 0x48, 0x89, 0xf0, 0x48, 0x83, 0xe0, 0xfe, 0x49, 0x39, 0xc2,
|
|
61
|
+
0x73, 0x62, 0xf3, 0x42, 0x0f, 0x6f, 0x0c, 0xd7, 0x66, 0x0f, 0xdb, 0xc8,
|
|
62
|
+
0x66, 0x0f, 0x6f, 0xf1, 0x66, 0x0f, 0x38, 0x29, 0xf2, 0x66, 0x0f, 0x6f,
|
|
63
|
+
0xf9, 0x66, 0x0f, 0x38, 0x29, 0xfb, 0x66, 0x0f, 0xeb, 0xf7, 0x66, 0x0f,
|
|
64
|
+
0x6f, 0xf9, 0x66, 0x0f, 0x38, 0x29, 0xfc, 0x66, 0x0f, 0xeb, 0xf7, 0x66,
|
|
65
|
+
0x0f, 0x6f, 0xf9, 0x66, 0x0f, 0x38, 0x29, 0xfd, 0x66, 0x0f, 0xeb, 0xf7,
|
|
66
|
+
0x66, 0x0f, 0x50, 0xce, 0x84, 0xc9, 0x74, 0x1a, 0xf6, 0xc1, 0x01, 0x74,
|
|
67
|
+
0x05, 0xe8, 0x68, 0x00, 0x00, 0x00, 0xf6, 0xc1, 0x02, 0x74, 0x0b, 0x49,
|
|
68
|
+
0xff, 0xc2, 0xe8, 0x5b, 0x00, 0x00, 0x00, 0x49, 0xff, 0xca, 0x49, 0x83,
|
|
69
|
+
0xc2, 0x02, 0xeb, 0x99, 0x49, 0x39, 0xf2, 0x73, 0x5a, 0x4a, 0x8b, 0x04,
|
|
70
|
+
0xd7, 0x48, 0x21, 0xd0, 0x31, 0xc9, 0x4c, 0x39, 0xc1, 0x73, 0x4c, 0x49,
|
|
71
|
+
0x3b, 0x04, 0xcc, 0x75, 0x07, 0xe8, 0x34, 0x00, 0x00, 0x00, 0xeb, 0x3f,
|
|
72
|
+
0x48, 0xff, 0xc1, 0xeb, 0xe9, 0x4d, 0x31, 0xd2, 0x49, 0x39, 0xf2, 0x73,
|
|
73
|
+
0x32, 0x4a, 0x8b, 0x04, 0xd7, 0x48, 0x21, 0xd0, 0x31, 0xc9, 0x4c, 0x39,
|
|
74
|
+
0xc1, 0x73, 0x12, 0x49, 0x3b, 0x04, 0xcc, 0x75, 0x07, 0xe8, 0x0c, 0x00,
|
|
75
|
+
0x00, 0x00, 0xeb, 0x05, 0x48, 0xff, 0xc1, 0xeb, 0xe9, 0x49, 0xff, 0xc2,
|
|
76
|
+
0xeb, 0xd6, 0x4c, 0x39, 0xdb, 0x73, 0x04, 0x45, 0x89, 0x14, 0x99, 0x48,
|
|
77
|
+
0xff, 0xc3, 0xc3, 0x48, 0x89, 0xd8, 0x41, 0x5c, 0x5b, 0x5d, 0xc3, 0x66,
|
|
78
|
+
0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x48, 0x89, 0xe5,
|
|
79
|
+
0x53, 0x41, 0x54, 0x31, 0xdb, 0x48, 0x85, 0xf6, 0x0f, 0x84, 0xc3, 0x00,
|
|
80
|
+
0x00, 0x00, 0x49, 0x89, 0xcc, 0x66, 0x48, 0x0f, 0x6e, 0xc2, 0x66, 0x0f,
|
|
81
|
+
0x6c, 0xc0, 0x66, 0x48, 0x0f, 0x6e, 0xd1, 0x66, 0x0f, 0x6c, 0xd2, 0x4d,
|
|
82
|
+
0x31, 0xd2, 0x49, 0x89, 0xf3, 0x49, 0x83, 0xe3, 0xfc, 0x4d, 0x39, 0xda,
|
|
83
|
+
0x73, 0x77, 0xf3, 0x42, 0x0f, 0x6f, 0x0c, 0xd7, 0xf3, 0x42, 0x0f, 0x6f,
|
|
84
|
+
0x5c, 0xd7, 0x10, 0x66, 0x0f, 0xdb, 0xc8, 0x66, 0x0f, 0xdb, 0xd8, 0x66,
|
|
85
|
+
0x0f, 0x38, 0x29, 0xca, 0x66, 0x0f, 0x38, 0x29, 0xda, 0x66, 0x0f, 0x6f,
|
|
86
|
+
0xe1, 0x66, 0x0f, 0xeb, 0xe3, 0x66, 0x0f, 0x50, 0xc4, 0x85, 0xc0, 0x74,
|
|
87
|
+
0x42, 0x66, 0x0f, 0x50, 0xc1, 0xa8, 0x01, 0x74, 0x05, 0xe8, 0x56, 0x00,
|
|
88
|
+
0x00, 0x00, 0xa8, 0x02, 0x74, 0x0b, 0x49, 0xff, 0xc2, 0xe8, 0x4a, 0x00,
|
|
89
|
+
0x00, 0x00, 0x49, 0xff, 0xca, 0x66, 0x0f, 0x50, 0xc3, 0xa8, 0x01, 0x74,
|
|
90
|
+
0x0d, 0x49, 0x83, 0xc2, 0x02, 0xe8, 0x36, 0x00, 0x00, 0x00, 0x49, 0x83,
|
|
91
|
+
0xea, 0x02, 0xa8, 0x02, 0x74, 0x0d, 0x49, 0x83, 0xc2, 0x03, 0xe8, 0x25,
|
|
92
|
+
0x00, 0x00, 0x00, 0x49, 0x83, 0xea, 0x03, 0x49, 0x83, 0xc2, 0x04, 0xeb,
|
|
93
|
+
0x84, 0x49, 0x39, 0xf2, 0x73, 0x23, 0x4a, 0x8b, 0x04, 0xd7, 0x48, 0x21,
|
|
94
|
+
0xd0, 0x4c, 0x39, 0xe0, 0x75, 0x05, 0xe8, 0x05, 0x00, 0x00, 0x00, 0x49,
|
|
95
|
+
0xff, 0xc2, 0xeb, 0xe5, 0x4c, 0x39, 0xcb, 0x73, 0x04, 0x45, 0x89, 0x14,
|
|
96
|
+
0x98, 0x48, 0xff, 0xc3, 0xc3, 0x48, 0x89, 0xd8, 0x41, 0x5c, 0x5b, 0x5d,
|
|
97
|
+
0xc3
|
|
98
|
+
]);
|
|
99
|
+
export const SYMBOLS = {
|
|
100
|
+
scan: 0x220,
|
|
101
|
+
scan1: 0x380,
|
|
102
|
+
scan1_parallel: 0x110,
|
|
103
|
+
scan_parallel: 0x0,
|
|
104
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface Hit {
|
|
2
|
+
value: NativePointer;
|
|
3
|
+
index: number;
|
|
4
|
+
}
|
|
5
|
+
export declare const DEFAULT_ISA_MASK: UInt64;
|
|
6
|
+
export declare class Scanner {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(nthreads?: number);
|
|
9
|
+
scanRemoteRegion(remoteBase: NativePointer, localBuf: NativePointer, byteLen: number, mask: UInt64, targets: (UInt64 | number)[], capPerThread?: number): Hit[];
|
|
10
|
+
scanLocal(buf: NativePointer, qcount: number | UInt64, mask: UInt64, targets: (UInt64 | number)[], capPerThread?: number): Hit[];
|
|
11
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { SCAN_ARM64_BYTES, SYMBOLS as SYMBOLS_ARM64 } from "./bytes-arm64.js";
|
|
2
|
+
import { SCAN_X86_64_BYTES, SYMBOLS as SYMBOLS_X86_64 } from "./bytes-x86_64.js";
|
|
3
|
+
// arm64e PAC + non-pointer-isa bits masked off; leaves bits 3..47.
|
|
4
|
+
export const DEFAULT_ISA_MASK = uint64("0x00007ffffffffff8");
|
|
5
|
+
const PARALLEL_THRESHOLD_BYTES = 4 * 1024 * 1024;
|
|
6
|
+
const QOS_CLASS_USER_INITIATED = 0x21;
|
|
7
|
+
export class Scanner {
|
|
8
|
+
#scan;
|
|
9
|
+
#scan1;
|
|
10
|
+
#scanParallel;
|
|
11
|
+
#scan1Parallel;
|
|
12
|
+
#dispatchApplyF;
|
|
13
|
+
#queue;
|
|
14
|
+
#nthreads;
|
|
15
|
+
// Pin the JIT page so the runtime doesn't reclaim it while the
|
|
16
|
+
// NativeFunction descriptors below still hold raw pointers into it.
|
|
17
|
+
#code;
|
|
18
|
+
constructor(nthreads) {
|
|
19
|
+
const blob = selectBlob();
|
|
20
|
+
this.#code = Memory.alloc(Math.max(blob.bytes.byteLength, Process.pageSize));
|
|
21
|
+
Memory.patchCode(this.#code, blob.bytes.byteLength, (dst) => {
|
|
22
|
+
dst.writeByteArray(blob.bytes.buffer);
|
|
23
|
+
});
|
|
24
|
+
this.#scan = new NativeFunction(this.#code.add(blob.symbols.scan), "uint64", ["pointer", "uint64", "uint64", "pointer", "uint64", "pointer", "uint64"]);
|
|
25
|
+
this.#scan1 = new NativeFunction(this.#code.add(blob.symbols.scan1), "uint64", ["pointer", "uint64", "uint64", "uint64", "pointer", "uint64"]);
|
|
26
|
+
this.#scanParallel = new NativeFunction(this.#code.add(blob.symbols.scan_parallel), "void", ["pointer", "pointer", "pointer", "uint64", "uint64", "pointer", "uint64", "pointer", "uint64",
|
|
27
|
+
"pointer", "pointer", "uint64"]);
|
|
28
|
+
this.#scan1Parallel = new NativeFunction(this.#code.add(blob.symbols.scan1_parallel), "void", ["pointer", "pointer", "pointer", "uint64", "uint64", "uint64", "pointer", "uint64",
|
|
29
|
+
"pointer", "pointer", "uint64"]);
|
|
30
|
+
const libSystem = Process.getModuleByName("libSystem.B.dylib");
|
|
31
|
+
this.#dispatchApplyF = libSystem.getExportByName("dispatch_apply_f");
|
|
32
|
+
const getQueue = new NativeFunction(libSystem.getExportByName("dispatch_get_global_queue"), "pointer", ["long", "ulong"]);
|
|
33
|
+
this.#queue = getQueue(QOS_CLASS_USER_INITIATED, 0);
|
|
34
|
+
this.#nthreads = hwThreadCount(libSystem, nthreads);
|
|
35
|
+
}
|
|
36
|
+
scanRemoteRegion(remoteBase, localBuf, byteLen, mask, targets, capPerThread = 1024) {
|
|
37
|
+
const qcount = Math.floor(byteLen / 8);
|
|
38
|
+
const localHits = this.scanLocal(localBuf, qcount, mask, targets, capPerThread);
|
|
39
|
+
return localHits.map(h => ({
|
|
40
|
+
value: remoteBase.add(h.index * 8),
|
|
41
|
+
index: h.index,
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
scanLocal(buf, qcount, mask, targets, capPerThread = 1024) {
|
|
45
|
+
const qc = uint64(qcount);
|
|
46
|
+
const small = qc.toNumber() * 8 < PARALLEL_THRESHOLD_BYTES;
|
|
47
|
+
if (targets.length === 1) {
|
|
48
|
+
const target = uint64(targets[0]).and(mask);
|
|
49
|
+
if (small) {
|
|
50
|
+
return this.#runScan1Single(buf, qc, mask, target, capPerThread);
|
|
51
|
+
}
|
|
52
|
+
return this.#runScan1Parallel(buf, qc, mask, target, capPerThread);
|
|
53
|
+
}
|
|
54
|
+
const targetsMem = packTargets(targets, mask);
|
|
55
|
+
if (small) {
|
|
56
|
+
return this.#runScanSingle(buf, qc, mask, targetsMem, targets.length, capPerThread);
|
|
57
|
+
}
|
|
58
|
+
return this.#runScanParallel(buf, qc, mask, targetsMem, targets.length, capPerThread);
|
|
59
|
+
}
|
|
60
|
+
#runScan1Single(buf, qc, mask, target, cap) {
|
|
61
|
+
const out = Memory.alloc(cap * 4);
|
|
62
|
+
const hits = this.#scan1(buf, qc, mask, target, out, uint64(cap)).toNumber();
|
|
63
|
+
return readHits(buf, out, Math.min(hits, cap), 0);
|
|
64
|
+
}
|
|
65
|
+
#runScan1Parallel(buf, qc, mask, target, capPerThread) {
|
|
66
|
+
const nthreads = this.#nthreads;
|
|
67
|
+
const scratch = allocScratch(nthreads, capPerThread);
|
|
68
|
+
this.#scan1Parallel(this.#dispatchApplyF, this.#queue, buf, qc, mask, target, scratch.outFlat, uint64(capPerThread), scratch.counts, scratch.offs, uint64(nthreads));
|
|
69
|
+
return collectHits(buf, scratch.outFlat, scratch.counts, scratch.offs, nthreads, capPerThread);
|
|
70
|
+
}
|
|
71
|
+
#runScanSingle(buf, qc, mask, targetsMem, ntargets, cap) {
|
|
72
|
+
const out = Memory.alloc(cap * 4);
|
|
73
|
+
const hits = this.#scan(buf, qc, mask, targetsMem, uint64(ntargets), out, uint64(cap)).toNumber();
|
|
74
|
+
return readHits(buf, out, Math.min(hits, cap), 0);
|
|
75
|
+
}
|
|
76
|
+
#runScanParallel(buf, qc, mask, targetsMem, ntargets, capPerThread) {
|
|
77
|
+
const nthreads = this.#nthreads;
|
|
78
|
+
const scratch = allocScratch(nthreads, capPerThread);
|
|
79
|
+
this.#scanParallel(this.#dispatchApplyF, this.#queue, buf, qc, mask, targetsMem, uint64(ntargets), scratch.outFlat, uint64(capPerThread), scratch.counts, scratch.offs, uint64(nthreads));
|
|
80
|
+
return collectHits(buf, scratch.outFlat, scratch.counts, scratch.offs, nthreads, capPerThread);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function allocScratch(nthreads, capPerThread) {
|
|
84
|
+
const outFlatBytes = nthreads * capPerThread * 4;
|
|
85
|
+
const countsBytes = nthreads * 8;
|
|
86
|
+
const offsBytes = nthreads * 8;
|
|
87
|
+
const scratch = Memory.alloc(outFlatBytes + countsBytes + offsBytes);
|
|
88
|
+
return {
|
|
89
|
+
outFlat: scratch,
|
|
90
|
+
counts: scratch.add(outFlatBytes),
|
|
91
|
+
offs: scratch.add(outFlatBytes + countsBytes),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function packTargets(targets, mask) {
|
|
95
|
+
const mem = Memory.alloc(Math.max(1, targets.length) * 8);
|
|
96
|
+
for (let i = 0; i !== targets.length; i++) {
|
|
97
|
+
const masked = uint64(targets[i]).and(mask);
|
|
98
|
+
mem.add(i * 8).writeU64(masked);
|
|
99
|
+
}
|
|
100
|
+
return mem;
|
|
101
|
+
}
|
|
102
|
+
function collectHits(buf, outFlat, counts, offs, nthreads, capPerThread) {
|
|
103
|
+
const hits = [];
|
|
104
|
+
for (let i = 0; i !== nthreads; i++) {
|
|
105
|
+
const count = counts.add(i * 8).readU64().toNumber();
|
|
106
|
+
const chunkOff = offs.add(i * 8).readU64().toNumber();
|
|
107
|
+
const base = outFlat.add(i * capPerThread * 4);
|
|
108
|
+
hits.push(...readHits(buf, base, Math.min(count, capPerThread), chunkOff));
|
|
109
|
+
}
|
|
110
|
+
return hits;
|
|
111
|
+
}
|
|
112
|
+
function readHits(buf, out, n, chunkOff) {
|
|
113
|
+
const hits = [];
|
|
114
|
+
for (let j = 0; j !== n; j++) {
|
|
115
|
+
const index = chunkOff + out.add(j * 4).readU32();
|
|
116
|
+
hits.push({ value: buf.add(index * 8), index });
|
|
117
|
+
}
|
|
118
|
+
return hits;
|
|
119
|
+
}
|
|
120
|
+
function selectBlob() {
|
|
121
|
+
if (Process.arch === "x64") {
|
|
122
|
+
return { bytes: SCAN_X86_64_BYTES, symbols: SYMBOLS_X86_64 };
|
|
123
|
+
}
|
|
124
|
+
if (Process.arch === "arm64") {
|
|
125
|
+
return { bytes: SCAN_ARM64_BYTES, symbols: SYMBOLS_ARM64 };
|
|
126
|
+
}
|
|
127
|
+
throw new Error(`frida-mem-scan: unsupported arch ${Process.arch}`);
|
|
128
|
+
}
|
|
129
|
+
function hwThreadCount(libSystem, override) {
|
|
130
|
+
if (override !== undefined) {
|
|
131
|
+
return override;
|
|
132
|
+
}
|
|
133
|
+
const sysctlbyname = new NativeFunction(libSystem.getExportByName("sysctlbyname"), "int", ["pointer", "pointer", "pointer", "pointer", "size_t"]);
|
|
134
|
+
const name = Memory.allocUtf8String("hw.logicalcpu");
|
|
135
|
+
const out = Memory.alloc(4);
|
|
136
|
+
const len = Memory.alloc(8);
|
|
137
|
+
len.writeU64(4);
|
|
138
|
+
sysctlbyname(name, out, len, NULL, 0);
|
|
139
|
+
return out.readU32();
|
|
140
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function resolveTarget(t: string): UInt64;
|
package/dist/symbols.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function resolveTarget(t) {
|
|
2
|
+
if (!t.includes("!")) {
|
|
3
|
+
return uint64(t);
|
|
4
|
+
}
|
|
5
|
+
const m = t.match(/^([^!]+)!([^+]+)(?:\+(0x[0-9a-fA-F]+|\d+))?$/);
|
|
6
|
+
if (m === null) {
|
|
7
|
+
throw new Error(`bad target spec: ${t}`);
|
|
8
|
+
}
|
|
9
|
+
const [, modName, symName, offStr] = m;
|
|
10
|
+
let addr = Process.getModuleByName(modName).getSymbolByName(symName);
|
|
11
|
+
if (offStr !== undefined) {
|
|
12
|
+
const off = offStr.startsWith("0x") ? parseInt(offStr, 16) : parseInt(offStr, 10);
|
|
13
|
+
addr = addr.add(off);
|
|
14
|
+
}
|
|
15
|
+
return uint64(addr.toString());
|
|
16
|
+
}
|
package/dist/target.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ProcessMemory, Region, RegionFilter } from "./process/types.js";
|
|
2
|
+
export type TargetSpec = string | NativePointer | UInt64 | number;
|
|
3
|
+
export interface FindOpts {
|
|
4
|
+
mask?: UInt64;
|
|
5
|
+
filter?: RegionFilter;
|
|
6
|
+
capPerThread?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ScanHit {
|
|
9
|
+
addr: NativePointer;
|
|
10
|
+
target: UInt64;
|
|
11
|
+
region: {
|
|
12
|
+
base: NativePointer;
|
|
13
|
+
size: number;
|
|
14
|
+
tag: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare class Target {
|
|
18
|
+
#private;
|
|
19
|
+
readonly memory: ProcessMemory;
|
|
20
|
+
static self(): Target;
|
|
21
|
+
static pid(pid: number): Target;
|
|
22
|
+
constructor(memory: ProcessMemory);
|
|
23
|
+
find(targets: TargetSpec[], opts?: FindOpts): ScanHit[];
|
|
24
|
+
read(addr: NativePointer, size: number): ArrayBuffer;
|
|
25
|
+
regions(filter?: RegionFilter): Iterable<Region>;
|
|
26
|
+
}
|
package/dist/target.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { openProcessMemory } from "./process/index.js";
|
|
2
|
+
import { DEFAULT_ISA_MASK, Scanner } from "./scanner/index.js";
|
|
3
|
+
import { resolveTarget } from "./symbols.js";
|
|
4
|
+
export class Target {
|
|
5
|
+
memory;
|
|
6
|
+
#scanner = null;
|
|
7
|
+
static self() {
|
|
8
|
+
return new Target(openProcessMemory(Process.id));
|
|
9
|
+
}
|
|
10
|
+
static pid(pid) {
|
|
11
|
+
return new Target(openProcessMemory(pid));
|
|
12
|
+
}
|
|
13
|
+
constructor(memory) {
|
|
14
|
+
this.memory = memory;
|
|
15
|
+
}
|
|
16
|
+
find(targets, opts = {}) {
|
|
17
|
+
const mask = opts.mask ?? DEFAULT_ISA_MASK;
|
|
18
|
+
const cap = opts.capPerThread ?? 1024;
|
|
19
|
+
const filter = opts.filter ?? { readable: true };
|
|
20
|
+
const targetVals = targets.map(normalizeTarget);
|
|
21
|
+
const maskedTargets = targetVals.map(v => v.and(mask));
|
|
22
|
+
const sc = this.#getScanner();
|
|
23
|
+
const hits = [];
|
|
24
|
+
for (const region of this.memory.regions(filter)) {
|
|
25
|
+
const sz = region.size.toNumber();
|
|
26
|
+
const buf = Memory.alloc(sz);
|
|
27
|
+
if (!this.memory.readInto(region.base, buf, sz)) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const regionHits = sc.scanRemoteRegion(region.base, buf, sz, mask, targetVals, cap);
|
|
31
|
+
const regionInfo = { base: region.base, size: sz, tag: region.tag };
|
|
32
|
+
for (const h of regionHits) {
|
|
33
|
+
hits.push({
|
|
34
|
+
addr: h.value,
|
|
35
|
+
target: pickMatchingTarget(maskedTargets, h.value.readU64().and(mask)),
|
|
36
|
+
region: regionInfo,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return hits;
|
|
41
|
+
}
|
|
42
|
+
read(addr, size) {
|
|
43
|
+
const buf = this.memory.read(addr, size);
|
|
44
|
+
if (buf === null) {
|
|
45
|
+
throw new Error(`read(${addr}, ${size}) failed`);
|
|
46
|
+
}
|
|
47
|
+
return buf;
|
|
48
|
+
}
|
|
49
|
+
regions(filter) {
|
|
50
|
+
return this.memory.regions(filter);
|
|
51
|
+
}
|
|
52
|
+
#getScanner() {
|
|
53
|
+
if (this.#scanner === null) {
|
|
54
|
+
this.#scanner = new Scanner();
|
|
55
|
+
}
|
|
56
|
+
return this.#scanner;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function normalizeTarget(t) {
|
|
60
|
+
if (typeof t === "string") {
|
|
61
|
+
return resolveTarget(t);
|
|
62
|
+
}
|
|
63
|
+
if (typeof t === "number") {
|
|
64
|
+
return uint64(t);
|
|
65
|
+
}
|
|
66
|
+
if (t instanceof NativePointer) {
|
|
67
|
+
return uint64(t.toString());
|
|
68
|
+
}
|
|
69
|
+
return t;
|
|
70
|
+
}
|
|
71
|
+
function pickMatchingTarget(maskedTargets, slot) {
|
|
72
|
+
for (const t of maskedTargets) {
|
|
73
|
+
if (t.compare(slot) === 0) {
|
|
74
|
+
return t;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return slot;
|
|
78
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "frida-mem-scan",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Fast SIMD-accelerated memory scanner for Frida — in-process and cross-process (PID).",
|
|
5
|
+
"author": "Ole André Vadla Ravnås <oleavr@frida.re>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": "github:oleavr/frida-mem-scan",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"cross-process",
|
|
10
|
+
"frida",
|
|
11
|
+
"frida-gum",
|
|
12
|
+
"mach",
|
|
13
|
+
"memory",
|
|
14
|
+
"neon",
|
|
15
|
+
"scanner",
|
|
16
|
+
"simd",
|
|
17
|
+
"sse"
|
|
18
|
+
],
|
|
19
|
+
"main": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"files": [
|
|
22
|
+
"/dist/**/*.js",
|
|
23
|
+
"/dist/**/*.d.ts"
|
|
24
|
+
],
|
|
25
|
+
"type": "module",
|
|
26
|
+
"scripts": {
|
|
27
|
+
"prepare": "npm run build",
|
|
28
|
+
"build": "tsc",
|
|
29
|
+
"watch": "tsc -w"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/frida-gum": "^19.1.0",
|
|
33
|
+
"@types/node": "^18.19.130",
|
|
34
|
+
"typescript": "^6.0.3"
|
|
35
|
+
}
|
|
36
|
+
}
|