This page describes uses for the frida-trace --init-session / -S command
line option, and how to utilize it in your work.
What is the –init-session option?
The --init-session option executes any number of user-written JavaScript code
files during the frida-trace engine initialization stage. These files are
executed before the first function handler is called.
Its power comes from the ability to define globally visible functions and store
data in the global state object, which is passed as a parameter to every
handler called.
The state object allows you to maintain information across function calls.
Data stored in state are accessible to all called handlers.
Uses for the –init-session option
The --init-session / -S option guarantees that JavaScript source code of
your choice is executed before the frida-trace engine begins its tracing.
Possible applications of this feature include:
Executing custom code that creates both code and data objects of your choice,
doing this before the first function handler is invoked.
Creating a library of shared code, allowing the sharing of fine-tuned and
debugged JavaScript code that can be called globally by any handler, at any
time.
The frida-trace JavaScript code is often written as one-time “throw-away” code.
If, however, you find yourself frequently copying and pasting code between
handlers and projects, consider saving the code in a shared library. Once
written and debugged, you can reuse the functions and data in future projects.
Detailed Example: Creating a shared-code library
In this example, we demonstrate using the --init-session / -S option to
enhance tracing of the Microsoft Windows ExtTextOutW() function. We describe
the components in a top-down fashion, beginning with the ExtTextOutW.js
JavaScript handler function, working our way down to the shared code files.
ExtTextOutW(): Function Signature
In my Windows system, the ExtTextOutW() function to monitor resides in
gdi32full.dll. Here is the C syntax of the function:
Leveraging JavaScript code in our shared code libraries, we produce an enhanced
tracing output.
The enhanced trace output
Before showing the handler code and the shared code libraries, here is the
enhanced tracing output itself:
Notice the following tracing enhancements:
The options field is converted to textual form
The lprect memory pointer is displayed as both a hex memory dump and a
textual string
The lpString memory pointer is displayed as both a hex memory dump and a
textual string
The lpDx integer pointer is displayed as both a hex memory dump and an
integer
The textual conversions and hex memory dumps are functions within our shared code
libraries. Let’s see our ExtTextOutW() handler JavaScript code, which will
make use of the shared code.
Handler: ExtTextOutW.js
Here is our ExeTextOutW() handler code. We enhance it by invoking shared code
functions. These functions exist in the outer scope, as any top-level functions
defined in session scripts become visible to all handlers. The functions are
defined when the shared code JavaScript files are executed by frida-trace via
the --init-session / -S command line option.
Note that, besides calling standard Frida functions (e.g., toInt32(),
isNull(), readUtf16String()), there are calls to our shared code functions
(e.g., cloneArgs(), decodeExttextoutOptions(), prettyHexdump(),
rectStructToString()). The shared code functions have been debugged and
refined, and are ready to be called by any handler, at any time.
Shared Code: core.js
The “core.js” shared code library contains core, or basic, functions that are
meant to be reused by frida-trace handlers and shared code libraries.
Writing a shared code library is simple: your shared library source files define
functions and data objects, storing the latter in the global state object.
Once stored there, any handler can access them through state.propertyName.
Shared Code: ms-windows.js
The “ms-windows.js” shared code library consists of MS Windows-related utility
functions, and is built on top of the core.js library.
The two -S command line options provide the paths to the “core.js” and
“ms-windows.js” shared library source files.
Touching just about anything in the Word application with the cursor will
generate ExtTextOutW() traces.
Points to Consider
Here are some points to consider when using the -S option.
Use different code source files to group your shared functions
For clarity sake, you can have several shared code files for different groups of
functions. In the above example, the common and basic functions reside in
“core.js”, while MS Windows specific function are found in “ms-windows.js”.
In other projects you may have files for Android-related functions, for Linux
functions, etc.
Implementing namespaces
As the number of shared library code files you use grows, you may experience
name clashes due to “namespace pollution”. This can occur if two different
shared code files implement a function with the same name. If within your own
organization, you can modify the name. If, however, you are using third-party
shared code libraries, this might be more difficult.
A possible solution is for a shared library to store its functions on a global
object named descriptively, and correspondingly for data stored on “state”.