frida-fs 4.0.0 → 4.0.1
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 +10 -0
- package/index.js +60 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,3 +9,13 @@ const fs = require('frida-fs');
|
|
|
9
9
|
|
|
10
10
|
fs.createReadStream('/etc/hosts').pipe(networkStream);
|
|
11
11
|
```
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
const fs = require('frida-fs');
|
|
15
|
+
|
|
16
|
+
for (const elm of fs.list("/proc/self/")) {
|
|
17
|
+
console.log(JSON.stringify(elm));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
console.log(fs.readFileSync("/etc/hosts"));
|
|
21
|
+
```
|
package/index.js
CHANGED
|
@@ -412,6 +412,24 @@ const statSpecs = {
|
|
|
412
412
|
'blksize': [ 48, 'S32' ],
|
|
413
413
|
}
|
|
414
414
|
},
|
|
415
|
+
'linux-32-stat64': {
|
|
416
|
+
size: 104,
|
|
417
|
+
fields: {
|
|
418
|
+
'dev': [ 0, 'U64' ],
|
|
419
|
+
'mode': [ 16, 'U32' ],
|
|
420
|
+
'nlink': [ 20, 'U32' ],
|
|
421
|
+
'ino': [ 96, 'U64' ],
|
|
422
|
+
'uid': [ 24, 'U32' ],
|
|
423
|
+
'gid': [ 28, 'U32' ],
|
|
424
|
+
'rdev': [ 32, 'U64' ],
|
|
425
|
+
'atime': [ 72, readTimespec32 ],
|
|
426
|
+
'mtime': [ 80, readTimespec32 ],
|
|
427
|
+
'ctime': [ 88, readTimespec32 ],
|
|
428
|
+
'size': [ 48, 'S64' ],
|
|
429
|
+
'blocks': [ 64, 'S64' ],
|
|
430
|
+
'blksize': [ 56, 'S32' ],
|
|
431
|
+
}
|
|
432
|
+
},
|
|
415
433
|
'linux-64': {
|
|
416
434
|
size: 144,
|
|
417
435
|
fields: {
|
|
@@ -431,9 +449,34 @@ const statSpecs = {
|
|
|
431
449
|
},
|
|
432
450
|
},
|
|
433
451
|
};
|
|
434
|
-
|
|
452
|
+
let cachedStatSpec = null;
|
|
435
453
|
const statBufSize = 256;
|
|
436
454
|
|
|
455
|
+
function getStatSpec() {
|
|
456
|
+
if (cachedStatSpec !== null)
|
|
457
|
+
return cachedStatSpec;
|
|
458
|
+
|
|
459
|
+
const api = getApi();
|
|
460
|
+
const stat64Impl = api.stat64 ?? api.__xstat64;
|
|
461
|
+
|
|
462
|
+
let platformId = `${platform}-${pointerSize * 8}`;
|
|
463
|
+
if (platformId === 'linux-32') {
|
|
464
|
+
if (stat64Impl !== undefined)
|
|
465
|
+
platformId += '-stat64';
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const statSpec = statSpecs[platformId];
|
|
469
|
+
if (statSpec === undefined)
|
|
470
|
+
throw new Error('Current OS is not yet supported; please open a PR');
|
|
471
|
+
|
|
472
|
+
statSpec._stat = stat64Impl ?? api.stat;
|
|
473
|
+
statSpec._lstat = api.lstat64 ?? api.__lxstat64 ?? api.lstat;
|
|
474
|
+
|
|
475
|
+
cachedStatSpec = statSpec;
|
|
476
|
+
|
|
477
|
+
return statSpec;
|
|
478
|
+
}
|
|
479
|
+
|
|
437
480
|
class Stats {
|
|
438
481
|
isFile() {
|
|
439
482
|
return (this.mode & S_IFMT) === S_IFREG;
|
|
@@ -465,21 +508,14 @@ class Stats {
|
|
|
465
508
|
}
|
|
466
509
|
|
|
467
510
|
function statSync(path) {
|
|
468
|
-
|
|
469
|
-
const impl = api.stat64 || api.stat;
|
|
470
|
-
return performStat(impl, path);
|
|
511
|
+
return performStat(getStatSpec()._stat, path);
|
|
471
512
|
}
|
|
472
513
|
|
|
473
514
|
function lstatSync(path) {
|
|
474
|
-
|
|
475
|
-
const impl = api.lstat64 || api.lstat;
|
|
476
|
-
return performStat(impl, path);
|
|
515
|
+
return performStat(getStatSpec()._lstat, path);
|
|
477
516
|
}
|
|
478
517
|
|
|
479
518
|
function performStat(impl, path) {
|
|
480
|
-
if (statSpec === null)
|
|
481
|
-
throw new Error('Current OS is not yet supported; please open a PR');
|
|
482
|
-
|
|
483
519
|
const buf = Memory.alloc(statBufSize);
|
|
484
520
|
const result = impl(Memory.allocUtf8String(path), buf);
|
|
485
521
|
if (result.value !== 0)
|
|
@@ -529,7 +565,7 @@ function statsHasField(name) {
|
|
|
529
565
|
}
|
|
530
566
|
|
|
531
567
|
function statsReadField(name) {
|
|
532
|
-
let field =
|
|
568
|
+
let field = getStatSpec().fields[name];
|
|
533
569
|
if (field === undefined) {
|
|
534
570
|
if (name === 'birthtime') {
|
|
535
571
|
return statsReadField.call(this, 'ctime');
|
|
@@ -612,11 +648,18 @@ const apiSpec = [
|
|
|
612
648
|
['unlink', SF, 'int', ['pointer']],
|
|
613
649
|
['stat', SF, 'int', ['pointer', 'pointer']],
|
|
614
650
|
['stat64', SF, 'int', ['pointer', 'pointer']],
|
|
651
|
+
['__xstat64', SF, 'int', ['int', 'pointer', 'pointer'], invokeXstat],
|
|
615
652
|
['lstat', SF, 'int', ['pointer', 'pointer']],
|
|
616
653
|
['lstat64', SF, 'int', ['pointer', 'pointer']],
|
|
654
|
+
['__lxstat64', SF, 'int', ['int', 'pointer', 'pointer'], invokeXstat],
|
|
617
655
|
['strerror', NF, 'pointer', ['int']],
|
|
618
656
|
];
|
|
619
657
|
|
|
658
|
+
function invokeXstat(impl, path, buf) {
|
|
659
|
+
const STAT_VER_LINUX = 3;
|
|
660
|
+
return impl(STAT_VER_LINUX, path, buf);
|
|
661
|
+
}
|
|
662
|
+
|
|
620
663
|
let cachedApi = null;
|
|
621
664
|
function getApi() {
|
|
622
665
|
if (cachedApi === null) {
|
|
@@ -634,13 +677,16 @@ function addApiPlaceholder(api, entry) {
|
|
|
634
677
|
Object.defineProperty(api, name, {
|
|
635
678
|
configurable: true,
|
|
636
679
|
get() {
|
|
637
|
-
const [, Ctor, retType, argTypes] = entry;
|
|
680
|
+
const [, Ctor, retType, argTypes, wrapper] = entry;
|
|
638
681
|
|
|
639
682
|
let impl = null;
|
|
640
683
|
const address = Module.findExportByName(null, name);
|
|
641
684
|
if (address !== null)
|
|
642
685
|
impl = new Ctor(address, retType, argTypes);
|
|
643
686
|
|
|
687
|
+
if (wrapper !== undefined)
|
|
688
|
+
impl = wrapper.bind(null, impl);
|
|
689
|
+
|
|
644
690
|
Object.defineProperty(api, name, { value: impl });
|
|
645
691
|
|
|
646
692
|
return impl;
|
|
@@ -649,11 +695,11 @@ function addApiPlaceholder(api, entry) {
|
|
|
649
695
|
}
|
|
650
696
|
|
|
651
697
|
export function createReadStream(path) {
|
|
652
|
-
|
|
698
|
+
return new ReadStream(path);
|
|
653
699
|
}
|
|
654
700
|
|
|
655
701
|
export function createWriteStream(path) {
|
|
656
|
-
|
|
702
|
+
return new WriteStream(path);
|
|
657
703
|
}
|
|
658
704
|
|
|
659
705
|
export const readdir = callbackify(readdirSync);
|