/** * @file ScriptEngineEval.h * @author M.H. Gholamrezaei (gholamrezaei.mh@gmail.com) * @author Sina Karvandi (sina@rayanfam.com) * @author Alee Amini (aleeaminiz@gmail.com) * @brief Shared Headers for Script engine * @details * @version 0.1 * @date 2020-10-22 * * @copyright This project is released under the GNU Public License v3. * */ #pragma once /** * @brief global variable to save the result of script-engine statement * tests * */ UINT64 g_CurrentExprEvalResult; /** * @brief global variable to detect if there was an error in the result * of script-engine statement tests * */ BOOLEAN g_CurrentExprEvalResultHasError; #ifndef PacketChunkSize # define PacketChunkSize 3000 #endif // !PacketChunkSize // // Wrapper headers // #ifdef SCRIPT_ENGINE_KERNEL_MODE UINT64 ScriptEngineWrapperGetInstructionPointer(); UINT64 ScriptEngineWrapperGetAddressOfReservedBuffer(PDEBUGGER_EVENT_ACTION Action); BOOLEAN CheckMemoryAccessSafety(UINT64 TargetAddress, UINT32 Size); UINT32 VmxrootCompatibleStrlen(const CHAR * S); UINT32 VmxrootCompatibleWcslen(const wchar_t * S); BOOLEAN MemoryMapperReadMemorySafeOnTargetProcess(UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead); #endif // SCRIPT_ENGINE_KERNEL_MODE typedef unsigned long long QWORD; typedef unsigned __int64 UINT64, *PUINT64; typedef unsigned long DWORD; typedef int BOOL; typedef unsigned char BYTE; typedef unsigned short WORD; typedef int INT; typedef unsigned int UINT; typedef unsigned int * PUINT; typedef unsigned __int64 ULONG64, *PULONG64; typedef unsigned __int64 DWORD64, *PDWORD64; #define VOID void typedef char CHAR; typedef wchar_t WCHAR; typedef unsigned char UCHAR; typedef unsigned short USHORT; typedef unsigned long ULONG; typedef UCHAR BOOLEAN; // winnt typedef BOOLEAN * PBOOLEAN; // winnt typedef signed char INT8, *PINT8; typedef signed short INT16, *PINT16; typedef signed int INT32, *PINT32; typedef signed __int64 INT64, *PINT64; typedef unsigned char UINT8, *PUINT8; typedef unsigned short UINT16, *PUINT16; typedef unsigned int UINT32, *PUINT32; typedef unsigned __int64 UINT64, *PUINT64; #define FALSE 0 #define TRUE 1 #define UPPER_56_BITS 0xffffffffffffff00 #define UPPER_48_BITS 0xffffffffffff0000 #define UPPER_32_BITS 0xffffffff00000000 #define LOWER_32_BITS 0x00000000ffffffff #define LOWER_16_BITS 0x000000000000ffff #define LOWER_8_BITS 0x00000000000000ff #define SECOND_LOWER_8_BITS 0x000000000000ff00 #define UPPER_48_BITS_AND_LOWER_8_BITS 0xffffffffffff00ff /** * @brief EFLAGS/RFLAGS * */ #define X86_FLAGS_CF (1 << 0) #define X86_FLAGS_PF (1 << 2) #define X86_FLAGS_AF (1 << 4) #define X86_FLAGS_ZF (1 << 6) #define X86_FLAGS_SF (1 << 7) #define X86_FLAGS_TF (1 << 8) #define X86_FLAGS_IF (1 << 9) #define X86_FLAGS_DF (1 << 10) #define X86_FLAGS_OF (1 << 11) #define X86_FLAGS_STATUS_MASK (0xfff) #define X86_FLAGS_IOPL_MASK (3 << 12) #define X86_FLAGS_IOPL_SHIFT (12) #define X86_FLAGS_IOPL_SHIFT_2ND_BIT (13) #define X86_FLAGS_NT (1 << 14) #define X86_FLAGS_RF (1 << 16) #define X86_FLAGS_VM (1 << 17) #define X86_FLAGS_AC (1 << 18) #define X86_FLAGS_VIF (1 << 19) #define X86_FLAGS_VIP (1 << 20) #define X86_FLAGS_ID (1 << 21) #define X86_FLAGS_RESERVED_ONES 0x2 #define X86_FLAGS_RESERVED 0xffc0802a #define X86_FLAGS_RESERVED_BITS 0xffc38028 #define X86_FLAGS_FIXED 0x00000002 /** * @brief Integer gp registers (this structure is defined in * two places, make sure to change it in two places) * */ #ifndef GUEST_REGS_DEFINED # define GUEST_REGS_DEFINED typedef struct _GUEST_REGS { ULONG64 rax; // 0x00 ULONG64 rcx; // 0x08 ULONG64 rdx; // 0x10 ULONG64 rbx; // 0x18 ULONG64 rsp; // 0x20 ULONG64 rbp; // 0x28 ULONG64 rsi; // 0x30 ULONG64 rdi; // 0x38 ULONG64 r8; // 0x40 ULONG64 r9; // 0x48 ULONG64 r10; // 0x50 ULONG64 r11; // 0x58 ULONG64 r12; // 0x60 ULONG64 r13; // 0x68 ULONG64 r14; // 0x70 ULONG64 r15; // 0x78 } GUEST_REGS, *PGUEST_REGS; #endif #define LOWORD(l) ((WORD)(l)) #define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF)) #define LOBYTE(w) ((BYTE)(w)) #define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF)) #define MAX_TEMP_COUNT 32 // TODO: Extract number of variables from input of ScriptEngine // and allocate variableList Dynamically. #define MAX_VAR_COUNT 512 #define MAX_FUNCTION_NAME_LENGTH 32 ////////////////////////////////////////////////// // Imports // ////////////////////////////////////////////////// #ifdef SCRIPT_ENGINE_USER_MODE extern "C" { __declspec(dllimport) PSYMBOL_BUFFER ScriptEngineParse(char * str); __declspec(dllimport) void PrintSymbolBuffer(const PSYMBOL_BUFFER SymbolBuffer); __declspec(dllimport) void PrintSymbol(PSYMBOL Symbol); __declspec(dllimport) void RemoveSymbolBuffer(PSYMBOL_BUFFER SymbolBuffer); // // pdb parser // __declspec(dllimport) UINT64 ScriptEngineConvertNameToAddress(const char * FunctionOrVariableName, PBOOLEAN WasFound); __declspec(dllimport) UINT32 ScriptEngineLoadFileSymbol(UINT64 BaseAddress, const char * PdbFileName); __declspec(dllimport) UINT32 ScriptEngineUnloadAllSymbols(); __declspec(dllimport) UINT32 ScriptEngineUnloadModuleSymbol(char * ModuleName); __declspec(dllimport) UINT32 ScriptEngineSearchSymbolForMask(const char * SearchMask); __declspec(dllimport) BOOLEAN ScriptEngineConvertFileToPdbPath(const char * LocalFilePath, char * ResultPath); __declspec(dllimport) BOOLEAN ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails(const char * LocalFilePath, char * PdbFilePath, char * GuidAndAgeDetails); __declspec(dllimport) BOOLEAN ScriptEngineSymbolInitLoad(PVOID BufferToStoreDetails, UINT32 StoredLength, BOOLEAN DownloadIfAvailable, const char * SymbolPath, BOOLEAN IsSilentLoad); __declspec(dllimport) VOID ScriptEngineSymbolAbortLoading(); } #endif // SCRIPT_ENGINE_USER_MODE UINT64 GetValue(PGUEST_REGS GuestRegs, ACTION_BUFFER ActionBuffer, UINT64 * g_TempList, UINT64 * g_VariableList, PSYMBOL Symbol); // // *** Pseudo registers *** // // $tid UINT64 ScriptEnginePseudoRegGetTid() { #ifdef SCRIPT_ENGINE_USER_MODE return GetCurrentThreadId(); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return PsGetCurrentThreadId(); #endif // SCRIPT_ENGINE_KERNEL_MODE } // $core UINT64 ScriptEnginePseudoRegGetCore() { #ifdef SCRIPT_ENGINE_USER_MODE return GetCurrentProcessorNumber(); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return KeGetCurrentProcessorNumber(); #endif // SCRIPT_ENGINE_KERNEL_MODE } // $pid UINT64 ScriptEnginePseudoRegGetPid() { #ifdef SCRIPT_ENGINE_USER_MODE return GetCurrentProcessId(); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return PsGetCurrentProcessId(); #endif // SCRIPT_ENGINE_KERNEL_MODE } // $proc UINT64 ScriptEnginePseudoRegGetProc() { #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return PsGetCurrentProcess(); #endif // SCRIPT_ENGINE_KERNEL_MODE } // $thread UINT64 ScriptEnginePseudoRegGetThread() { #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return PsGetCurrentThread(); #endif // SCRIPT_ENGINE_KERNEL_MODE } // $peb UINT64 ScriptEnginePseudoRegGetPeb() { #ifdef SCRIPT_ENGINE_USER_MODE // // Hand-rolled structs ( may cause conflict depending on your dev env ) // struct PROCESS_BASIC_INFORMATION { PVOID Reserved1; PVOID PebBaseAddress; PVOID Reserved2[2]; ULONG_PTR UniqueProcessId; PVOID Reserved3; }; struct PEB_LDR_DATA { BYTE Reserved1[8]; PVOID Reserved2[3]; LIST_ENTRY InMemoryOrderModuleList; }; struct PEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2[1]; PVOID Reserved3[2]; struct PEB_LDR_DATA * Ldr; PVOID ProcessParameters; /* PRTL_USER_PROCESS_PARAMETERS */ BYTE Reserved4[104]; PVOID Reserved5[52]; PVOID PostProcessInitRoutine; /* PPS_POST_PROCESS_INIT_ROUTINE */ BYTE Reserved6[128]; PVOID Reserved7[1]; ULONG SessionId; }; struct UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; }; struct LDR_MODULE { LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID BaseAddress; PVOID EntryPoint; ULONG SizeOfImage; struct UNICODE_STRING FullDllName; struct UNICODE_STRING BaseDllName; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; LIST_ENTRY HashTableEntry; ULONG TimeDateStamp; }; enum PROCESSINFOCLASS { ProcessBasicInformation = 0, ProcessDebugPort = 7, ProcessWow64Information = 26, ProcessImageFileName = 27 }; LPCWSTR NTDLL_NAME = L"ntdll.dll"; LPCSTR NTQUERYINFO_NAME = "NtQueryInformationProcess"; HMODULE NtdllMod; HANDLE ThisProcess; NTSTATUS NtCallRet; ULONG BytesReturned; // // function pointer to house result from GetProcAddress // NTSTATUS(WINAPI * QueryInfoProcPtr) (HANDLE, enum PROCESSINFOCLASS, PVOID, ULONG, PULONG); struct PROCESS_BASIC_INFORMATION BasicInfo; struct PEB * PebPtr; struct LDR_MODULE * modPtr; /* retrieve pseudo-handle */ ThisProcess = GetCurrentProcess(); // // get address to already loaded module // NtdllMod = LoadLibraryW(NTDLL_NAME); // // get pointer to query function // QueryInfoProcPtr = (NTSTATUS(WINAPI *)(HANDLE, enum PROCESSINFOCLASS, PVOID, ULONG, PULONG))GetProcAddress(NtdllMod, NTQUERYINFO_NAME); // // call function on self; introspect // NtCallRet = QueryInfoProcPtr(ThisProcess, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), &BytesReturned); // // get peb ptr and decode some if its fields // PebPtr = (struct PEB *)BasicInfo.PebBaseAddress; return (UINT64)PebPtr; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE // // PEB doesn't make sense in kernel-mode // return NULL; #endif // SCRIPT_ENGINE_KERNEL_MODE } // $teb UINT64 ScriptEnginePseudoRegGetTeb() { #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return PsGetCurrentThreadTeb(); #endif // SCRIPT_ENGINE_KERNEL_MODE } // $ip UINT64 ScriptEnginePseudoRegGetIp() { #ifdef SCRIPT_ENGINE_USER_MODE // // $ip doesn't have meaning in user-moderds // return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return ScriptEngineWrapperGetInstructionPointer(); #endif // SCRIPT_ENGINE_KERNEL_MODE } // $buffer UINT64 ScriptEnginePseudoRegGetBuffer(UINT64 * CorrespondingAction) { #ifdef SCRIPT_ENGINE_USER_MODE // // $buffer doesn't mean anything in user-mode // return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return ScriptEngineWrapperGetAddressOfReservedBuffer(CorrespondingAction); #endif // SCRIPT_ENGINE_KERNEL_MODE } // // Check whether the address is valid or // BOOLEAN ScriptEngineCheckAddressValidity(PUINT64 Address, UINT32 Length) { #ifdef SCRIPT_ENGINE_USER_MODE // // Actually, there is no way to check this validity as it causes cpu // errors, so the only solution is using SEH which is stupid idea, // sure we don't want to create SEH frame each time we need to check // a function address, so I don't know what to do, let's return TRUE // for now // return TRUE; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE if (VirtualAddressToPhysicalAddress(Address) == 0) { return FALSE; } else { if (VirtualAddressToPhysicalAddress(Address + Length) == 0) { return FALSE; } else { return TRUE; } } #endif // SCRIPT_ENGINE_KERNEL_MODE } // // *** Keywords *** // // poi UINT64 ScriptEngineKeywordPoi(PUINT64 Address, BOOL * HasError) { UINT64 Result = NULL; #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!CheckMemoryAccessSafety(Address, sizeof(UINT64))) { *HasError = TRUE; return NULL; } #endif // SCRIPT_ENGINE_KERNEL_MODE #ifdef SCRIPT_ENGINE_USER_MODE Result = *Address; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperReadMemorySafeOnTargetProcess(Address, &Result, sizeof(UINT64)); #endif // SCRIPT_ENGINE_KERNEL_MODE return Result; } // hi WORD ScriptEngineKeywordHi(PUINT64 Address, BOOL * HasError) { QWORD Result = NULL; #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!CheckMemoryAccessSafety(Address, sizeof(UINT64))) { *HasError = TRUE; return NULL; } #endif // SCRIPT_ENGINE_KERNEL_MODE #ifdef SCRIPT_ENGINE_USER_MODE Result = *Address; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperReadMemorySafeOnTargetProcess(Address, &Result, sizeof(UINT64)); #endif // SCRIPT_ENGINE_KERNEL_MODE return HIWORD(Result); } // low WORD ScriptEngineKeywordLow(PUINT64 Address, BOOL * HasError) { QWORD Result = NULL; #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!CheckMemoryAccessSafety(Address, sizeof(UINT64))) { *HasError = TRUE; return NULL; } #endif // SCRIPT_ENGINE_KERNEL_MODE #ifdef SCRIPT_ENGINE_USER_MODE Result = *Address; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperReadMemorySafeOnTargetProcess(Address, &Result, sizeof(UINT64)); #endif // SCRIPT_ENGINE_KERNEL_MODE return LOWORD(Result); } // db BYTE ScriptEngineKeywordDb(PUINT64 Address, BOOL * HasError) { BYTE Result = NULL; #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!CheckMemoryAccessSafety(Address, sizeof(BYTE))) { *HasError = TRUE; return NULL; } #endif // SCRIPT_ENGINE_KERNEL_MODE #ifdef SCRIPT_ENGINE_USER_MODE Result = *Address; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperReadMemorySafeOnTargetProcess(Address, &Result, sizeof(BYTE)); #endif // SCRIPT_ENGINE_KERNEL_MODE return Result; } // dd WORD ScriptEngineKeywordDd(PUINT64 Address, BOOL * HasError) { WORD Result = NULL; #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!CheckMemoryAccessSafety(Address, sizeof(WORD))) { *HasError = TRUE; return NULL; } #endif // SCRIPT_ENGINE_KERNEL_MODE #ifdef SCRIPT_ENGINE_USER_MODE Result = *Address; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperReadMemorySafeOnTargetProcess(Address, &Result, sizeof(WORD)); #endif // SCRIPT_ENGINE_KERNEL_MODE return Result; } // dw DWORD ScriptEngineKeywordDw(PUINT64 Address, BOOL * HasError) { DWORD Result = NULL; #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!CheckMemoryAccessSafety(Address, sizeof(DWORD))) { *HasError = TRUE; return NULL; } #endif // SCRIPT_ENGINE_KERNEL_MODE #ifdef SCRIPT_ENGINE_USER_MODE Result = *Address; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperReadMemorySafeOnTargetProcess(Address, &Result, sizeof(DWORD)); #endif // SCRIPT_ENGINE_KERNEL_MODE return Result; } // dq QWORD ScriptEngineKeywordDq(PUINT64 Address, BOOL * HasError) { QWORD Result = NULL; #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!CheckMemoryAccessSafety(Address, sizeof(DWORD))) { *HasError = TRUE; return NULL; } #endif // SCRIPT_ENGINE_KERNEL_MODE #ifdef SCRIPT_ENGINE_USER_MODE Result = *Address; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperReadMemorySafeOnTargetProcess(Address, &Result, sizeof(QWORD)); #endif // SCRIPT_ENGINE_KERNEL_MODE return Result; } // // *** Functions *** // // eq BOOLEAN ScriptEngineFunctionEq(UINT64 Address, QWORD Value, BOOL * HasError) { #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!CheckMemoryAccessSafety(Address, sizeof(QWORD))) { // // Instead of indicating an error, just return false // to assign it as a return result to a variable // // *HasError = TRUE; return FALSE; } #endif // SCRIPT_ENGINE_KERNEL_MODE #ifdef SCRIPT_ENGINE_USER_MODE *(UINT64 *)Address = Value; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperWriteMemorySafeOnTargetProcess(Address, &Value, sizeof(QWORD)); #endif // SCRIPT_ENGINE_KERNEL_MODE return TRUE; } // ed BOOLEAN ScriptEngineFunctionEd(UINT64 Address, DWORD Value, BOOL * HasError) { #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!CheckMemoryAccessSafety(Address, sizeof(DWORD))) { // // Instead of indicating an error, just return false // to assign it as a return result to a variable // // *HasError = TRUE; return FALSE; } #endif // SCRIPT_ENGINE_KERNEL_MODE #ifdef SCRIPT_ENGINE_USER_MODE *(DWORD *)Address = Value; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperWriteMemorySafeOnTargetProcess(Address, &Value, sizeof(DWORD)); #endif // SCRIPT_ENGINE_KERNEL_MODE return TRUE; } // eb BOOLEAN ScriptEngineFunctionEb(UINT64 Address, BYTE Value, BOOL * HasError) { #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!CheckMemoryAccessSafety(Address, sizeof(BYTE))) { // // Instead of indicating an error, just return false // to assign it as a return result to a variable // // *HasError = TRUE; return FALSE; } #endif // SCRIPT_ENGINE_KERNEL_MODE #ifdef SCRIPT_ENGINE_USER_MODE *(BYTE *)Address = Value; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperWriteMemorySafeOnTargetProcess(Address, &Value, sizeof(BYTE)); #endif // SCRIPT_ENGINE_KERNEL_MODE return TRUE; } // print VOID ScriptEngineFunctionPrint(UINT64 Tag, BOOLEAN ImmediateMessagePassing, UINT64 Value) { #ifdef SCRIPT_ENGINE_USER_MODE ShowMessages("%llx\n", Value); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE LogSimpleWithTag(Tag, ImmediateMessagePassing, "%llx", Value); #endif // SCRIPT_ENGINE_KERNEL_MODE } VOID ScriptEngineFunctionTestStatement(UINT64 Tag, BOOLEAN ImmediateMessagePassing, UINT64 Value) { g_CurrentExprEvalResult = Value; g_CurrentExprEvalResultHasError = FALSE; } // // Spinlock functions // // spinlock_lock VOID ScriptEngineFunctionSpinlockLock(volatile LONG * Lock) { #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing on user-mode // return; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SpinlockLock(Lock); #endif // SCRIPT_ENGINE_KERNEL_MODE } // spinlock_unlock VOID ScriptEngineFunctionSpinlockUnlock(volatile LONG * Lock) { #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing on user-mode // return; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SpinlockUnlock(Lock); #endif // SCRIPT_ENGINE_KERNEL_MODE } // spinlock_lock_custom_wait VOID ScriptEngineFunctionSpinlockLockCustomWait(volatile long * Lock, unsigned MaxWait) { #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing on user-mode // return; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SpinlockLockWithCustomWait(Lock, MaxWait); #endif // SCRIPT_ENGINE_KERNEL_MODE } // // String length functions // // strlen UINT64 ScriptEngineFunctionStrlen(const char * Address) { UINT64 Result = 0; #ifdef SCRIPT_ENGINE_USER_MODE Result = strlen(Address); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE Result = VmxrootCompatibleStrlen(Address); #endif // SCRIPT_ENGINE_KERNEL_MODE return Result; } // wcslen UINT64 ScriptEngineFunctionWcslen(const wchar_t * Address) { UINT64 Result = 0; #ifdef SCRIPT_ENGINE_USER_MODE Result = wcslen(Address); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE Result = VmxrootCompatibleWcslen(Address); #endif // SCRIPT_ENGINE_KERNEL_MODE return Result; } // // Interlocked atomic functions // // interlocked_exchange long long ScriptEngineFunctionInterlockedExchange(long long volatile * Target, long long Value) { long long Result = 0; Result = InterlockedExchange64(Target, Value); return Result; } // interlocked_exchange_add long long ScriptEngineFunctionInterlockedExchangeAdd(long long volatile * Addend, long long Value) { long long Result = 0; Result = InterlockedExchangeAdd64(Addend, Value); return Result; } // interlocked_exchange_increment long long ScriptEngineFunctionInterlockedIncrement(long long volatile * Addend) { long long Result = 0; Result = InterlockedIncrement64(Addend); return Result; } // interlocked_exchange_decrement long long ScriptEngineFunctionInterlockedDecrement(long long volatile * Addend) { long long Result = 0; Result = InterlockedDecrement64(Addend); return Result; } // interlocked_compare_exchange long long ScriptEngineFunctionInterlockedCompareExchange( long long volatile * Destination, long long ExChange, long long Comperand) { long long Result = 0; Result = InterlockedCompareExchange64(Destination, ExChange, Comperand); return Result; } // enable_event VOID ScriptEngineFunctionEnableEvent(UINT64 Tag, BOOLEAN ImmediateMessagePassing, UINT64 Value) { #ifdef SCRIPT_ENGINE_USER_MODE ShowMessages("err, enabling events is not possible in user-mode\n"); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!DebuggerEnableEvent(Value + DebuggerEventTagStartSeed)) { LogInfo("Invalid tag id (%d).", Value); } #endif // SCRIPT_ENGINE_KERNEL_MODE } // disable_event VOID ScriptEngineFunctionDisableEvent(UINT64 Tag, BOOLEAN ImmediateMessagePassing, UINT64 Value) { #ifdef SCRIPT_ENGINE_USER_MODE ShowMessages("err, disabling events is not possible in user-mode\n"); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE if (!DebuggerDisableEvent(Value + DebuggerEventTagStartSeed)) { LogInfo("Invalid tag id (%d).", Value); } #endif // SCRIPT_ENGINE_KERNEL_MODE } // pause VOID ScriptEngineFunctionPause(UINT64 Tag, BOOLEAN ImmediateMessagePassing, PGUEST_REGS GuestRegs, UINT64 Context) { #ifdef SCRIPT_ENGINE_USER_MODE ShowMessages("err, breaking is not possible in user-mode\n"); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE // // pause(); function is only working when kernel debugger is working // it's not designed to work on vmi-mode (local debugging) // if (g_KernelDebuggerState) { DEBUGGER_TRIGGERED_EVENT_DETAILS ContextAndTag = {0}; UINT32 CurrentProcessorIndex = KeGetCurrentProcessorNumber(); if (g_GuestState[CurrentProcessorIndex].IsOnVmxRootMode) { // // The guest is already in vmx-root mode // Halt other cores // ContextAndTag.Tag = Tag; ContextAndTag.Context = Context; KdHandleBreakpointAndDebugBreakpoints( CurrentProcessorIndex, GuestRegs, DEBUGGEE_PAUSING_REASON_DEBUGGEE_EVENT_TRIGGERED, &ContextAndTag); } else { // // The guest is on vmx non-root mode, the first parameter // is context and the second parameter is tag // AsmVmxVmcall(VMCALL_VM_EXIT_HALT_SYSTEM_AS_A_RESULT_OF_TRIGGERING_EVENT, Context, Tag, 0); } } else { LogInfo("The 'pause();' function is called but you're not allowed to use it on vmi-mode (local debugging)"); } #endif // SCRIPT_ENGINE_KERNEL_MODE } VOID ScriptEngineFunctionFormats(UINT64 Tag, BOOLEAN ImmediateMessagePassing, UINT64 Value) { #ifdef SCRIPT_ENGINE_USER_MODE g_CurrentExprEvalResult = Value; g_CurrentExprEvalResultHasError = FALSE; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE if (g_KernelDebuggerState) { KdSendFormatsFunctionResult(Value); } else { LogSimpleWithTag(Tag, ImmediateMessagePassing, "%llx\n", Value); } #endif // SCRIPT_ENGINE_KERNEL_MODE } UINT32 CustomStrlen(UINT64 StrAddr, BOOLEAN IsWstring) { #ifdef SCRIPT_ENGINE_USER_MODE if (IsWstring) { return wcslen((const wchar_t *)StrAddr); } else { return strlen((const char *)StrAddr); } #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE if (IsWstring) { return VmxrootCompatibleWcslen((const wchar_t *)StrAddr); } else { return VmxrootCompatibleStrlen((const CHAR *)StrAddr); } #endif // SCRIPT_ENGINE_KERNEL_MODE } BOOLEAN CheckIfStringIsSafe(UINT64 StrAddr, BOOLEAN IsWstring) { #ifdef SCRIPT_ENGINE_USER_MODE return TRUE; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE // // At least two chars (wchar_t is 4 byte) // if (CheckMemoryAccessSafety(StrAddr, IsWstring ? 4 : 2)) { return TRUE; } else { return FALSE; } #endif // SCRIPT_ENGINE_KERNEL_MODE } VOID ApplyFormatSpecifier(const CHAR * CurrentSpecifier, CHAR * FinalBuffer, PUINT32 CurrentProcessedPositionFromStartOfFormat, PUINT32 CurrentPositionInFinalBuffer, UINT64 Val, UINT32 SizeOfFinalBuffer) { UINT32 TempBufferLen = 0; CHAR TempBuffer[50 + 1] = { 0}; // Maximum uint64_t is 18446744073709551615 + 1 thus its 20 character // for maximum buffer + 1 end char null but we alloc 50 to be sure *CurrentProcessedPositionFromStartOfFormat = *CurrentProcessedPositionFromStartOfFormat + strlen(CurrentSpecifier); sprintf(TempBuffer, CurrentSpecifier, Val); TempBufferLen = strlen(TempBuffer); // // Check final buffer capacity // if (*CurrentPositionInFinalBuffer + TempBufferLen > SizeOfFinalBuffer) { // // Over passed buffer // return; } memcpy(&FinalBuffer[*CurrentPositionInFinalBuffer], TempBuffer, TempBufferLen); *CurrentPositionInFinalBuffer = *CurrentPositionInFinalBuffer + TempBufferLen; } size_t WcharToChar(const wchar_t * src, char * dest, size_t dest_len) { wchar_t Code; size_t i; i = 0; while (src[i] != '\0' && i < (dest_len - 1)) { Code = src[i]; if (Code < 128) dest[i] = (char)Code; else { dest[i] = '?'; if (Code >= 0xD800 && Code <= 0xD8FF) { // // Lead surrogate, skip the next code unit, which is the trail // i++; } } i++; } return i - 1; } BOOLEAN ApplyStringFormatSpecifier(const CHAR * CurrentSpecifier, CHAR * FinalBuffer, PUINT32 CurrentProcessedPositionFromStartOfFormat, PUINT32 CurrentPositionInFinalBuffer, UINT64 Val, BOOLEAN IsWstring, UINT32 SizeOfFinalBuffer) { UINT32 StringSize; wchar_t WstrBuffer[50]; CHAR AsciiBuffer[sizeof(WstrBuffer) / 2]; UINT32 StringSizeInByte; /* because of wide-char */ UINT32 CountOfBlocks; UINT32 CountOfBytesToRead; UINT32 CopiedBlockLen; // // First we have to check if string is valid or not // if (!CheckIfStringIsSafe(Val, IsWstring)) { return FALSE; } // // get the length of the string (format) identifier // *CurrentProcessedPositionFromStartOfFormat += strlen(CurrentSpecifier); // // Get string len // StringSize = CustomStrlen(Val, IsWstring); // // Check final buffer capacity // if (*CurrentPositionInFinalBuffer + StringSize > SizeOfFinalBuffer) { // // Over passed buffer // return TRUE; } // // Move the buffer string into the target buffer // if (IsWstring) { // // Parse wstring // StringSizeInByte = StringSize * 2; /* because of wide-char */ // // compute the ceiling // if (StringSizeInByte % sizeof(WstrBuffer) == 0) { CountOfBlocks = StringSizeInByte / sizeof(WstrBuffer); } else { CountOfBlocks = (StringSizeInByte / sizeof(WstrBuffer)) + 1; } for (size_t i = 0; i < CountOfBlocks; i++) { // // Zero the buffers // RtlZeroMemory(WstrBuffer, sizeof(WstrBuffer)); RtlZeroMemory(AsciiBuffer, sizeof(AsciiBuffer)); // // Check for the last block // if (i == CountOfBlocks - 1) { // // A portion of block // #ifdef SCRIPT_ENGINE_USER_MODE memcpy(WstrBuffer, (void *)(Val + (i * sizeof(WstrBuffer))), StringSizeInByte % sizeof(WstrBuffer)); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperReadMemorySafeOnTargetProcess( (void *)(Val + (i * sizeof(WstrBuffer))), WstrBuffer, StringSizeInByte % sizeof(WstrBuffer)); #endif // SCRIPT_ENGINE_KERNEL_MODE } else { // // A complete block // #ifdef SCRIPT_ENGINE_USER_MODE memcpy(WstrBuffer, (void *)(Val + (i * sizeof(WstrBuffer))), sizeof(WstrBuffer)); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperReadMemorySafeOnTargetProcess( (void *)(Val + (i * sizeof(WstrBuffer))), WstrBuffer, sizeof(WstrBuffer)); #endif // SCRIPT_ENGINE_KERNEL_MODE } // // Here we have the filled WstrBuffer // We should convert WstrBuffer to AsciiBuffer // CopiedBlockLen = WcharToChar(WstrBuffer, AsciiBuffer, sizeof(AsciiBuffer) + 1); // // Now we should move the AsciiBuffer to the target buffer // (when we filled AsciiBuffer the memory here is safe so we // can use memcpy in both user-mode and vmx-root mode) // memcpy(&FinalBuffer[*CurrentPositionInFinalBuffer], (void *)AsciiBuffer, CopiedBlockLen + 1); *CurrentPositionInFinalBuffer += CopiedBlockLen + 1; } } else { // // Parse string // #ifdef SCRIPT_ENGINE_USER_MODE memcpy(&FinalBuffer[*CurrentPositionInFinalBuffer], (void *)Val, StringSize); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE MemoryMapperReadMemorySafeOnTargetProcess( Val, &FinalBuffer[*CurrentPositionInFinalBuffer], StringSize); #endif // SCRIPT_ENGINE_KERNEL_MODE *CurrentPositionInFinalBuffer += StringSize; } return TRUE; } VOID ScriptEngineFunctionPrintf(PGUEST_REGS GuestRegs, ACTION_BUFFER ActionDetail, UINT64 * g_TempList, UINT64 * g_VariableList, UINT64 Tag, BOOLEAN ImmediateMessagePassing, char * Format, UINT64 ArgCount, PSYMBOL FirstArg, BOOLEAN * HasError) { // // The printf function // char FinalBuffer[PacketChunkSize] = {0}; UINT32 CurrentPositionInFinalBuffer = 0; UINT32 CurrentProcessedPositionFromStartOfFormat = 0; BOOLEAN WithoutAnyFormatSpecifier = TRUE; UINT64 Val; UINT32 Position; UINT32 LenOfFormats = strlen(Format) + 1; PSYMBOL Symbol; *HasError = FALSE; for (int i = 0; i < ArgCount; i++) { WithoutAnyFormatSpecifier = FALSE; Symbol = FirstArg + i; // // Address is either wstring (%ws) or string (%s) // Position = (Symbol->Type >> 32) + 1; SYMBOL TempSymbol = {0}; memcpy(&TempSymbol, Symbol, sizeof(SYMBOL)); TempSymbol.Type &= 0x7fffffff; Val = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, &TempSymbol); CHAR PercentageChar = Format[Position]; /* printf("position = %d is %c%c \n", Position, PercentageChar, IndicatorChar1); */ if (CurrentProcessedPositionFromStartOfFormat != Position) { // // There is some strings before this format specifier // we should move it to the buffer // UINT32 StringLen = Position - CurrentProcessedPositionFromStartOfFormat; // // Check final buffer capacity // if (CurrentPositionInFinalBuffer + StringLen < sizeof(FinalBuffer)) { memcpy(&FinalBuffer[CurrentPositionInFinalBuffer], &Format[CurrentProcessedPositionFromStartOfFormat], StringLen); CurrentProcessedPositionFromStartOfFormat += StringLen; CurrentPositionInFinalBuffer += StringLen; } } // // Double check and apply // if (PercentageChar == '%') { // // Set first character of specifier // CHAR FormatSpecifier[5] = {0}; FormatSpecifier[0] = '%'; // // Read second char // CHAR IndicatorChar2 = Format[Position + 1]; // // Check if IndicatorChar2 is 2 character long or more // if (IndicatorChar2 == 'l' || IndicatorChar2 == 'w' || IndicatorChar2 == 'h') { // // Set second char in format specifier // FormatSpecifier[1] = IndicatorChar2; if (IndicatorChar2 == 'l' && Format[Position + 2] == 'l') { // // Set third character in format specifier "ll" // FormatSpecifier[2] = 'l'; // // Set last character // FormatSpecifier[3] = Format[Position + 3]; } else { // // Set last character // FormatSpecifier[2] = Format[Position + 2]; } } else { // // It's a one char specifier (Set last character) // FormatSpecifier[1] = IndicatorChar2; } // // Apply the specifier // if (!strncmp(FormatSpecifier, "%s", 2)) { // // for string // if (!ApplyStringFormatSpecifier( "%s", FinalBuffer, &CurrentProcessedPositionFromStartOfFormat, &CurrentPositionInFinalBuffer, Val, FALSE, sizeof(FinalBuffer))) { *HasError = TRUE; return; } } else if (!strncmp(FormatSpecifier, "%ls", 3) || !strncmp(FormatSpecifier, "%ws", 3)) { // // for wide string (not important if %ls or %ws , only the length is // important) // if (!ApplyStringFormatSpecifier( "%ws", FinalBuffer, &CurrentProcessedPositionFromStartOfFormat, &CurrentPositionInFinalBuffer, Val, TRUE, sizeof(FinalBuffer))) { *HasError = TRUE; return; } } else { ApplyFormatSpecifier(FormatSpecifier, FinalBuffer, &CurrentProcessedPositionFromStartOfFormat, &CurrentPositionInFinalBuffer, Val, sizeof(FinalBuffer)); } } } if (WithoutAnyFormatSpecifier) { // // Means that it's just a simple print without any format specifier // if (LenOfFormats < sizeof(FinalBuffer)) { memcpy(FinalBuffer, Format, LenOfFormats); } } else { // // Check if there is anything after the last format specifier // if (LenOfFormats > CurrentProcessedPositionFromStartOfFormat) { UINT32 RemainedLen = LenOfFormats - CurrentProcessedPositionFromStartOfFormat; if (CurrentPositionInFinalBuffer + RemainedLen < sizeof(FinalBuffer)) { memcpy(&FinalBuffer[CurrentPositionInFinalBuffer], &Format[CurrentProcessedPositionFromStartOfFormat], RemainedLen); } } } // // Print final result // #ifdef SCRIPT_ENGINE_USER_MODE printf("%s", FinalBuffer); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE LogSimpleWithTag(Tag, ImmediateMessagePassing, "%s", FinalBuffer); #endif // SCRIPT_ENGINE_KERNEL_MODE } UINT64 GetRegValue(PGUEST_REGS GuestRegs, REGS_ENUM RegId) { switch (RegId) { case REGISTER_RAX: return GuestRegs->rax; break; case REGISTER_EAX: return (GuestRegs->rax & LOWER_32_BITS); break; case REGISTER_AX: return (GuestRegs->rax & LOWER_16_BITS); break; case REGISTER_AH: return (GuestRegs->rax & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_AL: return (GuestRegs->rax & LOWER_8_BITS); break; case REGISTER_RCX: return GuestRegs->rcx; break; case REGISTER_ECX: return (GuestRegs->rcx & LOWER_32_BITS); break; case REGISTER_CX: return (GuestRegs->rcx & LOWER_16_BITS); break; case REGISTER_CH: return (GuestRegs->rcx & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_CL: return (GuestRegs->rcx & LOWER_8_BITS); break; case REGISTER_RDX: return GuestRegs->rdx; break; case REGISTER_EDX: return (GuestRegs->rdx & LOWER_32_BITS); break; case REGISTER_DX: return (GuestRegs->rdx & LOWER_16_BITS); break; case REGISTER_DH: return (GuestRegs->rdx & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_DL: return (GuestRegs->rdx & LOWER_8_BITS); break; case REGISTER_RBX: return GuestRegs->rbx; break; case REGISTER_EBX: return (GuestRegs->rbx & LOWER_32_BITS); break; case REGISTER_BX: return (GuestRegs->rbx & LOWER_16_BITS); break; case REGISTER_BH: return (GuestRegs->rbx & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_BL: return (GuestRegs->rbx & LOWER_8_BITS); break; case REGISTER_RSP: return GuestRegs->rsp; break; case REGISTER_ESP: return (GuestRegs->rsp & LOWER_32_BITS); break; case REGISTER_SP: return (GuestRegs->rsp & LOWER_16_BITS); break; case REGISTER_SPL: return (GuestRegs->rsp & LOWER_8_BITS); break; case REGISTER_RBP: return GuestRegs->rbp; break; case REGISTER_EBP: return (GuestRegs->rbp & LOWER_32_BITS); break; case REGISTER_BP: return (GuestRegs->rbp & LOWER_16_BITS); break; case REGISTER_BPL: return (GuestRegs->rbp & LOWER_8_BITS); break; case REGISTER_RSI: return GuestRegs->rsi; break; case REGISTER_ESI: return (GuestRegs->rsi & LOWER_32_BITS); break; case REGISTER_SI: return (GuestRegs->rsi & LOWER_16_BITS); break; case REGISTER_SIL: return (GuestRegs->rsi & LOWER_8_BITS); break; case REGISTER_RDI: return GuestRegs->rdi; break; case REGISTER_EDI: return (GuestRegs->rdi & LOWER_32_BITS); break; case REGISTER_DI: return (GuestRegs->rdi & LOWER_16_BITS); break; case REGISTER_DIL: return (GuestRegs->rdi & LOWER_8_BITS); break; case REGISTER_R8: return GuestRegs->r8; break; case REGISTER_R8D: return (GuestRegs->r8 & LOWER_32_BITS); break; case REGISTER_R8W: return (GuestRegs->r8 & LOWER_16_BITS); break; case REGISTER_R8H: return (GuestRegs->r8 & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_R8L: return (GuestRegs->r8 & LOWER_8_BITS); break; case REGISTER_R9: return GuestRegs->r9; break; case REGISTER_R9D: return (GuestRegs->r9 & LOWER_32_BITS); break; case REGISTER_R9W: return (GuestRegs->r9 & LOWER_16_BITS); break; case REGISTER_R9H: return (GuestRegs->r9 & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_R9L: return (GuestRegs->r9 & LOWER_8_BITS); break; case REGISTER_R10: return GuestRegs->r10; break; case REGISTER_R10D: return (GuestRegs->r10 & LOWER_32_BITS); break; case REGISTER_R10W: return (GuestRegs->r10 & LOWER_16_BITS); break; case REGISTER_R10H: return (GuestRegs->r10 & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_R10L: return (GuestRegs->r10 & LOWER_8_BITS); break; case REGISTER_R11: return GuestRegs->r11; break; case REGISTER_R11D: return (GuestRegs->r11 & LOWER_32_BITS); break; case REGISTER_R11W: return (GuestRegs->r11 & LOWER_16_BITS); break; case REGISTER_R11H: return (GuestRegs->r11 & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_R11L: return (GuestRegs->r11 & LOWER_8_BITS); break; case REGISTER_R12: return GuestRegs->r12; break; case REGISTER_R12D: return (GuestRegs->r12 & LOWER_32_BITS); break; case REGISTER_R12W: return (GuestRegs->r12 & LOWER_16_BITS); break; case REGISTER_R12H: return (GuestRegs->r12 & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_R12L: return (GuestRegs->r12 & LOWER_8_BITS); break; case REGISTER_R13: return GuestRegs->r13; break; case REGISTER_R13D: return (GuestRegs->r13 & LOWER_32_BITS); break; case REGISTER_R13W: return (GuestRegs->r13 & LOWER_16_BITS); break; case REGISTER_R13H: return (GuestRegs->r13 & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_R13L: return (GuestRegs->r13 & LOWER_8_BITS); break; case REGISTER_R14: return GuestRegs->r14; break; case REGISTER_R14D: return (GuestRegs->r14 & LOWER_32_BITS); break; case REGISTER_R14W: return (GuestRegs->r14 & LOWER_16_BITS); break; case REGISTER_R14H: return (GuestRegs->r14 & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_R14L: return (GuestRegs->r14 & LOWER_8_BITS); break; case REGISTER_R15: return GuestRegs->r15; break; case REGISTER_R15D: return (GuestRegs->r15 & LOWER_32_BITS); break; case REGISTER_R15W: return (GuestRegs->r15 & LOWER_16_BITS); break; case REGISTER_R15H: return (GuestRegs->r15 & SECOND_LOWER_8_BITS) >> 8; break; case REGISTER_R15L: return (GuestRegs->r15 & LOWER_8_BITS); break; case REGISTER_DS: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestDs().SEL; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_ES: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestEs().SEL; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_FS: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestFs().SEL; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_GS: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestGs().SEL; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CS: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestCs().SEL; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_SS: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestSs().SEL; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_RFLAGS: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestRFlags(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_EFLAGS: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & LOWER_32_BITS); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_FLAGS: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & LOWER_16_BITS); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CF: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & X86_FLAGS_CF) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_PF: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (0x1 << X86_FLAGS_PF)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_AF: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_AF)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_ZF: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_ZF)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_SF: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_SF)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_TF: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_TF)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_IF: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_IF)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DF: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_DF)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_OF: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_OF)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_IOPL: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return ((GetGuestRFlags() & (0b11 << X86_FLAGS_IOPL_SHIFT)) >> 12); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_NT: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_NT)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_RF: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_RF)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_VM: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_VM)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_AC: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_AC)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_VIF: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_VIF)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_VIP: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_VIP)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_ID: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRFlags() & (X86_FLAGS_ID)) != NULL ? TRUE : FALSE; #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_RIP: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestRIP(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_EIP: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRIP() & LOWER_32_BITS); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_IP: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return (GetGuestRIP() & LOWER_16_BITS); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_IDTR: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestIdtr(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_LDTR: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestLdtr(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_TR: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestTr(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_GDTR: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestGdtr(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CR0: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestCr0(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CR2: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestCr2(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CR3: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestCr3(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CR4: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestCr4(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CR8: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestCr8(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR0: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestDr0(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR1: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestDr1(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR2: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestDr2(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR3: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestDr3(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR6: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestDr6(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR7: #ifdef SCRIPT_ENGINE_USER_MODE return NULL; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE return GetGuestDr7(); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case INVALID: #ifdef SCRIPT_ENGINE_USER_MODE ShowMessages("error in reading register"); #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE LogInfo("Error in reading register"); #endif // SCRIPT_ENGINE_KERNEL_MODE return INVALID; break; } } UINT64 GetPseudoRegValue(PSYMBOL Symbol, ACTION_BUFFER ActionBuffer) { switch (Symbol->Value) { case PSEUDO_REGISTER_TID: return ScriptEnginePseudoRegGetTid(); case PSEUDO_REGISTER_PID: return ScriptEnginePseudoRegGetPid(); case PSEUDO_REGISTER_CORE: return ScriptEnginePseudoRegGetCore(); case PSEUDO_REGISTER_PROC: return ScriptEnginePseudoRegGetProc(); case PSEUDO_REGISTER_THREAD: return ScriptEnginePseudoRegGetThread(); case PSEUDO_REGISTER_PEB: return ScriptEnginePseudoRegGetPeb(); case PSEUDO_REGISTER_TEB: return ScriptEnginePseudoRegGetTeb(); case PSEUDO_REGISTER_IP: return ScriptEnginePseudoRegGetIp(); case PSEUDO_REGISTER_BUFFER: if (ActionBuffer.CurrentAction != NULL) { return ScriptEnginePseudoRegGetBuffer( (UINT64 *)ActionBuffer.CurrentAction); } else { return NULL; } case PSEUDO_REGISTER_CONTEXT: return ActionBuffer.Context; case INVALID: #ifdef SCRIPT_ENGINE_USER_MODE ShowMessages("error in reading regesiter"); #endif // SCRIPT_ENGINE_USER_MODE return INVALID; // TODO: Add all the register } } UINT64 GetValue(PGUEST_REGS GuestRegs, ACTION_BUFFER ActionBuffer, UINT64 * g_TempList, UINT64 * g_VariableList, PSYMBOL Symbol) { switch (Symbol->Type) { case SYMBOL_ID_TYPE: return g_VariableList[Symbol->Value]; case SYMBOL_NUM_TYPE: return Symbol->Value; case SYMBOL_REGISTER_TYPE: return GetRegValue(GuestRegs, (REGS_ENUM)Symbol->Value); case SYMBOL_PSEUDO_REG_TYPE: return GetPseudoRegValue(Symbol, ActionBuffer); case SYMBOL_TEMP_TYPE: return g_TempList[Symbol->Value]; } } VOID SetRegValue(PGUEST_REGS GuestRegs, PSYMBOL Symbol, UINT64 Value) { switch (Symbol->Value) { case REGISTER_RAX: GuestRegs->rax = Value; break; case REGISTER_EAX: GuestRegs->rax = (GuestRegs->rax & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_AX: GuestRegs->rax = (GuestRegs->rax & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_AH: GuestRegs->rax = (GuestRegs->rax & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_AL: GuestRegs->rax = (GuestRegs->rax & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_RCX: GuestRegs->rcx = Value; break; case REGISTER_ECX: GuestRegs->rcx = (GuestRegs->rcx & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_CX: GuestRegs->rcx = (GuestRegs->rcx & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_CH: GuestRegs->rcx = (GuestRegs->rcx & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_CL: GuestRegs->rcx = (GuestRegs->rcx & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_RDX: GuestRegs->rdx = Value; break; case REGISTER_EDX: GuestRegs->rdx = (GuestRegs->rdx & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_DX: GuestRegs->rdx = (GuestRegs->rdx & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_DH: GuestRegs->rdx = (GuestRegs->rdx & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_DL: GuestRegs->rdx = (GuestRegs->rdx & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_RBX: GuestRegs->rbx = Value; break; case REGISTER_EBX: GuestRegs->rbx = (GuestRegs->rbx & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_BX: GuestRegs->rbx = (GuestRegs->rbx & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_BH: GuestRegs->rbx = (GuestRegs->rbx & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_BL: GuestRegs->rbx = (GuestRegs->rbx & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_RSP: #ifdef SCRIPT_ENGINE_USER_MODE GuestRegs->rsp = Value; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE GuestRegs->rsp = Value; SetGuestRSP(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_ESP: #ifdef SCRIPT_ENGINE_USER_MODE GuestRegs->rsp = Value; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE GuestRegs->rsp = (GuestRegs->rsp & UPPER_32_BITS) | (Value & LOWER_32_BITS); SetGuestRSP(GuestRegs->rsp); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_SP: #ifdef SCRIPT_ENGINE_USER_MODE GuestRegs->rsp = Value; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE GuestRegs->rsp = (GuestRegs->rsp & UPPER_48_BITS) | (Value & LOWER_16_BITS); SetGuestRSP(GuestRegs->rsp); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_SPL: #ifdef SCRIPT_ENGINE_USER_MODE GuestRegs->rsp = Value; #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE GuestRegs->rsp = (GuestRegs->rsp & UPPER_56_BITS) | (Value & LOWER_8_BITS); SetGuestRSP(GuestRegs->rsp); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_RBP: GuestRegs->rbp = Value; break; case REGISTER_EBP: GuestRegs->rbp = (GuestRegs->rbp & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_BP: GuestRegs->rbp = (GuestRegs->rbp & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_BPL: GuestRegs->rbp = (GuestRegs->rbp & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_RSI: GuestRegs->rsi = Value; break; case REGISTER_ESI: GuestRegs->rsi = (GuestRegs->rsi & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_SI: GuestRegs->rsi = (GuestRegs->rsi & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_SIL: GuestRegs->rsi = (GuestRegs->rsi & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_RDI: GuestRegs->rdi = Value; break; case REGISTER_EDI: GuestRegs->rdi = (GuestRegs->rdi & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_DI: GuestRegs->rdi = (GuestRegs->rdi & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_DIL: GuestRegs->rdi = (GuestRegs->rdi & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_R8: GuestRegs->r8 = Value; break; case REGISTER_R8D: GuestRegs->r8 = (GuestRegs->r8 & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_R8W: GuestRegs->r8 = (GuestRegs->r8 & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_R8H: GuestRegs->r8 = (GuestRegs->r8 & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_R8L: GuestRegs->r8 = (GuestRegs->r8 & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_R9: GuestRegs->r9 = Value; break; case REGISTER_R9D: GuestRegs->r9 = (GuestRegs->r9 & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_R9W: GuestRegs->r9 = (GuestRegs->r9 & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_R9H: GuestRegs->r9 = (GuestRegs->r9 & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_R9L: GuestRegs->r9 = (GuestRegs->r9 & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_R10: GuestRegs->r10 = Value; break; case REGISTER_R10D: GuestRegs->r10 = (GuestRegs->r10 & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_R10W: GuestRegs->r10 = (GuestRegs->r10 & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_R10H: GuestRegs->r10 = (GuestRegs->r10 & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_R10L: GuestRegs->r10 = (GuestRegs->r10 & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_R11: GuestRegs->r11 = Value; break; case REGISTER_R11D: GuestRegs->r11 = (GuestRegs->r11 & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_R11W: GuestRegs->r11 = (GuestRegs->r11 & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_R11H: GuestRegs->r11 = (GuestRegs->r11 & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_R11L: GuestRegs->r11 = (GuestRegs->r11 & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_R12: GuestRegs->r12 = Value; break; case REGISTER_R12D: GuestRegs->r12 = (GuestRegs->r12 & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_R12W: GuestRegs->r12 = (GuestRegs->r12 & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_R12H: GuestRegs->r12 = (GuestRegs->r12 & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_R12L: GuestRegs->r12 = (GuestRegs->r12 & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_R13: GuestRegs->r13 = Value; break; case REGISTER_R13D: GuestRegs->r13 = (GuestRegs->r13 & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_R13W: GuestRegs->r13 = (GuestRegs->r13 & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_R13H: GuestRegs->r13 = (GuestRegs->r13 & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_R13L: GuestRegs->r13 = (GuestRegs->r13 & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_R14: GuestRegs->r14 = Value; break; case REGISTER_R14D: GuestRegs->r14 = (GuestRegs->r14 & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_R14W: GuestRegs->r14 = (GuestRegs->r14 & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_R14H: GuestRegs->r14 = (GuestRegs->r14 & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_R14L: GuestRegs->r14 = (GuestRegs->r14 & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_R15: GuestRegs->r15 = Value; break; case REGISTER_R15D: GuestRegs->r15 = (GuestRegs->r15 & UPPER_32_BITS) | (Value & LOWER_32_BITS); break; case REGISTER_R15W: GuestRegs->r15 = (GuestRegs->r15 & UPPER_48_BITS) | (Value & LOWER_16_BITS); break; case REGISTER_R15H: GuestRegs->r15 = (GuestRegs->r15 & UPPER_48_BITS_AND_LOWER_8_BITS) | ((Value << 8) & SECOND_LOWER_8_BITS); break; case REGISTER_R15L: GuestRegs->r15 = (GuestRegs->r15 & UPPER_56_BITS) | (Value & LOWER_8_BITS); break; case REGISTER_DS: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE Value = Value & LOWER_16_BITS; SetGuestDsSel((PSEGMENT_SELECTOR)&Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_ES: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE Value = Value & LOWER_16_BITS; SetGuestEsSel((PSEGMENT_SELECTOR)&Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_FS: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE Value = Value & LOWER_16_BITS; SetGuestFsSel((PSEGMENT_SELECTOR)&Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_GS: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE Value = Value & LOWER_16_BITS; SetGuestGsSel((PSEGMENT_SELECTOR)&Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CS: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE Value = Value & LOWER_16_BITS; SetGuestCsSel((PSEGMENT_SELECTOR)&Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_SS: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE Value = Value & LOWER_16_BITS; SetGuestSsSel((PSEGMENT_SELECTOR)&Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_RFLAGS: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_EFLAGS: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags((GetGuestRFlags() & UPPER_32_BITS) | (Value & LOWER_32_BITS)); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_FLAGS: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags((GetGuestRFlags() & UPPER_48_BITS) | (Value & LOWER_16_BITS)); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CF: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_CF) : GetGuestRFlags() & (~(X86_FLAGS_CF))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_PF: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_PF) : GetGuestRFlags() & (~(X86_FLAGS_PF << 2))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_AF: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_AF) : GetGuestRFlags() & (~(X86_FLAGS_AF))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_ZF: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_ZF) : GetGuestRFlags() & (~(X86_FLAGS_ZF))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_SF: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_SF) : GetGuestRFlags() & (~(X86_FLAGS_SF))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_TF: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_TF) : GetGuestRFlags() & (~(X86_FLAGS_TF))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_IF: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_IF) : GetGuestRFlags() & (~(X86_FLAGS_IF))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DF: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_DF) : GetGuestRFlags() & (~(X86_FLAGS_DF))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_OF: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_OF) : GetGuestRFlags() & (~(X86_FLAGS_OF))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_IOPL: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (1 << X86_FLAGS_IOPL_SHIFT) : GetGuestRFlags() & (~(1 << X86_FLAGS_IOPL_SHIFT))); SetGuestRFlags(Value & 0x2 ? GetGuestRFlags() | (1 << X86_FLAGS_IOPL_SHIFT_2ND_BIT) : GetGuestRFlags() & (~(1 << X86_FLAGS_IOPL_SHIFT_2ND_BIT))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_NT: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_NT) : GetGuestRFlags() & (~(X86_FLAGS_NT))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_RF: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_RF) : GetGuestRFlags() & (~(X86_FLAGS_RF))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_VM: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_VM) : GetGuestRFlags() & (~(X86_FLAGS_VM))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_AC: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_AC) : GetGuestRFlags() & (~(X86_FLAGS_AC))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_VIF: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_VIF) : GetGuestRFlags() & (~(X86_FLAGS_VIF))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_VIP: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_VIP) : GetGuestRFlags() & (~(X86_FLAGS_VIP))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_ID: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRFlags(Value & TRUE ? GetGuestRFlags() | (X86_FLAGS_ID) : GetGuestRFlags() & (~(X86_FLAGS_ID))); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_RIP: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRIP(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_EIP: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRIP((GetGuestRIP() & UPPER_32_BITS) | (Value & LOWER_32_BITS)); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_IP: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestRIP((GetGuestRIP() & UPPER_48_BITS) | (Value & LOWER_16_BITS)); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_IDTR: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestIdtr(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_LDTR: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestLdtr(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_GDTR: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestGdtr(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_TR: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestTr(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CR0: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestCr0(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CR2: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestCr2(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CR3: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestCr3(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CR4: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestCr4(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_CR8: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestCr8(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR0: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestDr0(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR1: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestDr1(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR2: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestDr2(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR3: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestDr3(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR6: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestDr6(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; case REGISTER_DR7: #ifdef SCRIPT_ENGINE_USER_MODE // // Nothing to do // #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE SetGuestDr7(Value); #endif // SCRIPT_ENGINE_KERNEL_MODE break; } } VOID SetValue(PGUEST_REGS GuestRegs, UINT64 * g_TempList, UINT64 * g_VariableList, PSYMBOL Symbol, UINT64 Value) { switch (Symbol->Type) { case SYMBOL_ID_TYPE: g_VariableList[Symbol->Value] = Value; return; case SYMBOL_TEMP_TYPE: g_TempList[Symbol->Value] = Value; return; case SYMBOL_REGISTER_TYPE: SetRegValue(GuestRegs, Symbol, Value); return; } } VOID ScriptEngineGetOperatorName(PSYMBOL OperatorSymbol, CHAR * BufferForName) { switch (OperatorSymbol->Value) { case FUNC_POI: memcpy(BufferForName, "poi", 3); break; case FUNC_DB: memcpy(BufferForName, "db", 2); break; case FUNC_DD: memcpy(BufferForName, "dd", 2); break; case FUNC_DW: memcpy(BufferForName, "dw", 2); break; case FUNC_DQ: memcpy(BufferForName, "dq", 2); break; case FUNC_HI: memcpy(BufferForName, "hi", 2); break; case FUNC_LOW: memcpy(BufferForName, "low", 3); break; default: memcpy(BufferForName, "error", 5); break; } } BOOL ScriptEngineExecute(PGUEST_REGS GuestRegs, ACTION_BUFFER ActionDetail, UINT64 * g_TempList, UINT64 * g_VariableList, PSYMBOL_BUFFER CodeBuffer, int * Indx, PSYMBOL ErrorOperator) { PSYMBOL Operator; PSYMBOL Src0; PSYMBOL Src1; PSYMBOL Src2; PSYMBOL Des; UINT64 SrcVal0; UINT64 SrcVal1; UINT64 SrcVal2; UINT64 DesVal; BOOL HasError = FALSE; Operator = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *ErrorOperator = *Operator; *Indx = *Indx + 1; if (Operator->Type != SYMBOL_SEMANTIC_RULE_TYPE) { #ifdef SCRIPT_ENGINE_USER_MODE ShowMessages("err, expecting operator type\n"); return HasError; #endif // SCRIPT_ENGINE_USER_MODE }; switch (Operator->Value) { case FUNC_ED: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineFunctionEd(SrcVal1, SrcVal0, &HasError); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_EB: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineFunctionEb(SrcVal1, SrcVal0, &HasError); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_EQ: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineFunctionEq(SrcVal1, SrcVal0, &HasError); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_INTERLOCKED_EXCHANGE: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineFunctionInterlockedExchange((volatile long long *)SrcVal1, SrcVal0); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_INTERLOCKED_EXCHANGE_ADD: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineFunctionInterlockedExchangeAdd((volatile long long *)SrcVal1, SrcVal0); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_INTERLOCKED_COMPARE_EXCHANGE: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Src2 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal2 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineFunctionInterlockedCompareExchange((volatile long long *)SrcVal2, SrcVal1, SrcVal0); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_SPINLOCK_LOCK_CUSTOM_WAIT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); ScriptEngineFunctionSpinlockLockCustomWait((volatile long *)SrcVal1, SrcVal0); return HasError; case FUNC_PAUSE: ScriptEngineFunctionPause(ActionDetail.Tag, ActionDetail.ImmediatelySendTheResults, GuestRegs, ActionDetail.Context); return HasError; case FUNC_OR: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 | SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_INC: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); DesVal = SrcVal0 + 1; Des = Src0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_DEC: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); DesVal = SrcVal0 - 1; Des = Src0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_XOR: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 ^ SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_AND: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 & SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_ASR: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 >> SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_ASL: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 << SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_ADD: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 + SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_SUB: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 - SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_MUL: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 * SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_DIV: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; if (SrcVal0 == 0) { HasError = TRUE; return HasError; } DesVal = SrcVal1 / SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_MOD: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; if (SrcVal0 == 0) { HasError = TRUE; return HasError; } DesVal = SrcVal1 % SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_GT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 > SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_LT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 < SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_EGT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 >= SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_ELT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 <= SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_EQUAL: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 == SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_NEQ: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal1 != SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_POI: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineKeywordPoi((PUINT64)GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0), &HasError); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_DB: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineKeywordDb((PUINT64)GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0), &HasError); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_DW: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineKeywordDb((PUINT64)GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0), &HasError); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_DQ: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineKeywordDq((PUINT64)GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0), &HasError); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_NOT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ~SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_CHECK_ADDRESS: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; #ifdef SCRIPT_ENGINE_USER_MODE DesVal = 1; // TRUE by default in user-mode #endif // SCRIPT_ENGINE_USER_MODE #ifdef SCRIPT_ENGINE_KERNEL_MODE if (CheckMemoryAccessSafety(SrcVal0, sizeof(BYTE))) { DesVal = 1; // TRUE } else { DesVal = 0; // FALSE } #endif // SCRIPT_ENGINE_KERNEL_MODE #ifdef SCRIPT_ENGINE_USER_MODE DesVal = 1; // TRUE by default in user-mode #endif // SCRIPT_ENGINE_USER_MODE SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_STRLEN: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineFunctionStrlen((const char *)SrcVal0); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_WCSLEN: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineFunctionWcslen((const wchar_t *)SrcVal0); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_INTERLOCKED_EXCHANGE_INCREMENT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineFunctionInterlockedIncrement((volatile long long *)SrcVal0); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_INTERLOCKED_EXCHANGE_DECREMENT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineFunctionInterlockedDecrement((volatile long long *)SrcVal0); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_NEG: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = -(INT64)SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_HI: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineKeywordHi((PUINT64)GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0), &HasError); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_LOW: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = ScriptEngineKeywordLow((PUINT64)GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0), &HasError); SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_MOV: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Des = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; DesVal = SrcVal0; SetValue(GuestRegs, g_TempList, g_VariableList, Des, DesVal); return HasError; case FUNC_PRINT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); // // Call the target function // ScriptEngineFunctionPrint(ActionDetail.Tag, ActionDetail.ImmediatelySendTheResults, SrcVal0); return HasError; case FUNC_TEST_STATEMENT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); // // Call the target function // ScriptEngineFunctionTestStatement(ActionDetail.Tag, ActionDetail.ImmediatelySendTheResults, SrcVal0); return HasError; case FUNC_SPINLOCK_LOCK: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); // // Call the target function // ScriptEngineFunctionSpinlockLock((volatile LONG *)SrcVal0); return HasError; case FUNC_SPINLOCK_UNLOCK: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); // // Call the target function // ScriptEngineFunctionSpinlockUnlock((volatile LONG *)SrcVal0); return HasError; case FUNC_DISABLE_EVENT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); ScriptEngineFunctionDisableEvent( ActionDetail.Tag, ActionDetail.ImmediatelySendTheResults, SrcVal0); return HasError; case FUNC_ENABLE_EVENT: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); ScriptEngineFunctionEnableEvent( ActionDetail.Tag, ActionDetail.ImmediatelySendTheResults, SrcVal0); return HasError; case FUNC_FORMATS: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); // // Call the target function // ScriptEngineFunctionFormats( ActionDetail.Tag, ActionDetail.ImmediatelySendTheResults, SrcVal0); return HasError; case (FUNC_JZ): Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); if (SrcVal1 == 0) { *Indx = SrcVal0; } return HasError; case (FUNC_JNZ): Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal1 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src1); if (SrcVal1 != 0) { *Indx = SrcVal0; } return HasError; case (FUNC_JMP): Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; SrcVal0 = GetValue(GuestRegs, ActionDetail, g_TempList, g_VariableList, Src0); *Indx = SrcVal0; return HasError; case FUNC_PRINTF: Src0 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; // // Call the target function // *Indx = *Indx + ((sizeof(unsigned long long) + strlen((char *)&Src0->Value)) / sizeof(SYMBOL)); Src1 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + 1; PSYMBOL Src2 = NULL; if (Src1->Value > 0) { Src2 = (PSYMBOL)((unsigned long long)CodeBuffer->Head + (unsigned long long)(*Indx * sizeof(SYMBOL))); *Indx = *Indx + Src1->Value; } ScriptEngineFunctionPrintf( GuestRegs, ActionDetail, g_TempList, g_VariableList, ActionDetail.Tag, ActionDetail.ImmediatelySendTheResults, (char *)&Src0->Value, Src1->Value, Src2, (BOOLEAN *)&HasError); return HasError; } }