mirror of
https://github.com/vtil-project/VTIL-Core
synced 2026-08-17 08:23:03 -04:00
Segmented into categories, implemented copy on write references.
This commit is contained in:
parent
ad7f01ab8b
commit
ce193cb8e6
22 changed files with 248 additions and 65 deletions
|
|
@ -93,23 +93,27 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="asserts.hpp" />
|
||||
<ClInclude Include="disassembly.hpp" />
|
||||
<ClInclude Include="emulator.hpp" />
|
||||
<ClInclude Include="formatting.hpp" />
|
||||
<ClInclude Include="includes\vtil\common.hpp" />
|
||||
<ClInclude Include="assembler.hpp" />
|
||||
<ClInclude Include="logger.hpp" />
|
||||
<ClInclude Include="register_details.hpp" />
|
||||
<ClInclude Include="rwx_allocator.hpp" />
|
||||
<ClInclude Include="amd64\assembler.hpp" />
|
||||
<ClInclude Include="amd64\disassembly.hpp" />
|
||||
<ClInclude Include="amd64\emulator.hpp" />
|
||||
<ClInclude Include="amd64\register_details.hpp" />
|
||||
<ClInclude Include="includes\vtil\common" />
|
||||
<ClInclude Include="includes\vtil\io" />
|
||||
<ClInclude Include="includes\vtil\memory" />
|
||||
<ClInclude Include="includes\vtil\amd64" />
|
||||
<ClInclude Include="io\asserts.hpp" />
|
||||
<ClInclude Include="io\formatting.hpp" />
|
||||
<ClInclude Include="io\logger.hpp" />
|
||||
<ClInclude Include="memory\copy_on_write.hpp" />
|
||||
<ClInclude Include="memory\rwx_allocator.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="disassembly.cpp" />
|
||||
<ClCompile Include="emulator.cpp" />
|
||||
<ClCompile Include="assembler.cpp" />
|
||||
<ClCompile Include="logger.cpp" />
|
||||
<ClCompile Include="register_details.cpp" />
|
||||
<ClCompile Include="rwx_allocator.cpp" />
|
||||
<ClCompile Include="amd64\assembler.cpp" />
|
||||
<ClCompile Include="amd64\disassembly.cpp" />
|
||||
<ClCompile Include="amd64\emulator.cpp" />
|
||||
<ClCompile Include="amd64\register_details.cpp" />
|
||||
<ClCompile Include="io\logger.cpp" />
|
||||
<ClCompile Include="memory\rwx_allocator.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
|||
|
|
@ -4,61 +4,81 @@
|
|||
<Filter Include="Memory">
|
||||
<UniqueIdentifier>{424c679d-7468-453f-8b9d-7d282aaf9470}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="x86">
|
||||
<UniqueIdentifier>{cb6f5bfd-fdca-47fe-bbb7-e91d8e5ba642}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emulation">
|
||||
<UniqueIdentifier>{673822af-de5d-4c16-9306-ac6c1441f341}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="I/O">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="amd64">
|
||||
<UniqueIdentifier>{cb6f5bfd-fdca-47fe-bbb7-e91d8e5ba642}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="amd64\Emulation">
|
||||
<UniqueIdentifier>{673822af-de5d-4c16-9306-ac6c1441f341}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Includes">
|
||||
<UniqueIdentifier>{14333603-a637-4356-854a-db631a744d42}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="amd64\Core">
|
||||
<UniqueIdentifier>{dbf4733d-3814-4218-9474-cf4b4e3c5719}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="formatting.hpp">
|
||||
<Filter>I/O</Filter>
|
||||
<ClInclude Include="amd64\register_details.hpp">
|
||||
<Filter>amd64</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="logger.hpp">
|
||||
<Filter>I/O</Filter>
|
||||
<ClInclude Include="amd64\assembler.hpp">
|
||||
<Filter>amd64\Core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="asserts.hpp">
|
||||
<Filter>I/O</Filter>
|
||||
<ClInclude Include="amd64\disassembly.hpp">
|
||||
<Filter>amd64\Core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rwx_allocator.hpp">
|
||||
<ClInclude Include="amd64\emulator.hpp">
|
||||
<Filter>amd64\Emulation</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="memory\copy_on_write.hpp">
|
||||
<Filter>Memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="register_details.hpp">
|
||||
<Filter>x86</Filter>
|
||||
<ClInclude Include="memory\rwx_allocator.hpp">
|
||||
<Filter>Memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="emulator.hpp">
|
||||
<Filter>Emulation</Filter>
|
||||
<ClInclude Include="io\asserts.hpp">
|
||||
<Filter>I/O</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="includes\vtil\common.hpp" />
|
||||
<ClInclude Include="disassembly.hpp">
|
||||
<Filter>x86</Filter>
|
||||
<ClInclude Include="io\formatting.hpp">
|
||||
<Filter>I/O</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="assembler.hpp">
|
||||
<Filter>x86</Filter>
|
||||
<ClInclude Include="io\logger.hpp">
|
||||
<Filter>I/O</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="includes\vtil\amd64">
|
||||
<Filter>Includes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="includes\vtil\common">
|
||||
<Filter>Includes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="includes\vtil\io">
|
||||
<Filter>Includes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="includes\vtil\memory">
|
||||
<Filter>Includes</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="register_details.cpp">
|
||||
<Filter>x86</Filter>
|
||||
<ClCompile Include="amd64\register_details.cpp">
|
||||
<Filter>amd64</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rwx_allocator.cpp">
|
||||
<ClCompile Include="amd64\assembler.cpp">
|
||||
<Filter>amd64\Core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="amd64\disassembly.cpp">
|
||||
<Filter>amd64\Core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="amd64\emulator.cpp">
|
||||
<Filter>amd64\Emulation</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="memory\rwx_allocator.cpp">
|
||||
<Filter>Memory</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="emulator.cpp">
|
||||
<Filter>Emulation</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="disassembly.cpp">
|
||||
<Filter>x86</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="assembler.cpp">
|
||||
<Filter>x86</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="logger.cpp">
|
||||
<ClCompile Include="io\logger.cpp">
|
||||
<Filter>I/O</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include <cstring>
|
||||
#include <set>
|
||||
#include <capstone/capstone.h>
|
||||
#include "formatting.hpp"
|
||||
#include "..\io\formatting.hpp"
|
||||
|
||||
namespace vtil::x86
|
||||
{
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#include "emulator.hpp"
|
||||
#include "..\io\asserts.hpp"
|
||||
|
||||
namespace vtil
|
||||
{
|
||||
|
|
@ -87,7 +88,6 @@ namespace vtil
|
|||
// Resolves the offset<0> where the value is saved at for the given register
|
||||
// and the number of bytes<1> it takes.
|
||||
//
|
||||
|
||||
inline std::pair<int32_t, uint8_t> emulator::resolve( x86_reg reg ) const
|
||||
{
|
||||
auto [base_reg, offset, size] = x86::resolve_mapping( reg );
|
||||
|
|
@ -118,7 +118,6 @@ namespace vtil
|
|||
|
||||
// Sets the value of a register.
|
||||
//
|
||||
|
||||
inline emulator& emulator::set( x86_reg reg, uint64_t value )
|
||||
{
|
||||
auto [off, sz] = resolve( reg );
|
||||
|
|
@ -128,7 +127,6 @@ namespace vtil
|
|||
|
||||
// Gets the value of a register.
|
||||
//
|
||||
|
||||
inline uint64_t emulator::get( x86_reg reg ) const
|
||||
{
|
||||
uint64_t value = 0;
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
#include <tuple>
|
||||
#include <string>
|
||||
#include "disassembly.hpp"
|
||||
#include "asserts.hpp"
|
||||
#include "..\io\asserts.hpp"
|
||||
|
||||
namespace vtil::x86
|
||||
{
|
||||
5
VTIL-Common/includes/vtil/amd64
Normal file
5
VTIL-Common/includes/vtil/amd64
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
#include "..\..\amd64\emulator.hpp"
|
||||
#include "..\..\amd64\assembler.hpp"
|
||||
#include "..\..\amd64\disassembly.hpp"
|
||||
#include "..\..\amd64\register_details.hpp"
|
||||
4
VTIL-Common/includes/vtil/common
Normal file
4
VTIL-Common/includes/vtil/common
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include <vtil/memory>
|
||||
#include <vtil/io>
|
||||
#include <vtil/amd64>
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#pragma once
|
||||
#include "..\..\asserts.hpp"
|
||||
#include "..\..\formatting.hpp"
|
||||
#include "..\..\logger.hpp"
|
||||
#include "..\..\rwx_allocator.hpp"
|
||||
#include "..\..\emulator.hpp"
|
||||
#include "..\..\assembler.hpp"
|
||||
#include "..\..\disassembly.hpp"
|
||||
#include "..\..\register_details.hpp"
|
||||
4
VTIL-Common/includes/vtil/io
Normal file
4
VTIL-Common/includes/vtil/io
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "..\..\io\asserts.hpp"
|
||||
#include "..\..\io\formatting.hpp"
|
||||
#include "..\..\io\logger.hpp"
|
||||
3
VTIL-Common/includes/vtil/memory
Normal file
3
VTIL-Common/includes/vtil/memory
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
#include "..\..\memory\rwx_allocator.hpp"
|
||||
#include "..\..\memory\copy_on_write.hpp"
|
||||
|
|
@ -7,6 +7,12 @@
|
|||
#define FMT_INS_OPR "%-12s"
|
||||
#define FMT_INS FMT_INS_MNM " " FMT_INS_OPR " " FMT_INS_OPR " " FMT_INS_OPR " " FMT_INS_OPR
|
||||
|
||||
// Billion dollar company yes? (::fix_parameter throws a warning otherwise.)
|
||||
//
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning (disable:1011)
|
||||
#endif
|
||||
|
||||
namespace vtil::format
|
||||
{
|
||||
// Suffixes used to indicate registers of N bytes.
|
||||
148
VTIL-Common/memory/copy_on_write.hpp
Normal file
148
VTIL-Common/memory/copy_on_write.hpp
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
#pragma once
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include "..\io\asserts.hpp"
|
||||
|
||||
// Thanks visual studio.
|
||||
//
|
||||
#ifdef __INTELLISENSE__
|
||||
#define __builtin_frame_address(level) ((void*)1337)
|
||||
#endif
|
||||
|
||||
// The copy-on-write interface defined here is used to avoid deep duplications of
|
||||
// containers such as trees when a VTIL routine is working with them.
|
||||
//
|
||||
namespace vtil
|
||||
{
|
||||
// This structure is used to describe copy-on-write references.
|
||||
//
|
||||
template<typename T>
|
||||
struct shared_reference
|
||||
{
|
||||
// The original reference and current state.
|
||||
//
|
||||
std::shared_ptr<T> reference;
|
||||
bool is_owning = false;
|
||||
bool is_locked = false;
|
||||
|
||||
// Null reference construction.
|
||||
//
|
||||
shared_reference() {}
|
||||
shared_reference( std::nullptr_t ) {}
|
||||
|
||||
// Owning reference constructor.
|
||||
//
|
||||
shared_reference( T&& obj ) : reference( std::make_shared<T>( std::forward<T>( obj ) ) ), is_owning( true ) {}
|
||||
template<typename... params, typename = std::enable_if_t<std::is_same_v<std::remove_cvref_t<params...>, shared_reference<T>>>>
|
||||
shared_reference( params&&... p ) : reference( std::make_shared<T>( std::forward<params>( p )... ) ), is_owning( true ) {}
|
||||
|
||||
// Copy-on-write reference construction and assignment.
|
||||
//
|
||||
shared_reference( const shared_reference& ref ) : reference( ref.reference ), is_locked( ref.is_locked ) {}
|
||||
shared_reference& operator=( const shared_reference& o ) { reference = o.reference; is_locked = o.is_locked; is_owning = false; return *this; }
|
||||
|
||||
// Construction and assignment operator for rvalue references.
|
||||
//
|
||||
shared_reference( shared_reference&& ref ) : reference( std::move( ref.reference ) ), is_owning( std::move( ref.is_owning ) ), is_locked( std::move( ref.is_locked ) ) {}
|
||||
shared_reference& operator=( shared_reference&& o ) { reference = std::move( o.reference ); is_owning = std::move( o.is_owning ); is_locked = std::move( o.is_locked ); return *this; }
|
||||
|
||||
// Simple validity checks.
|
||||
|
||||
bool is_valid() const { return ( bool ) reference; }
|
||||
operator bool() const { return is_valid(); }
|
||||
|
||||
// Locks the current reference, a locked reference cannot be upgraded
|
||||
// to a copy-on-write reference as is.
|
||||
//
|
||||
shared_reference& lock() { is_locked = true; is_owning = false; return *this; }
|
||||
|
||||
// Unlocks the current reference, should be called before storing the reference.
|
||||
//
|
||||
shared_reference& unlock()
|
||||
{
|
||||
// If reference is locked, we need to copy it.
|
||||
//
|
||||
if ( is_locked )
|
||||
{
|
||||
// Create a copy and change reference to point at it.
|
||||
//
|
||||
reference = std::make_shared<T>( *reference );
|
||||
|
||||
// Mark as unlocked and owning.
|
||||
//
|
||||
is_locked = true;
|
||||
is_owning = true;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Converts this reference to an owning one if it is not one already and
|
||||
// returns the pointer to the base type with no const-qualifiers.
|
||||
//
|
||||
T* own()
|
||||
{
|
||||
fassert( is_valid() );
|
||||
|
||||
// If copy-on-write, convert to owning first.
|
||||
//
|
||||
if ( !is_owning )
|
||||
{
|
||||
// If use counter is above 1 or reference is locked, we need
|
||||
// to make a copy before modifying the reference.
|
||||
//
|
||||
if ( reference.use_count() > 1 || is_locked )
|
||||
reference = std::make_shared<T>( *reference );
|
||||
|
||||
// Mark as unlocked and owning.
|
||||
//
|
||||
is_owning = true;
|
||||
is_locked = false;
|
||||
}
|
||||
|
||||
// Redirect the operator to the reference.
|
||||
//
|
||||
return reference.operator->();
|
||||
}
|
||||
|
||||
// Basic comparison operators are redirected to the pointer type.
|
||||
//
|
||||
bool operator==( const shared_reference& o ) const { return reference == o.reference; }
|
||||
bool operator<( const shared_reference& o ) const { return reference < o.reference; }
|
||||
|
||||
// Redirect pointer and dereferencing operator to the reference and cast to const-qualified equivalent.
|
||||
//
|
||||
const T* operator->() const { fassert( is_valid() ); return reference.operator->(); }
|
||||
const T& operator*() const { fassert( is_valid() ); return *reference; }
|
||||
|
||||
// Syntax sugar for ::own() using add operator.
|
||||
//
|
||||
T* operator+() { return own(); }
|
||||
};
|
||||
|
||||
// Local references are used to create copy-on-write references to values on stack,
|
||||
// note that they should not be stored under any condition.
|
||||
//
|
||||
template<typename T>
|
||||
__forceinline shared_reference<T> make_local_reference( T* variable_pointer )
|
||||
{
|
||||
// Save current frame address.
|
||||
//
|
||||
void* creation_frame = __builtin_frame_address( 0 );
|
||||
|
||||
// Create a shared_reference from a custom std::shared_ptr.
|
||||
//
|
||||
shared_reference<T> output;
|
||||
output.reference = std::shared_ptr<T>{ variable_pointer, [ creation_frame ] ( T* ptr )
|
||||
{
|
||||
// Should not be destructed above current frame.
|
||||
//
|
||||
fassert( creation_frame > __builtin_frame_address( 0 ) );
|
||||
} };
|
||||
|
||||
// Mark as locked and return.
|
||||
//
|
||||
output.is_locked = true;
|
||||
return output;
|
||||
}
|
||||
};
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
#else
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#include "asserts.hpp"
|
||||
#include "..\io\asserts.hpp"
|
||||
#include "rwx_allocator.hpp"
|
||||
|
||||
namespace vtil
|
||||
Loading…
Add table
Add a link
Reference in a new issue