Sojobo is an emulator for the B2R2 framework. It was created to easier the analysis of potentially malicious files. It is totally developed in .NET so you don’t need to install or compile any other external libraries (the project is self contained).
With Sojobo you can:
- Emulate a (32 bit) PE binary
- Inspect the memory of the emulated process
- Read the process state
- Display a disassembly of the executed code
- Emulate functions in a managed language (C# || F#)
The concept is that you create a Sandbox for each emulated process (1 thread only). So typically the first step is to create a Win32Sandbox object:
var sandbox = new Win32Sandbox();
This object will emulate the process execution. You can use it to
obtain information on the running process and its environment. Before to
do so you have to load a binary inside the sandbox. This can be done by
using one of the available
Load method as in the following sample:
you can start the execution by executing the
Add Referenced Libraries
By default Sojobo include pre-compiled libraries that emulate the most used Windows functions. Sojobo analyzed the import table and according to the imported libraries it sets the emulated function to be invoked.
You can control this behavior with the
Win32SandboxSettings object, that you can pass as parameter to the sandbox constructor.
InitializeEnvironment is true (which is the default value), Sojobo tries to load all default libraries in order to emulate the functions. If it sets to false you have to provide your own library.
Adding a library is very easy and can be done with the
AddLibrary method. You can specify raw binaries or Assemblies. In order to intercept a function you have to follow a specific namespace pattern.
For example to emulate the function GetLastError from Kernel32 you have to create with name Kernel32 and function name GetLastError as in the following example:
public static class Kernel32
public static CallbackResult GetLastError(ISandbox sandbox)
var functionReturnValue = BitVectorFactory.Create(0x57);
return new CallbackResult(functionReturnValue.ToOption(), CallingConvention.Cdecl);
The first parameter must be of type
ISandbox. You can specify other parameters, which value will be read from the stack. The type of the parameter must be
Each emulated function must return a
CallbackResult result object. Which specify a possible value to return and the calling convention (this information is very important since allows the sandbox to know if it must clean the stack according to the number of parameters accepted by the function).
If you decide to add a simple library (like a native one), it will be mapped in the process address space and the
PEB->Ldr value updated accordingly.
Sojobo supposes that the Library is invoked via a call, so before to invoke your emulated function it creates a new stack frame. It also destroy the stack frame when returns from the emulated function.
This kind of hook are only placed by inspecting the IAT, so you cannot use this method to set an arbitrary hook on a function. To do that you have to use memory hook, explained below.
Memory hooks allow to invoke your code once that the emulation reach a given address. You can place an hook by using the method
AddHook, as demonstrated in the following example:
where the signature of the
HookCallback function is:
public static void HookCallback(ISandbox sandbox)
You can specify a symbol name (as in the example above) or just a numeric address.
Each emulated process is represented by a
IProcessContainer. You can obtain a reference to this object by invoking the method
GetRunningProcess on the sandbox object.
The Process Container object allows you to access the registers and the memory address space. You can also setup an event handler in order to Step its execution, as showed in the following example:
var process = sandbox.GetRunningProcess();
process.Step += ProcessStep;
ProcessStep function has the following signature:
private static void ProcessStep(Object sender, IProcessContainer process)
IProcessContainer interface exports some useful methods to access various info. Below an excerpt of the interface:
/// Get the memory manager associated with the process
abstract Memory: MemoryManager with get
/// Get the CPU object associated with the process
abstract Cpu: Cpu with get
/// Return the Pid valued of the emulated process
abstract Pid: UInt32 with get
/// Return the actual program counter value
abstract ProgramCounter: EmulatedValue with get
/// get the memory region that is currenlty being executed by the process abstract GetActiveMemoryRegion: unit -> MemoryRegion
/// get a list of symbols that are imported by the binary
abstract GetImportedFunctions: unit -> Symbol seq
/// get the next instruction that is going to be executed
abstract GetInstruction: unit -> Instruction
/// Return an array of addresses related to the current call stack
/// The array is composed by walking the stack, if it corrupted, this
/// value will be corrupted too abstract GetCallStack: unit -> UInt64 array
/// Get the size in bit of the pointer for the current process
abstract GetPointerSize: unit -> Int32
It is possible to access the process memory via the Memory Manager. You can use it to reads or writes the process memory.
The memory manager was created in order to easy the reading of structures from memory. So if you want to read the PEB structure (a rather complex structure) from memory, you don’t need to read a buffer and parse it, you can just define the class (it is already defined in Sojobo so don’t need to do it) and read it, as showed in the following example:
var peb = proc.Memory.ReadMemory
You can read specific registry value or set its value by using the
Cpu object. In particular by using these two functions
B2R2, Sojobo and all their tools are written in F#. This may cause some trouble to an C# developer, so I created a new project
ES.Sojobo.CSharp that makes some tasks easier.
If you plan to write your own tool in C# make sure to reference this library and use its extension methods or factory methods to created object that are not very friendly to create in C# (like the F# Option type).
In order to compile Sojobo you need .NET Core to be installed and Visual Studio. To compile just run build.bat.