-
Notifications
You must be signed in to change notification settings - Fork 6
[QEUSTION]How does granary core work from a high-level insight? #23
Comments
This is a good question and the answer will not be obvious from looking at the code. I will address each question in different replies.
Granary depends on a number of global data structures. The code cache index (https://github.com/Granary/granary/blob/master/granary/code_cache.cc#L53) is one such data structure, and the memory available for the code cache code (https://github.com/Granary/granary/blob/master/granary/allocator.cc#L86) is another one. Space is reserved for these global data structures in the executable, and that space is allocated at load time by the kernel module loader. The static initializers solves two problems:
|
Granary sets the text sections of modules to read-only so that if the kernel invokes a module directly (and not through a dynamic wrapper), then the hardware will raise a page fault. Granary catches these faults so that it can gain control of the module's execution to ensure that all of the module's code is instrumented. Here's the code that does that:
|
Clear explainations. Thank you ;) |
Granary bootstraps by replacing the After Granary's notifier is called, the kernel will try to initialize the just-loaded module by invoking its
Case (3) is the simplest. In Granary, an instrumented Case (2) involves wrappers, and has previously been discussed. If Granary sees a control-flow instruction (CFI) transferring to kernel code, then Granary will either leave the CFI as is, or convert it to jump to a wrapped version of the function being called. This is so that Granary's type wrappers can search for module function pointers, and replace them with dynamic wrappers that transparently give Granary control over the module's execution, without incurring the cost of a page fault. Case (1) is the trickiest case of all because it goes into just how Granary maintains control. For the sake of space, I won't describe how Granary maintains control of indirect CFIs (e.g. The way that Granary maintains control of direct CFIs is via "edge code". If native code contains the a
|
Hi all,
With pgoodman's help 👍 , I get much more clear about wrappers, watchpoints.
But I still know little details about granary core.
So, I start from granary's entry to follow how granary going on.
In init_granary (https://github.com/Granary/granary/blob/master/module.c#L601):
Could you tell me what's the purpose of that file?
sudo touch /dev/granary
, granary_initialise be invoked, which do various initializing things(init_code_cache, cpu_state::init_early,run all static initializer functions,and client::init).(https://github.com/Granary/granary/blob/master/granary/init.cc#L76)what's the meaning of static initializer function, what's the usages of them?
how granary work after this is even more harder for me(i.e. how to control and instrument target module's executions.).for example:
visit_app/host_instructions
?does it refer to instructions of a basic block in code cache?
Thank you very much ;)
The text was updated successfully, but these errors were encountered: