GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — SimpleCodeVirtualizer/VirtualizationExample.cpp at main · AlSch092/SimpleCodeVirtualizer Expand file tree/ Copy pathVirtualizationExample.cppMore file actions 191 lines (164 loc) · 6.31 KB / Copy pathVirtualizationExample.cppFile metadata and controls191 lines (164 loc) · 6.31 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 //Experimental code virtualization - AlSch092 @ Github #include <iostream> #include "VirtualMachine.hpp" using namespace std; #define DEFAULT_STACK_SIZE 1024 VirtualMachine* machine = new VirtualMachine(DEFAULT_STACK_SIZE); //make global instance instead of making each routine need a parameter for this type /* Virtualized_AddIntegers - test for VM_PUSH, VM_ADD, VM_GET_TOP_STACK opcodes */ int Virtualized_AddIntegers() { UINT a = 10, b = 15, c = 0; #ifdef USING_OBFUSCATE UINT bytecode[] //while less space efficient, using default int size for each element instead of uint8_t allow us to pass local variables into the bytecode directly { (UINT)VM_Opcode::VM_PUSH OBFUSCATE, a , //only opcodes should be obfuscated right now (UINT)VM_Opcode::VM_PUSH OBFUSCATE, b , (UINT)VM_Opcode::VM_ADD OBFUSCATE, (UINT)VM_Opcode::VM_GET_TOP_STACK OBFUSCATE, (UINT)&c, (UINT)VM_Opcode::VM_END_FUNC OBFUSCATE }; #else UINT bytecode[] //while less space efficient, using default int size for each element instead of uint8_t allow us to pass local variables into the bytecode directly { (UINT)VM_Opcode::VM_PUSH, a, (UINT)VM_Opcode::VM_PUSH, b, (UINT)VM_Opcode::VM_ADD, (UINT)VM_Opcode::VM_GET_TOP_STACK, (UINT)& c, (UINT)VM_Opcode::VM_END_FUNC }; #endif if (machine->Execute(bytecode, sizeof(bytecode) / sizeof(UINT))) { cout << "Virtualized_AddIntegers - bytecode executed successfully" << endl; } else { cout << "Failed to execute bytecode, please ensure bytecode is properly structured and doesn't reference non-existing registers" << endl; } return c; } float Virtualized_AddFloat() { float a = 3.1415, b = 1.10, c = 0; #ifdef USING_OBFUSCATE UINT bytecode[] { (UINT)VM_Opcode::VM_PUSH OBFUSCATE, (UINT)0 , //only opcodes should be obfuscated right now (UINT)VM_Opcode::VM_PUSH OBFUSCATE, (UINT)0 , (UINT)VM_Opcode::VM_FL_ADD OBFUSCATE, (UINT)VM_Opcode::VM_GET_TOP_STACK OBFUSCATE, (UINT)&c, (UINT)VM_Opcode::VM_END_FUNC OBFUSCATE }; #else UINT bytecode[] { (UINT)VM_Opcode::VM_PUSH, a, (UINT)VM_Opcode::VM_PUSH, b, (UINT)VM_Opcode::VM_ADD, (UINT)VM_Opcode::VM_GET_TOP_STACK, (UINT)&c, (UINT)VM_Opcode::VM_END_FUNC }; #endif memcpy((void*)&bytecode[1], &a, sizeof(UINT)); //obviously using memcpy is not ideal for scalability, hopefully we'll figure out some elegant way to mix types in bytecode - possibly union types? memcpy((void*)&bytecode[3], &b, sizeof(UINT)); if (machine->Execute(bytecode, sizeof(bytecode) / sizeof(UINT))) { cout << "Virtualized_AddDouble - bytecode executed successfully" << endl; } else { cout << "Failed to execute bytecode, please ensure bytecode is properly structured and doesn't reference non-existing registers" << endl; } return c; } /* Virtualized_StdOut - test for VM_STDOUT opcode */ void Virtualized_StdOut() { const char* text = "Hello from called routine"; #ifdef USING_OBFUSCATE UINT bytecode[] { (UINT)VM_Opcode::VM_STDOUT OBFUSCATE, (UINT)text, (UINT)VM_Opcode::VM_END_FUNC OBFUSCATE }; #else UINT bytecode[] { (UINT)VM_Opcode::VM_STDOUT, (UINT)&text, (UINT)VM_Opcode::VM_END_FUNC }; #endif if (machine->Execute(bytecode, sizeof(bytecode) / sizeof(UINT))) { cout << "Virtualized_CalledRoutine - bytecode executed successfully" << endl; } else { cout << "Failed to execute bytecode, please ensure bytecode is properly structured and doesn't reference non-existing registers" << endl; } } /* Virtualized_CalledRoutine - routine to be called by Virtualized_CallRoutine to prove that VM_CALL opcode works */ template<typename ...Args> void Virtualized_CalledRoutine(Args ... vals) //routine called by Virtualized_CallRoutine { ((cout << "Hello from called routine - parameter val=" << vals << endl), ...); } /* Virtualized_CallRoutine - test for VM_CALL opcode */ void Virtualized_CallRoutine() { UINT a = 1000; //example parameters to be used in `Virtualized_CalledRoutine` UINT b = 2000; UINT c = 3000; UINT d = 4000; UINT e = 5000; //n-th parameter above 4 should go into rsp+20 + n*8 UINT f = 6000; using CalledRoutineType = void(*)(UINT, UINT, UINT, UINT, UINT, UINT); //for the sake of testing different # of parameters, we'll use a function template /w parameter pack CalledRoutineType funcPtr_pack = &Virtualized_CalledRoutine<UINT, UINT, UINT, UINT, UINT, UINT>; //forward declare a function pointer since we're using parameter pack, otherwise we will get a compile error UINT callAddress = (UINT) funcPtr_pack; #ifdef USING_OBFUSCATE UINT bytecode[] //while less space efficient, using default int size for each element instead of uint8_t allow us to pass local variables into the bytecode directly { (UINT)VM_Opcode::VM_PUSH OBFUSCATE, a, (UINT)VM_Opcode::VM_PUSH OBFUSCATE, b, (UINT)VM_Opcode::VM_PUSH OBFUSCATE, c, (UINT)VM_Opcode::VM_PUSH OBFUSCATE, d, (UINT)VM_Opcode::VM_PUSH OBFUSCATE, e, (UINT)VM_Opcode::VM_PUSH OBFUSCATE, f, (UINT)VM_Opcode::VM_CALL OBFUSCATE, 6, callAddress, //6 parameters (UINT)VM_Opcode::VM_END_FUNC OBFUSCATE }; #else UINT bytecode[] { (UINT)VM_Opcode::VM_PUSH, a, (UINT)VM_Opcode::VM_CALL, 1, callAddress, (UINT)VM_Opcode::VM_END_FUNC }; #endif if (machine->Execute(bytecode, sizeof(bytecode) / sizeof(UINT))) { cout << "Virtualized_CallRoutine - bytecode executed successfully" << endl; } else { cout << "Failed to execute bytecode, please ensure bytecode is properly structured and doesn't reference non-existing registers" << endl; } } int main() { int result = Virtualized_AddIntegers(); cout << "result=" << result << " after adding `a` to `b`" << endl; float result_f = Virtualized_AddFloat(); cout << "result_f=" << result_f << " after adding `a` to `b`" << endl; Virtualized_CallRoutine(); Virtualized_StdOut(); return 0; } |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |