Skip to content

Berkeley-Correctness-Group/jalangi

 
 

Repository files navigation

Jalangi

Introduction

Jalangi is a framework for writing heavy-weight dynamic analyses for JavaScript. Jalangi incorporates two key techniques:

  1. selective record-replay, a technique which enables to record and to faithfully replay a user-selected part of the program, and
  2. shadow values and shadow execution, which enables easy implementation of heavy-weight dynamic analyses. In the distribution you will find several analyses:
  • concolic testing,
  • an analysis to track origins of nulls and undefined,
  • an analysis to infer likely types of objects fields and functions,
  • an analysis to profile object allocation and usage,
  • a simple form of taint analysis,
  • an experimental pure symbolic execution engine (currently undocumented)

An evaluation of Jalangi on the SunSpider benchmark suite and on five web applications shows that Jalangi has an average slowdown of 26X during recording and 30X slowdown during replay and analysis. The slowdowns are comparable with slowdowns reported for similar tools, such as PIN and Valgrind for x86 binaries.

A demo of Jalangi integrated with the Tizen IDE is available at http://srl.cs.berkeley.edu/~ksen/jalangi.html. Note that the IDE plugin is not open-source. Slides are available at http://srl.cs.berkeley.edu/~ksen/slides/jalangi-jstools13.pdf and our paper on Jalangi is available at http://srl.cs.berkeley.edu/~ksen/papers/jalangi.pdf.

Requirements

