Skip to content

lachrist/aran

Repository files navigation

Aran aran-logo

Aran is a npm module for instrumenting JavaScript code. Aran was designed as a generic infrastructure for building various development-time dynamic program analyses such as: object and function profiling, debugging, control-flow tracing, taint analysis, and concolic testing. Aran is a JavaScript library without any dependencies that only exports functions for manipulating estree. Hence, additional work is required to deploy program analysis onto projects.

Disclaimer: Aran started as an academic research project and is used at SOFT lab to support publications and run experiments. Aran provides extensive support for ECMAScript2024 and achieves a 99.7% success rate against test262. However, it has rarely been used to instrument large-scale programs and performance overhead may cause issues when analyzing time-sensitive programs.

Getting Started

Aran can be installed with npm install aran. Since Aran exclusively manipulates estree, it requires both a parser and a code generator to function. We recommend using acorn as the parser and astring as the code generator. Below is a minimal working example demonstrating the use of acorn.parse, aran.instrument, and astring.generate:

npm install aran acorn astring
import { generate } from "astring";
import { parse } from "acorn";
import { instrument } from "aran";

globalThis._ARAN_ADVICE_ = {
  "apply@around": (_state, callee, this_arg, args, location) => {
    console.dir({ callee, this_arg, args, location });
    return Reflect.apply(callee, this_arg, args);
  },
};

globalThis.eval(
  generate(
    instrument(
      {
        kind: "eval",
        path: "main",
        root: parse("console.log('Hello!');", { ecmaVersion: 2024 }),
      },
      {
        mode: "standalone",
        advice_global_variable: "_ARAN_ADVICE_",
        pointcut: ["apply@around"],
      },
    ),
  ),
);
{
  callee: [Function: readGlobalVariable],
  this_arg: undefined,
  args: [ 'console' ],
  location: 'main#$.body.0.expression.callee.object'
}
{
  callee: [Function: getValueProperty],
  this_arg: undefined,
  args: [
    Object [console],
    'log'
  ],
  location: 'main#$.body.0.expression.callee'
}
{
  callee: [Function: log],
  this_arg: Object [console],
  args: [ 'Hello!' ],
  location: 'main#$.body.0.expression'
}
Hello!

Live Demo

live-demo

API

typedoc

Aran's flowchart

Aran simplifies the instrumentation of JavaScript code by transpiling it into a minimal variant called AranLang. Instrumentation is performed on AranLang before transpiling it back to JavaScript. Aran provides the following functions:

  • setupile: Generates a setup program (JavaScript) that should be evaluated before any AranLang program. This requirement can be removed by setting conf.mode of retropile to "standalone" instead of "normal". The standalone mode works only with single-source programs.
  • transpile: Transpile an JavaScript program to AranLang.
  • weaveStandard: Weave a standard aspect into an AranLang program.
  • weaveFlexible: Weave a flexible aspect into an AranLang program.
  • retropile: Transpile an AranLang program back to JavaScript.
  • instrument: Instrument a JavaScript program by chaining: transpile, weaveStandard, and retropile.

Known Issues

Beside performance overhead, Aran has some known issues that may cause instrumented programs to no behave as their pre-instrumented version.

Most of these issues requires fairly convoluted code to arise. In practice, the issue that is most susceptible to cause a program to behave differentially is early script declaration.

Acknowledgments

I'm Laurent Christophe a phd student at the Vrij Universiteit of Brussel. My promoters are Coen De Roover and Wolfgang De Meuter.

vub soft tearless

About

JavaScript Code Instrumenter

Resources

License

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •