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?
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
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
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
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
ExtTextOutW(): Function Signature
In my Windows system, the ExtTextOutW() function to monitor resides in
gdi32full.dll. Here is the C syntax of the function:
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
The lpString memory pointer is displayed as both a hex memory dump and a
The lpDx integer pointer is displayed as both a hex memory dump and an
The textual conversions and hex memory dumps are functions within our shared code
make use of the shared code.
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
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
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”.