frida-fs 3.0.2 → 4.0.2
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 +97 -26
- package/package.json +2 -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
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import {Buffer} from 'buffer';
|
|
2
|
+
import stream from 'stream';
|
|
2
3
|
|
|
3
4
|
const {platform, pointerSize} = Process;
|
|
4
5
|
|
|
@@ -127,6 +128,7 @@ class ReadStream extends stream.Readable {
|
|
|
127
128
|
.catch(error => {
|
|
128
129
|
this._readRequest = null;
|
|
129
130
|
this._closeInput();
|
|
131
|
+
this.emit('error', error);
|
|
130
132
|
this.push(null);
|
|
131
133
|
});
|
|
132
134
|
}
|
|
@@ -412,6 +414,24 @@ const statSpecs = {
|
|
|
412
414
|
'blksize': [ 48, 'S32' ],
|
|
413
415
|
}
|
|
414
416
|
},
|
|
417
|
+
'linux-32-stat64': {
|
|
418
|
+
size: 104,
|
|
419
|
+
fields: {
|
|
420
|
+
'dev': [ 0, 'U64' ],
|
|
421
|
+
'mode': [ 16, 'U32' ],
|
|
422
|
+
'nlink': [ 20, 'U32' ],
|
|
423
|
+
'ino': [ 96, 'U64' ],
|
|
424
|
+
'uid': [ 24, 'U32' ],
|
|
425
|
+
'gid': [ 28, 'U32' ],
|
|
426
|
+
'rdev': [ 32, 'U64' ],
|
|
427
|
+
'atime': [ 72, readTimespec32 ],
|
|
428
|
+
'mtime': [ 80, readTimespec32 ],
|
|
429
|
+
'ctime': [ 88, readTimespec32 ],
|
|
430
|
+
'size': [ 48, 'S64' ],
|
|
431
|
+
'blocks': [ 64, 'S64' ],
|
|
432
|
+
'blksize': [ 56, 'S32' ],
|
|
433
|
+
}
|
|
434
|
+
},
|
|
415
435
|
'linux-64': {
|
|
416
436
|
size: 144,
|
|
417
437
|
fields: {
|
|
@@ -431,9 +451,34 @@ const statSpecs = {
|
|
|
431
451
|
},
|
|
432
452
|
},
|
|
433
453
|
};
|
|
434
|
-
|
|
454
|
+
let cachedStatSpec = null;
|
|
435
455
|
const statBufSize = 256;
|
|
436
456
|
|
|
457
|
+
function getStatSpec() {
|
|
458
|
+
if (cachedStatSpec !== null)
|
|
459
|
+
return cachedStatSpec;
|
|
460
|
+
|
|
461
|
+
const api = getApi();
|
|
462
|
+
const stat64Impl = api.stat64 ?? api.__xstat64;
|
|
463
|
+
|
|
464
|
+
let platformId = `${platform}-${pointerSize * 8}`;
|
|
465
|
+
if (platformId === 'linux-32') {
|
|
466
|
+
if (stat64Impl !== undefined)
|
|
467
|
+
platformId += '-stat64';
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
const statSpec = statSpecs[platformId];
|
|
471
|
+
if (statSpec === undefined)
|
|
472
|
+
throw new Error('Current OS is not yet supported; please open a PR');
|
|
473
|
+
|
|
474
|
+
statSpec._stat = stat64Impl ?? api.stat;
|
|
475
|
+
statSpec._lstat = api.lstat64 ?? api.__lxstat64 ?? api.lstat;
|
|
476
|
+
|
|
477
|
+
cachedStatSpec = statSpec;
|
|
478
|
+
|
|
479
|
+
return statSpec;
|
|
480
|
+
}
|
|
481
|
+
|
|
437
482
|
class Stats {
|
|
438
483
|
isFile() {
|
|
439
484
|
return (this.mode & S_IFMT) === S_IFREG;
|
|
@@ -465,21 +510,14 @@ class Stats {
|
|
|
465
510
|
}
|
|
466
511
|
|
|
467
512
|
function statSync(path) {
|
|
468
|
-
|
|
469
|
-
const impl = api.stat64 || api.stat;
|
|
470
|
-
return performStat(impl, path);
|
|
513
|
+
return performStat(getStatSpec()._stat, path);
|
|
471
514
|
}
|
|
472
515
|
|
|
473
516
|
function lstatSync(path) {
|
|
474
|
-
|
|
475
|
-
const impl = api.lstat64 || api.lstat;
|
|
476
|
-
return performStat(impl, path);
|
|
517
|
+
return performStat(getStatSpec()._lstat, path);
|
|
477
518
|
}
|
|
478
519
|
|
|
479
520
|
function performStat(impl, path) {
|
|
480
|
-
if (statSpec === null)
|
|
481
|
-
throw new Error('Current OS is not yet supported; please open a PR');
|
|
482
|
-
|
|
483
521
|
const buf = Memory.alloc(statBufSize);
|
|
484
522
|
const result = impl(Memory.allocUtf8String(path), buf);
|
|
485
523
|
if (result.value !== 0)
|
|
@@ -529,7 +567,7 @@ function statsHasField(name) {
|
|
|
529
567
|
}
|
|
530
568
|
|
|
531
569
|
function statsReadField(name) {
|
|
532
|
-
let field =
|
|
570
|
+
let field = getStatSpec().fields[name];
|
|
533
571
|
if (field === undefined) {
|
|
534
572
|
if (name === 'birthtime') {
|
|
535
573
|
return statsReadField.call(this, 'ctime');
|
|
@@ -612,11 +650,18 @@ const apiSpec = [
|
|
|
612
650
|
['unlink', SF, 'int', ['pointer']],
|
|
613
651
|
['stat', SF, 'int', ['pointer', 'pointer']],
|
|
614
652
|
['stat64', SF, 'int', ['pointer', 'pointer']],
|
|
653
|
+
['__xstat64', SF, 'int', ['int', 'pointer', 'pointer'], invokeXstat],
|
|
615
654
|
['lstat', SF, 'int', ['pointer', 'pointer']],
|
|
616
655
|
['lstat64', SF, 'int', ['pointer', 'pointer']],
|
|
656
|
+
['__lxstat64', SF, 'int', ['int', 'pointer', 'pointer'], invokeXstat],
|
|
617
657
|
['strerror', NF, 'pointer', ['int']],
|
|
618
658
|
];
|
|
619
659
|
|
|
660
|
+
function invokeXstat(impl, path, buf) {
|
|
661
|
+
const STAT_VER_LINUX = 3;
|
|
662
|
+
return impl(STAT_VER_LINUX, path, buf);
|
|
663
|
+
}
|
|
664
|
+
|
|
620
665
|
let cachedApi = null;
|
|
621
666
|
function getApi() {
|
|
622
667
|
if (cachedApi === null) {
|
|
@@ -634,13 +679,16 @@ function addApiPlaceholder(api, entry) {
|
|
|
634
679
|
Object.defineProperty(api, name, {
|
|
635
680
|
configurable: true,
|
|
636
681
|
get() {
|
|
637
|
-
const [, Ctor, retType, argTypes] = entry;
|
|
682
|
+
const [, Ctor, retType, argTypes, wrapper] = entry;
|
|
638
683
|
|
|
639
684
|
let impl = null;
|
|
640
685
|
const address = Module.findExportByName(null, name);
|
|
641
686
|
if (address !== null)
|
|
642
687
|
impl = new Ctor(address, retType, argTypes);
|
|
643
688
|
|
|
689
|
+
if (wrapper !== undefined)
|
|
690
|
+
impl = wrapper.bind(null, impl);
|
|
691
|
+
|
|
644
692
|
Object.defineProperty(api, name, { value: impl });
|
|
645
693
|
|
|
646
694
|
return impl;
|
|
@@ -648,26 +696,49 @@ function addApiPlaceholder(api, entry) {
|
|
|
648
696
|
});
|
|
649
697
|
}
|
|
650
698
|
|
|
651
|
-
|
|
699
|
+
export function createReadStream(path) {
|
|
700
|
+
return new ReadStream(path);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
export function createWriteStream(path) {
|
|
704
|
+
return new WriteStream(path);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
export const readdir = callbackify(readdirSync);
|
|
708
|
+
export const readFile = callbackify(readFileSync);
|
|
709
|
+
export const readlink = callbackify(readlinkSync);
|
|
710
|
+
export const unlink = callbackify(unlinkSync);
|
|
711
|
+
export const stat = callbackify(statSync);
|
|
712
|
+
export const lstat = callbackify(lstatSync);
|
|
713
|
+
|
|
714
|
+
export {
|
|
652
715
|
constants,
|
|
653
|
-
createReadStream(path) {
|
|
654
|
-
return new ReadStream(path);
|
|
655
|
-
},
|
|
656
|
-
createWriteStream(path) {
|
|
657
|
-
return new WriteStream(path);
|
|
658
|
-
},
|
|
659
|
-
readdir: callbackify(readdirSync),
|
|
660
716
|
readdirSync,
|
|
661
717
|
list,
|
|
662
|
-
readFile: callbackify(readFileSync),
|
|
663
718
|
readFileSync,
|
|
664
|
-
readlink: callbackify(readlinkSync),
|
|
665
719
|
readlinkSync,
|
|
666
|
-
unlink: callbackify(unlinkSync),
|
|
667
720
|
unlinkSync,
|
|
668
|
-
stat: callbackify(statSync),
|
|
669
721
|
statSync,
|
|
670
|
-
|
|
722
|
+
lstatSync,
|
|
723
|
+
Stats,
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
export default {
|
|
727
|
+
constants,
|
|
728
|
+
createReadStream,
|
|
729
|
+
createWriteStream,
|
|
730
|
+
readdir,
|
|
731
|
+
readdirSync,
|
|
732
|
+
list,
|
|
733
|
+
readFile,
|
|
734
|
+
readFileSync,
|
|
735
|
+
readlink,
|
|
736
|
+
readlinkSync,
|
|
737
|
+
unlink,
|
|
738
|
+
unlinkSync,
|
|
739
|
+
stat,
|
|
740
|
+
statSync,
|
|
741
|
+
lstat,
|
|
671
742
|
lstatSync,
|
|
672
743
|
Stats,
|
|
673
744
|
};
|