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.
Files changed (3) hide show
  1. package/README.md +10 -0
  2. package/index.js +60 -14
  3. 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
- const statSpec = statSpecs[`${platform}-${pointerSize * 8}`] || null;
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
- const api = getApi();
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
- const api = getApi();
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 = statSpec.fields[name];
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
- return new ReadStream(path);
698
+ return new ReadStream(path);
653
699
  }
654
700
 
655
701
  export function createWriteStream(path) {
656
- return new WriteStream(path);
702
+ return new WriteStream(path);
657
703
  }
658
704
 
659
705
  export const readdir = callbackify(readdirSync);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frida-fs",
3
- "version": "4.0.0",
3
+ "version": "4.0.1",
4
4
  "description": "Create a stream from a filesystem resource",
5
5
  "main": "index.js",
6
6
  "type": "module",