-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
1,964 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# MAMBO - Dynamic Binary Instrumentation on ARM and RISC-V 💻 Welcome!! | ||
|
||
Access the slides [here](presentation.pdf). | ||
|
||
## Getting Started | ||
|
||
- Install Docker | ||
|
||
Visit the [link](https://github.com/beehive-lab/mambo/tree/master/docker) to find details about MAMBO on Docker. | ||
|
||
- Directory structure | ||
|
||
Each exercise contains the following folders: | ||
- `code`: This folder contains the template of the MAMBO plugin for each exercise that you need to modify/add code in the `TODO` sections. | ||
|
||
- `solution`: This folder contains the implemented MAMBO plugin for each exercise. | ||
|
||
> [!NOTE] | ||
> MAMBO can be also run natively, without Docker, on Armv8 Linux machines. Speak to us if you wish to do so and have any problems. | ||
> [!NOTE] | ||
> After completing Exercise 1 you can either continue with your current code or start from the code template provided for you in subsequent exercises. | ||
``` | ||
. | ||
├── appendix -- Bonus exercise with the use of gdb for debugging MAMBO and target applications | ||
│ └── README.md | ||
├── exercise1 -- The repository for Exercise 1 | ||
│ ├── code | ||
│ │ └── tutorial.c | ||
│ ├── README.md | ||
│ └── solution | ||
│ └── solution.c | ||
├── exercise2 -- The repository for Exercise 2 | ||
│ ├── code | ||
│ │ └── tutorial.c | ||
│ ├── README.md | ||
│ └── solution | ||
│ └── solution.c | ||
├── exercise3 -- The repository for Exercise 3 | ||
│ ├── code | ||
│ │ └── tutorial.c | ||
│ ├── README.md | ||
│ └── solution | ||
│ └── solution.c | ||
├── exercise4 -- The repository for Exercise 4 | ||
│ ├── code | ||
│ │ └── tutorial.c | ||
│ ├── README.md | ||
│ └── solution | ||
│ └── solution.c | ||
├── introduction -- The repository for Introduction | ||
│ ├── code | ||
│ │ ├── Makefile | ||
│ │ ├── test.c | ||
| | └── tutorial.c | ||
│ ├── mambo | ||
│ │ └── makefile | ||
│ └── README.md | ||
└── README.md | ||
``` | ||
|
||
## Introduction | ||
Follow the [link](introduction/README.md) to start with the Introduction. | ||
|
||
## Exercise 1 - Callbacks and scan-time code analysis | ||
Follow the [link](exercise1/README.md) to start Exercise 1. | ||
|
||
## Exercise 2 - Extending Scan-time Analysis | ||
Follow the [link](exercise2/README.md) to start Exercise 2. | ||
|
||
## Exercise 3 - Run-time Instrumentation | ||
Follow the [link](exercise3/README.md) to start Exercise 3. | ||
|
||
## Exercise 4 - Advanced Instrumentation | ||
Follow the [link](exercise4/README.md) to start Exercise 4. | ||
|
||
## Appendix | ||
Follow the [link](appendix/README.md) to start the additional exercises. | ||
|
||
#### ✏️ Please help us improve the MAMBO tutorial by following the [link](https://forms.office.com/e/ZtDJSEgWhH). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Appendix | ||
The following will teach you how to debug both MAMBO and an application running under MAMBO, using gdb. This is a useful skill to have if you wish to contribute to the development of MAMBO, or are developing complex plugins. | ||
|
||
## Pre-requisites | ||
You will need gdb installed on the system. | ||
|
||
## Running MAMBO with gdb | ||
1. Run MAMBO with gdb `gdb ./dbm`. Note that this launches gdb with the MAMBO binary. | ||
2. Run the application under MAMBO after running gdb: `run binary-to-run`. For example, to run ls: `run /bin/ls`. | ||
|
||
> [!TIP] | ||
> Arguments for the application can be passed directly to `gdb` using the `--args` flag, e.g. `gdb --args ./dbm /bin/ls`. | ||
## Setting a breakpoint within MAMBO | ||
To inspect MAMBO internals such as the scanner or dispatcher, simply set a breakpoint at the required line. For example, to break when scanning a new aarch64 basic block: `break arch/aarch64/scanner_a64.c:scan_a64`. Now run the application as before. | ||
|
||
You will now see gdb break within the scanner. | ||
|
||
To step through the scanner line by line, type: `layout src`. This will switch to a view displaying the source code. Step through using `n`. | ||
|
||
## Inspecting a basic block | ||
You can find the start address of a basic block by stepping through the scanner as described above. | ||
Typing `print start_address` will print the starting address of the current basic block. Similarly, `print basic_block` will print the number of the current basic block being scanned. | ||
|
||
To inspect a basic block as it is constructed (or any other time), type `disassemble <start-address>, <start-address>+<offset>`. This will print out the instructions at this range of memory. | ||
|
||
Alternatively, you can follow execution out of the scanner and back into the code cache by stepping through instructions until you reach the code cache. Note, that there is no source code available to display here, because this code is not internal to MAMBO, rather it is generated by scanning basic blocks from the loaded binary. Type `layout asm` to switch to an assembler view of memory and step through the code cache using `ni` to step instruction by instruction. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
# Exercise 1: Callbacks and Scan-time Code Analysis | ||
|
||
In this exercise, you will learn about the basic structure of a MAMBO plugin and how to add new callbacks to extend the scan time functionality. The specific task of this exercise is: | ||
___ | ||
**Extend the functionality of the given plugin by adding two new callbacks before and after basic blocks to print start and end address of those basic blocks.** | ||
___ | ||
|
||
## Step 1: Basics of a MAMBO Plugin | ||
|
||
### MAMBO Plugins | ||
|
||
DBM frameworks work by scanning the code of the application and then passing it to the plugin. The plugin analyses and instruments the code, before returning control back to the DBM framework, which translates the code as necessary to maintain correct execution. | ||
|
||
### Structure of a MAMBO Plugin | ||
|
||
Before continuing the initial code for this exercise has to be copied to `$MAMBO_ROOT/plugins`: | ||
|
||
```shell | ||
cp $MAMBO_ROOT/docs/tutorials/hipeac2024/exercise1/code/tutorial.c $MAMBO_ROOT/plugins/ | ||
``` | ||
|
||
Now have a look at the copied code. All its parts are explained below. | ||
|
||
1. `PLUGINS_NEW` : Informs MAMBO that the plugin uses the current plugin API (this is used to support legacy plugins that were developed before MAMBO API had been re-written). | ||
2. `include "../plugins.h"` : The main file that includes all the necessary `.h` files related to the interaction of MAMBO and plugins. Functions such as callback-related and code generation functions are listed in `plugins.h`. | ||
3. `__attribute__((constructor))` : Compiler directive that causes the function to run before `main` and is used by MAMBO to setup the plugin. | ||
|
||
> [!NOTE] | ||
> You can find `plugins.h` under `$MAMBO_ROOT`. | ||
### Basic DBI functions of the given MAMBO Plugin | ||
|
||
MAMBO functions used in the given plugin are: | ||
|
||
1. `mambo_register_plugin()` : The main function for registering a plugin in a MAMBO context. (see below) | ||
2. `mambo_register_pre_thread_cb()` : An event hook that runs before each application thread is started. It is a very useful event mainly because it is able to track active threads. Also, this event hook assists users to allocate and initialise thread private resources. | ||
3. `mambo_register_post_thread_cb()` : An event hook that runs just before any application thread exits either via thread termination or application exit. Its main purpose is to track active threads, aggregate and output data from thread-level analysis and instrumentation, and release thread-private resources. | ||
4. `mambo_get_thread_id()` : A function that returns the `thread_id` of the active thread. Useful for multi-threaded program analysis. | ||
|
||
### MAMBO Context (ctx) | ||
|
||
Plugins should use an init function with `__attribute__((constructor))` to register themselves using `mambo_register_plugin()`. Once a plugin is registered, it can install callbacks for various events. | ||
|
||
```c | ||
mambo_context * ctx = mambo_register_plugin(); | ||
``` | ||
|
||
Context provides necessary data structures which users need to analyse/instrument the code. There are various fields such as: | ||
|
||
```c | ||
ctx->code.read_address // The untranslated application address of an instruction. | ||
|
||
ctx->code.write_p // The current code cache address to place the next instruction. | ||
|
||
ctx->code.inst // The enum of the decoded instruction. | ||
``` | ||
|
||
The full code can be found under `$MAMBO_ROOT/api/plugin_support.h`. | ||
|
||
### Tasks: | ||
|
||
- [ ] Copy the given plugin of this exercise (`tutorial.c`) into `$MAMBO_ROOT/plugins`. | ||
- [ ] Run the `test` application under MAMBO. | ||
|
||
> [!NOTE] | ||
> You should see one thread entered and one exited, since it is a single threaded binary. | ||
## Step 2: Extending the MAMBO Plugin with New Callbacks | ||
|
||
### Pre Basic Block Callback (`mambo_register_pre_basic_block_cb`) | ||
|
||
The `mambo_register_pre_basic_block_cb` event runs just before scanning a single-entry and single-exit code region. See below for the definition of the function and its arguments: | ||
|
||
```c | ||
int mambo_register_pre_basic_block_cb(mambo_context *ctx, mambo_callback cb); | ||
``` | ||
The `mambo_callback` is simply a pointer to a function with the following signature: | ||
```c | ||
int (*mambo_callback)(mambo_context *ctx); | ||
``` | ||
|
||
>[!TIP] | ||
> This callback can generate basic block-level instrumentation. | ||
### Post Basic Block Callback (`mambo_register_post_basic_block_cb`) | ||
|
||
The `mambo_register_post_basic_block_cb` event runs after scanning a single-entry and single exit code region. See below for the definition of the function and its arguments: | ||
|
||
```c | ||
int mambo_register_post_basic_block_cb(mambo_context *ctx, mambo_callback cb); | ||
``` | ||
>[!TIP] | ||
> This callback can be used to backpatch instrumentation in the basic block based on information not available earlier (e.g. basic block size). | ||
> [!NOTE] | ||
> It is important to note that these callbacks enable analysis at **scan time**. | ||
### Printing the Source Address | ||
Finally, once the basic blocks callbacks are added the source address of the beginning and end of the basic blocks should be printed. For that MAMBO provides a helper function: | ||
```c | ||
void *mambo_get_source_addr(mambo_context *ctx); | ||
``` | ||
|
||
It takes the MAMBO context and returns the currently scanned source address. For example: | ||
|
||
```c | ||
void* source_addr = mambo_get_source_addr(ctx); | ||
``` | ||
|
||
Putting it all together: | ||
|
||
```c | ||
int tutorial_pre_basic_block_cb(mambo_context* ctx) { | ||
void* source_addr = mambo_get_source_addr(ctx); | ||
|
||
printf("Basic block starts at address: %p!\n", source_addr); | ||
} | ||
|
||
int tutorial_post_basic_block_cb(mambo_context* ctx) { | ||
void* source_addr = mambo_get_source_addr(ctx); | ||
|
||
fprintf(stderr, "Basic block ends at address: %p!\n", source_addr); | ||
} | ||
``` | ||
Remember callbacks have to be registered in the constructor function, for example: | ||
```c | ||
mambo_register_pre_basic_block_cb(ctx, &tutorial_pre_basic_block_cb); | ||
mambo_register_post_basic_block_cb(ctx, &tutorial_post_basic_block_cb); | ||
``` | ||
|
||
### Tasks | ||
|
||
- [ ] Extend the given plugin with `mambo_register_pre_basic_block_cb`, `mambo_register_post_basic_block_cb` callbacks to print the start and end address of basic blocks. | ||
- [ ] Evaluate the `test` application under MAMBO. | ||
|
||
### Evaluation | ||
|
||
> [!NOTE] | ||
> Every time the plugin is updated the whole DBM tool has to be recompiled with `make`. | ||
You may notice that the number of printed basic blocks is much larger than the expected given that the test binary is a simple loop. This is because MAMBO runs both the binary and `libc` start process. | ||
|
||
## Next Steps 👏 | ||
|
||
This is the end of Exercise 1. Feel free to ask us any questions or proceed to [Exercise 2](../exercise2/README.md). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
This file is part of MAMBO, a low-overhead dynamic binary modification tool: | ||
https://github.com/beehive-lab/mambo | ||
Copyright 2024 University of Manchester | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
#ifdef PLUGINS_NEW | ||
|
||
#include <assert.h> | ||
#include <stdio.h> | ||
|
||
#include "../plugins.h" | ||
|
||
int tutorial_pre_thread_cb(mambo_context* ctx) { | ||
fprintf(stderr, "[DEBUG] Starting thread %d!\n", mambo_get_thread_id(ctx)); | ||
} | ||
|
||
int tutorial_post_thread_cb(mambo_context* ctx) { | ||
fprintf(stderr, "[DEBUG] Stopping thread %d!\n", mambo_get_thread_id(ctx)); | ||
} | ||
|
||
/* TODO: Add pre_basic_block_cb here. */ | ||
|
||
/* TODO: Add post_basic_block_cb here. */ | ||
|
||
__attribute__((constructor)) | ||
void init_tutorial() { | ||
mambo_context *ctx = mambo_register_plugin(); | ||
assert(ctx != NULL); | ||
|
||
mambo_register_pre_thread_cb(ctx, &tutorial_pre_thread_cb); | ||
mambo_register_post_thread_cb(ctx, &tutorial_post_thread_cb); | ||
|
||
/* TODO: Register *_basic_block_cb here. */ | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
This file is part of MAMBO, a low-overhead dynamic binary modification tool: | ||
https://github.com/beehive-lab/mambo | ||
Copyright 2024 University of Manchester | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
#ifdef PLUGINS_NEW | ||
|
||
#include <assert.h> | ||
#include <stdio.h> | ||
|
||
#include "../plugins.h" | ||
|
||
int tutorial_pre_thread_cb(mambo_context* ctx) { | ||
fprintf(stderr, "[DEBUG] Starting thread %d!\n", mambo_get_thread_id(ctx)); | ||
} | ||
|
||
int tutorial_post_thread_cb(mambo_context* ctx) { | ||
fprintf(stderr, "[DEBUG] Stopping thread %d!\n", mambo_get_thread_id(ctx)); | ||
} | ||
|
||
int tutorial_pre_basic_block_cb(mambo_context* ctx) { | ||
void* source_addr = mambo_get_source_addr(ctx); | ||
|
||
fprintf(stderr, "Basic block starts at address: %p!\n", source_addr); | ||
} | ||
|
||
int tutorial_post_basic_block_cb(mambo_context* ctx) { | ||
void* source_addr = mambo_get_source_addr(ctx); | ||
|
||
fprintf(stderr, "Basic block ends at address: %p!\n", source_addr); | ||
} | ||
|
||
__attribute__((constructor)) | ||
void init_tutorial() { | ||
mambo_context *ctx = mambo_register_plugin(); | ||
assert(ctx != NULL); | ||
|
||
mambo_register_pre_thread_cb(ctx, &tutorial_pre_thread_cb); | ||
mambo_register_post_thread_cb(ctx, &tutorial_post_thread_cb); | ||
|
||
mambo_register_pre_basic_block_cb(ctx, &tutorial_pre_basic_block_cb); | ||
mambo_register_post_basic_block_cb(ctx, &tutorial_post_basic_block_cb); | ||
} | ||
|
||
#endif |
Oops, something went wrong.