Archive for the ‘Computer’ Category
Music Annoyance
I just found this very nice blog article(http://technotales.wordpress.com/2007/10/03/like-slime-for-vim/) which describes howto controll a ruby-repl inside a screen window, which is a perfect solution for a problem that rosed up to me a few days ago. At that time i was very bored and tried to annoy people at entropia with manual pitching songs at their music-system. As always when doing such repeating tasks i was asking myself how i could automate it. Now that i have a answer to the question i came up with the following ruby code:
( http://bl0rg.net/~nanoc/lass_leiern.rb )
Place your bet on how long i will survive after using it at entropia on a full sunday evening now
Building a Javascript Call Tracer using SpiderMonkey
Since I’m working on analyzing Javascript software i wanted to have a tool to generate function call-graphs like the ones known from the famous reverse-engineering tool IDA-Pro.
As i didn’t find such a tool, i decided to code it myself using SpiderMonkey, the Javascript engine used in Firefox, and Graphviz. Some people might know that in the past i allready created such call-graph tools for other languages and it might look silly to them that i do it over and over again, but i see it more as “hello-world” example to learn more about a programming-language or application internals.
As SpiderMonkey is a interpreter the code must be executed to do the analysis which is a disadvantage as you sometimes cannot trust the code. But as to my knowledge no environment for static JavaScript analysis exists, this approach is the fastest to get a working solution.
First I’m using an example from the Mozilla developers resource called “How_to_embed_the_JavaScript_engine”[1] to explain some general concepts one must deal with when developing applications using SpiderMonkey.
JSRuntime *rt;
JSContext *cx;
JSObject *global;
JSClass global_class = { "global",0,
JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,
JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub
};
rt = JS_NewRuntime(0x100000);
cx = JS_NewContext(rt, 0x1000);
global = JS_NewObject(cx, &global_class, NULL, NULL);
JS_InitStandardClasses(cx, global);
This example illustrates the three key components of a SpiderMonkey Javascript application.
- The first the JavaScript-Runtime is the memory space where every application data like variables, objects and scriptcode are stored.
- The Second component, the JavaScript-Context, is the component in which your code is actually processed. The Context can compile/execute scripts, can get/set object properties or call JavaScript functions. If you are using SpiderMonkey in a single-thread application you will only need one context.
- The third component is the Global Object which acts as sort of a parent object for everything you create in the JavaScript-Context. If you create a variable or function in the JavaScript-Context these are stored as properties of the global object. Normally you will only create one global object in your application and then use it all the time. At this point i also need to mention that it is possible to create custom objects, but i haven’t needed these yet so i cant say much about them.
Now that we know the core components we can actually run some JavaScript code which is as simple as using the function “JS_EvaluateScript” which takes a pointer to our context and a JavaScript source string and returns the result of the execution as a JavaScript object.
As I’m a lazy guy I’m going to use an command-line argument as our code-string.
char *source = argv[1]; ok = JS_EvaluateScript(cx, global, source, strlen(source), NULL, 0, &rval);
The last needed step to complete our tracer and plot nice pictures is of course the actual tracing of function calls. SpiderMonkey supplies us with the so called JSDBG-API[2], which allows developers to use often needed debugging features like handling break/watch-point or set hooks on events that occur while executing the code. The function most interesting for us here is the JS_SetCallHook function which calls a given hook function every time a function in the script is entered or leaved.
Our hooking function must be of the type JSInterpreterFunction which has the following
layout:
void * (JSContext *cx, JSStackFrame *fp, JSBool before, JSBool *ok, void *closure)
If our hook is called it is supplied with the stack-frame that was currently in
use by the JavaScript interpreter at the moment of the hook-trigger.
This is important because we need to determine the name of the function that triggered our hook and the name of the calling parent to build our call-graph. Getting the name of the function is straight forward and can be achieved through the API calls JS_GetFrameFunction() and JS_GetFunctionName().
JS_GetFrameFunction gets us a JSFunction object and a StackFrame out of the actual context, and JS_GetFunctionName returns a Pointer to the name of the function.
One could assume that the Stack-Frame which is implemented as a linked list could be used to determine the name of the parent function, but i couldn’t get this working so i guess I`m doing something wrong ![]()
To get around that Problem I’m using a simple stack implementation to keep trace of the parents myself.
If you have taken a closer look at the layout of the hook you would have recognized that it contains a variable called “before” which can be used to determine if the hook is called on entering or exiting of the script-function. I use this to write the new Function-Name to my name-stack on entering and to delete the name from the top on leaving.
Now we know everything needed to generate our first graph.
Therefore I’m using the following simple JavaScript example:
function add(x, y){
return (x+y);
}
function sub(x, y){
return (x-y);
}
function calc(x, y, z){
if(x == "add"){
add(y, z);
}else if(x == "sub"){
sub(y, z);
}
}
calc("add", 2, 2);
calc("sub", 2, 1);
which results the following graph:
One has to note that just dumping JavaScript code from the Browser to this tracer is not possible at this point because we didnt implemented the DOM and other stuff the Browser normally has by default.
These have to be added by the developer himself but this is a way to large topic for this post and is therefore left for the reader who wants to get deeper into the subject.
Beside the use of generating pretty graph pictures like the one above, one could
also use the tracing to do many other tasks like building a signature for a given script or layout the data flow of a given variable through a script.
You can get my example code at:
http://bl0rg.net/~nanoc/javascript_trace.tar.bz2
———————————————————————————————————
References:
[1] : http://developer.mozilla.org/en/How_to_embed_the_JavaScript_engine
[2] : http://developer.mozilla.org/en/JavaScript
You are currently browsing the archives for the Computer category.
