diff --git a/SHM_TEST_get.c b/SHM_TEST_get.c new file mode 100644 index 0000000..78289d0 --- /dev/null +++ b/SHM_TEST_get.c @@ -0,0 +1,68 @@ +//compile with gcc -o SHM_TEST_get SHM_TEST_get.c -lrt + +#include +#include +#include +#include +#include +#include +#include +#include + +#define STORAGE_ID "/SHM_TEST" +#define STORAGE_SIZE 0x100000 + +struct shmem_data { + uint32_t num_edges; + unsigned char edges[]; +}; + + +int main(int argc, char *argv[]) +{ + int res; + int fd; + char data[STORAGE_SIZE]; + struct shmem_data* data1; + pid_t pid; + void *addr; + char* shm_key = getenv("SHM_ID"); + + pid = getpid(); + + // get shared memory file descriptor (NOT a file) + if (shm_key) + fd = shm_open(shm_key, O_RDONLY, S_IRUSR | S_IWUSR); + else + fd = shm_open(STORAGE_ID, O_RDONLY, S_IRUSR | S_IWUSR); + + if (fd == -1) + { + perror("open"); + return 10; + } + + // map shared memory to process address space + addr = mmap(NULL, STORAGE_SIZE, PROT_READ, MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) + { + perror("mmap"); + return 30; + } + + // place data into memory + //memcpy(data, addr, STORAGE_SIZE); + data1 = addr; + int counter=0; + //printf("Size %u\n", (*data1).num_edges); + for (int i=0;inum_edges;i++) { + if (0 != data1->edges[i / 8] && (1 << (i % 8))) { + //printf("cov\n"); + counter++; + } + //else + // printf("-\n"); + } + printf("SHM Edges %u :: %d / %u --> %6.2f coverage\n",(*data1).num_edges,counter,data1->num_edges,100.0 * counter / data1->num_edges ); + return 0; +} diff --git a/SHM_TEST_set.c b/SHM_TEST_set.c new file mode 100644 index 0000000..82d05ac --- /dev/null +++ b/SHM_TEST_set.c @@ -0,0 +1,96 @@ +// compile with +// gcc -o SHM_TEST_set SHM_TEST_set.c -lrt +// run fuzzilli patched javascript engine with environmentvariable SHM_ID=/SHM_TEST + +#include +#include +#include +#include +#include +#include +#include + +#define STORAGE_ID "/SHM_TEST" +#define STORAGE_SIZE 0x100000 +#define DATA "Hello, World! From PID %d 0000000000000" + +int go_on = 1; +void handle_sigint(int sigint) { + go_on = 0; +} + +int main(int argc, char *argv[]) +{ + int res; + int fd; + int len; + pid_t pid; + void *addr; + char data[STORAGE_SIZE]; + char* shm_key = getenv("SHM_ID"); + signal(SIGINT, handle_sigint); + signal(SIGTERM, handle_sigint); + //signal(SIGABRT, handle_sigint); + //signal(SIGKILL, handle_sigint); + + pid = getpid(); + sprintf(data, DATA, pid); + + // get shared memory file descriptor (NOT a file) + if (shm_key) + fd = shm_open(shm_key, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + else + fd = shm_open(STORAGE_ID, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + + if (fd == -1) + { + perror("open"); + return 10; + } + + // extend shared memory object as by default it's initialized with size 0 + res = ftruncate(fd, STORAGE_SIZE); + if (res == -1) + { + perror("ftruncate"); + return 20; + } + + // map shared memory to process address space + addr = mmap(NULL, STORAGE_SIZE, PROT_WRITE, MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) + { + perror("mmap"); + return 30; + } + + // place data into memory + len = strlen(data) + 1; + memcpy(addr, data, STORAGE_SIZE); + + // wait for someone to read it + while (go_on) + sleep(1); + + // mmap cleanup + res = munmap(addr, STORAGE_SIZE); + if (res == -1) + { + perror("munmap"); + return 40; + } + + // shm_open cleanup + if (shm_key) + fd = shm_unlink(shm_key); + else + fd = shm_unlink(STORAGE_ID); + + if (fd == -1) + { + perror("unlink"); + return 100; + } + + return 0; +} diff --git a/esbuilder/jsbuilder.js b/esbuilder/jsbuilder.js index 7d98898..25e2a73 100644 --- a/esbuilder/jsbuilder.js +++ b/esbuilder/jsbuilder.js @@ -8,6 +8,11 @@ var rawValue = require('./raw'); var variable = require('./variable').default; var reference = require('./reference'); +//require('../espath/lib/path'); + +var ValueInfo = require('../espath/lib/path').valueinfo; +var ValueType = require('../espath/lib/path').valuetype; +var ValueMap = require('../espath/lib/path').valuemap; var definition = require('./definition'); var PatternVisitor = require('./pattern-visitor').default; @@ -1574,7 +1579,7 @@ class Builder extends esbuilder.Builder{ console.log(parent.object); let objValuetype = this.pathManager.acquire(parent.object)._valueType; var valueinfo = this.currentValueTable().get(objValuetype.getSymIndex(0x74)); - node.name = random.randomElement([...valueinfo.getProps().keys()]); + if (valueinfo) {node.name = random.randomElement([...valueinfo.getProps().keys()]);} break; } @@ -2535,4 +2540,4 @@ class Builder extends esbuilder.Builder{ } -exports.default = Builder; \ No newline at end of file +exports.default = Builder; diff --git a/espath/lib/path-manager.js b/espath/lib/path-manager.js index 6bdb713..5867b65 100644 --- a/espath/lib/path-manager.js +++ b/espath/lib/path-manager.js @@ -148,8 +148,10 @@ class PathManager{ __updateValueMap(node, path){ var objPath; objPath = this.acquire(node.object); - for(let prop of this.__valueTable.get(objPath._valueType.__symIndex).__props){ - path.valueMap.set(prop[0],prop[1]); + if (objPath._valueType) { + for(let prop of this.__valueTable.get(objPath._valueType.__symIndex).__props){ + path.valueMap.set(prop[0],prop[1]); + } } } @@ -364,7 +366,7 @@ class PathManager{ classType = new ValueInfo(0x0040); for(let method of node.body){ console.log(method); - if(/Identifier/.test(method.key.type)){ + if(method.key && /Identifier/.test(method.key.type)){ classType.__props.set(method.key.name, this.acquire(method)._valueType);//this.__currentValueMap.get(property.key.name)); } } @@ -374,7 +376,7 @@ class PathManager{ valuetype = new ValueType(0x0040,["classType"+(this.__valueTable.size-1)]); for(let method of node.body){ - if(/Identifier/.test(method.key.type)){ + if(method.key && /Identifier/.test(method.key.type)){ this.__currentValueMap.delete(method.key.name); } } @@ -460,7 +462,7 @@ class PathManager{ path = this.acquire(node); calleePath = this.acquire(node.callee); if(path){ - if(calleePath._valueType.getType() & 0x20){ + if(this.__valueTable.get(calleePath._valueType.getSymIndex(0x20)) && calleePath._valueType.getType() & 0x20){ console.log(calleePath._valueType); path.setPathValue(this.__valueTable.get(calleePath._valueType.getSymIndex(0x20)).__desc.ret); }else{ @@ -528,12 +530,12 @@ class PathManager{ case "MemberExpression": let objPath = this.acquire(node.left.object); let propPath = this.acquire(node.left.property); - if(objPath._valueType.__type >= 0x0010){ // make sure obj is not a literal + if(objPath._valueType && objPath._valueType.__type >= 0x0010){ // make sure obj is not a literal valueInfo = this.__valueTable.get(objPath._valueType.getSymIndex(0x70)); - if(/Identifier/.test(propPath.node.type)){ + if(valueInfo && /Identifier/.test(propPath.node.type)){ valueInfo.updateProp(propPath.node.name,right_path.getType()); } - else if(/Literal/.test(propPath.node.type)){ + else if(valueInfo && /Literal/.test(propPath.node.type)){ // if(valueInfo.__props.has(propPath.node.value)){ // valueInfo.__props.get(propPath.node.value).update(right_path._valueType); // }else{ @@ -634,10 +636,10 @@ class PathManager{ var path = this.acquire(node); var objPath = this.acquire(node.object); var propPath = this.acquire(node.property); - if(objPath._valueType.__type >= 0x10 || objPath._valueType.__type&0x0004 ){ // not a literal + if(objPath._valueType && (objPath._valueType.__type >= 0x10 || objPath._valueType.__type&0x0004 )){ // not a literal var objType = this.__valueTable.get(objPath._valueType.getSymIndex(0x74)); // get the value from valueTable if(/Identifier/.test(node.property.type)){ // update the value of current path - if(objType.hasProp(node.property.name)){ + if(objType && objType.hasProp(node.property.name)){ path.setPathValue(objType.getProp(node.property.name)); }else{ //path._valueType = new ValueType(); // there is no prop in the obj @@ -650,9 +652,16 @@ class PathManager{ path.setPathValue(new ValueType(0x00ff,["anyType"])); } } - for(let availableType of objPath._valueType.__symIndex){ - for(let [k, v] of this.__valueTable.get(availableType).__props){ - this.__currentValueMap.delete(k); + if (objPath._valueType) { + for(let availableType of objPath._valueType.__symIndex){ + //if (this.__valueTable.get(availableType)) + { + if (this.__valueTable.get(availableType)) { + for(let [k, v] of this.__valueTable.get(availableType).__props){ + this.__currentValueMap.delete(k); + } + } + } } } if(/Identifier/.test(propPath.node.type)){ @@ -744,7 +753,7 @@ class PathManager{ let path, objPath, currentEnv; path = this.acquire(node); objPath = this.acquire(node.object); - if(path){ + if(path && objPath._valueType){ for(let availableType of objPath._valueType.__symIndex){ for(let [k,v] of this.__valueTable.get(availableType).__props){ // for(let [k,v] of this.__valueTable.get(availableType)){ this.__currentValueMap.delete(k); diff --git a/espath/lib/path.js b/espath/lib/path.js index e1485fc..a239a5e 100644 --- a/espath/lib/path.js +++ b/espath/lib/path.js @@ -136,11 +136,13 @@ class ValueMap extends Map{ super(); if(src){ for(let [k, vtype] of src){ + if (vtype) { let newType = new ValueType(vtype.__type, vtype.__symIndex); this.set(k,newType); } } } + } /** * @@ -366,10 +368,12 @@ class ValueType{ * merge the two types */ update(type){ + if (type) { this.updateType(type.__type); if(type.__symIndex) this.updateSymIndex(type.__symIndex); else{} // do nothing + } } setType(_type){ @@ -421,4 +425,4 @@ class ValueType{ module.exports.path = Path; module.exports.valueinfo = ValueInfo; module.exports.valuetype = ValueType; -module.exports.valuemap = ValueMap; \ No newline at end of file +module.exports.valuemap = ValueMap; diff --git a/generator.js b/generator.js index cd142f5..ca56f88 100644 --- a/generator.js +++ b/generator.js @@ -246,8 +246,11 @@ TrimStackTracePath = function(){}; ` var preSrcAst = esprima.parse(preSrc).body; +//for (var i=0;i<10;i++) +// testMutate(); +//return; -var ast = JSON.parse(raw); +var ast = esprima.parse(raw); ast.body = preSrcAst.concat(ast.body); diff --git a/node_modules/.bin/escodegen b/node_modules/.bin/escodegen deleted file mode 100644 index 01a7c32..0000000 --- a/node_modules/.bin/escodegen +++ /dev/null @@ -1 +0,0 @@ -../escodegen/bin/escodegen.js \ No newline at end of file diff --git a/node_modules/.bin/escodegen b/node_modules/.bin/escodegen new file mode 120000 index 0000000..01a7c32 --- /dev/null +++ b/node_modules/.bin/escodegen @@ -0,0 +1 @@ +../escodegen/bin/escodegen.js \ No newline at end of file diff --git a/node_modules/.bin/esgenerate b/node_modules/.bin/esgenerate deleted file mode 100644 index 7d0293e..0000000 --- a/node_modules/.bin/esgenerate +++ /dev/null @@ -1 +0,0 @@ -../escodegen/bin/esgenerate.js \ No newline at end of file diff --git a/node_modules/.bin/esgenerate b/node_modules/.bin/esgenerate new file mode 120000 index 0000000..7d0293e --- /dev/null +++ b/node_modules/.bin/esgenerate @@ -0,0 +1 @@ +../escodegen/bin/esgenerate.js \ No newline at end of file diff --git a/node_modules/escodegen/bin/escodegen.js b/node_modules/escodegen/bin/escodegen.js old mode 100644 new mode 100755 diff --git a/node_modules/escodegen/bin/esgenerate.js b/node_modules/escodegen/bin/esgenerate.js old mode 100644 new mode 100755 diff --git a/node_modules/escodegen/package.json b/node_modules/escodegen/package.json index 2ec61af..6af67fe 100644 --- a/node_modules/escodegen/package.json +++ b/node_modules/escodegen/package.json @@ -6,14 +6,14 @@ "_location": "/escodegen", "_phantomChildren": {}, "_requested": { - "type": "range", - "registry": true, - "raw": "escodegen@^1.11.0", - "name": "escodegen", "escapedName": "escodegen", + "fetchSpec": "^1.11.0", + "name": "escodegen", + "raw": "escodegen@^1.11.0", "rawSpec": "^1.11.0", + "registry": true, "saveSpec": null, - "fetchSpec": "^1.11.0" + "type": "range" }, "_requiredBy": [ "#USER", @@ -24,8 +24,8 @@ "_spec": "escodegen@^1.11.0", "_where": "/Users/android/Project/ASTFuzz", "bin": { - "esgenerate": "./bin/esgenerate.js", - "escodegen": "./bin/escodegen.js" + "escodegen": "./bin/escodegen.js", + "esgenerate": "./bin/esgenerate.js" }, "bugs": { "url": "https://github.com/estools/escodegen/issues" @@ -75,6 +75,8 @@ "optionalDependencies": { "source-map": "~0.6.1" }, + "readme": "## Escodegen\n[![npm version](https://badge.fury.io/js/escodegen.svg)](http://badge.fury.io/js/escodegen)\n[![Build Status](https://secure.travis-ci.org/estools/escodegen.svg)](http://travis-ci.org/estools/escodegen)\n[![Dependency Status](https://david-dm.org/estools/escodegen.svg)](https://david-dm.org/estools/escodegen)\n[![devDependency Status](https://david-dm.org/estools/escodegen/dev-status.svg)](https://david-dm.org/estools/escodegen#info=devDependencies)\n\nEscodegen ([escodegen](http://github.com/estools/escodegen)) is an\n[ECMAScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm)\n(also popularly known as [JavaScript](http://en.wikipedia.org/wiki/JavaScript))\ncode generator from [Mozilla's Parser API](https://developer.mozilla.org/en/SpiderMonkey/Parser_API)\nAST. See the [online generator](https://estools.github.io/escodegen/demo/index.html)\nfor a demo.\n\n\n### Install\n\nEscodegen can be used in a web browser:\n\n \n\nescodegen.browser.js can be found in tagged revisions on GitHub.\n\nOr in a Node.js application via npm:\n\n npm install escodegen\n\n### Usage\n\nA simple example: the program\n\n escodegen.generate({\n type: 'BinaryExpression',\n operator: '+',\n left: { type: 'Literal', value: 40 },\n right: { type: 'Literal', value: 2 }\n });\n\nproduces the string `'40 + 2'`.\n\nSee the [API page](https://github.com/estools/escodegen/wiki/API) for\noptions. To run the tests, execute `npm test` in the root directory.\n\n### Building browser bundle / minified browser bundle\n\nAt first, execute `npm install` to install the all dev dependencies.\nAfter that,\n\n npm run-script build\n\nwill generate `escodegen.browser.js`, which can be used in browser environments.\n\nAnd,\n\n npm run-script build-min\n\nwill generate the minified file `escodegen.browser.min.js`.\n\n### License\n\n#### Escodegen\n\nCopyright (C) 2012 [Yusuke Suzuki](http://github.com/Constellation)\n (twitter: [@Constellation](http://twitter.com/Constellation)) and other contributors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n", + "readmeFilename": "README.md", "repository": { "type": "git", "url": "git+ssh://git@github.com/estools/escodegen.git" diff --git a/page.json b/page.json deleted file mode 100644 index 17829ad..0000000 --- a/page.json +++ /dev/null @@ -1 +0,0 @@ -{"type":"Program","body":[{"type":"VariableDeclaration","kind":"var","declarations":[{"type":"VariableDeclarator","id":{"type":"Identifier","name":"var_0","mutated":true},"init":{"type":"Literal","value":false,"mutated":true},"mutated":true},{"type":"VariableDeclarator","id":{"type":"Identifier","name":"var_1","mutated":true},"init":{"type":"Literal","value":"4p%*'kJKe","mutated":true},"mutated":true},{"type":"VariableDeclarator","id":{"type":"Identifier","name":"var_2","mutated":true},"init":{"type":"Literal","value":"rG%GqC1C<","mutated":true},"mutated":true},{"type":"VariableDeclarator","id":{"type":"Identifier","name":"var_3","mutated":true},"init":{"type":"Literal","value":0.788369,"mutated":true},"mutated":true},{"type":"VariableDeclarator","id":{"type":"Identifier","name":"var_4","mutated":true},"init":null,"mutated":true},{"type":"VariableDeclarator","id":{"type":"Identifier","name":"var_5","mutated":true},"init":{"type":"Literal","value":"i{","mutated":true},"mutated":true}],"mutated":true},{"type":"VariableDeclaration","kind":"var","declarations":[{"type":"VariableDeclarator","id":{"type":"Identifier","name":"var_6","mutated":true},"init":{"type":"Literal","value":"8d6XUhG@oso%`~F';nclD`,zNf","mutated":true},"mutated":true}],"mutated":true},{"type":"FunctionDeclaration","async":false,"generator":false,"id":{"type":"Identifier","name":"func_0","mutated":true},"params":[{"type":"AssignmentPattern","right":{"type":"BinaryExpression","operator":"!==","left":{"type":"Identifier","name":"var_1","mutated":true},"right":{"type":"Identifier","name":"var_6","mutated":true},"mutated":true},"left":{"type":"Identifier","name":"param_0","mutated":true},"operator":"=","mutated":true},{"type":"AssignmentPattern","right":{"type":"BinaryExpression","operator":"!==","left":{"type":"Identifier","name":"var_1","mutated":true},"right":{"type":"Identifier","name":"var_2","mutated":true},"mutated":true},"left":{"type":"Identifier","name":"param_1","mutated":true},"operator":"=","mutated":true}],"body":{"type":"BlockStatement","body":[{"type":"EmptyStatement","mutated":true},{"type":"ExpressionStatement","expression":{"type":"CallExpression","callee":{"type":"MemberExpression","computed":true,"object":{"type":"BinaryExpression","operator":"-","left":{"type":"Identifier","name":"var_2","mutated":true},"right":{"type":"ArrayExpression","elements":[{"type":"Identifier","name":"var_5","mutated":true},{"type":"Identifier","name":"var_5","mutated":true},{"type":"UpdateExpression","argument":{"type":"Identifier","name":"var_2","mutated":true},"operator":"--","prefix":false,"mutated":true},{"type":"UpdateExpression","argument":{"type":"Identifier","name":"var_5","mutated":true},"operator":"++","prefix":true,"mutated":true},{"type":"ArrowFunctionExpression","async":false,"generator":false,"id":null,"params":[],"body":{"type":"BlockStatement","body":[{"type":"EmptyStatement","mutated":true}],"mutated":true},"mutated":true}],"mutated":true},"mutated":true},"property":{"type":"AssignmentExpression","left":{"type":"Identifier","name":"param_0","mutated":true},"right":{"type":"Literal","value":"k)oD","mutated":true},"operator":"^=","mutated":true},"mutated":true},"arguments":[],"mutated":true},"mutated":true}],"mutated":true},"mutated":true},{"type":"ExpressionStatement","expression":{"type":"UnaryExpression","argument":{"type":"Identifier","name":"func_0","mutated":true},"operator":"~","mutated":true},"mutated":true}],"mutated":true} \ No newline at end of file diff --git a/testcase.js b/testcase.js index 1089c72..0f20c18 100644 --- a/testcase.js +++ b/testcase.js @@ -7,11 +7,24 @@ var espath = require('./espath/lib'); var random = require('./random'); var generator = require('./esbuilder'); - +var sleep = require('system-sleep'); var rf=require("fs"); +console.log = function() {} + +/** +* two command line arguments, first filename and second, if anything the shared memory is not rebuild +*/ + + + +if (process.argv[2]) + base_file = process.argv[2]; +else + base_file = 'page.js'; +var tmpfile = "/dev/shm/r"+process.pid+".js" /** * * Tools function while mutate and generate @@ -71,14 +84,22 @@ function testBuilder(){ //rf.writeFileSync('page.js',page); } -//testRun() -testBuilder() +var counter=0; +var success=0; -for(let i=0;i<10000;i++){ +//testRun(0) +//testBuilder() + +if (!process.argv[3]) {var cproc = child_process.execFile("./SHM_TEST_set");} + + +for(var i=0;i<10000000;i++){ //console.log(i); //testBuilder(); + if (!testRun()) break; } +if (!process.argv[3]) {cproc.kill('SIGINT');} function currentVaribles(path){ let currentVaribles = []; @@ -117,7 +138,7 @@ function currentLiteral(vars){ function testMutate(){ - var raw=rf.readFileSync("page.js","utf-8"); + var raw=rf.readFileSync(base_file,"utf-8"); var ast = esprima.parse(raw); @@ -224,7 +245,7 @@ function testMutate(){ rf.writeFileSync('page.json',dump(ast)); var page = escodegen.generate(ast); // console.log(page); - rf.writeFileSync('r.js',page); + rf.writeFileSync(tmpfile,page); } function testTraverse(){ @@ -258,7 +279,20 @@ function testTraverse(){ function testRun(){ testMutate(); - child_process.execFileSync("/Users/android/Project/webkit/WebKitBuild/Debug/bin/jsc",["r.js"],{timeout:4000}); + console.error("started ", success, "of", counter, "->", (100.0*success/counter).toFixed(2), "%" ); + counter++; + try { + console.error(child_process.execFileSync("/media/detlef/Fast/KALI/fuzzer/gecko-dev/js/src/fuzzbuild_OPT.OBJ/dist/bin/js",[tmpfile],{timeout:4000,stdio:'pipe',encoding:'utf-8'})); + //console.log(child_process.execFileSync("/media/detlef/Fast/KALI/fuzzer/ASTFuzz/a.out",["r.js"],{timeout:4000})); + console.error(child_process.execFileSync("./SHM_TEST_get",{encoding:'utf-8'})); + success++; + } catch (err) { + //console.error(err); + if (err.signal == 'SIGSEGV') {console.error(err.signal,process.pid,err.stderr); return 0;} + } + console.error("done"); +// sleep(10000); + return 1; }