Exemple #1
0
  analyzer.run(function () {
    let cx;
    let c=0;
    // Look for any JS object in order to build a new JSContext
    for(var i in analyzer.graph) {
      let o = analyzer.graph[i];
      if (o.name.indexOf("JS Object (Ob") != 0)
        continue;
      obj = api.getPointerForAddress(o.address);
      if (!cx)  {
        let rt = api.JS_GetObjectRuntime(obj);
        cx = api.JS_NewContext(rt, 8192);
      }
      let attributes = api.enumerate(cx, obj);
      console.log("attribute: " + JSON.stringify(attributes));
      let id = api.createJsid();
      api.JS_GetObjectId(cx, obj, id.address());
      if (c++ > 10)
        break;
    }

    if (!cx) {
      assert.fail("Unable to fetch any JSContext from CC");
      done();
      return;
    }

    done();
  });
Exemple #2
0
 let paths = path.map(function (o) {
   let classname = jsapi.getClassName(o);
   return {
     self: o,
     src: classname == "Function" ? jsapi.stringifyFunction(cx, o) : "",
     name: classname,
     enum: jsapi.enumerate(cx, o)
   };
 });
Exemple #3
0
function dumpObject(cx, description, leak) {
  let obj = jsapi.getPointerForAddress(leak.address);
  log("");
  log(">>> " + description + " " + obj + " - "+leak.name);

  // In case of proxy, dump the target object
  if (leak.name == "JS Object (Proxy)") {
    let target;
    leak.edges.some(function (e) {
      if (e.name == "private") {
        target = e.to;
        return true;
      }
      return false;
    });
    if (target) {
      dumpObjectEdges("proxy", leak);
      dumpObject(cx, "proxy target object", target);
      return;
    }
    else {
      console.error("!!! Unable to find private edged of Proxy");
    }
  }

  // There is enough information in fragment class name...
  if (leak.name.indexOf("FragmentOrElement") == 0)
    return;

  // When using bind for ex, the binded function because a native method
  // so that we won't be able to decompile the function source.
  // The original function is eventually stored in 'parent' edge.
  // Otherwise, parent is just the global object.
  if (leak.name.indexOf("JS Object (Function") == 0) {
    let parent = getEdgeWithName(leak, "parent");
    if (parent.name.indexOf("JS Object (Function") == 0) {
      log("Binded function for:");
      dumpObject(cx, "Function parent", parent);
      return;
    }
  }

  if (leak.name == "JS Object (ChromeWindow)" ||
      leak.name == "JS Object (Window)" ||
      leak.name == "Backstagepass" ||
      leak.name == "Sandbox") {
    let d = inspect.getGlobalDescription(cx, obj);
    log("Global description:")
    log(JSON.stringify(d, null, 2));
    return;
  }

  if (leak.name == "nsXPCWrappedJS (nsIDOMEventListener)") {
    dumpObjectEdges("nsXPCWrappedJS", leak);
    leak.owners
        .filter(function (e) {return e.name == "mListeners[i]";})
        .forEach(function (e) {
          dumpObject(cx, "event manager", e.from);
        });
    leak.edges
        .filter(function (e) {return e.name == "root";})
        .forEach(function (e) {
          dumpObject(cx, "root", e.to);
        });
    return;
  }

  if (leak.name == "nsEventListenerManager") {
    dumpObjectEdges("nsEventListenerManager", leak);
    leak.owners
        .filter(function (e) {return e.name == "target";})
        .forEach(function (e) {
          dumpObject(cx, "event.target", e.from);
        });
    return;
  }

  if (leak.name.indexOf("JS Object (") == -1 || leak.name == "JS Object (Call)") {
    dumpObjectEdges(leak.name, leak);
    return;
  }

  if (leak.name.indexOf("JS Object (Function") == 0) {
    let global = getPathToGlobal(leak, []);
    log(" * global: " + global);
    if (global)
      log(" * global description: " +
                  JSON.stringify(inspect.getGlobalDescription(cx, global)));
    log("Function source:\n" + jsapi.stringifyFunction(cx, obj));
  }

  if (!verbose)
    return;
  let path = [];
  let global = getPathToGlobal(leak, path);
  let paths = path.map(function (o) {
    let classname = jsapi.getClassName(o);
    return {
      self: o,
      src: classname == "Function" ? jsapi.stringifyFunction(cx, o) : "",
      name: classname,
      enum: jsapi.enumerate(cx, o)
    };
  });
  log(" * global: "+global);
  if (global)
    log(" * global description: " +
                JSON.stringify(inspect.getGlobalDescription(cx, global)));

  let n=0;
  let nMax = 100;
  leak.edges.forEach(function (e) {
    let o2 = jsapi.getPointerForAddress(e.to.address);
    let g2;
    if (e.to.name.indexOf("JS Object (") == 0) {
      if (n++>nMax) return;
      g2 = getPathToGlobal(e.to, []);
    }
    log(" * edge." + e.name + " " + o2 + "=" + e.to.name + (g2?" global:"+g2:""));
  });
  n=0;
  leak.owners.forEach(function (e) {
    let o2 = jsapi.getPointerForAddress(e.from.address);
    let g2;
    if (e.from.name.indexOf("JS Object (") == 0) {
      if (n++>nMax) return;
      g2 = getPathToGlobal(e.from, []);
    }
    log(" * owner." + e.name + " " + o2 + "=" + e.from.name + (g2?" global:"+g2:""));
  });
  log(" * enum: \n" + JSON.stringify(jsapi.enumerate(cx, obj), null, 4));
  log(" * name: " + jsapi.getPropertyString(cx, obj, "name"));
  log("<<<");
}