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.
Files changed (3) hide show
  1. package/README.md +10 -0
  2. package/index.js +143 -35
  3. 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
- const stream = require('stream');
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: 0xf000,
7
- S_IFREG: 0x8000,
8
- S_IFDIR: 0x4000,
9
- S_IFCHR: 0x2000,
10
- S_IFBLK: 0x6000,
11
- S_IFIFO: 0x1000,
12
- S_IFLNK: 0xa000,
13
- S_IFSOCK: 0xc000,
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
- const statSpec = statSpecs[`${platform}-${pointerSize * 8}`] || null;
452
+ let cachedStatSpec = null;
426
453
  const statBufSize = 256;
427
454
 
428
- function Stats() {
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
- const api = getApi();
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
- const api = getApi();
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 = statSpec.fields[name];
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
- module.exports = {
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
  };
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "frida-fs",
3
- "version": "3.0.1",
3
+ "version": "4.0.1",
4
4
  "description": "Create a stream from a filesystem resource",
5
5
  "main": "index.js",
6
+ "type": "module",
6
7
  "files": [
7
8
  "/index.js"
8
9
  ],