frida-fs 3.0.1 → 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 +143 -35
- 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,16 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
import stream from 'stream';
|
|
2
2
|
|
|
3
3
|
const {platform, pointerSize} = Process;
|
|
4
4
|
|
|
5
|
+
const S_IFMT = 0xf000;
|
|
6
|
+
const S_IFREG = 0x8000;
|
|
7
|
+
const S_IFDIR = 0x4000;
|
|
8
|
+
const S_IFCHR = 0x2000;
|
|
9
|
+
const S_IFBLK = 0x6000;
|
|
10
|
+
const S_IFIFO = 0x1000;
|
|
11
|
+
const S_IFLNK = 0xa000;
|
|
12
|
+
const S_IFSOCK = 0xc000;
|
|
13
|
+
|
|
5
14
|
const universalConstants = {
|
|
6
|
-
S_IFMT
|
|
7
|
-
S_IFREG
|
|
8
|
-
S_IFDIR
|
|
9
|
-
S_IFCHR
|
|
10
|
-
S_IFBLK
|
|
11
|
-
S_IFIFO
|
|
12
|
-
S_IFLNK
|
|
13
|
-
S_IFSOCK
|
|
15
|
+
S_IFMT,
|
|
16
|
+
S_IFREG,
|
|
17
|
+
S_IFDIR,
|
|
18
|
+
S_IFCHR,
|
|
19
|
+
S_IFBLK,
|
|
20
|
+
S_IFIFO,
|
|
21
|
+
S_IFLNK,
|
|
22
|
+
S_IFSOCK,
|
|
14
23
|
|
|
15
24
|
S_IRWXU: 448,
|
|
16
25
|
S_IRUSR: 256,
|
|
@@ -403,6 +412,24 @@ const statSpecs = {
|
|
|
403
412
|
'blksize': [ 48, 'S32' ],
|
|
404
413
|
}
|
|
405
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
|
+
},
|
|
406
433
|
'linux-64': {
|
|
407
434
|
size: 144,
|
|
408
435
|
fields: {
|
|
@@ -422,28 +449,73 @@ const statSpecs = {
|
|
|
422
449
|
},
|
|
423
450
|
},
|
|
424
451
|
};
|
|
425
|
-
|
|
452
|
+
let cachedStatSpec = null;
|
|
426
453
|
const statBufSize = 256;
|
|
427
454
|
|
|
428
|
-
function
|
|
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
|
+
|
|
480
|
+
class Stats {
|
|
481
|
+
isFile() {
|
|
482
|
+
return (this.mode & S_IFMT) === S_IFREG;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
isDirectory() {
|
|
486
|
+
return (this.mode & S_IFMT) === S_IFDIR;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
isCharacterDevice() {
|
|
490
|
+
return (this.mode & S_IFMT) === S_IFCHR;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
isBlockDevice() {
|
|
494
|
+
return (this.mode & S_IFMT) === S_IFBLK;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
isFIFO() {
|
|
498
|
+
return (this.mode & S_IFMT) === S_IFIFO;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
isSymbolicLink() {
|
|
502
|
+
return (this.mode & S_IFMT) === S_IFLNK;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
isSocket() {
|
|
506
|
+
return (this.mode & S_IFMT) === S_IFSOCK;
|
|
507
|
+
}
|
|
429
508
|
}
|
|
430
509
|
|
|
431
510
|
function statSync(path) {
|
|
432
|
-
|
|
433
|
-
const impl = api.stat64 || api.stat;
|
|
434
|
-
return performStat(impl, path);
|
|
511
|
+
return performStat(getStatSpec()._stat, path);
|
|
435
512
|
}
|
|
436
513
|
|
|
437
514
|
function lstatSync(path) {
|
|
438
|
-
|
|
439
|
-
const impl = api.lstat64 || api.lstat;
|
|
440
|
-
return performStat(impl, path);
|
|
515
|
+
return performStat(getStatSpec()._lstat, path);
|
|
441
516
|
}
|
|
442
517
|
|
|
443
518
|
function performStat(impl, path) {
|
|
444
|
-
if (statSpec === null)
|
|
445
|
-
throw new Error('Current OS is not yet supported; please open a PR');
|
|
446
|
-
|
|
447
519
|
const buf = Memory.alloc(statBufSize);
|
|
448
520
|
const result = impl(Memory.allocUtf8String(path), buf);
|
|
449
521
|
if (result.value !== 0)
|
|
@@ -466,6 +538,8 @@ function performStat(impl, path) {
|
|
|
466
538
|
case 'buffer':
|
|
467
539
|
return buf;
|
|
468
540
|
default:
|
|
541
|
+
if (property in target)
|
|
542
|
+
return target[property];
|
|
469
543
|
const value = statsReadField.call(receiver, property);
|
|
470
544
|
return (value !== null) ? value : undefined;
|
|
471
545
|
}
|
|
@@ -491,7 +565,7 @@ function statsHasField(name) {
|
|
|
491
565
|
}
|
|
492
566
|
|
|
493
567
|
function statsReadField(name) {
|
|
494
|
-
let field =
|
|
568
|
+
let field = getStatSpec().fields[name];
|
|
495
569
|
if (field === undefined) {
|
|
496
570
|
if (name === 'birthtime') {
|
|
497
571
|
return statsReadField.call(this, 'ctime');
|
|
@@ -574,11 +648,18 @@ const apiSpec = [
|
|
|
574
648
|
['unlink', SF, 'int', ['pointer']],
|
|
575
649
|
['stat', SF, 'int', ['pointer', 'pointer']],
|
|
576
650
|
['stat64', SF, 'int', ['pointer', 'pointer']],
|
|
651
|
+
['__xstat64', SF, 'int', ['int', 'pointer', 'pointer'], invokeXstat],
|
|
577
652
|
['lstat', SF, 'int', ['pointer', 'pointer']],
|
|
578
653
|
['lstat64', SF, 'int', ['pointer', 'pointer']],
|
|
654
|
+
['__lxstat64', SF, 'int', ['int', 'pointer', 'pointer'], invokeXstat],
|
|
579
655
|
['strerror', NF, 'pointer', ['int']],
|
|
580
656
|
];
|
|
581
657
|
|
|
658
|
+
function invokeXstat(impl, path, buf) {
|
|
659
|
+
const STAT_VER_LINUX = 3;
|
|
660
|
+
return impl(STAT_VER_LINUX, path, buf);
|
|
661
|
+
}
|
|
662
|
+
|
|
582
663
|
let cachedApi = null;
|
|
583
664
|
function getApi() {
|
|
584
665
|
if (cachedApi === null) {
|
|
@@ -596,13 +677,16 @@ function addApiPlaceholder(api, entry) {
|
|
|
596
677
|
Object.defineProperty(api, name, {
|
|
597
678
|
configurable: true,
|
|
598
679
|
get() {
|
|
599
|
-
const [, Ctor, retType, argTypes] = entry;
|
|
680
|
+
const [, Ctor, retType, argTypes, wrapper] = entry;
|
|
600
681
|
|
|
601
682
|
let impl = null;
|
|
602
683
|
const address = Module.findExportByName(null, name);
|
|
603
684
|
if (address !== null)
|
|
604
685
|
impl = new Ctor(address, retType, argTypes);
|
|
605
686
|
|
|
687
|
+
if (wrapper !== undefined)
|
|
688
|
+
impl = wrapper.bind(null, impl);
|
|
689
|
+
|
|
606
690
|
Object.defineProperty(api, name, { value: impl });
|
|
607
691
|
|
|
608
692
|
return impl;
|
|
@@ -610,25 +694,49 @@ function addApiPlaceholder(api, entry) {
|
|
|
610
694
|
});
|
|
611
695
|
}
|
|
612
696
|
|
|
613
|
-
|
|
697
|
+
export function createReadStream(path) {
|
|
698
|
+
return new ReadStream(path);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
export function createWriteStream(path) {
|
|
702
|
+
return new WriteStream(path);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
export const readdir = callbackify(readdirSync);
|
|
706
|
+
export const readFile = callbackify(readFileSync);
|
|
707
|
+
export const readlink = callbackify(readlinkSync);
|
|
708
|
+
export const unlink = callbackify(unlinkSync);
|
|
709
|
+
export const stat = callbackify(statSync);
|
|
710
|
+
export const lstat = callbackify(lstatSync);
|
|
711
|
+
|
|
712
|
+
export {
|
|
614
713
|
constants,
|
|
615
|
-
createReadStream(path) {
|
|
616
|
-
return new ReadStream(path);
|
|
617
|
-
},
|
|
618
|
-
createWriteStream(path) {
|
|
619
|
-
return new WriteStream(path);
|
|
620
|
-
},
|
|
621
|
-
readdir: callbackify(readdirSync),
|
|
622
714
|
readdirSync,
|
|
623
715
|
list,
|
|
624
|
-
readFile: callbackify(readFileSync),
|
|
625
716
|
readFileSync,
|
|
626
|
-
readlink: callbackify(readlinkSync),
|
|
627
717
|
readlinkSync,
|
|
628
|
-
unlink: callbackify(unlinkSync),
|
|
629
718
|
unlinkSync,
|
|
630
|
-
stat: callbackify(statSync),
|
|
631
719
|
statSync,
|
|
632
|
-
lstat: callbackify(lstatSync),
|
|
633
720
|
lstatSync,
|
|
721
|
+
Stats,
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
export default {
|
|
725
|
+
constants,
|
|
726
|
+
createReadStream,
|
|
727
|
+
createWriteStream,
|
|
728
|
+
readdir,
|
|
729
|
+
readdirSync,
|
|
730
|
+
list,
|
|
731
|
+
readFile,
|
|
732
|
+
readFileSync,
|
|
733
|
+
readlink,
|
|
734
|
+
readlinkSync,
|
|
735
|
+
unlink,
|
|
736
|
+
unlinkSync,
|
|
737
|
+
stat,
|
|
738
|
+
statSync,
|
|
739
|
+
lstat,
|
|
740
|
+
lstatSync,
|
|
741
|
+
Stats,
|
|
634
742
|
};
|