├── .gitignore ├── ctai ├── utils │ ├── empty_type.hpp │ ├── bad_value.hpp │ ├── predicate.hpp │ ├── operand_size.hpp │ └── mem_reg_operations.hpp ├── tests │ ├── instructions │ │ ├── execute │ │ │ ├── tests_execute.hpp │ │ │ ├── tests_ex_popa.hpp │ │ │ └── tests_ex_pusha.hpp │ │ ├── tests_instructions.hpp │ │ └── matchers │ │ │ ├── tests_matchers.hpp │ │ │ ├── tests_pusha_matcher.hpp │ │ │ ├── tests_call_matcher.hpp │ │ │ └── tests_sys_exit_thread_matcher.hpp │ ├── tests_main.hpp │ ├── tests_macros.hpp │ └── tests_memory_alloc.hpp ├── io │ ├── io.hpp │ ├── output.hpp │ └── input.hpp ├── traits.hpp ├── execute │ ├── execution_result.hpp │ ├── instructions │ │ ├── ex_jmp.hpp │ │ ├── ex_dec.hpp │ │ ├── ex_inc.hpp │ │ ├── ex_je.hpp │ │ ├── ex_jl.hpp │ │ ├── ex_jne.hpp │ │ ├── ex_jg.hpp │ │ ├── sys │ │ │ ├── ex_sys_exit_thread.hpp │ │ │ ├── ex_sys_read.hpp │ │ │ ├── ex_sys_free.hpp │ │ │ ├── ex_sys_write.hpp │ │ │ ├── ex_sys_malloc.hpp │ │ │ ├── ex_sys_try_lock_mutex.hpp │ │ │ ├── ex_sys_is_thread_running.hpp │ │ │ └── ex_sys_create_thread.hpp │ │ ├── ex_ret.hpp │ │ ├── ex_pop.hpp │ │ ├── ex_call.hpp │ │ ├── ex_add.hpp │ │ ├── execute_instruction.hpp │ │ ├── ex_sub.hpp │ │ ├── ex_push.hpp │ │ ├── ex_cmp.hpp │ │ ├── ex_popa.hpp │ │ ├── ex_mul.hpp │ │ ├── ex_div.hpp │ │ └── ex_pusha.hpp │ ├── eip_adjust.hpp │ └── execute_code.hpp ├── memory │ ├── memory_free.hpp │ ├── memory_alloc.hpp │ └── memory.hpp ├── thread │ ├── scheduler_round_robin.hpp │ └── thread.hpp ├── containers │ ├── queue.hpp │ └── gen │ │ ├── drop_front_impl_gen.hpp.pump │ │ └── drop_front_impl_gen.hpp ├── kernel │ ├── memory.hpp │ ├── mutex.hpp │ ├── thread.hpp │ ├── io.hpp │ └── utils.hpp ├── instructions │ └── matchers │ │ ├── plus_minus_decoder.hpp │ │ ├── sys_free_matcher.hpp │ │ ├── sys_malloc_matcher.hpp │ │ ├── popa_matcher.hpp │ │ ├── pusha_matcher.hpp │ │ ├── sys_try_lock_mutex_matcher.hpp │ │ ├── ret_matcher.hpp │ │ ├── mem_size_decoder.hpp │ │ ├── sys_exit_thread_matcher.hpp │ │ ├── sys_read_matcher.hpp │ │ ├── sys_write_matcher.hpp │ │ ├── sys_create_thread_matcher.hpp │ │ ├── sys_is_thread_running_matcher.hpp │ │ ├── dec_matcher.hpp │ │ ├── inc_matcher.hpp │ │ ├── div_matcher.hpp │ │ ├── mul_matcher.hpp │ │ ├── je_matcher.hpp │ │ ├── pop_matcher.hpp │ │ ├── jg_matcher.hpp │ │ ├── jl_matcher.hpp │ │ ├── push_matcher.hpp │ │ ├── jne_matcher.hpp │ │ ├── sub_matcher.hpp │ │ ├── operand_decoder.hpp │ │ ├── call_matcher.hpp │ │ ├── add_matcher.hpp │ │ ├── cmp_matcher.hpp │ │ ├── instructions_matchers.hpp │ │ ├── jge_matcher.hpp │ │ └── jmp_matcher.hpp ├── tokenize │ ├── syscalls_tokens.hpp │ └── tokenizer.hpp ├── runtime │ └── io.hpp ├── declare_code.hpp ├── doc │ ├── system_calls.txt │ └── utils.txt ├── values │ └── values.hpp ├── flags.hpp ├── labels.hpp ├── execute.hpp ├── assembler │ ├── assembler.hpp │ ├── label_substitute.hpp │ └── label_extract.hpp ├── tuple.hpp ├── eip_change.hpp ├── machine │ └── machine_state.hpp ├── opcode │ └── opcodes.hpp └── CMakeLists.txt ├── images ├── multithread_fib_with_sync.png └── multithread_fib_without_sync.png ├── CMakeLists.txt ├── examples ├── v1.0 │ ├── hello_world.cpp │ └── fobinacci.cpp └── v2.0 │ └── multithread_fib_without_sync.cpp └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | cmake-build-debug/* 2 | cmake-build-debug/ 3 | build/* 4 | build/ 5 | .idea/* 6 | .idea/ 7 | -------------------------------------------------------------------------------- /ctai/utils/empty_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ctai::utils 4 | { 5 | struct empty_type {}; 6 | } -------------------------------------------------------------------------------- /ctai/tests/instructions/execute/tests_execute.hpp: -------------------------------------------------------------------------------- 1 | #include "tests_ex_pusha.hpp" 2 | #include "tests_ex_popa.hpp" 3 | -------------------------------------------------------------------------------- /images/multithread_fib_with_sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stryku/ctai/HEAD/images/multithread_fib_with_sync.png -------------------------------------------------------------------------------- /images/multithread_fib_without_sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stryku/ctai/HEAD/images/multithread_fib_without_sync.png -------------------------------------------------------------------------------- /ctai/utils/bad_value.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace ctai::utils 6 | { 7 | constexpr auto bad_value = static_cast(-1); 8 | } -------------------------------------------------------------------------------- /ctai/tests/instructions/tests_instructions.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tests/instructions/matchers/tests_matchers.hpp" 4 | #include "ctai/tests/instructions/execute/tests_execute.hpp" -------------------------------------------------------------------------------- /ctai/tests/instructions/matchers/tests_matchers.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "tests_call_matcher.hpp" 4 | #include "tests_sys_exit_thread_matcher.hpp" 5 | #include "tests_pusha_matcher.hpp" 6 | -------------------------------------------------------------------------------- /ctai/utils/predicate.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ctai::utils 4 | { 5 | template 6 | constexpr auto predicate_v = predicate::template value; 7 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(ctai) 3 | 4 | add_definitions(-std=c++1z -ftemplate-backtrace-limit=0 -ftemplate-depth=8096) 5 | set(CMAKE_CXX_COMPILER clang++-4.0) 6 | 7 | add_subdirectory(ctai) -------------------------------------------------------------------------------- /ctai/io/io.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "io/output.hpp" 4 | 5 | namespace ctai 6 | { 7 | namespace io 8 | { 9 | template 10 | using write = output::append; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ctai/tests/tests_main.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "tests/tests_values_container.hpp" 4 | #include "tests/tests_tuple.hpp" 5 | #include "tests/tests_memory_metadata.hpp" 6 | #include "tests/tests_memory_alloc.hpp" 7 | #include "tests/tests_memory.hpp" 8 | 9 | #include "ctai/tests/instructions/tests_instructions.hpp" -------------------------------------------------------------------------------- /ctai/traits.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | template 7 | constexpr auto is_value_in_v = ((val == values) || ...); 8 | 9 | template 10 | constexpr auto is_type_in_v = ((std::is_same::value) || ...); -------------------------------------------------------------------------------- /examples/v1.0/hello_world.cpp: -------------------------------------------------------------------------------- 1 | #include "ctai/string.hpp" 2 | #include "ctai/execute.hpp" 3 | 4 | #include 5 | 6 | using code = decltype( 7 | "push ebx " 8 | "pop eax " 9 | "exit"_s); 10 | constexpr auto ret_val = cai::execute_code; 11 | 12 | int main() 13 | { 14 | std::cout << std::hex << ret_val; 15 | return 0; 16 | } -------------------------------------------------------------------------------- /ctai/execute/execution_result.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace ctai 6 | { 7 | namespace execute2 8 | { 9 | template 10 | struct execution_result 11 | { 12 | using output = output_t; 13 | static constexpr auto ret_val = ret_val_v; 14 | }; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ctai/memory/memory_free.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "memory/memory.hpp" 4 | #include "memory/memory_metadata.hpp" 5 | #include "ctai/traits.hpp" 6 | 7 | #include 8 | 9 | namespace ctai 10 | { 11 | namespace memory 12 | { 13 | template 14 | using free = metadata::free_block; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ctai/io/output.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/string.hpp" 4 | 5 | namespace ctai 6 | { 7 | namespace io 8 | { 9 | namespace output 10 | { 11 | template 12 | using buffer = ctai::string; 13 | 14 | template 15 | using append = ctai::string_append; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ctai/tests/tests_macros.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace std 6 | { 7 | template 8 | constexpr auto is_same_v = std::is_same::value; 9 | } 10 | 11 | #define ASSERT(x) static_assert(x, ""); 12 | #define ASSERT_EQ(a, b) static_assert(a == b, ""); 13 | #define ASSERT_NOT_EQ(a, b) static_assert(a != b, ""); 14 | #define ASSERT_EQ_T(a, b) static_assert(std::is_same_v, ""); -------------------------------------------------------------------------------- /ctai/thread/scheduler_round_robin.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/containers/queue.hpp" 4 | 5 | namespace ctai 6 | { 7 | namespace thread 8 | { 9 | namespace schedule 10 | { 11 | template 12 | struct next 13 | { 14 | using result_thread = queue::front; 15 | using result_threads_queue = queue::pop; 16 | }; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ctai/containers/queue.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "tuple/tuple.hpp" 4 | 5 | namespace ctai 6 | { 7 | namespace queue 8 | { 9 | template 10 | using queue = tuple_n::tuple; 11 | 12 | template 13 | using front = tuple_n::front; 14 | 15 | template 16 | using pop = tuple_n::drop_front; 17 | 18 | template 19 | using push = tuple_n::append; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ctai/kernel/memory.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/string.hpp" 4 | #include "ctai/declare_code.hpp" 5 | 6 | namespace ctai 7 | { 8 | namespace include 9 | { 10 | using sys_malloc = decltype( 11 | ":sys_malloc " 12 | "sys_malloc " 13 | "ret "_s 14 | ); 15 | 16 | using sys_free = decltype( 17 | ":sys_free " 18 | "sys_free " 19 | "ret "_s 20 | ); 21 | 22 | using memory = ctai::declare_code; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/plus_minus_decoder.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tokenize/tokens.hpp" 4 | 5 | #include 6 | 7 | namespace ctai 8 | { 9 | namespace details 10 | { 11 | 12 | template 13 | struct plus_minus_decoder_impl; 14 | 15 | template 16 | struct plus_minus_decoder_impl 17 | { 18 | static constexpr bool value = std::is_same::value; 19 | }; 20 | } 21 | 22 | template 23 | constexpr auto is_plus = details::plus_minus_decoder_impl::value; 24 | } 25 | -------------------------------------------------------------------------------- /ctai/io/input.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/string.hpp" 4 | #include "ctai/declare_code.hpp" 5 | 6 | namespace ctai 7 | { 8 | namespace io 9 | { 10 | namespace input 11 | { 12 | template 13 | using buffer = ctai::string; 14 | 15 | template 16 | constexpr char front = ctai::string_front; 17 | 18 | template 19 | using pop = ctai::string_pop_front; 20 | 21 | template 22 | using declare_input = declare_code; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ctai/tokenize/syscalls_tokens.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/string.hpp" 4 | 5 | namespace ctai 6 | { 7 | namespace tokens 8 | { 9 | using tok_sys_malloc = decltype("sys_malloc"_s); 10 | using tok_sys_free = decltype("sys_free"_s); 11 | using tok_sys_exit_thread = decltype("sys_exit_thread"_s); 12 | using tok_sys_create_thread = decltype("sys_create_thread"_s); 13 | using tok_sys_write = decltype("sys_write"_s); 14 | using tok_sys_read = decltype("sys_read"_s); 15 | using tok_sys_is_thread_running = decltype("sys_is_thread_running"_s); 16 | using tok_sys_try_lock_mutex = decltype("sys_try_lock_mutex"_s); 17 | } 18 | } -------------------------------------------------------------------------------- /ctai/runtime/io.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "io/output.hpp" 4 | 5 | #include 6 | 7 | namespace ctai 8 | { 9 | namespace runtime 10 | { 11 | namespace io 12 | { 13 | namespace details 14 | { 15 | template 16 | constexpr auto make_runtime_output_impl(ctai::io::output::buffer) 17 | { 18 | return std::array{chars...}; 19 | } 20 | } 21 | 22 | template 23 | constexpr auto make_runtime_output() 24 | { 25 | return details::make_runtime_output_impl(buffer{}); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_jmp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/execute/eip_adjust.hpp" 5 | #include "ctai/thread/thread.hpp" 6 | 7 | #include 8 | 9 | namespace ctai 10 | { 11 | namespace execute2 12 | { 13 | template 14 | struct ex_instruction, ip, rest_of_opcodes...> 15 | { 16 | using final_regs_state = set_reg(ip)>; 17 | using result_thread = thread::set_registers; 18 | using result_machine_state = machine_state_t; 19 | }; 20 | } 21 | } -------------------------------------------------------------------------------- /ctai/execute/eip_adjust.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/eip_change.hpp" 6 | 7 | #include 8 | #include 9 | 10 | namespace ctai 11 | { 12 | namespace details 13 | { 14 | template 15 | struct adjust_eip_impl 16 | { 17 | static constexpr auto eip_val = get_reg + eip_change; 18 | using regs_state = set_reg; 19 | }; 20 | } 21 | 22 | template 23 | using adjust_eip = typename details::adjust_eip_impl::regs_state; 24 | } 25 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/sys_free_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/syscalls_tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | #include "ctai/eip_change.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | //sys_malloc 14 | template 15 | struct matcher_impl> 18 | { 19 | using instruction = values_container_n::values_container>; 20 | using instruction_tokens = tuple; 21 | static constexpr auto eip_change = get_eip_change; 22 | using rest_of_tokens_t = tuple; 23 | }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/sys_malloc_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/syscalls_tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | #include "ctai/eip_change.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | //sys_malloc 14 | template 15 | struct matcher_impl> 18 | { 19 | using instruction = values_container_n::values_container>; 20 | using instruction_tokens = tuple; 21 | static constexpr auto eip_change = get_eip_change; 22 | using rest_of_tokens_t = tuple; 23 | }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ctai/utils/operand_size.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/register.hpp" 4 | #include "ctai/traits.hpp" 5 | 6 | #include 7 | 8 | namespace ctai 9 | { 10 | namespace utils 11 | { 12 | enum class operand_size 13 | { 14 | SIZE_8, 15 | SIZE_16, 16 | SIZE_32 17 | }; 18 | 19 | template 20 | constexpr auto reg_size = is_value_in_v 21 | ? operand_size::SIZE_8 22 | : is_value_in_v 23 | ? operand_size::SIZE_16 24 | : operand_size::SIZE_32; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ctai/declare_code.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "string.hpp" 4 | 5 | namespace ctai 6 | { 7 | namespace details 8 | { 9 | template 10 | struct declare_code_impl; 11 | 12 | template 13 | struct declare_code_impl 14 | { 15 | using next_code = string_merge; 16 | using result = typename declare_code_impl::result; 17 | }; 18 | 19 | template 20 | struct declare_code_impl 21 | { 22 | using result = current_code; 23 | }; 24 | } 25 | 26 | template 27 | using declare_code = typename details::declare_code_impl, functions...>::result; 28 | } 29 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/popa_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | #include "ctai/eip_change.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | //popa 14 | template 15 | struct matcher_impl> 16 | { 17 | using instruction = values_container_n::values_container>; 18 | 19 | static constexpr auto eip_change = get_eip_change; 20 | using instruction_tokens = tuple; 21 | 22 | using rest_of_tokens_t = tuple; 23 | }; 24 | } 25 | 26 | template 27 | using instruction_match = typename details::matcher_impl; 28 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/pusha_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | #include "ctai/eip_change.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | //pusha 14 | template 15 | struct matcher_impl> 16 | { 17 | using instruction = values_container_n::values_container>; 18 | 19 | static constexpr auto eip_change = get_eip_change; 20 | using instruction_tokens = tuple; 21 | 22 | using rest_of_tokens_t = tuple; 23 | }; 24 | } 25 | 26 | template 27 | using instruction_match = typename details::matcher_impl; 28 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/sys_try_lock_mutex_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/syscalls_tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | #include "ctai/eip_change.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | //sys_try_lock_mutex 14 | template 15 | struct matcher_impl> 18 | { 19 | using instruction = values_container_n::values_container>; 20 | using instruction_tokens = tuple; 21 | static constexpr auto eip_change = get_eip_change; 22 | using rest_of_tokens_t = tuple; 23 | }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ctai/kernel/mutex.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/string.hpp" 4 | #include "ctai/declare_code.hpp" 5 | 6 | namespace ctai 7 | { 8 | namespace include 9 | { 10 | using lock_mutex = decltype( 11 | ":lock_mutex " 12 | "push eax " 13 | "push ebx " 14 | 15 | "mov ebx , eax " 16 | 17 | ":__mutex_lock_mutex_loop " 18 | "sys_try_lock_mutex " 19 | "cmp eax , 1 " 20 | "jne .__mutex_lock_mutex_loop " // todo sleep till end of turn 21 | 22 | "pop ebx " 23 | "pop eax " 24 | "ret "_s 25 | ); 26 | 27 | using unlock_mutex = decltype( 28 | ":unlock_mutex " 29 | "mov BYTE PTR [ eax ] , 0 " 30 | "ret "_s 31 | ); 32 | 33 | using mutex = ctai::declare_code; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/ret_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | #include "ctai/eip_change.hpp" 9 | 10 | namespace ctai 11 | { 12 | namespace details 13 | { 14 | //ret 15 | template 16 | struct matcher_impl> 17 | { 18 | using instruction = values_container_n::values_container>; 19 | 20 | static constexpr auto eip_change = get_eip_change; 21 | using instruction_tokens = tuple; 22 | 23 | using rest_of_tokens_t = tuple; 24 | }; 25 | } 26 | 27 | template 28 | using instruction_match = typename details::matcher_impl; 29 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/mem_size_decoder.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tokenize/tokens.hpp" 4 | #include "ctai/instructions/ids_vaules.hpp" 5 | 6 | #include 7 | 8 | namespace ctai 9 | { 10 | namespace details 11 | { 12 | 13 | template 14 | struct mem_size_decoder_impl; 15 | 16 | template 17 | struct mem_size_decoder_impl 18 | { 19 | static constexpr auto value = std::is_same::value ? memory::id_t::s_8 20 | : std::is_same::value ? memory::id_t::s_16 21 | : memory::id_t::s_32; 22 | }; 23 | } 24 | 25 | template 26 | constexpr auto mem_size_decoder = details::mem_size_decoder_impl::value; 27 | } 28 | -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_dec.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/thread/thread.hpp" 4 | #include "ctai/execute/eip_adjust.hpp" 5 | 6 | namespace ctai 7 | { 8 | namespace execute2 9 | { 10 | //dec register 11 | template 13 | struct ex_instruction, reg1, rest_of_opcodes...> 14 | { 15 | using registers = typename thread_t::registers; 16 | 17 | static constexpr auto val1 = get_reg>; 18 | 19 | using new_regs_state = set_reg, static_cast(val1 - 1)>; 20 | 21 | using final_regs_state = adjust_eip; 22 | 23 | using result_thread = thread::set_registers; 24 | using result_machine_state = machine_state_t; 25 | }; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_inc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/thread/thread.hpp" 4 | #include "ctai/execute/eip_adjust.hpp" 5 | 6 | namespace ctai 7 | { 8 | namespace execute2 9 | { 10 | //inc register 11 | template 13 | struct ex_instruction, reg1, rest_of_opcodes...> 14 | { 15 | using registers = typename thread_t::registers; 16 | 17 | static constexpr auto val1 = get_reg>; 18 | 19 | using new_regs_state = set_reg, static_cast(val1 + 1)>; 20 | 21 | using final_regs_state = adjust_eip; 22 | 23 | using result_thread = thread::set_registers; 24 | using result_machine_state = machine_state_t; 25 | }; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/sys_exit_thread_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/syscalls_tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | 8 | namespace ctai 9 | { 10 | namespace details 11 | { 12 | //exit_thread 13 | template 14 | struct matcher_impl> 17 | { 18 | using instruction = values_container_n::values_container>; 19 | using instruction_tokens = tuple; 20 | static constexpr auto eip_change = get_eip_change; 21 | using rest_of_tokens_t = tuple; 22 | }; 23 | } 24 | 25 | template 26 | using instruction_match = typename details::matcher_impl; 27 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/sys_read_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/syscalls_tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | #include "ctai/eip_change.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | //sys_read 14 | template 15 | struct matcher_impl> 18 | { 19 | using instruction = values_container_n::values_container>; 20 | using instruction_tokens = tuple; 21 | static constexpr auto eip_change = get_eip_change; 22 | using rest_of_tokens_t = tuple; 23 | }; 24 | } 25 | 26 | template 27 | using instruction_match = typename details::matcher_impl; 28 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/sys_write_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/syscalls_tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | #include "ctai/eip_change.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | //sys_write 14 | template 15 | struct matcher_impl> 18 | { 19 | using instruction = values_container_n::values_container>; 20 | using instruction_tokens = tuple; 21 | static constexpr auto eip_change = get_eip_change; 22 | using rest_of_tokens_t = tuple; 23 | }; 24 | } 25 | 26 | template 27 | using instruction_match = typename details::matcher_impl; 28 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/sys_create_thread_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/syscalls_tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | #include "ctai/eip_change.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | //create_thread 14 | template 15 | struct matcher_impl> 18 | { 19 | using instruction = values_container_n::values_container>; 20 | using instruction_tokens = tuple; 21 | static constexpr auto eip_change = get_eip_change; 22 | using rest_of_tokens_t = tuple; 23 | }; 24 | } 25 | 26 | template 27 | using instruction_match = typename details::matcher_impl; 28 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/sys_is_thread_running_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/syscalls_tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | #include "ctai/eip_change.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | //sys_is_thread_running 14 | template 15 | struct matcher_impl> 18 | { 19 | using instruction = values_container_n::values_container>; 20 | using instruction_tokens = tuple; 21 | static constexpr auto eip_change = get_eip_change; 22 | using rest_of_tokens_t = tuple; 23 | }; 24 | } 25 | 26 | template 27 | using instruction_match = typename details::matcher_impl; 28 | } -------------------------------------------------------------------------------- /ctai/utils/mem_reg_operations.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "memory/memory.hpp" 4 | #include "ctai/register.hpp" 5 | 6 | namespace ctai 7 | { 8 | namespace utils 9 | { 10 | namespace details 11 | { 12 | template 15 | struct pop_reg_32_impl 16 | { 17 | static constexpr auto esp = get_reg; 18 | static constexpr auto next_esp = esp + 4; 19 | static constexpr auto value = memory::get_32; 20 | using registers_after_esp = set_reg; 21 | using result_registers = set_reg; 22 | }; 23 | } 24 | 25 | template 28 | using pop_reg_32 = typename details::pop_reg_32_impl::result_registers; 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_je.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/execute/eip_adjust.hpp" 5 | #include "ctai/thread/thread.hpp" 6 | 7 | #include 8 | 9 | namespace ctai 10 | { 11 | namespace execute2 12 | { 13 | template 14 | struct ex_instruction, ip, rest_of_opcodes...> 15 | { 16 | static constexpr auto flags_v = typename thread_t::flags{}; 17 | 18 | static constexpr bool should_jmp = (flags_v.ZF == true); 19 | using final_regs_state = std::conditional_t< 20 | should_jmp, 21 | set_reg(ip)>, 22 | adjust_eip>; 23 | 24 | using result_thread = thread::set_registers; 25 | using result_machine_state = machine_state_t; 26 | }; 27 | } 28 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_jl.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/execute/eip_adjust.hpp" 5 | #include "ctai/thread/thread.hpp" 6 | 7 | #include 8 | 9 | namespace ctai 10 | { 11 | namespace execute2 12 | { 13 | template 14 | struct ex_instruction, ip, rest_of_opcodes...> 15 | { 16 | static constexpr auto flags_v = typename thread_t::flags{}; 17 | 18 | static constexpr bool should_jmp = (flags_v.CF == true); 19 | using final_regs_state = std::conditional_t< 20 | should_jmp, 21 | set_reg(ip)>, 22 | adjust_eip>; 23 | 24 | using result_thread = thread::set_registers; 25 | using result_machine_state = machine_state_t; 26 | }; 27 | } 28 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_jne.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/execute/eip_adjust.hpp" 5 | #include "ctai/thread/thread.hpp" 6 | 7 | #include 8 | 9 | namespace ctai 10 | { 11 | namespace execute2 12 | { 13 | template 14 | struct ex_instruction, ip, rest_of_opcodes...> 15 | { 16 | static constexpr auto flags_v = typename thread_t::flags{}; 17 | 18 | static constexpr bool should_jmp = (static_cast(flags_v.ZF) == 0); 19 | using final_regs_state = std::conditional_t< 20 | should_jmp, 21 | set_reg(ip)>, 22 | adjust_eip>; 23 | 24 | using result_thread = thread::set_registers; 25 | using result_machine_state = machine_state_t; 26 | }; 27 | } 28 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_jg.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/execute/eip_adjust.hpp" 5 | #include "ctai/thread/thread.hpp" 6 | 7 | #include 8 | 9 | namespace ctai 10 | { 11 | namespace execute2 12 | { 13 | template 14 | struct ex_instruction, ip, rest_of_opcodes...> 15 | { 16 | static constexpr auto flags_v = typename thread_t::flags{}; 17 | 18 | static constexpr bool should_jmp = (flags_v.ZF == false && flags_v.CF == false); 19 | using final_regs_state = std::conditional_t< 20 | should_jmp, 21 | set_reg(ip)>, 22 | adjust_eip>; 23 | 24 | using result_thread = thread::set_registers; 25 | using result_machine_state = machine_state_t; 26 | }; 27 | } 28 | } -------------------------------------------------------------------------------- /ctai/tests/instructions/matchers/tests_pusha_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/containers/values_container.hpp" 4 | #include "ctai/instructions/matchers/call_matcher.hpp" 5 | #include "ctai/instructions/matchers/instructions_matchers.hpp" 6 | #include "ctai/instructions/ids_vaules.hpp" 7 | #include "ctai/tuple.hpp" 8 | 9 | namespace ctai::tests::pusha_matcher 10 | { 11 | template 12 | using vc = ctai::values_container_n::values_container; 13 | 14 | namespace test_pusha_matcher_opcodes 15 | { 16 | using expected_opcodes = vc>; 17 | using test_result = instruction_match, string<>, string<>>>::instruction; 18 | 19 | ASSERT_EQ_T(test_result, expected_opcodes); 20 | } 21 | 22 | namespace test_pusha_matcher_tokens 23 | { 24 | using expected_tokens = ctai::tuple; 25 | using test_result = instruction_match, string<>, string<>>>::instruction_tokens; 26 | 27 | ASSERT_EQ_T(test_result, expected_tokens); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ctai/doc/system_calls.txt: -------------------------------------------------------------------------------- 1 | int sys_create_thread(); 2 | params 3 | ebx - start point 4 | ecx - priority 5 | edx - pointer to args 6 | returns: 7 | eax: 8 | 0 - no enough memory 9 | non 0 - ok, returned value is new thread id 10 | 11 | NO_RETURN sys_exit_thread(); 12 | 13 | void sys_write(); 14 | write a character stored in the al register to stdout 15 | 16 | void sys_read(); 17 | read a character from stdin and store it in the al register 18 | 19 | int sys_is_thread_running(int thread_id) 20 | params 21 | ebx - thread id 22 | returns: 23 | eax: 24 | 0 - not running 25 | 1 - running 26 | 27 | 28 | void* sys_malloc() 29 | params 30 | eax - size of memory to allocate 31 | returns: 32 | eax: 33 | NULL - malloc failed 34 | not NULL - pointer to allocated memory 35 | invalidates 36 | eax 37 | 38 | int sys_try_lock_mutex() 39 | params 40 | ebx - mutex pointer 41 | returns: 42 | eax: 43 | 0 - lock fail 44 | 1 - lock success 45 | invalidates 46 | eax -------------------------------------------------------------------------------- /ctai/execute/instructions/sys/ex_sys_exit_thread.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "values/values.hpp" 7 | #include "ctai/execute/eip_adjust.hpp" 8 | 9 | #include 10 | #include 11 | 12 | namespace ctai 13 | { 14 | namespace execute2 15 | { 16 | //exit_thread 17 | template 18 | struct ex_instruction, 21 | rest_of_opcodes...> 22 | { 23 | using result_thread = thread::thread; 28 | using result_machine_state = machine_state_t; 29 | }; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/dec_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | #include "ctai/eip_change.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | // dec register 14 | template 15 | struct matcher_impl> 19 | { 20 | static constexpr auto instruction_type = inst::id_t::DEC; 21 | 22 | using instruction = values_container_n::values_container, 23 | token_to_reg_opcode>; 24 | 25 | using instruction_tokens = tuple; 27 | 28 | static constexpr auto eip_change = get_eip_change; 29 | 30 | using rest_of_tokens_t = tuple; 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ctai/tests/instructions/matchers/tests_call_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/containers/values_container.hpp" 4 | #include "ctai/instructions/matchers/call_matcher.hpp" 5 | #include "ctai/instructions/matchers/instructions_matchers.hpp" 6 | #include "ctai/instructions/ids_vaules.hpp" 7 | #include "ctai/tuple.hpp" 8 | 9 | namespace ctai::tests::call_matcher 10 | { 11 | template 12 | using vc = ctai::values_container_n::values_container; 13 | 14 | namespace test_call_matcher_opcodes 15 | { 16 | using expected_opcodes = vc, static_cast(22)>; 17 | using test_result = instruction_match, string<>, string<>>>::instruction; 18 | 19 | ASSERT_EQ_T(test_result, expected_opcodes); 20 | } 21 | 22 | namespace test_call_matcher_tokens 23 | { 24 | using expected_tokens = ctai::tuple>; 25 | using test_result = instruction_match, string<>, string<>>>::instruction_tokens; 26 | 27 | ASSERT_EQ_T(test_result, expected_tokens); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ctai/tests/instructions/matchers/tests_sys_exit_thread_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/containers/values_container.hpp" 4 | #include "ctai/instructions/matchers/sys_exit_thread_matcher.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/tokenize/syscalls_tokens.hpp" 7 | #include "ctai/tuple.hpp" 8 | 9 | namespace ctai::tests::sys_exit_thread_matcher 10 | { 11 | template 12 | using vc = ctai::values_container_n::values_container; 13 | 14 | namespace test_sys_exit_thread_matcher_opcodes 15 | { 16 | using expected_opcodes = vc>; 17 | using test_result = instruction_match, string<>>>::instruction; 18 | 19 | ASSERT_EQ_T(test_result, expected_opcodes); 20 | } 21 | 22 | namespace test_sys_exit_thread_matcher_tokens 23 | { 24 | using expected_tokens = ctai::tuple; 25 | using test_result = instruction_match, string<>>>::instruction_tokens; 26 | 27 | ASSERT_EQ_T(test_result, expected_tokens); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/inc_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/containers/values_container.hpp" 7 | #include "ctai/eip_change.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | // inc register 14 | template 15 | struct matcher_impl> 18 | { 19 | static constexpr auto instruction_type = inst::id_t::INC; 20 | 21 | using instruction = values_container_n::values_container, 22 | token_to_reg_opcode>; 23 | 24 | using instruction_tokens = tuple; 26 | 27 | static constexpr auto eip_change = get_eip_change; 28 | 29 | using rest_of_tokens_t = tuple; 30 | }; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/div_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | #include "ctai/eip_change.hpp" 9 | 10 | namespace ctai 11 | { 12 | namespace details 13 | { 14 | // div reg 15 | template 16 | struct matcher_impl> 20 | { 21 | static constexpr auto instruction_type = inst::id_t::DIV_REG; 22 | 23 | using instruction = values_container_n::values_container, 24 | operand_decoder>; 25 | 26 | static constexpr auto eip_change = get_eip_change; 27 | 28 | using instruction_tokens = tuple; 30 | 31 | using rest_of_tokens_t = tuple; 32 | }; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/mul_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | #include "ctai/eip_change.hpp" 9 | 10 | namespace ctai 11 | { 12 | namespace details 13 | { 14 | // mul reg 15 | template 16 | struct matcher_impl> 19 | { 20 | static constexpr auto instruction_type = inst::id_t::MUL_REG; 21 | 22 | using instruction = values_container_n::values_container, 23 | operand_decoder>; 24 | 25 | static constexpr auto eip_change = get_eip_change; 26 | using instruction_tokens = tuple; 28 | 29 | using rest_of_tokens_t = tuple; 30 | }; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_ret.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "values/values.hpp" 7 | #include "ctai/execute/eip_adjust.hpp" 8 | #include "ctai/thread/thread.hpp" 9 | #include "ctai/utils/mem_reg_operations.hpp" 10 | 11 | namespace ctai 12 | { 13 | namespace execute2 14 | { 15 | template 18 | struct ex_instruction, 21 | rest_of_opcodes...> 22 | { 23 | 24 | using next_registers = utils::pop_reg_32; 27 | using result_thread = thread::thread; 32 | 33 | using result_machine_state = machine_state_t; 34 | }; 35 | } 36 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/je_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | #include "ctai/eip_change.hpp" 9 | 10 | namespace ctai 11 | { 12 | namespace details 13 | { 14 | // je instruction pointer / label 15 | template 16 | struct matcher_impl> 19 | { 20 | static constexpr auto instruction_type = inst::id_t::JE; 21 | static constexpr auto decoded = is_label_token ? 0 : operand_decoder; 22 | 23 | using instruction = values_container_n::values_container, 24 | decoded>; 25 | using instruction_tokens = tuple; 27 | 28 | static constexpr auto eip_change = get_eip_change; 29 | 30 | using rest_of_tokens_t = tuple; 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/v1.0/fobinacci.cpp: -------------------------------------------------------------------------------- 1 | #include "ctai/string.hpp" 2 | #include "ctai/execute.hpp" 3 | 4 | #include 5 | 6 | using code = decltype( 7 | "mov ebp , esp " 8 | "push eax " // declare four variables 9 | "push eax " 10 | "push eax " 11 | "push eax " 12 | "mov DWORD PTR [ ebp + 8 ] , 0 " 13 | "mov DWORD PTR [ ebp + 12 ] , 1 " 14 | "mov DWORD PTR [ ebp + 16 ] , 1 " 15 | "mov DWORD PTR [ ebp + 4 ] , 1 " 16 | ":loop_label " 17 | "mov eax , DWORD PTR [ ebp + 4 ] " 18 | "mov ebx , 15 " //we want to get 15th fibonacci element 19 | "cmp eax , ebx " 20 | "jge .end_label " 21 | "mov edx , DWORD PTR [ ebp + 8 ] " 22 | "mov eax , DWORD PTR [ ebp + 12 ] " 23 | "add eax , edx " 24 | "mov DWORD PTR [ ebp + 16 ] , eax " 25 | "mov eax , DWORD PTR [ ebp + 12 ] " 26 | "mov DWORD PTR [ ebp + 8 ] , eax " 27 | "mov eax , DWORD PTR [ ebp + 16 ] " 28 | "mov DWORD PTR [ ebp + 12 ] , eax " 29 | "mov eax , DWORD PTR [ ebp + 4 ] " 30 | "mov ebx , 1 " 31 | "add eax , ebx " 32 | "mov DWORD PTR [ ebp + 4 ] , eax " 33 | "jmp .loop_label " 34 | ":end_label " 35 | "mov eax , DWORD PTR [ ebp + 16 ] " 36 | "exit"_s); 37 | 38 | int main() 39 | { 40 | std::cout << "15th element of fibonacci series is: " << cai::execute_code; 41 | return 0; 42 | } -------------------------------------------------------------------------------- /ctai/kernel/thread.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/string.hpp" 4 | 5 | namespace ctai 6 | { 7 | namespace include 8 | { 9 | using sys_exit_thread = decltype( 10 | ":sys_exit_thread " 11 | "sys_exit_thread "_s); 12 | 13 | using sys_create_thread = decltype( 14 | ":sys_create_thread " 15 | "sys_create_thread " 16 | "ret "_s); 17 | 18 | using sys_is_thread_running = decltype( 19 | ":sys_is_thread_running " 20 | "sys_is_thread_running " 21 | "ret "_s 22 | ); 23 | 24 | using join_thread = decltype( 25 | ":join_thread " 26 | "push ebx " 27 | 28 | "mov ebx , eax " //move thread id 29 | 30 | ":_jt_check_loop " //wait while thread is running 31 | "call .sys_is_thread_running " 32 | "cmp eax , 0 " 33 | "jne ._jt_check_loop " 34 | 35 | "pop ebx " 36 | "ret "_s 37 | ); 38 | 39 | using thread = ctai::declare_code; 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_pop.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "values/values.hpp" 7 | #include "ctai/execute/eip_adjust.hpp" 8 | #include "ctai/thread/thread.hpp" 9 | 10 | #include 11 | #include "ctai/machine/machine_state.hpp" 12 | #include "ctai/utils/mem_reg_operations.hpp" 13 | 14 | namespace ctai 15 | { 16 | namespace execute2 17 | { 18 | template 19 | struct ex_instruction, 22 | reg, 23 | rest_of_opcodes...> 24 | { 25 | using registers = typename thread_t::registers; 26 | 27 | static constexpr auto esp_val = get_reg; 28 | 29 | using pop_result = utils::pop_reg_32>; 31 | 32 | using final_registers = adjust_eip; 33 | 34 | using result_thread = thread::set_registers; 35 | 36 | using result_machine_state = machine_state_t; 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ctai/containers/gen/drop_front_impl_gen.hpp.pump: -------------------------------------------------------------------------------- 1 | template 2 | struct drop_front_impl_gen_10; 3 | template 4 | struct drop_front_impl_gen_100; 5 | 6 | 7 | template 8 | struct drop_front_impl_gen_10 9 | { 10 | using result = values_container_n::values_container; 11 | }; 12 | 13 | template < auto... rest_of_values> 14 | struct drop_front_impl_gen_100 15 | { 16 | using result = values_container_n::values_container; 17 | }; 18 | 19 | 20 | $var n0 = 10 21 | $range i0 10..n0 22 | $for i0 [[ 23 | $$ Meta loop. 24 | $range j 1..i0 25 | template <$for j [[auto to_drop$j, ]] auto... rest_of_values> 26 | struct drop_front_impl_gen_10 27 | { 28 | using result = values_container_n::values_container; 29 | }; 30 | 31 | ]] 32 | 33 | 34 | $var n = 100 35 | $range i 100..n 36 | $for i [[ 37 | $$ Meta loop. 38 | $range j 1..i 39 | template <$for j [[auto to_drop$j, ]] auto... rest_of_values> 40 | struct drop_front_impl_gen_100 41 | { 42 | using result = values_container_n::values_container; 43 | }; 44 | 45 | ]] 46 | -------------------------------------------------------------------------------- /ctai/execute/instructions/sys/ex_sys_read.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "ctai/execute/eip_adjust.hpp" 7 | #include "ctai/thread/thread.hpp" 8 | #include "ctai/machine/machine_state.hpp" 9 | #include "ctai/io/input.hpp" 10 | 11 | #include 12 | #include 13 | 14 | namespace ctai 15 | { 16 | namespace execute2 17 | { 18 | template 19 | struct ex_instruction, 22 | rest_of_opcodes...> 23 | { 24 | using current_input = typename machine_state_t::input; 25 | static constexpr auto read_char = io::input::front; 26 | 27 | using registers_after_al = set_reg; 28 | 29 | using final_registers = adjust_eip; 30 | using result_thread = thread::set_registers; 31 | 32 | using next_input = io::input::pop; 33 | using result_machine_state = machine::set_input; 34 | }; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ctai/values/values.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "ctai/containers/values_container.hpp" 6 | 7 | namespace ctai 8 | { 9 | namespace values 10 | { 11 | // 12 | //split_to_byte_values_container 13 | // 14 | namespace details 15 | { 16 | template 17 | struct split_to_byte_values_container_impl 18 | { 19 | template 20 | using vc = values_container_n::values_container; 21 | 22 | using result = typename std::conditional_t, 24 | typename std::conditional_t> 8), value & 0xff>, 26 | vc<((value & 0xff000000) >> 24), ((value & 0xff0000) >> 16), ((value & 0xff00) >> 8), value & 0xff>>>; 27 | }; 28 | } 29 | 30 | template 31 | using split_to_byte_values_container = typename details::split_to_byte_values_container_impl::result; 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/pop_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | //pop op 14 | template 15 | struct matcher_impl> 16 | { 17 | using instruction = values_container_n::values_container, 18 | operand_decoder>; 19 | 20 | static constexpr auto eip_change = get_eip_change; 21 | using instruction_tokens = tuple; 22 | 23 | using rest_of_tokens_t = tuple; 24 | }; 25 | } 26 | 27 | template 28 | using instruction_match = typename details::matcher_impl; 29 | 30 | namespace tests 31 | { 32 | static_assert(std::is_same, string<>>>::instruction, 33 | values_container_n::values_container, regs::to_size>>::value, ""); 34 | } 35 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/sys/ex_sys_free.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "ctai/execute/eip_adjust.hpp" 7 | #include "ctai/thread/thread.hpp" 8 | #include "ctai/machine/machine_state.hpp" 9 | #include "ctai/memory/memory_free.hpp" 10 | 11 | #include 12 | #include 13 | 14 | namespace ctai 15 | { 16 | namespace execute2 17 | { 18 | template 19 | struct ex_instruction, 22 | rest_of_opcodes...> 23 | { 24 | static constexpr auto ptr_to_free = get_reg; 25 | using free_result = memory::free; 26 | using memory_result = memory::set_metadata; 27 | 28 | using final_registers = adjust_eip; 29 | using result_thread = thread::set_registers; 30 | 31 | using result_machine_state = machine::set_memory; 32 | }; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/jg_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | #include "ctai/eip_change.hpp" 9 | 10 | namespace ctai 11 | { 12 | namespace details 13 | { 14 | // jg instruction pointer / label 15 | template 16 | struct matcher_impl> 19 | { 20 | static constexpr auto instruction_type = inst::id_t::JG; 21 | static constexpr auto decoded = is_label_token ? 0 : operand_decoder; 22 | 23 | using instruction = values_container_n::values_container, 24 | decoded>; 25 | using instruction_tokens = tuple; 27 | 28 | static constexpr auto eip_change = get_eip_change; 29 | 30 | using rest_of_tokens_t = tuple; 31 | }; 32 | } 33 | 34 | template 35 | using instruction_match = typename details::matcher_impl; 36 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/jl_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | #include "ctai/eip_change.hpp" 9 | 10 | namespace ctai 11 | { 12 | namespace details 13 | { 14 | // jl instruction pointer / label 15 | template 16 | struct matcher_impl> 19 | { 20 | static constexpr auto instruction_type = inst::id_t::JL; 21 | static constexpr auto decoded = is_label_token ? 0 : operand_decoder; 22 | 23 | using instruction = values_container_n::values_container, 24 | decoded>; 25 | using instruction_tokens = tuple; 27 | 28 | static constexpr auto eip_change = get_eip_change; 29 | 30 | using rest_of_tokens_t = tuple; 31 | }; 32 | } 33 | 34 | template 35 | using instruction_match = typename details::matcher_impl; 36 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/push_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | //push op 14 | template 15 | struct matcher_impl> 16 | { 17 | using instruction = values_container_n::values_container, 18 | operand_decoder>; 19 | 20 | static constexpr auto eip_change = get_eip_change; 21 | using instruction_tokens = tuple; 22 | 23 | using rest_of_tokens_t = tuple; 24 | }; 25 | } 26 | 27 | template 28 | using instruction_match = typename details::matcher_impl; 29 | 30 | namespace tests 31 | { 32 | static_assert(std::is_same, string<>>>::instruction, 33 | values_container_n::values_container, regs::to_size>>::value, ""); 34 | } 35 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/jne_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | #include "ctai/eip_change.hpp" 9 | 10 | namespace ctai 11 | { 12 | namespace details 13 | { 14 | // jmp instruction_pointer or label 15 | template 16 | struct matcher_impl> 20 | { 21 | static constexpr auto instruction_type = inst::id_t::JNE; 22 | 23 | static constexpr auto decoded = is_label_token ? 0 24 | : operand_decoder; 25 | 26 | using instruction = values_container_n::values_container, 27 | decoded>; 28 | 29 | static constexpr auto eip_change = get_eip_change; 30 | using instruction_tokens = tuple; 32 | 33 | using rest_of_tokens_t = tuple; 34 | }; 35 | } 36 | 37 | template 38 | using instruction_match = typename details::matcher_impl; 39 | } -------------------------------------------------------------------------------- /ctai/flags.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ctai 4 | { 5 | template 6 | struct flags 7 | { 8 | static constexpr auto CF = cf; 9 | static constexpr auto ZF = zf; 10 | static constexpr auto SF = sf; 11 | static constexpr auto OF = of; 12 | }; 13 | 14 | using startup_flags_state = flags; 15 | 16 | 17 | namespace details 18 | { 19 | template 20 | struct to_flags_impl; 21 | 22 | 23 | template 24 | struct to_flags_impl< 25 | flags> 26 | { 27 | using type = flags; 28 | }; 29 | } 30 | 31 | template 32 | using to_flags = typename details::to_flags_impl::type; 33 | 34 | template 35 | using set_cf = flags{}.ZF, to_flags{}.SF, to_flags{}.OF>; 36 | 37 | template 38 | using set_zf = flags{}.CF, value, to_flags{}.SF, to_flags{}.OF>; 39 | 40 | template 41 | using set_sf = flags{}.CF, to_flags{}.ZF, value, to_flags{}.OF>; 42 | 43 | template 44 | using set_of = flags{}.CF, to_flags{}.ZF, to_flags{}.SF, value>; 45 | } 46 | -------------------------------------------------------------------------------- /ctai/execute/instructions/sys/ex_sys_write.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "ctai/execute/eip_adjust.hpp" 7 | #include "ctai/thread/thread.hpp" 8 | #include "ctai/machine/machine_state.hpp" 9 | #include "ctai/io/output.hpp" 10 | 11 | #include 12 | #include 13 | 14 | namespace ctai 15 | { 16 | namespace execute2 17 | { 18 | template 19 | struct ex_instruction, 22 | rest_of_opcodes...> 23 | { 24 | using final_registers = adjust_eip; 25 | using result_thread = thread::set_registers; 26 | 27 | static constexpr auto character = static_cast(get_reg); 28 | 29 | using next_output = io::write; 31 | 32 | using result_machine_state = machine::set_output; 33 | 34 | //using aaa = typename machine_state_t::aaa; 35 | //using aada = typename result_machine_state::bbb; 36 | //using asd = typename thread_t::it; 37 | //using asds = typename result_thread::rt; 38 | }; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ctai/execute/instructions/sys/ex_sys_malloc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "ctai/execute/eip_adjust.hpp" 7 | #include "ctai/thread/thread.hpp" 8 | #include "ctai/machine/machine_state.hpp" 9 | #include "ctai/memory/memory_alloc.hpp" 10 | 11 | #include 12 | #include 13 | 14 | namespace ctai 15 | { 16 | namespace execute2 17 | { 18 | template 19 | struct ex_instruction, 22 | rest_of_opcodes...> 23 | { 24 | static constexpr auto size_to_alloc = get_reg; 25 | using alloc_result = memory::alloc; 26 | 27 | using registers_after_eax = set_reg; 28 | 29 | using final_registers = adjust_eip; 30 | using result_thread = thread::set_registers; 31 | 32 | using result_machine_state = machine::set_memory; 33 | using asdd = typename result_machine_state::memory::metadata_t; 34 | }; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/sub_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | // sub reg, reg/val 14 | template 15 | struct matcher_impl> 20 | { 21 | static constexpr auto instruction_type = is_reg_token ? inst::id_t::SUB_REG_REG : inst::id_t::SUB_REG_VAL; 22 | 23 | using instruction = values_container_n::values_container, 24 | token_to_reg_opcode, 25 | operand_decoder>; 26 | 27 | static constexpr auto eip_change = get_eip_change; 28 | using instruction_tokens = tuple; 32 | 33 | using rest_of_tokens_t = tuple; 34 | }; 35 | } 36 | } -------------------------------------------------------------------------------- /ctai/labels.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "tuple.hpp" 4 | 5 | #include 6 | 7 | namespace ctai 8 | { 9 | template 10 | struct label_metadata {}; 11 | 12 | // 13 | // labels_add 14 | // 15 | namespace details 16 | { 17 | template 18 | struct label_add_impl; 19 | 20 | template 21 | struct label_add_impl, name, ip> 22 | { 23 | using type = tuple>; 24 | }; 25 | } 26 | 27 | template 28 | using labels_add = typename details::label_add_impl::type; 29 | 30 | // 31 | // labels_get_ip 32 | // 33 | namespace details 34 | { 35 | template 36 | struct labels_get_ip_impl; 37 | 38 | template 39 | struct labels_get_ip_impl, current_labels...>, name> 40 | { 41 | static constexpr auto ip = ip_v; 42 | }; 43 | 44 | template 45 | struct labels_get_ip_impl, name> 46 | { 47 | static constexpr auto ip = labels_get_ip_impl, name>::ip; 48 | }; 49 | } 50 | 51 | template 52 | constexpr auto labels_get_ip = details::labels_get_ip_impl::ip; 53 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/sys/ex_sys_try_lock_mutex.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "ctai/execute/eip_adjust.hpp" 7 | #include "ctai/thread/thread.hpp" 8 | #include "ctai/machine/machine_state.hpp" 9 | #include "ctai/io/input.hpp" 10 | 11 | #include 12 | #include 13 | 14 | namespace ctai 15 | { 16 | namespace execute2 17 | { 18 | template 19 | struct ex_instruction, 22 | rest_of_opcodes...> 23 | { 24 | static constexpr auto ebx_value = get_reg; 25 | static constexpr auto mutex_value = memory::get_8; 26 | static constexpr auto set_to_eax = mutex_value ? 0 : 1; //if mutex already has value 1, it's already locked - return 0 27 | 28 | using result_memory = memory::set_8; 29 | 30 | using registers_after_eax = set_reg; 31 | using final_registers = adjust_eip; 32 | using result_thread = thread::set_registers; 33 | 34 | using result_machine_state = machine::set_memory; 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/operand_decoder.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | 7 | #include 8 | 9 | // We assume that operand can be reg or const value 10 | namespace ctai 11 | { 12 | namespace details 13 | { 14 | template 15 | struct reg_token_decoder 16 | { 17 | static constexpr size_t value = token_to_reg_opcode; 18 | }; 19 | 20 | template 21 | struct const_val_token_decoder 22 | { 23 | static constexpr size_t value = string_to_int; 24 | }; 25 | 26 | template 27 | struct operand_decoder_impl; 28 | 29 | template 30 | struct operand_decoder_impl 31 | { 32 | static constexpr size_t value = 33 | std::conditional_t, 34 | reg_token_decoder, 35 | const_val_token_decoder>::value; 36 | }; 37 | 38 | template 39 | struct operand_decoder_impl> 40 | { 41 | static constexpr size_t value = 0; 42 | }; 43 | } 44 | 45 | template 46 | constexpr auto operand_decoder = details::operand_decoder_impl::value; 47 | 48 | namespace tests 49 | { 50 | static_assert(operand_decoder == regs::to_size,""); 51 | static_assert(operand_decoder == 2,""); 52 | static_assert(operand_decoder == -2,""); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ctai/memory/memory_alloc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "memory/memory.hpp" 4 | #include "memory/memory_metadata.hpp" 5 | #include "ctai/traits.hpp" 6 | 7 | #include 8 | 9 | namespace ctai 10 | { 11 | namespace memory 12 | { 13 | namespace details 14 | { 15 | template 16 | struct reserve_block 17 | { 18 | using result_metadata = metadata::reserve_block; 19 | using result_memory = ctai::memory::set_metadata; 21 | }; 22 | 23 | template 24 | struct reserve_block 25 | { 26 | using result_memory = memory_t; 27 | }; 28 | 29 | template 30 | struct alloc_impl 31 | { 32 | static constexpr auto found_block_ptr = metadata::find_unused_block_of_size; 33 | 34 | using result_memory = typename reserve_block::result_memory; 37 | 38 | static constexpr auto result_ptr = found_block_ptr != utils::bad_value ? found_block_ptr 39 | : 0; 40 | }; 41 | } 42 | 43 | template 44 | using alloc = typename details::alloc_impl; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ctai/tests/tests_memory_alloc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "tests/tests_macros.hpp" 4 | #include "ctai/containers/values_container.hpp" 5 | #include "memory/memory_metadata.hpp" 6 | #include "memory/memory_alloc.hpp" 7 | 8 | namespace ctai::tests::memory_alloc 9 | { 10 | namespace test_alloc 11 | { 12 | namespace alloc_success 13 | { 14 | namespace t1 15 | { 16 | using start_metadata = ctai::memory::metadata::memory_metadata, 17 | ctai::tuple_n::tuple<>>; 18 | 19 | using start_memory = ctai::memory::memory<2, 20 | ctai::values_container_n::values_container<>, 21 | start_metadata>; 22 | 23 | constexpr auto result = ctai::memory::alloc::result_ptr; 24 | 25 | ASSERT_NOT_EQ(result, 0); 26 | } 27 | } 28 | 29 | namespace alloc_fail 30 | { 31 | namespace t1 32 | { 33 | using start_metadata = ctai::memory::metadata::memory_metadata, 34 | ctai::tuple_n::tuple<>>; 35 | 36 | using start_memory = ctai::memory::memory<2, 37 | ctai::values_container_n::values_container<>, 38 | start_metadata>; 39 | 40 | constexpr auto result = ctai::memory::alloc::result_ptr; 41 | 42 | ASSERT_EQ(result, 0); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ctai/doc/utils.txt: -------------------------------------------------------------------------------- 1 | thread 2 | void join_thread() 3 | params 4 | eax - thread id to join 5 | 6 | mutex 7 | void lock_mutex() 8 | params 9 | eax - pointer to mutex 10 | 11 | void unlock_mutex() 12 | params 13 | eax - pointer to mutex 14 | 15 | io 16 | uint getline() 17 | params 18 | al - delimiter 19 | ebx - pointer where to store word 20 | returns 21 | eax - number of read characters 22 | invalidates 23 | eax 24 | ebx 25 | hints 26 | getline will add null at the end of read word thus buffer in fact need to be one more byte bigger than max expected word 27 | 28 | uint read_uint() 29 | returns 30 | eax - read value 31 | invalidates 32 | eax 33 | 34 | void write_string() 35 | returns 36 | eax - pointer to the c-style string 37 | 38 | utils 39 | bool is_digit() 40 | params 41 | al - character to check 42 | returns 43 | al 44 | 0 - isn't a digit 45 | 1 - is a digit 46 | invalidates 47 | al 48 | 49 | int atoui() 50 | params 51 | eax - pointer to ascii uint representation 52 | returns 53 | eax - converted int 54 | invalidates 55 | eax 56 | 57 | void uitoa() 58 | params 59 | eax - uint to convert 60 | ebx - pointer where store ascii uint 61 | returns 62 | - 63 | invalidates 64 | eax 65 | hints 66 | uitoa will add NULL at the end of ascii chars thus buffer in fact need to be one more byte bigger than max expected chars count 67 | 68 | void mem_reverse() 69 | params 70 | eax - pointer to memory 71 | ebx - size to reverse 72 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/call_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/eip_change.hpp" 8 | #include "ctai/string.hpp" 9 | #include "ctai/containers/values_container.hpp" 10 | 11 | namespace ctai 12 | { 13 | namespace details 14 | { 15 | // call .label 16 | template 17 | struct matcher_impl, 20 | rest_of_tokens...>> 21 | { 22 | static constexpr auto instruction_type = inst::id_t::CALL_VAL; 23 | 24 | using instruction = values_container_n::values_container, 25 | 0>; 26 | 27 | static constexpr auto eip_change = get_eip_change; 28 | using instruction_tokens = tuple>; 30 | 31 | using rest_of_tokens_t = tuple; 32 | }; 33 | 34 | // call instruction_pointer 35 | template 36 | struct matcher_impl> 39 | { 40 | static constexpr auto instruction_type = inst::id_t::CALL_VAL; 41 | 42 | using instruction = values_container_n::values_container< 43 | inst::to_size, 44 | operand_decoder>; 45 | 46 | static constexpr auto eip_change = get_eip_change; 47 | using instruction_tokens = tuple; 49 | 50 | using rest_of_tokens_t = tuple; 51 | }; 52 | } 53 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/add_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | // add reg, reg/val 14 | template 15 | struct matcher_impl> 21 | { 22 | static constexpr auto instruction_type = is_reg_token ? inst::id_t::ADD_REG_REG : inst::id_t::ADD_REG_VAL; 23 | 24 | using instruction = values_container_n::values_container, 25 | token_to_reg_opcode, 26 | operand_decoder>; 27 | 28 | static constexpr auto eip_change = get_eip_change; 29 | using instruction_tokens = tuple; 33 | 34 | using rest_of_tokens_t = tuple; 35 | }; 36 | } 37 | 38 | template 39 | using instruction_match = typename details::matcher_impl; 40 | 41 | namespace tests 42 | { 43 | static_assert(std::is_same, string<>>>::instruction, 44 | values_container_n::values_container< 45 | inst::to_size, 46 | regs::to_size, 47 | regs::to_size 48 | >>::value, ""); 49 | } 50 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/sys/ex_sys_is_thread_running.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "ctai/execute/eip_adjust.hpp" 7 | #include "ctai/thread/thread.hpp" 8 | #include "ctai/machine/machine_state.hpp" 9 | #include "ctai/io/output.hpp" 10 | 11 | #include 12 | #include 13 | #include "ctai/utils/empty_type.hpp" 14 | 15 | namespace ctai 16 | { 17 | namespace execute2 18 | { 19 | namespace details 20 | { 21 | template 22 | struct find_thread_predicate 23 | { 24 | template 25 | static constexpr auto value = (thread_t::id == id); 26 | }; 27 | } 28 | 29 | template 30 | struct ex_instruction, 33 | rest_of_opcodes...> 34 | { 35 | //using asd = typename machine_state_t::threads::qqqqqq; 36 | 37 | // using asd = typename thread_t::qqqqqq; 38 | 39 | 40 | static constexpr auto id = get_reg; 41 | using find_result = tuple_n::find_if>; 43 | static constexpr auto is_running = !(std::is_same::value); 44 | 45 | using retisters_after_eax = set_reg(is_running)>; 48 | 49 | using final_registers = adjust_eip; 50 | 51 | using result_thread = thread::set_registers; 52 | 53 | // using asd = typename result_thread::qqqqqq; 54 | 55 | using result_machine_state = machine_state_t; 56 | }; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/cmp_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | // add reg, reg/val 14 | template 15 | struct matcher_impl> 21 | { 22 | static constexpr auto instruction_type = is_reg_token ? inst::id_t::CMP_REG_REG 23 | : inst::id_t::CMP_REG_VAL; 24 | 25 | using instruction = values_container_n::values_container, 26 | token_to_reg_opcode, 27 | operand_decoder>; 28 | 29 | static constexpr auto eip_change = get_eip_change; 30 | using instruction_tokens = tuple; 34 | 35 | using rest_of_tokens_t = tuple; 36 | }; 37 | } 38 | 39 | template 40 | using instruction_match = typename details::matcher_impl; 41 | 42 | namespace tests 43 | { 44 | static_assert(std::is_same, string<>>>::instruction, 45 | values_container_n::values_container< 46 | inst::to_size, 47 | regs::to_size, 48 | regs::to_size 49 | >>::value, ""); 50 | } 51 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_call.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "values/values.hpp" 7 | #include "ctai/execute/eip_adjust.hpp" 8 | #include "ctai/thread/thread.hpp" 9 | 10 | namespace ctai 11 | { 12 | namespace execute2 13 | { 14 | template 18 | struct ex_instruction, 21 | ip, 22 | rest_of_opcodes...> 23 | { 24 | static constexpr auto current_esp = get_reg; 25 | static constexpr auto next_esp = current_esp - 4; 26 | 27 | using registers_after_eip = adjust_eip; 28 | static constexpr auto eip_after_ret = get_reg; 29 | 30 | using next_registers = set_reg; 31 | 32 | using final_registers = set_reg(ip)>; 33 | 34 | using result_thread = thread::thread; 39 | 40 | using splitted_value = values::split_to_byte_values_container; 41 | using result_memory = values_container_n::set_from_container; 44 | 45 | using result_machine_state = machine::set_memory_block; 46 | }; 47 | } 48 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/thread/thread.hpp" 4 | #include "ctai/execute/eip_adjust.hpp" 5 | 6 | namespace ctai 7 | { 8 | namespace execute2 9 | { 10 | namespace details 11 | { 12 | template 14 | struct ex_add_impl 15 | { 16 | using registers = typename thread_t::registers; 17 | 18 | static constexpr auto val1 = get_reg>; 19 | 20 | using new_regs_state = set_reg, static_cast(val1 + val)>; 21 | 22 | using final_regs_state = adjust_eip; 23 | 24 | using result_thread = thread::set_registers; 25 | using result_machine_state = machine_state_t; 26 | }; 27 | } 28 | 29 | template 31 | struct ex_instruction, reg1, val, rest_of_opcodes...> 32 | { 33 | using registers = typename thread_t::registers; 34 | 35 | using add_result = details::ex_add_impl; 36 | 37 | using result_thread = typename add_result::result_thread; 38 | using result_machine_state = typename add_result::result_machine_state; 39 | }; 40 | 41 | template 43 | struct ex_instruction, reg1, reg2, rest_of_opcodes...> 44 | { 45 | using registers = typename thread_t::registers; 46 | 47 | using add_result = details::ex_add_impl>>; 48 | 49 | using result_thread = typename add_result::result_thread; 50 | using result_machine_state = typename add_result::result_machine_state; 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ctai/instructions/matchers/instructions_matchers.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/eip_change.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | template 14 | struct matcher_impl; 15 | 16 | template 17 | struct matcher_impl> 18 | { 19 | using instruction = values_container_n::values_container>; 20 | static constexpr auto eip_change = get_eip_change; 21 | 22 | using instruction_tokens = tuple; 23 | using rest_of_tokens_t = tuple; 24 | }; 25 | } 26 | 27 | template 28 | using instruction_match = typename details::matcher_impl; 29 | } 30 | 31 | #include "push_matcher.hpp" 32 | #include "pusha_matcher.hpp" 33 | #include "pop_matcher.hpp" 34 | #include "popa_matcher.hpp" 35 | #include "mov_matcher.hpp" 36 | #include "add_matcher.hpp" 37 | #include "mul_matcher.hpp" 38 | #include "sub_matcher.hpp" 39 | #include "jmp_matcher.hpp" 40 | #include "jge_matcher.hpp" 41 | #include "inc_matcher.hpp" 42 | #include "dec_matcher.hpp" 43 | #include "jne_matcher.hpp" 44 | #include "jg_matcher.hpp" 45 | #include "jl_matcher.hpp" 46 | #include "je_matcher.hpp" 47 | #include "cmp_matcher.hpp" 48 | #include "call_matcher.hpp" 49 | #include "ret_matcher.hpp" 50 | #include "div_matcher.hpp" 51 | #include "sys_exit_thread_matcher.hpp" 52 | #include "sys_create_thread_matcher.hpp" 53 | #include "sys_write_matcher.hpp" 54 | #include "sys_read_matcher.hpp" 55 | #include "sys_is_thread_running_matcher.hpp" 56 | #include "sys_malloc_matcher.hpp" 57 | #include "sys_free_matcher.hpp" 58 | #include "sys_try_lock_mutex_matcher.hpp" 59 | 60 | namespace ctai 61 | { 62 | namespace tests 63 | { 64 | static_assert(std::is_same, string<>>>::instruction, 65 | values_container_n::values_container, regs::to_size>>::value, ""); 66 | } 67 | } -------------------------------------------------------------------------------- /ctai/execute.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "register.hpp" 5 | #include "tuple.hpp" 6 | #include "machine_state.hpp" 7 | #include "execute/ex_instruction.hpp" 8 | #include "execute/ex_push.hpp" 9 | #include "ctai/tokenize/tokenizer.hpp" 10 | #include "ctai/assembler/assembler.hpp" 11 | #include "ctai/assembler/label_substitute.hpp" 12 | #include "ctai/assembler/label_extract.hpp" 13 | 14 | #include 15 | 16 | namespace ctai 17 | { 18 | namespace details 19 | { 20 | template 21 | struct execute_impl; 22 | 23 | template 24 | struct execute_impl, rest_of_instructions...>> 25 | { 26 | using regs_state = typename to_machine_state::registers_state_t; 27 | static constexpr auto ret_val = get_reg; 28 | }; 29 | 30 | template 31 | struct execute_impl 32 | { 33 | using next_machine_state = execute_instruction; 34 | using next_opcodes = get_next_instruction; 35 | static constexpr auto ret_val = execute_impl::ret_val; 36 | }; 37 | } 38 | 39 | namespace details 40 | { 41 | template 42 | struct prepare_and_execute 43 | { 44 | using tokens = tokenize; 45 | using extract_labels_result = extract_labels; 46 | using tokens_without_labels = typename extract_labels_result::tokens; 47 | using labels_metadata = typename extract_labels_result::labels; 48 | using tokens_after_labels_substitution = substutite_labels; 49 | using opcodes = assemble; 50 | using machine_state = startup_machine_state; 51 | 52 | static constexpr auto ret_val = execute_impl::ret_val; 53 | }; 54 | } 55 | 56 | //todo change execute_code -> execute 57 | template 58 | constexpr auto execute_code = details::prepare_and_execute::ret_val; 59 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/jge_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | // jmp instruction_pointer 14 | template 15 | struct matcher_impl> 18 | { 19 | static constexpr auto instruction_type = inst::id_t::JGE; 20 | 21 | using instruction = values_container_n::values_container, 22 | operand_decoder>; 23 | 24 | static constexpr auto eip_change = get_eip_change; 25 | using instruction_tokens = tuple; 27 | 28 | using rest_of_tokens_t = tuple; 29 | }; 30 | 31 | // jmp .label_name 32 | template 33 | struct matcher_impl, 35 | rest_of_tokens...>> 36 | { 37 | static constexpr auto instruction_type = inst::id_t::JGE; 38 | 39 | using instruction = values_container, 40 | 0>; 41 | 42 | static constexpr auto eip_change = get_eip_change; 43 | using instruction_tokens = tuple>; 45 | 46 | using rest_of_tokens_t = tuple; 47 | }; 48 | } 49 | 50 | template 51 | using instruction_match = typename details::matcher_impl; 52 | 53 | namespace tests 54 | { 55 | static_assert(std::is_same, string<>>>::instruction, 56 | values_container_n::values_container< 57 | inst::to_size, 58 | static_cast(22) 59 | >>::value, ""); 60 | } 61 | } -------------------------------------------------------------------------------- /ctai/instructions/matchers/jmp_matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/tuple.hpp" 4 | #include "ctai/tokenize/tokens.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "operand_decoder.hpp" 7 | #include "ctai/containers/values_container.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | // jmp instruction_pointer 14 | template 15 | struct matcher_impl> 19 | { 20 | static constexpr auto instruction_type = inst::id_t::JMP; 21 | 22 | using instruction = values_container_n::values_container< 23 | inst::to_size, 24 | operand_decoder>; 25 | 26 | static constexpr auto eip_change = get_eip_change; 27 | using instruction_tokens = tuple< 28 | tokens::tok_jmp, 29 | ip>; 30 | 31 | using rest_of_tokens_t = tuple; 32 | }; 33 | 34 | //TODO remove this 35 | //jmp .label_name 36 | template 37 | struct matcher_impl, 39 | rest_of_tokens...>> 40 | { 41 | static constexpr auto instruction_type = inst::id_t::JMP; 42 | 43 | using instruction = values_container_n::values_container, 44 | 0>; 45 | 46 | static constexpr auto eip_change = get_eip_change; 47 | using instruction_tokens = tuple>; 49 | 50 | using rest_of_tokens_t = tuple; 51 | }; 52 | } 53 | 54 | template 55 | using instruction_match = typename details::matcher_impl; 56 | 57 | namespace tests 58 | { 59 | static_assert(std::is_same, string<>>>::instruction, 60 | values_container_n::values_container< 61 | inst::to_size, 62 | static_cast(22) 63 | >>::value, ""); 64 | } 65 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/execute_instruction.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/containers/values_container.hpp" 4 | 5 | namespace ctai 6 | { 7 | namespace execute2 8 | { 9 | template 10 | struct ex_instruction; 11 | } 12 | } 13 | 14 | #include "ex_push.hpp" 15 | #include "ex_pusha.hpp" 16 | #include "ex_pop.hpp" 17 | #include "ex_ret.hpp" 18 | #include "ex_call.hpp" 19 | #include "ex_popa.hpp" 20 | #include "ex_mov.hpp" 21 | #include "ex_jne.hpp" 22 | #include "ex_je.hpp" 23 | #include "ex_jg.hpp" 24 | #include "ex_jl.hpp" 25 | #include "ex_jmp.hpp" 26 | #include "ex_inc.hpp" 27 | #include "ex_cmp.hpp" 28 | #include "ex_add.hpp" 29 | #include "ex_mul.hpp" 30 | #include "ex_sub.hpp" 31 | #include "ex_div.hpp" 32 | #include "ex_dec.hpp" 33 | #include "ctai/execute/instructions/sys/ex_sys_exit_thread.hpp" 34 | #include "ctai/execute/instructions/sys/ex_sys_create_thread.hpp" 35 | #include "ctai/execute/instructions/sys/ex_sys_write.hpp" 36 | #include "ctai/execute/instructions/sys/ex_sys_read.hpp" 37 | #include "ctai/execute/instructions/sys/ex_sys_is_thread_running.hpp" 38 | #include "ctai/execute/instructions/sys/ex_sys_malloc.hpp" 39 | #include "ctai/execute/instructions/sys/ex_sys_free.hpp" 40 | #include "ctai/execute/instructions/sys/ex_sys_try_lock_mutex.hpp" 41 | 42 | namespace ctai 43 | { 44 | namespace execute2 45 | { 46 | namespace details 47 | { 48 | template 51 | struct execute_instruction_impl; 52 | 53 | template 56 | struct execute_instruction_impl> 59 | { 60 | using result = ex_instruction; 63 | }; 64 | } 65 | 66 | template 69 | using execute_instruction = typename details::execute_instruction_impl::result; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_sub.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/thread/thread.hpp" 4 | #include "ctai/execute/eip_adjust.hpp" 5 | 6 | namespace ctai 7 | { 8 | namespace execute2 9 | { 10 | namespace details 11 | { 12 | template 14 | struct ex_sub_impl 15 | { 16 | using registers = typename thread_t::registers; 17 | 18 | static constexpr auto val1 = get_reg>; 19 | 20 | using new_regs_state = set_reg, static_cast(val1 - val)>; 21 | 22 | using final_regs_state = adjust_eip; 23 | 24 | using result_thread = thread::set_registers; 25 | using result_machine_state = machine_state_t; 26 | }; 27 | } 28 | 29 | template 31 | struct ex_instruction, reg1, val, rest_of_opcodes...> 32 | { 33 | using registers = typename thread_t::registers; 34 | 35 | using sub_result = details::ex_sub_impl; 39 | 40 | using result_thread = typename sub_result::result_thread; 41 | using result_machine_state = typename sub_result::result_machine_state; 42 | }; 43 | 44 | template 46 | struct ex_instruction, reg1, reg2, rest_of_opcodes...> 47 | { 48 | using registers = typename thread_t::registers; 49 | 50 | using sub_result = details::ex_sub_impl>>; 54 | 55 | using result_thread = typename sub_result::result_thread; 56 | using result_machine_state = typename sub_result::result_machine_state; 57 | }; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ctai/assembler/assembler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/matchers/instructions_matchers.hpp" 4 | #include "ctai/instructions/matchers/push_matcher.hpp" 5 | #include "ctai/tuple.hpp" 6 | #include "containers/values_container.hpp" 7 | 8 | namespace ctai 9 | { 10 | 11 | // 12 | // get_instruction 13 | // 14 | namespace details 15 | { 16 | template 17 | struct get_instruction_impl; 18 | 19 | template 20 | struct get_instruction_impl> 21 | { 22 | using match = instruction_match>; 23 | using instruction = typename match::instruction; 24 | using res_of_tokens = typename match::rest_of_tokens_t; 25 | }; 26 | } 27 | 28 | template 29 | using get_instruction = details::get_instruction_impl; 30 | 31 | namespace details 32 | { 33 | template > 34 | struct assemble_impl; 35 | 36 | template 37 | struct assemble_impl, curr_instructions> 38 | { 39 | using instructions_result = curr_instructions; 40 | }; 41 | 42 | template 43 | struct assemble_impl 44 | { 45 | using instruction = get_instruction; 46 | 47 | using next_instructions = values_container_n::merge; 48 | using next_tokens = typename instruction::res_of_tokens; 49 | 50 | using instructions_result = typename assemble_impl::instructions_result; 51 | }; 52 | } 53 | 54 | template 55 | using assemble = typename details::assemble_impl::instructions_result; 56 | 57 | namespace tests 58 | { 59 | //push eax 60 | static_assert(std::is_same>, 61 | values_container_n::values_container, regs::to_size>>::value,""); 62 | 63 | //push eax 64 | //pop ebx 65 | static_assert(std::is_same>, 66 | values_container_n::values_container, regs::to_size, 67 | inst::to_size, regs::to_size>>::value,""); 68 | } 69 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_push.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "values/values.hpp" 7 | #include "ctai/execute/eip_adjust.hpp" 8 | #include "ctai/thread/thread.hpp" 9 | 10 | #include 11 | #include "ctai/machine/machine_state.hpp" 12 | 13 | namespace ctai 14 | { 15 | namespace execute2 16 | { 17 | namespace details 18 | { 19 | template 22 | struct ex_push_impl 23 | { 24 | static constexpr auto current_esp = get_reg; 25 | static constexpr auto next_esp = current_esp - sizeof(value); 26 | 27 | using next_registers = set_reg; 28 | using final_registers = adjust_eip; 29 | 30 | using next_thread = thread::thread; 35 | 36 | using splitted_value = values::split_to_byte_values_container; 37 | using next_memory_block = values_container_n::set_from_container; 38 | }; 39 | } 40 | 41 | 42 | template 43 | struct ex_instruction, 46 | reg, 47 | rest_of_opcodes...> 48 | { 49 | static constexpr auto reg_val = get_reg>; 50 | 51 | using push_result = details::ex_push_impl; 54 | 55 | using next_memory = memory::set_memory_block; 57 | using result_machine_state = machine::set_memory; 58 | 59 | using result_thread = typename push_result::next_thread; 60 | }; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ctai/kernel/io.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/string.hpp" 4 | 5 | namespace ctai 6 | { 7 | namespace include 8 | { 9 | using sys_write = decltype( 10 | ":sys_write " 11 | "sys_write " 12 | "ret "_s); 13 | 14 | using sys_read = decltype( 15 | ":sys_read " 16 | "sys_read " 17 | "ret "_s); 18 | 19 | using getline = decltype( 20 | ":getline " 21 | "push ecx " 22 | "mov ecx , ebx " // move pointer to eax 23 | 24 | "mov ah , al " // move delimiter to ah 25 | 26 | ":__iog_read_loop " 27 | "sys_read " 28 | "cmp ah , al " 29 | "je .__iog_finish " 30 | "mov BYTE PTR [ ecx ] , al " 31 | "inc ecx " 32 | "jmp .__iog_read_loop " 33 | 34 | ":__iog_finish " 35 | "mov BYTE PTR [ ecx ] , 0 " 36 | "sub ecx , ebx " //calculate digits count 37 | "mov eax , ecx " 38 | 39 | "pop ecx " 40 | "ret "_s 41 | ); 42 | 43 | using read_uint = decltype( 44 | ":read_uint " 45 | "push ebx " 46 | "push ecx " 47 | "sub esp , 11 " //space for read digits 48 | 49 | "mov ebx , esp " //pointer to store input 50 | "mov al , ' ' " //getline delimiter 51 | "call .getline " //getline returns digits count in eax 52 | 53 | "mov eax , ebx " //pointer to ascii number 54 | "call .atoui " //value is in eax 55 | 56 | "add esp , 11 " 57 | "pop ecx " 58 | "pop ebx " 59 | "ret "_s 60 | ); 61 | 62 | using write_string = decltype( 63 | ":write_string " 64 | "push eax " 65 | "push ebx " 66 | 67 | "mov ebx , eax "//move pointer to ebx 68 | "mov eax , 0 " 69 | 70 | ":__io_write_string_loop " 71 | "mov al , BYTE PTR [ ebx ] "//get char from buffer 72 | "inc ebx " 73 | 74 | //jump to end when we reached the NULL 75 | "cmp al , 0 " 76 | "je .__io_write_string_end " 77 | 78 | "sys_write "//write to stdout if not NULL 79 | "jmp .__io_write_string_loop "//and loop 80 | 81 | 82 | ":__io_write_string_end " 83 | "pop ebx " 84 | "pop eax " 85 | "ret "_s 86 | ); 87 | 88 | using io = declare_code; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # compile-time (simplified) x86 assembly interpreter 2 | 3 | Hello World example: 4 | 5 | ```cpp 6 | #include "string.hpp" 7 | #include "execute.hpp" 8 | 9 | #include 10 | 11 | using code = decltype( 12 | "push ebx " 13 | "pop eax " 14 | "exit"_s); 15 | constexpr auto ret_val = cai::execute_code; 16 | 17 | int main() 18 | { 19 | std::cout << std::hex << ret_val; 20 | return 0; 21 | } 22 | ``` 23 | 24 | `cai::execute_code` will parse, tokenize, execute code and return value from eax register. 25 | Startup `ebx` value is `0xbada55`. 26 | Above program will push ebx to stack and pop from stack to eax. So eax will eventually contain `0xbada55`. 27 | 28 | ## Supported features 29 | 1. Multithreading (including priorities) 30 | 2. Dynamic memory 31 | 3. input/output 32 | 4. Couple of syscalls and stdlib functions 33 | 5. Asm instructions 34 | 35 | Of course awesomeness comes by default. 36 | 37 | ## Examples 38 | 1. [Multithread fibonacci without synchronization](https://github.com/stryku/ctai/blob/master/examples/v2.0/multithread_fib_without_sync.cpp) 39 | 40 | Output: 41 | 42 | ![alt text](https://github.com/stryku/ctai/blob/master/images/multithread_fib_without_sync.png "Compiled program output") 43 | 44 | 2. [Multithread fibonacci with synchronization](https://github.com/stryku/ctai/blob/master/examples/v2.0/multithread_fib_with_sync.cpp) 45 | 46 | Execution flow: 47 | ``` 48 | MASTER THREAD: 49 | create two slave threads 50 | join these threads 51 | exit thread 52 | 53 | SLAVE THREAD: 54 | lock input mutex 55 | read element to calculate from stdin 56 | unlock input mutex 57 | calculate fibonacci for this element 58 | lock output mutex 59 | write result to stdout 60 | unlock output mutex 61 | exit thread 62 | ``` 63 | 64 | Output: 65 | 66 | ![alt text](https://github.com/stryku/ctai/blob/master/images/multithread_fib_with_sync.png "Compiled program output") 67 | 68 | 3. [Unrealized dream](https://github.com/stryku/ctai/blob/master/examples/v2.0/unrealized_dream.cpp) 69 | 70 | Didn't managed to compile this beast. My machine doesn't have enough amount of RAM, but here's the flow: 71 | ``` 72 | MASTER THREAD 73 | read N from input - number of elements to calculate 74 | create structure that will fit 75 | -N-element array of uint8_t for elements 76 | -N-element array of uint32_t for results 77 | -(N + 5)-element array of uint16_t for tasks. + 5 because five tasks to end slave thread 78 | -5-element array of uint32_t for slaves ids 79 | create tasks 80 | -N tasks to calculate fibonacci element 81 | -five tasks to end slave thread 82 | create five slave threads. Pass pointer to the structure in `args` argument 83 | join slaves 84 | write results to stdout 85 | exit thread 86 | 87 | 88 | SLAVE THREAD 89 | while true 90 | lock tasks array mutex 91 | get next task 92 | unlock tasks array mutex 93 | if next task is fibonacci 94 | calculate fibonacci 95 | lock results array mutex 96 | write result to array 97 | unlock results array mutex 98 | else if task is exit 99 | exit thread 100 | ``` 101 | 102 | 103 | ## Documentation 104 | In `doc` folder you can find syscalls and stdlib funcitons documentations. For now there is no documentation with supported asm instructions. 105 | -------------------------------------------------------------------------------- /ctai/thread/thread.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/containers/values_container.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/flags.hpp" 6 | 7 | #include 8 | 9 | namespace ctai 10 | { 11 | namespace thread 12 | { 13 | template 18 | struct thread 19 | { 20 | static constexpr auto id = id_v; 21 | static constexpr auto priority = priority_v; 22 | static constexpr auto finished = finished_v; 23 | using registers = registers_t; 24 | using flags = flags_t; 25 | }; 26 | 27 | // 28 | //get_next_opcodes 29 | // 30 | namespace details 31 | { 32 | template 33 | struct get_next_opcodes_impl 34 | { 35 | static constexpr auto eip = get_reg; 36 | 37 | using result = values_container_n::drop_front; 38 | }; 39 | } 40 | 41 | template 42 | using get_next_opcodes = typename details::get_next_opcodes_impl::result; 43 | 44 | // 45 | //create 46 | // 47 | namespace details 48 | { 49 | template 50 | struct create_impl 51 | { 52 | using registers = registers_state<0, //eax 53 | 0, //ebx 54 | 0, //ecx 55 | 0, //edx 56 | esp, //esp 57 | 0, 58 | 0, 59 | 0, 60 | eip>;//eip 61 | 62 | using flags_t = startup_flags_state; 63 | 64 | using result = thread; 69 | }; 70 | } 71 | 72 | template 73 | using create = typename details::create_impl::result; 74 | 75 | template 76 | using set_registers = thread; 81 | 82 | template 83 | using set_flags = thread; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_cmp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ex_call.hpp" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace ctai 11 | { 12 | namespace execute2 13 | { 14 | namespace details 15 | { 16 | template 20 | struct ex_cmp_impl 21 | { 22 | using registers = typename thread_t::registers; 23 | static constexpr int64_t result = static_cast(val1) - static_cast(val2); 24 | 25 | static constexpr bool zf = (val1 == val2); 26 | static constexpr bool cf = (static_cast(val1) < static_cast(val2)); //set if borrow 27 | static constexpr bool sf = (result < 0); 28 | static constexpr bool of = (result < static_cast(std::numeric_limits::min()) || 29 | result > static_cast(std::numeric_limits::max())); 30 | 31 | using new_flags_state = flags; 32 | 33 | using final_regs_state = adjust_eip; 34 | using thread_after_registers = thread::set_registers; 35 | using result_thread = thread::set_flags; 36 | 37 | using result_machine_state = machine_state_t; 38 | }; 39 | } 40 | 41 | //cmp reg, reg 42 | template 44 | struct ex_instruction, reg, reg2, rest_of_opcodes...> 45 | { 46 | using registers = typename thread_t::registers; 47 | using cmp_result = details::ex_cmp_impl>, 50 | get_reg>>; 51 | 52 | using result_thread = typename cmp_result::result_thread; 53 | using result_machine_state = typename cmp_result::result_machine_state; 54 | }; 55 | 56 | //cmp reg, val 57 | template 59 | struct ex_instruction, reg, value_v, rest_of_opcodes...> 60 | { 61 | using cmp_result = details::ex_cmp_impl>, 64 | value_v>; 65 | 66 | using result_thread = typename cmp_result::result_thread; 67 | using result_machine_state = typename cmp_result::result_machine_state; 68 | }; 69 | } 70 | } -------------------------------------------------------------------------------- /ctai/tuple.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ctai 4 | { 5 | template 6 | struct tuple 7 | {}; 8 | 9 | // 10 | //tuple_append 11 | // 12 | namespace details 13 | { 14 | template 15 | struct tuple_append_impl; 16 | 17 | template 18 | struct tuple_append_impl, tail> 19 | { 20 | using type = tuple; 21 | }; 22 | } 23 | 24 | template 25 | using tuple_append = typename details::tuple_append_impl::type; 26 | 27 | // 28 | // tuple_merge 29 | // 30 | namespace details 31 | { 32 | template 33 | struct tuple_merge_impl; 34 | 35 | template 36 | struct tuple_merge_impl, tuple> 37 | { 38 | using type = tuple; 39 | }; 40 | } 41 | 42 | template 43 | using tuple_merge = typename details::tuple_merge_impl::type; 44 | 45 | 46 | // 47 | // values_container 48 | // 49 | 50 | template 51 | struct values_container 52 | {}; 53 | 54 | // 55 | //values_append 56 | // 57 | namespace details 58 | { 59 | template 60 | struct values_append_impl; 61 | 62 | template 63 | struct values_append_impl, tail> 64 | { 65 | using type = values_container; 66 | }; 67 | } 68 | 69 | template 70 | using values_append = typename details::values_append_impl::type; 71 | 72 | // 73 | //values_merge 74 | // 75 | namespace details 76 | { 77 | template 78 | struct values_merge_impl; 79 | 80 | template 81 | struct values_merge_impl, values_container> 82 | { 83 | using type = values_container; 84 | }; 85 | } 86 | 87 | template 88 | using values_merge = typename details::values_merge_impl::type; 89 | 90 | namespace details 91 | { 92 | template 93 | struct values_drop_impl; 94 | 95 | template 96 | struct values_drop_impl<0, true, values_container> 97 | { 98 | using type = values_container; 99 | }; 100 | 101 | template 102 | struct values_drop_impl> 103 | { 104 | using type = typename values_drop_impl>::type; 107 | }; 108 | } 109 | 110 | template 111 | using values_drop = typename details::values_drop_impl::type; 112 | 113 | } -------------------------------------------------------------------------------- /ctai/tests/instructions/execute/tests_ex_popa.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "memory/memory.hpp" 4 | #include "ctai/execute/instructions/ex_popa.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/tokenize/tokens.hpp" 7 | #include "ctai/tuple.hpp" 8 | #include "tests/tests_macros.hpp" 9 | #include "ctai/machine/machine_state.hpp" 10 | 11 | namespace ctai::tests::ex_popa 12 | { 13 | template 14 | using vc = ctai::values_container_n::values_container; 15 | 16 | using test_memory = ctai::memory::memory<33, 17 | vc<0, //reserved 18 | 8, 8, 8, 8, 19 | 7, 7, 7, 7, 20 | 6, 6, 6, 6, 21 | 0, 0, 0, 33, //esp 22 | 4, 4, 4, 4, //ebx 23 | 3, 3, 3, 3, //edx 24 | 2, 2, 2, 2, //ecx 25 | 1, 1, 1, 1>>;//eax 26 | 27 | using test_registers = ctai::registers_state<0, //eax 28 | 0, //ebx 29 | 0, //ecx 30 | 0, //edx 31 | 1, //esp 32 | 0, 33 | 0, 34 | 0, 35 | 0>;//eip 36 | 37 | using test_thread = ctai::thread::thread; 42 | 43 | using test_machine_state = machine::state, 45 | ctai::tuple_n::tuple<>, 46 | ctai::io::output::buffer<>, 47 | ctai::io::input::buffer<>, 48 | 0, 0>; 49 | 50 | namespace test_ex_pusha 51 | { 52 | using expected_registers = ctai::registers_state<0x01010101, //eax 53 | 0x04040404, //ebx 54 | 0x02020202, //ecx 55 | 0x03030303, //edx 56 | 33, //esp 57 | 0x06060606, 58 | 0x07070707, 59 | 0x08080808, 60 | 1>;//eip 61 | 62 | using execute_result = ctai::execute2::ex_instruction>; 65 | 66 | using result_registers = typename execute_result::result_thread::registers; 67 | 68 | ASSERT_EQ_T(result_registers, expected_registers); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /ctai/tokenize/tokenizer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/string.hpp" 4 | #include "ctai/tuple.hpp" 5 | 6 | #include 7 | 8 | 9 | namespace ctai 10 | { 11 | // 12 | // get_token 13 | // 14 | namespace details 15 | { 16 | template > 17 | struct get_token_impl; 18 | 19 | template 20 | struct get_token_impl, current_token> 21 | { 22 | using result_token = current_token; 23 | using rest_of_string = string<>; 24 | }; 25 | 26 | template 27 | struct get_token_impl, current_token> 28 | { 29 | using result_token = current_token; 30 | using rest_of_string = string; 31 | }; 32 | 33 | //match space character: ' ' 34 | template 35 | struct get_token_impl, current_token> 36 | { 37 | using result_token = string<'\'', ' ', '\''>; 38 | using rest_of_string = string; 39 | }; 40 | 41 | template 42 | struct get_token_impl, current_token> 43 | { 44 | using string_without_token_char = string; 45 | 46 | using result_t = get_token_impl>; 47 | 48 | using result_token = typename result_t::result_token; 49 | using rest_of_string = typename result_t::rest_of_string; 50 | }; 51 | } 52 | 53 | template 54 | using get_token = details::get_token_impl; 55 | 56 | namespace details 57 | { 58 | template > 59 | struct tokenize_impl; 60 | 61 | template 62 | struct tokenize_impl, current_tokens> 63 | { 64 | using tokens = current_tokens; 65 | }; 66 | 67 | template 68 | struct tokenize_impl, current_tokens> 69 | { 70 | using str = string; 71 | using get_token_t = get_token; 72 | 73 | using next_tokens = tuple_append; 74 | using next_string = typename get_token_t::rest_of_string; 75 | 76 | using tokens = typename tokenize_impl::tokens; 77 | }; 78 | } 79 | 80 | template 81 | using tokenize = typename details::tokenize_impl::tokens; 82 | 83 | namespace tests 84 | { 85 | static_assert(std::is_same::result_token, 86 | decltype("abc"_s)>::value, ""); 87 | 88 | static_assert(std::is_same::rest_of_string, 89 | decltype("def"_s)>::value, ""); 90 | 91 | static_assert(std::is_same, 92 | tuple>::value, ""); 93 | } 94 | } -------------------------------------------------------------------------------- /ctai/tests/instructions/execute/tests_ex_pusha.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "memory/memory.hpp" 4 | #include "ctai/execute/instructions/ex_pusha.hpp" 5 | #include "ctai/instructions/ids_vaules.hpp" 6 | #include "ctai/tokenize/tokens.hpp" 7 | #include "ctai/tuple.hpp" 8 | #include "tests/tests_macros.hpp" 9 | #include "ctai/machine/machine_state.hpp" 10 | #include "tuple/tuple.hpp" 11 | 12 | 13 | namespace ctai::tests::ex_pusha 14 | { 15 | template 16 | using vc = ctai::values_container_n::values_container; 17 | 18 | using test_memory = ctai::memory::memory_create<33>; 19 | 20 | using test_registers = ctai::registers_state<0x01010101, //eax 21 | 0x04040404, //ebx 22 | 0x02020202, //ecx 23 | 0x03030303, //edx 24 | 33, //esp 25 | 0x06060606, 26 | 0x07070707, 27 | 0x08080808, 28 | 0>;//eip 29 | 30 | using test_thread = ctai::thread::thread; 35 | 36 | using test_machine_state = machine::state, 38 | ctai::tuple_n::tuple<>, 39 | ctai::io::output::buffer<>, 40 | ctai::io::input::buffer<>, 41 | 0, 42 | 0>; 43 | 44 | 45 | namespace test_ex_pusha 46 | { 47 | using expected_memory = ctai::memory::memory<33, 48 | vc(0), //reserved 49 | 8, 8, 8, 8, 50 | 7, 7, 7, 7, 51 | 6, 6, 6, 6, 52 | 0, 0, 0, 33, //esp 53 | 4, 4, 4, 4, //ebx 54 | 3, 3, 3, 3, //edx 55 | 2, 2, 2, 2, //ecx 56 | 1, 1, 1, 1>>;//eax 57 | 58 | using expected_mem_block = ctai::values_container_n::cast_values_to; 59 | 60 | constexpr auto expected_esp = 1; 61 | 62 | using execute_result = ctai::execute2::ex_instruction>; 65 | 66 | using result_machine_state = typename execute_result::result_machine_state; 67 | using result_mem_block = ctai::values_container_n::cast_values_to; 68 | 69 | using result_registers = typename execute_result::result_thread::registers; 70 | constexpr auto result_esp = ctai::get_reg; 71 | 72 | ASSERT_EQ_T(expected_mem_block, result_mem_block); 73 | ASSERT_EQ(expected_esp, result_esp); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /ctai/assembler/label_substitute.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/labels.hpp" 4 | #include "ctai/string.hpp" 5 | #include "ctai/instructions/matchers/instructions_matchers.hpp" 6 | 7 | namespace ctai 8 | { 9 | // 10 | // substitute_labels 11 | // 12 | namespace details 13 | { 14 | template > 15 | struct substitute_labels_impl; 16 | 17 | template 18 | struct substitute_labels_impl, labels, final_tokens> 19 | { 20 | using tokens = final_tokens; 21 | }; 22 | 23 | //label match 24 | template 25 | struct substitute_labels_impl< 26 | tuple, rest_of_tokens...>, 27 | labels, 28 | tuple> 29 | { 30 | static constexpr auto ip = labels_get_ip>; 31 | using str_ip = string_from_int; 32 | 33 | using substitued = substitute_labels_impl, 34 | labels, 35 | tuple>; 36 | 37 | using tokens = typename substitued::tokens; 38 | }; 39 | 40 | //character inside '' match 41 | template 42 | struct substitute_labels_impl< 43 | tuple, rest_of_tokens...>, 44 | labels, 45 | tuple> 46 | { 47 | using str_char = string_from_int; 48 | 49 | using substitued = substitute_labels_impl, 50 | labels, 51 | tuple>; 52 | 53 | using tokens = typename substitued::tokens; 54 | }; 55 | 56 | //normal token 57 | template 58 | struct substitute_labels_impl< 59 | tuple, 60 | labels, 61 | tuple> 62 | { 63 | using substitued = substitute_labels_impl, 64 | labels, 65 | tuple>; 66 | 67 | using tokens = typename substitued::tokens; 68 | }; 69 | } 70 | 71 | template 72 | using substutite_labels = typename details::substitute_labels_impl::tokens; 73 | 74 | namespace tests 75 | { 76 | static_assert( 77 | std::is_same< 78 | substutite_labels, tuple<>>, 79 | tuple 80 | >::value 81 | ,""); 82 | 83 | static_assert( 84 | std::is_same< 85 | substutite_labels, tuple>>, 86 | tuple 87 | >::value 88 | ,""); 89 | } 90 | } -------------------------------------------------------------------------------- /ctai/assembler/label_extract.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/labels.hpp" 4 | #include "ctai/string.hpp" 5 | #include "ctai/instructions/matchers/instructions_matchers.hpp" 6 | 7 | namespace ctai 8 | { 9 | // 10 | // extract_labels 11 | // 12 | namespace details 13 | { 14 | template , typename final_labels = tuple<>> 15 | struct extract_labels_impl; 16 | 17 | template 18 | struct extract_labels_impl, ip, final_tokens, final_labels> 19 | { 20 | using tokens = final_tokens; 21 | using labels = final_labels; 22 | }; 23 | 24 | //label match 25 | template 26 | struct extract_labels_impl, 27 | rest_of_tokens...>, 28 | current_ip, 29 | tuple, 30 | tuple> 31 | { 32 | using extracted = extract_labels_impl, 33 | current_ip, 34 | tuple, 35 | tuple, current_ip>>>; 37 | 38 | using tokens = typename extracted::tokens; 39 | using labels = typename extracted::labels; 40 | }; 41 | 42 | //normal instruction 43 | template 48 | struct extract_labels_impl, 49 | current_ip, 50 | tuple, 51 | result_labels> 52 | { 53 | using instruction = instruction_match>; 54 | using next_tokens = tuple_merge, typename instruction::instruction_tokens>; 55 | static constexpr auto nex_ip = current_ip + instruction::eip_change; 56 | 57 | using extracted = extract_labels_impl; 61 | 62 | using tokens = typename extracted::tokens; 63 | using labels = typename extracted::labels; 64 | }; 65 | } 66 | 67 | template 68 | using extract_labels = details::extract_labels_impl; 69 | 70 | namespace tests 71 | { 72 | static_assert( 73 | std::is_same>::tokens, 74 | tuple 75 | >::value 76 | ,""); 77 | 78 | static_assert( 79 | std::is_same>::labels, 80 | tuple, 81 | label_metadata> 82 | >::value 83 | ,""); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /ctai/eip_change.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "register.hpp" 5 | 6 | #include 7 | #include 8 | 9 | namespace ctai 10 | { 11 | namespace details 12 | { 13 | template 14 | constexpr size_t eip_change{0}; 15 | 16 | template <> constexpr size_t eip_change = 3; 17 | template <> constexpr size_t eip_change = 3; 18 | template <> constexpr size_t eip_change = 3; 19 | template <> constexpr size_t eip_change = 3; 20 | template <> constexpr size_t eip_change = 2; 21 | template <> constexpr size_t eip_change = 2; 22 | template <> constexpr size_t eip_change = 3; 23 | template <> constexpr size_t eip_change = 3; 24 | template <> constexpr size_t eip_change = 1; 25 | template <> constexpr size_t eip_change = 5; 26 | template <> constexpr size_t eip_change = 5; 27 | template <> constexpr size_t eip_change = 5; 28 | template <> constexpr size_t eip_change = 5; 29 | template <> constexpr size_t eip_change = 5; 30 | template <> constexpr size_t eip_change = 5; 31 | template <> constexpr size_t eip_change = 4; 32 | template <> constexpr size_t eip_change = 4; 33 | template <> constexpr size_t eip_change = 4; 34 | template <> constexpr size_t eip_change = 3; 35 | template <> constexpr size_t eip_change = 3; 36 | template <> constexpr size_t eip_change = 2; 37 | template <> constexpr size_t eip_change = 1; 38 | template <> constexpr size_t eip_change = 2; 39 | template <> constexpr size_t eip_change = 1; 40 | template <> constexpr size_t eip_change = 2; 41 | template <> constexpr size_t eip_change = 2; 42 | template <> constexpr size_t eip_change = 2; 43 | template <> constexpr size_t eip_change = 2; 44 | template <> constexpr size_t eip_change = 2; 45 | template <> constexpr size_t eip_change = 2; 46 | template <> constexpr size_t eip_change = 2; 47 | template <> constexpr size_t eip_change = 2; 48 | 49 | template <> constexpr size_t eip_change = 2; 50 | template <> constexpr size_t eip_change = 1; 51 | 52 | template <> constexpr size_t eip_change = 1; 53 | template <> constexpr size_t eip_change = 1; 54 | template <> constexpr size_t eip_change = 1; 55 | template <> constexpr size_t eip_change = 1; 56 | template <> constexpr size_t eip_change = 1; 57 | template <> constexpr size_t eip_change = 1; 58 | template <> constexpr size_t eip_change = 1; 59 | template <> constexpr size_t eip_change = 1; 60 | } 61 | 62 | template 63 | constexpr auto get_eip_change = details::eip_change; 64 | } 65 | -------------------------------------------------------------------------------- /ctai/machine/machine_state.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "memory/memory.hpp" 4 | 5 | #include 6 | 7 | namespace ctai 8 | { 9 | namespace machine 10 | { 11 | template 18 | struct state 19 | { 20 | using memory = memory_t; 21 | using opcodes = opcodes_t; 22 | using threads = threads_t; 23 | using output = output_t; 24 | using input = input_t; 25 | static constexpr auto time = time_v; 26 | static constexpr auto last_thread_id = last_thread_id_v; 27 | }; 28 | 29 | template 30 | using adjust_time = state; 37 | 38 | template 39 | using set_memory = state; 46 | 47 | template 48 | using set_memory_block = set_memory>; 50 | 51 | template 52 | using set_threads_and_time = state; 59 | 60 | template 61 | using set_output = state; 68 | 69 | template 70 | using set_input = state; 77 | 78 | template 79 | using set_threads = state; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_popa.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "values/values.hpp" 7 | #include "ctai/execute/eip_adjust.hpp" 8 | #include "ctai/thread/thread.hpp" 9 | 10 | #include 11 | 12 | namespace ctai 13 | { 14 | namespace execute2 15 | { 16 | namespace details 17 | { 18 | template 20 | struct pop_reg 21 | { 22 | static constexpr auto next_esp = esp + 4; 23 | static constexpr auto result_value = memory::get_32; 24 | }; 25 | 26 | template 28 | struct ex_popa_impl 29 | { 30 | static constexpr auto current_esp = get_reg; 31 | 32 | using registers = typename thread_t::registers; 33 | 34 | using pop_edi_result = pop_reg; 35 | using pop_esi_result = pop_reg; 36 | using pop_ebp_result = pop_reg; 37 | using pop_esp_result = pop_reg; 38 | using pop_ebx_result = pop_reg; 39 | using pop_edx_result = pop_reg; 40 | using pop_ecx_result = pop_reg; 41 | using pop_eax_result = pop_reg; 42 | 43 | using registers_after_eax = set_reg; 44 | using registers_after_ebx = set_reg; 45 | using registers_after_ecx = set_reg; 46 | using registers_after_edx = set_reg; 47 | using registers_after_esp = set_reg; 48 | using registers_after_ebp = set_reg; 49 | using registers_after_esi = set_reg; 50 | using registers_after_edi = set_reg; 51 | 52 | using final_registers = adjust_eip; 53 | 54 | using next_thread = thread::thread; 59 | 60 | 61 | using next_memory = memory_t; 62 | }; 63 | } 64 | 65 | 66 | template 67 | struct ex_instruction, 70 | rest_of_opcodes...> 71 | { 72 | using popa_result = details::ex_popa_impl; 74 | 75 | using result_thread = typename popa_result::next_thread; 76 | using result_machine_state = machine::set_memory; 77 | }; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /ctai/opcode/opcodes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "ctai/eip_change.hpp" 5 | #include 6 | 7 | namespace ctai 8 | { 9 | namespace opcode 10 | { 11 | template 12 | struct opcodes 13 | { 14 | static constexpr size_t opcodes_array[sizeof...(values)] = { values... }; 15 | }; 16 | 17 | // 18 | //create_opcodes_impl 19 | // 20 | namespace details 21 | { 22 | template 23 | struct create_opcodes_impl; 24 | 25 | template 26 | struct create_opcodes_impl> 27 | { 28 | using result = opcodes; 29 | }; 30 | } 31 | 32 | template 33 | using create_opcodes = typename details::create_opcodes_impl::result; 34 | 35 | // 36 | //get_next_opcodes 37 | // 38 | namespace details 39 | { 40 | template 41 | struct get_next_opcodes_impl; 42 | 43 | template 44 | struct get_next_opcodes_impl 45 | { 46 | using result = values_container_n::values_container; 47 | }; 48 | 49 | template 50 | struct get_next_opcodes_impl 51 | { 52 | using result = values_container_n::values_container; 54 | }; 55 | 56 | template 57 | struct get_next_opcodes_impl 58 | { 59 | using result = values_container_n::values_container; 62 | }; 63 | 64 | template 65 | struct get_next_opcodes_impl 66 | { 67 | using result = values_container_n::values_container; 71 | }; 72 | 73 | template 74 | struct get_next_opcodes_impl 75 | { 76 | using result = values_container_n::values_container; 81 | }; 82 | } 83 | 84 | template 85 | using get_next_opcodes = typename details::get_next_opcodes_impl>>::result; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_mul.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/execute/eip_adjust.hpp" 6 | #include "ctai/thread/thread.hpp" 7 | #include "ctai/utils/operand_size.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace execute2 12 | { 13 | namespace details 14 | { 15 | template 18 | struct ex_mul_impl; 19 | 20 | template 22 | struct ex_mul_impl 25 | { 26 | using registers = typename thread_t::registers; 27 | 28 | static constexpr auto al_value = get_reg; 29 | static constexpr auto reg_value = get_reg; 30 | static constexpr auto result = static_cast(al_value) * static_cast(reg_value); 31 | 32 | using result_registers = set_reg; 33 | }; 34 | 35 | template 37 | struct ex_mul_impl 40 | { 41 | using registers = typename thread_t::registers; 42 | 43 | static constexpr auto ax_value = get_reg; 44 | static constexpr auto reg_value = get_reg; 45 | static constexpr auto result = static_cast(ax_value) * static_cast(reg_value); 46 | 47 | using regs_state_after_ax = set_reg; 48 | using result_registers = set_reg> 16)>; 49 | }; 50 | 51 | template 53 | struct ex_mul_impl 56 | { 57 | using registers = typename thread_t::registers; 58 | 59 | static constexpr auto eax_value = get_reg; 60 | static constexpr auto reg_value = get_reg; 61 | static constexpr auto result = static_cast(eax_value) * static_cast(reg_value); 62 | 63 | using regs_state_after_eax = set_reg; 64 | using result_registers = set_reg> 32)>; 65 | }; 66 | } 67 | 68 | template 72 | struct ex_instruction, 75 | reg, 76 | rest_of_opcodes...> 77 | { 78 | static constexpr auto reg_size = utils::reg_size>; 79 | 80 | using registers_after_mul = typename details::ex_mul_impl, 82 | reg_size>::result_registers; 83 | 84 | using final_regs_state = adjust_eip; 85 | 86 | using result_thread = thread::set_registers; 87 | using result_machine_state = machine_state_t; 88 | }; 89 | } 90 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_div.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/execute/eip_adjust.hpp" 6 | #include "ctai/thread/thread.hpp" 7 | #include "ctai/utils/operand_size.hpp" 8 | 9 | namespace ctai 10 | { 11 | namespace execute2 12 | { 13 | namespace details 14 | { 15 | template 18 | struct ex_div_impl; 19 | 20 | template 22 | struct ex_div_impl 25 | { 26 | using registers = typename thread_t::registers; 27 | 28 | static constexpr auto ax_value = get_reg; 29 | static constexpr auto reg_value = get_reg; 30 | 31 | using registers_after_al = set_reg; 32 | using result_registers = set_reg; 33 | }; 34 | 35 | template 37 | struct ex_div_impl 40 | { 41 | using registers = typename thread_t::registers; 42 | 43 | static constexpr auto ax_value = get_reg; 44 | static constexpr auto dx_value = get_reg; 45 | static constexpr auto reg_value = get_reg; 46 | static constexpr auto value_to_div = (static_cast(dx_value) << 16 ) + static_cast(ax_value); 47 | 48 | using registers_after_ax = set_reg; 49 | using result_registers = set_reg; 50 | }; 51 | 52 | template 54 | struct ex_div_impl 57 | { 58 | using registers = typename thread_t::registers; 59 | 60 | static constexpr auto eax_value = get_reg; 61 | static constexpr auto edx_value = get_reg; 62 | static constexpr auto reg_value = get_reg; 63 | static constexpr auto value_to_div = (static_cast(edx_value) << 32 ) + static_cast(eax_value); 64 | 65 | using registers_after_eax = set_reg; 66 | using result_registers = set_reg; 67 | }; 68 | } 69 | 70 | template 74 | struct ex_instruction, 77 | reg, 78 | rest_of_opcodes...> 79 | { 80 | static constexpr auto reg_size = utils::reg_size>; 81 | 82 | using registers_after_div = typename details::ex_div_impl, 84 | reg_size>::result_registers; 85 | 86 | using final_regs_state = adjust_eip; 87 | 88 | using result_thread = thread::set_registers; 89 | using result_machine_state = machine_state_t; 90 | }; 91 | } 92 | } -------------------------------------------------------------------------------- /ctai/execute/instructions/ex_pusha.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "values/values.hpp" 7 | #include "ctai/execute/eip_adjust.hpp" 8 | #include "ctai/thread/thread.hpp" 9 | 10 | #include 11 | 12 | namespace ctai 13 | { 14 | namespace execute2 15 | { 16 | namespace details 17 | { 18 | template 21 | struct push_reg 22 | { 23 | static constexpr auto next_esp = esp - sizeof(value); 24 | using next_memory = memory::set_32; 25 | }; 26 | 27 | template 29 | struct ex_pusha_impl 30 | { 31 | static constexpr auto current_esp = get_reg; 32 | 33 | using registers = typename thread_t::registers; 34 | using push_eax_result = push_reg>; 35 | using push_ecx_result = push_reg>; 38 | using push_edx_result = push_reg>; 41 | using push_ebx_result = push_reg>; 44 | using push_esp_result = push_reg>; 47 | using push_ebp_result = push_reg>; 50 | using push_esi_result = push_reg>; 53 | using push_edi_result = push_reg>; 56 | 57 | 58 | using next_registers = set_reg; 59 | using final_registers = adjust_eip; 60 | 61 | using next_thread = thread::thread; 66 | 67 | 68 | using next_memory = typename push_edi_result::next_memory; 69 | }; 70 | } 71 | 72 | 73 | template 74 | struct ex_instruction, 77 | rest_of_opcodes...> 78 | { 79 | using pusha_result = details::ex_pusha_impl; 81 | 82 | using result_machine_state = machine::set_memory; 83 | 84 | using result_thread = typename pusha_result::next_thread; 85 | }; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /ctai/containers/gen/drop_front_impl_gen.hpp: -------------------------------------------------------------------------------- 1 | // This file was GENERATED by command: 2 | // pump.py drop_front_impl_gen.hpp.pump 3 | // DO NOT EDIT BY HAND!!! 4 | 5 | template 6 | struct drop_front_impl_gen_10; 7 | template 8 | struct drop_front_impl_gen_100; 9 | 10 | 11 | template 12 | struct drop_front_impl_gen_10 13 | { 14 | using result = values_container_n::values_container; 15 | }; 16 | 17 | template < auto... rest_of_values> 18 | struct drop_front_impl_gen_100 19 | { 20 | using result = values_container_n::values_container; 21 | }; 22 | 23 | template 26 | struct drop_front_impl_gen_10 29 | { 30 | using result = values_container_n::values_container; 31 | }; 32 | 33 | template 58 | struct drop_front_impl_gen_100 76 | { 77 | using result = values_container_n::values_container; 78 | }; 79 | -------------------------------------------------------------------------------- /ctai/kernel/utils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/string.hpp" 4 | 5 | namespace ctai 6 | { 7 | namespace include 8 | { 9 | using atoui = decltype( 10 | ":atoui " 11 | "push ebx " 12 | "push ecx " 13 | "push edx " 14 | "push esi " 15 | 16 | "mov ecx , eax " //string ptr 17 | "mov eax , 10 " 18 | "mov esi , 0 " //current value will be in esi 19 | 20 | ":__utils_atoui_convert_loop " 21 | "mov bl , BYTE PTR [ ecx ] " //get current char 22 | 23 | "cmp bl , 0 " 24 | "je .__utils_atoui_end " //jump to end if NULL 25 | 26 | "sub bl , '0' " //ascii to value 27 | 28 | "cmp esi , 0 " //if current value is > 0 we need to mul value by 10 29 | "je .__utils_atoui_no_mul " //if it's 0 don't mul 30 | "mul esi " 31 | "mov esi , eax " 32 | "mov eax , 10 " 33 | 34 | ":__utils_atoui_no_mul " 35 | "add esi , bl " //add to current value 36 | 37 | "inc ecx "//move to next character 38 | 39 | "jmp .__utils_atoui_convert_loop " 40 | 41 | ":__utils_atoui_end " 42 | "mov eax , esi " 43 | 44 | "pop esi " 45 | "pop edx " 46 | "pop ecx " 47 | "pop ebx " 48 | "ret "_s 49 | ); 50 | 51 | using uitoa = decltype( 52 | ":uitoa " 53 | "push ebx " 54 | "push ecx " 55 | "push edx " 56 | "push esi " 57 | "push edi " 58 | 59 | //ebx - pointer to buffer 60 | 61 | "mov ecx , eax " //ecx - value to convert 62 | "mov esi , 10 " //divide by 10 to get chars 63 | "mov edi , 0 " //count digits 64 | 65 | ":__utils_uitoa_convert_loop " 66 | "mov edx , 0 " //prepare edx do div 67 | "div esi " 68 | //now eax = current_value / 10 69 | //now edx = current_value % 10 70 | 71 | "add dl , '0' " //value to ascii 72 | "mov BYTE PTR [ ebx ] , dl " //store in buffer 73 | "inc ebx " 74 | "inc edi " 75 | 76 | //check if it's end of conversion 77 | "cmp eax , 0 " 78 | "jne .__utils_uitoa_convert_loop " //jump if not 79 | 80 | //if we are here, it's end of the conversion 81 | "mov BYTE PTR [ ebx ] , 0 " //add NULL at the end 82 | 83 | 84 | 85 | //no we need to reverse the string 86 | "mov eax , ebx " 87 | "sub eax , edi " // eax - pointer to string 88 | "mov ebx , edi " 89 | "dec ebx " //ebx - digits count 90 | "call .mem_reverse " 91 | 92 | "pop edi " 93 | "pop esi " 94 | "pop edx " 95 | "pop ecx " 96 | "pop ebx " 97 | "ret "_s 98 | ); 99 | 100 | using is_digit = decltype( 101 | ":is_digit " 102 | "cmp al , '0' " 103 | "jl .__uid_no " 104 | 105 | "cmp al , '9' " 106 | "jg .__uid_no " 107 | 108 | "mov al , 1 " 109 | "jmp .__uid_end " 110 | 111 | ":__uid_no " 112 | "mov al , 0 " 113 | 114 | ":__uid_end " 115 | "ret "_s 116 | ); 117 | 118 | using mem_reverse = decltype( 119 | ":mem_reverse " 120 | "push eax " 121 | "push ebx " 122 | "push ecx " 123 | 124 | "add ebx , eax " //ebx - pointer to end 125 | 126 | ":__utils_mem_reverse_loop " 127 | "mov cl , BYTE PTR [ eax ] " 128 | "mov ch , BYTE PTR [ ebx ] " 129 | 130 | "mov BYTE PTR [ eax ] , ch " 131 | "mov BYTE PTR [ ebx ] , cl " 132 | 133 | "inc eax " 134 | "dec ebx " 135 | 136 | "cmp eax , ebx " 137 | "jl .__utils_mem_reverse_loop " 138 | 139 | 140 | "pop ecx " 141 | "pop ebx " 142 | "pop eax " 143 | "ret "_s 144 | ); 145 | 146 | using utils = declare_code; 150 | } 151 | } -------------------------------------------------------------------------------- /ctai/memory/memory.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/containers/values_container.hpp" 4 | #include "memory/memory_metadata.hpp" 5 | #include "values/values.hpp" 6 | 7 | #include 8 | #include 9 | 10 | namespace ctai 11 | { 12 | namespace memory 13 | { 14 | template 15 | using memory_block = values_container_n::values_container; 16 | 17 | template , 19 | typename metadata_type = metadata::create> 20 | struct memory 21 | { 22 | static constexpr auto size = size_v; 23 | using memory_block_t = memory_block_type; 24 | using metadata_t = metadata_type; 25 | }; 26 | 27 | template 28 | using memory_create = memory; 29 | 30 | template 31 | using set_memory_block = memory; 34 | 35 | template 36 | using set_metadata = memory; 39 | 40 | // 41 | //get_8 42 | // 43 | template 44 | constexpr auto get_8 = values_container_n::get_1; 45 | 46 | // 47 | //get_16 48 | // 49 | namespace details 50 | { 51 | template 52 | struct get_16_impl 53 | { 54 | using bytes = values_container_n::get_2; 55 | static constexpr auto result = values_container_n::bytes_to_value_2; 56 | }; 57 | } 58 | 59 | template 60 | constexpr auto get_16 = details::get_16_impl::result; 61 | 62 | // 63 | //get_32 64 | // 65 | namespace details 66 | { 67 | template 68 | struct get_32_impl 69 | { 70 | using bytes = values_container_n::get_4; 71 | static constexpr auto result = values_container_n::bytes_to_value_4; 72 | }; 73 | } 74 | 75 | template 76 | constexpr auto get_32 = details::get_32_impl::result; 77 | 78 | 79 | // 80 | //get 81 | // 82 | namespace details 83 | { 84 | template 85 | struct get_impl; 86 | 87 | template 88 | struct get_impl 89 | { 90 | static constexpr auto result = get_8; 91 | }; 92 | 93 | template 94 | struct get_impl 95 | { 96 | static constexpr auto result = get_16; 97 | }; 98 | 99 | template 100 | struct get_impl 101 | { 102 | static constexpr auto result = get_32; 103 | }; 104 | } 105 | 106 | template 107 | constexpr auto get = details::get_impl::result; 108 | 109 | 110 | namespace details 111 | { 112 | template 113 | struct set_impl 114 | { 115 | using splitted_value = values::split_to_byte_values_container(value)>; 116 | using new_block = values_container_n::set_from_container; 117 | 118 | using result = memory; 121 | }; 122 | } 123 | 124 | template 125 | using set_8 = typename details::set_impl::result; 126 | 127 | template 128 | using set_16 = typename details::set_impl::result; 129 | 130 | template 131 | using set_32 = typename details::set_impl::result; 132 | 133 | template 134 | using set = typename details::set_impl::result; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /ctai/execute/instructions/sys/ex_sys_create_thread.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctai/instructions/ids_vaules.hpp" 4 | #include "ctai/register.hpp" 5 | #include "ctai/memory/memory.hpp" 6 | #include "ctai/memory/memory_alloc.hpp" 7 | #include "values/values.hpp" 8 | #include "ctai/execute/eip_adjust.hpp" 9 | #include "ctai/thread/thread.hpp" 10 | #include "ctai/containers/queue.hpp" 11 | 12 | #include 13 | #include "ctai/machine/machine_state.hpp" 14 | 15 | namespace ctai 16 | { 17 | namespace execute2 18 | { 19 | namespace details 20 | { 21 | constexpr auto new_stack_size = 128; 22 | 23 | template 24 | struct ex_sys_create_thread_result 25 | { 26 | static constexpr auto ret_val = ret_val_v; 27 | using result_memory = memory_t; 28 | using result_threads_queue = threads_queue; 29 | }; 30 | 31 | template 32 | using ex_sys_create_thread_impl_no_enough_memory = ex_sys_create_thread_result; 33 | 34 | template 35 | struct ex_sys_create_thread_after_alloc 36 | { 37 | using registers = typename thread_t::registers; 38 | 39 | static constexpr auto starting_point = get_reg; 40 | static constexpr auto priority = get_reg; 41 | static constexpr auto args = get_reg; 42 | 43 | static constexpr auto new_thread_stack_start = allocated_stack_ptr + new_stack_size - 4; //-4 because there will be pointer to args 44 | 45 | using new_thread = thread::create; //esp 49 | 50 | using new_threads_queue = queue::push; 51 | using memory_after_args_set = memory::set_32; 52 | 53 | using result = ex_sys_create_thread_result; 54 | }; 55 | 56 | template 57 | struct ex_sys_create_thread_impl 58 | { 59 | using alloc_result = memory::alloc; 60 | 61 | using result = typename std::conditional_t, 63 | ex_sys_create_thread_after_alloc>::result; 68 | }; 69 | } 70 | 71 | //create_thread 72 | template 73 | struct ex_instruction, 76 | rest_of_opcodes...> 77 | { 78 | using create_result = typename details::ex_sys_create_thread_impl::result; 82 | 83 | using registers_after_ret_val_set = set_reg; 86 | 87 | using final_registers = adjust_eip; 88 | 89 | using result_thread = thread::set_registers; 90 | using result_machine_state = machine::state; 97 | }; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /examples/v2.0/multithread_fib_without_sync.cpp: -------------------------------------------------------------------------------- 1 | #include "ctai/execute/execute_code.hpp" 2 | #include "ctai/declare_code.hpp" 3 | #include "ctai/runtime/io.hpp" 4 | #include "kernel/thread.hpp" 5 | #include "kernel/io.hpp" 6 | #include "kernel/utils.hpp" 7 | #include "kernel/memory.hpp" 8 | #include "kernel/mutex.hpp" 9 | 10 | #include 11 | 12 | //eax - element to calculate 13 | using fibonacci = decltype( 14 | ":fibonacci " 15 | "push esi " 16 | "push ecx " 17 | "push edx " 18 | 19 | "mov ecx , eax " 20 | "cmp eax , 0 " 21 | "je .fib_ret_0 " 22 | 23 | "mov edx , 0 " 24 | "mov esi , 1 " 25 | 26 | ":fib_loop " 27 | "mov eax , esi " 28 | "add edx , eax " 29 | "mov esi , edx " 30 | "mov edx , eax " 31 | "dec ecx " 32 | "cmp ecx , 0 " 33 | "jne .fib_loop " 34 | "jmp .fib_end " 35 | 36 | ":fib_ret_0 " 37 | "mov eax , 0 " 38 | 39 | ":fib_end " 40 | "pop edx " 41 | "pop ecx " 42 | "pop esi " 43 | "ret "_s 44 | ); 45 | 46 | //eax - fibonacci element 47 | //ecx - result 48 | using write_result = decltype( 49 | ":write_result " 50 | "push ebx " 51 | "push edi " 52 | "push ebp " 53 | 54 | "sub esp , 30 "//esp - buffer ptr 55 | "mov edi , eax "//edi - fibonacci element 56 | "mov ebp , esp "//ebp - buffer ptr 57 | 58 | //we will write something like this: 59 | //fib(15) = 610 60 | //and the new line 61 | 62 | //this is ugly but ctai doesn't support static data definitions yet 63 | 64 | //write fib( 65 | "mov BYTE PTR [ ebp ] , 'f' " 66 | "mov BYTE PTR [ ebp + 1 ] , 'i' " 67 | "mov BYTE PTR [ ebp + 2 ] , 'b' " 68 | "mov BYTE PTR [ ebp + 3 ] , '(' " 69 | "mov BYTE PTR [ ebp + 4 ] , 0 " 70 | "mov eax , ebp " 71 | "call .write_string " 72 | 73 | 74 | //write element 75 | //convert to string 76 | "mov ebx , ebp "//ebx - buffer ptr 77 | "mov eax , edi "//eax - fibonacci element 78 | "call .uitoa " 79 | 80 | //write to stdout 81 | "mov eax , ebp "//eax - buffer ptr 82 | "call .write_string " 83 | 84 | 85 | //write ) = 86 | "mov BYTE PTR [ eax ] , ')' " 87 | "mov BYTE PTR [ eax + 1 ] , ' ' " 88 | "mov BYTE PTR [ eax + 2 ] , '=' " 89 | "mov BYTE PTR [ eax + 3 ] , ' ' " 90 | "mov BYTE PTR [ eax + 3 ] , ' ' " 91 | "mov BYTE PTR [ eax + 4 ] , 0 " 92 | "mov eax , ebp " 93 | "call .write_string " 94 | 95 | 96 | //write result 97 | //convert to string 98 | "mov ebx , ebp "//ebx - buffer ptr 99 | "mov eax , ecx "//eax - fibonacci result 100 | "call .uitoa " 101 | 102 | //write result to stdout 103 | "mov eax , ebp "//eax - buffer ptr 104 | "call .write_string " 105 | 106 | //write new line 107 | "mov al , 10 " 108 | "call .sys_write " 109 | 110 | "add esp , 30 " 111 | 112 | "pop ebp " 113 | "pop edi " 114 | "pop ebx " 115 | "ret "_s 116 | ); 117 | 118 | using slave_code = decltype( 119 | ":slave_code " 120 | "call .read_uint " //eax - element to calculate 121 | "mov edx , eax "//edx - fib element to calculate 122 | 123 | //calculate fibonacci element 124 | "mov eax , edx "//eax - fibonacci element to calculate 125 | "call .fibonacci "//eax - calculated fibonacci element 126 | 127 | "mov ecx , eax " //ecx - calculated fibonacci element 128 | "mov eax , edx "//eax - fibonacci element to calculate 129 | "call .write_result " 130 | 131 | "call .sys_exit_thread "_s 132 | ); 133 | 134 | using main_code = decltype( 135 | ":main " 136 | //prepare arguments to create slaves threads 137 | "mov ebx , .slave_code "//slave thread entry point 138 | "mov ecx , 50 " //slave thread priority 139 | "mov edx , 0 " //pointer to args 140 | 141 | //create two slaves 142 | "call .sys_create_thread " //eax - slave 1 id 143 | "mov edi , eax "//edi slave 1 id 144 | 145 | "call .sys_create_thread " //eax - slave 2 id 146 | 147 | //join the slaves 148 | "call .join_thread "//join thread 2 149 | 150 | "mov eax , edi "//eax - slave 1 id 151 | "call .join_thread "//join thread 1 152 | 153 | "call .sys_exit_thread "_s 154 | ); 155 | 156 | using code = ctai::declare_code; 164 | 165 | 166 | //program input - two fibonacci elements to calculate 167 | using input_t = decltype( 168 | "15 10 "_s 169 | ); 170 | 171 | using execution_result = ctai::execute2::execute_code; 172 | 173 | int main() 174 | { 175 | constexpr auto output = ctai::runtime::io::make_runtime_output(); 176 | 177 | std::cout << "Executed instructions: " << execution_result::ret_val << "\n"; 178 | 179 | std::cout << "execution output: \n"; 180 | 181 | for(auto c : output) 182 | std::cout< 28 | struct execute_impl; 29 | 30 | template 36 | struct execute_impl, //empty threads queue 39 | output_t, 40 | input_t, 41 | time_v, 42 | last_thread_id>> 43 | { 44 | using output = output_t; 45 | static constexpr auto ret_val = time_v; 46 | using result = execute_impl; 47 | }; 48 | 49 | template 50 | struct execute_impl 51 | { 52 | using scheduler_result = thread::schedule::next; 53 | using thread_to_execute = typename scheduler_result::result_thread; 54 | using machine_state_to_execute = machine::set_threads; 55 | using thread_execution_result = execute2::execute_thread; 58 | 59 | using threads_queue_after_execution = typename thread_execution_result::result_machine_state::threads; 60 | 61 | using next_threads_queue = std::conditional_t>; 65 | 66 | using next_machine_state = machine::set_threads_and_time; 69 | 70 | using result = typename execute_impl::result; 71 | }; 72 | } 73 | 74 | namespace details 75 | { 76 | template 77 | struct prepare_and_execute 78 | { 79 | using tokens = tokenize; 80 | using extract_labels_result = extract_labels; 81 | using tokens_without_labels = typename extract_labels_result::tokens; 82 | using labels_metadata = typename extract_labels_result::labels; 83 | using tokens_after_labels_substitution = substutite_labels; 84 | using opcodes_values_container = assemble; 85 | using opcodes_t = opcode::create_opcodes; 86 | 87 | static constexpr auto main_ip = labels_get_ip>; 88 | static constexpr auto memory_size = static_cast(400); 89 | 90 | using root_thread = thread::create<18, //priority 91 | 0, //id 92 | main_ip, //eip 93 | memory_size>; //esp 94 | 95 | using memory_t = memory::memory_create; 96 | 97 | using machine_state = machine::state, 100 | io::output::buffer<>, 101 | input_t, 102 | 0,//time 103 | 0>; //thread id counter 104 | 105 | using execute_result = typename execute_impl::result; 106 | 107 | using result = execution_result; 109 | }; 110 | } 111 | 112 | template 113 | using execute_code = typename details::prepare_and_execute::result; 114 | } 115 | } 116 | --------------------------------------------------------------------------------