We tested Jalangi on Mac OS X 10.8 with Chromium browser. Jalangi should work on Mac OS 10.7, Ubuntu 11.0 and higher and Windows 7 or higher. Jalangi will NOT work with Firefox and IE.

  • Latest version of Node.js available at http://nodejs.org/. We have tested Jalangi with Node v0.8.22 and v0.10.3.
  • Sun's JDK 1.6 or higher. We have tested Jalangi with Java 1.6.0_43.
  • Command-line git.
  • libgmp (http://gmplib.org/) is required by cvc3. Concolic testing uses cvc3 and automaton.jar for constraint solving. The installation script checks if cvc3 and automaton.jar are installed properly.
  • Chrome browser if you need to test web apps.
  • Python (http://python.org) version 2.7 or higher

On Windows you need the following extra dependencies:

  • Install Microsoft Visual Studio 2010 (Free express version is fine).
  • If on 64bit also install Windows 7 64-bit SDK.

If you have a fresh installation of Ubuntu, you can install all the requirements by invoking the following commands from a terminal.

sudo apt-get update
sudo apt-get install python-software-properties python g++ make
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java7-installer
sudo update-java-alternatives -s java-7-oracle
sudo apt-get install git
sudo apt-get install libgmp10
sudo apt-get install chromium-browser

Installation

python ./scripts/install.py

If Installation succeeds, you should see the following message:

---> Installation successful.
---> run 'npm test' to make sure all tests pass

A Lubuntu virtual machine with pre-installed jalangi can be downloaded from http://srl.cs.berkeley.edu/~ksen/jalangi4.zip. You need VirtualBox available at https://www.virtualbox.org/ to run the virtual machine. Login and password for the jalangi account on the machine are jalangi and jalangi, respectively. Open a terminal, go to directory jalangi, and try ./scripts/testsym.

Run Tests

Run concolic testing tests.

python ./scripts/sym.py

Run no analysis and check if record and replay executions produce same output on some unit tests located under tests/unit/.

python ./scripts/units.py

Run all value tracking analysis on some unit tests located under tests/unit/.

python ./scripts/unitsv.py

Run no analysis and check if record and replay executions produce same output on the sunspider benchmarks located under tests/sunspider1/.

python scripts/testsp.py

Run all value tracking analysis on the sunspider benchmarks located under tests/sunspider1/.

python scripts/testspv.py

We also have test drivers implemented in JavaScript using mocha, located under node_test. So, to run the basic unit tests, you can do:

./node_modules/.bin/mocha --reporter spec node_test/unitTests.js

To run the entire test suite, simply run:

npm test

Run Browser Tests

Some automated tests can be run in the browser, using Selenium. To run these tests, first install the relevant dependencies:

sudo python scripts/install-dev.py

(sudo is needed to install the Python Selenium bindings.) Then, to run all browser tests, do:

python scripts/runbrowsertests.py

You should see Chrome windows opening and closing as the tests are run.

Other Scripts

Run likely type inference analysis on the sunspider benchmarks located under tests/sunspider1/.

python scripts/testsp_likelytype.py

Run tracker of origin of null and undefined on the sunspider benchmarks located under tests/sunspider1/.

python scripts/testsp_tracknull.py

Run a simple heap profiler on the sunspider benchmarks located under tests/sunspider1/.

python scripts/testsp_heapprofiling.py

Record an execution of tests/unit/qsort.js and create jalangi_trace.html which when loaded in a browser replays the execution.

./scripts/browserReplay tests/unit/qsort; path-to-chrome-browser jalangi_trace.html

Concolic testing

To perform concolic testing of some JavaScript code present in a file, say testme.js, insert the following 4 lines at the top of the file.

if (typeof window === "undefined") {
    require('../../src/js/InputManager');
    require(process.cwd()+'/inputs');
}

In the code, use J$.readInput(arg) to indicate the inputs to the program. Then run the following command to perform concolic testing:

python scripts/jalangi.py concolic -i 100000 testme

The -i argument bounds the total number of test inputs. The command generates a set of input files in the directory jalangi_tmp. The input files start with the prefix jalangi_inputs. Once the inputs are generated, you can run testme.js on those inputs by giving the following command:

 python scripts/jalangi.py rerunall testme

For example, open the file tests/unit/qsort.js and check how inputs are specified. Then run

 python scripts/jalangi.py concolic tests/unit/qsort 100
 python scripts/jalangi.py rerunall tests/unit/qsort

Open the file tests/unit/regex8.js and check how string inputs are specified. Then run

 python scripts/jalangi.py concolic tests/unit/regex8 100
 python scripts/jalangi.py rerunall tests/unit/regex8

Dynamic analysis

The JavaScript code in src/js/analyses/objectalloc/ObjectAllocationTrackerEngine.js implements a simple analysis that reports the number of objects created during an execution along with some auxiliary information. The analysis can be performed on a file testme.js by invoking the following command:

python scripts/jalangi.py analyze -a ./analyses/objectalloc/ObjectAllocationTrackerEngine testme

For example, try running the analysis on a sunspider benchmark by issuing the following command:

python scripts/jalangi.py analyze -a ./analyses/objectalloc/ObjectAllocationTrackerEngine tests/sunspider1/crypto-aes

Similarly, you can run a likely type inference analysis on another sunspider benchmark by calling the following command and you will notice some warnings.

python scripts/jalangi.py analyze -a ./analyses/likelytype/LikelyTypeInferEngine tests/sunspider1/crypto-sha1

Run the following to perform a simple form of taint analysis.

python scripts/jalangi.py analyze -a ./analyses/simpletaint/SimpleTaintEngine tests/sunspider1/crypto-sha1

You can run origin of null and undefined tracker on a toy example by issuing the following command:

python scripts/jalangi.py analyze -a ./analyses/trackundefinednull/UndefinedNullTrackingEngine tests/unit/track_undef_null

Record and replay a web application.


Jalangi provides a script for instrumenting a locally-stored web application, by instrumenting all discovered scripts on disk. Here is how to instrument the annex app using this script. First, run the instrumentDir.js script to instrument the app:

node src/js/commands/instrumentDir.js tests/tizen/annex /tmp

This creates an instrumented copy of annex in /tmp/annex. To see other options for instrumentDir.js, run it with the -h option.

Then, launch the Jalangi server and the HTML page by running

killall node
python scripts/jalangi.py rrserver file:///tmp/annex/index.html

You can now play the game for sometime. Try two moves. This will generate a jalangi_trace1 in the current directory. To ensure the trace is completely flushed, press Alt+Shift+T in the browser, and then close the browser window. You can run a dynamic analysis on the trace file by issuing the following commands (not that this differs slightly from above, due to the need to copy the trace):

cp jalangi_trace1 /tmp/annex
node src/js/commands/replay.js /tmp/annex/jalangi_trace1 ./analyses/objectalloc/ObjectAllocationTrackerEngine

Record and replay using the proxy server.


Jalangi also provides a proxy server to instrument code from live web sites. Here is how to instrument the annex app from above using the proxy server.

First start a HTTP server by running the following command. The command starts a simple Python based http server.

python scripts/jalangi.py server &

Then, launch the combined proxy and Jalangi record-replay server.

node src/js/commands/jalangi_proxy.js

You will see output like the following:

writing output to /tmp/instScripts/site0
listening on port 8501
Fri Dec 13 2013 16:02:34 GMT-0800 (PST) Server is listening on port 8080

The proxy server is listening on port 8501, and the record-replay server on port 8080. Instrumented scripts and the trace file will be written to /tmp/instScripts/site0.

Now, configure your browser to use the proxy server. The procedure will vary by operating system and by browser.
For browsers on Mac OS X, you can set the proxy server for a network adapter Wi-Fi with the following command:

sudo networksetup -setwebproxy Wi-Fi 127.0.0.1 8501 off

To stop using the proxy, run sudo networksetup -setwebproxystate Wi-Fi off.

Now, open Chrome and navigate to http://127.0.0.1:8181/tests/tizen/annex/index.html (not index_jalangi_.html). You can now play the game for sometime. Try two moves. This will generate a jalangi_trace1 in the output directory /tmp/instScripts/site0. To ensure the trace is completely flushed, press Alt+Shift+T in the browser, and then close the browser window. Once you are done playing, kill the proxy server process to complete dumping of certain metadata.

Now, you can run a dynamic analysis on the trace file by issuing the following commands.

node src/js/commands/replay.js /tmp/instScripts/site0/jalangi_trace1 ./analyses/objectalloc/ObjectAllocationTrackerEngine

Further examples of record and replay


node src/js/commands/instrumentDir.js tests/tizen/calculator /tmp

killall node
python scripts/jalangi.py rrserver file:///tmp/calculator/index.html

cp jalangi_trace1 /tmp/calculator
node src/js/commands/replay.js /tmp/calculator/jalangi_trace1 ./analyses/likelytype/LikelyTypeInferEngine

node src/js/commands/instrumentDir.js tests/tizen/go /tmp

killall node
python scripts/jalangi.py rrserver file:///tmp/go/index.html

cp jalangi_trace1 /tmp/go
node src/js/commands/replay.js /tmp/go/jalangi_trace1 ./analyses/likelytype/LikelyTypeInferEngine

In browser analysis of a web application.


Jalangi allows to run an analysis, which does not use ConcolicValue, in a browser. Here is how to instrument the annex app with an inbrowser analysis. First, run the instrumentDir.js script to instrument the app:

node src/js/commands/instrumentDir.js --analysis analyses/logundefinedread/logUndefinedRead.js tests/tizen/annex /tmp

This creates an instrumented copy of annex in /tmp/annex. To see other options for instrumentDir.js, run it with the -h option.

Then, open the HTML page in a browser (tested on Chrome) by running

open file:///tmp/annex/index.html

You can now play the game for sometime. Try two moves and see the console output. In the in-browser mode, one must not use ConcolicValue to wrap a program value. However, one could use shadow execution to collect statistics. Shadow memory is supported in the "inbrowser" mode. Shadow memory library can be accessed in an analysis via J$.Globals.smemory. smemory.getShadowObject(obj) returns the shadow object associated with obj if type of obj is "object" or "function". smemory.getShadowFrame(varName) returns the shadow frame that contains the variable named "varName".

The following shows how to run the object allocation tracker analysis on the annex game:

node src/js/commands/instrumentDir.js --analysis analyses/objectalloc/ObjectAllocationTrackerEngineIB.js tests/tizen/annex /tmp
open file:///tmp/annex/index.html

The following shows how to run the likely type inference analysis on the annex game:

node src/js/commands/instrumentDir.js --analysis analyses/likelytype/LikelyTypeInferEngineIB.js tests/tizen/annex /tmp
open file:///tmp/annex/index.html

About

Do research on top of Jalangi

Resources

License

Stars

Watchers

Forks

Packages

No packages published