diff --git a/hyperdbg/ScriptEngine/ScriptEngine.sln b/hyperdbg/ScriptEngine/ScriptEngine.sln
new file mode 100644
index 00000000..8d5104f4
--- /dev/null
+++ b/hyperdbg/ScriptEngine/ScriptEngine.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30320.27
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ScriptEngine", "ScriptEngine.vcxproj", "{C2D44C60-3F23-4972-8F60-21083B9FB112}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Debug|x64.ActiveCfg = Debug|x64
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Debug|x64.Build.0 = Debug|x64
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Release|x64.ActiveCfg = Release|x64
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {63144D94-C02B-4949-9356-0CFE750E5558}
+ EndGlobalSection
+EndGlobal
diff --git a/hyperdbg/ScriptEngine/ScriptEngine.vcxproj b/hyperdbg/ScriptEngine/ScriptEngine.vcxproj
new file mode 100644
index 00000000..b4f88601
--- /dev/null
+++ b/hyperdbg/ScriptEngine/ScriptEngine.vcxproj
@@ -0,0 +1,196 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {c2d44c60-3f23-4972-8f60-21083b9fb112}
+ ScriptEngine
+ 10.0
+
+
+
+ DynamicLibrary
+ true
+ v142
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v142
+ true
+ Unicode
+
+
+ DynamicLibrary
+ true
+ v142
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\Debug\
+
+
+ false
+ $(ProjectDir)..\build\Debug
+
+
+ true
+ $(SolutionDir)\build\Debug\
+
+
+ false
+ $(SolutionDir)\build\Release\
+
+
+
+ Level3
+ true
+ _CRT_SECURE_NO_WARNINGS;SCRIPTENGINE_EXPORTS
+ true
+ NotUsing
+ pch.h
+ MultiThreadedDebug
+
+
+ Windows
+ true
+ false
+
+
+ xcopy /y /d "D:\worktable\ScriptEngine\ScriptEngine\build\Debug\ScriptEngine.dll" "D:\worktable\ScriptEngine\ScriptEngineEmulator\x64\Debug"
+
+
+
+
+ Level3
+ true
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;SCRIPTENGINE_EXPORTS
+ true
+ NotUsing
+ pch.h
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+ false
+
+
+ xcopy /y /d $(ProjectDir)\build\Debug\ScriptEngine.dll $(ProjectDir)\..\ScriptEngineEmulator\x64\Debug
+
+
+
+
+ Level3
+ true
+ _CRT_SECURE_NO_WARNINGS;SCRIPTENGINE_EXPORTS
+ true
+ NotUsing
+ pch.h
+ MultiThreadedDebug
+
+
+ Windows
+ true
+ false
+
+
+
+
+
+
+
+
+ Level3
+ true
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;SCRIPTENGINE_EXPORTS
+ true
+ NotUsing
+ pch.h
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/ScriptEngine/ScriptEngine.vcxproj.filters b/hyperdbg/ScriptEngine/ScriptEngine.vcxproj.filters
new file mode 100644
index 00000000..1528f8f2
--- /dev/null
+++ b/hyperdbg/ScriptEngine/ScriptEngine.vcxproj.filters
@@ -0,0 +1,48 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/hyperdbg/ScriptEngine/dllmain.cpp b/hyperdbg/ScriptEngine/dllmain.cpp
new file mode 100644
index 00000000..ec23ae99
--- /dev/null
+++ b/hyperdbg/ScriptEngine/dllmain.cpp
@@ -0,0 +1,19 @@
+// dllmain.cpp : Defines the entry point for the DLL application.
+#include "pch.h"
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ )
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
diff --git a/hyperdbg/ScriptEngine/framework.h b/hyperdbg/ScriptEngine/framework.h
new file mode 100644
index 00000000..54b83e94
--- /dev/null
+++ b/hyperdbg/ScriptEngine/framework.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files
+#include
diff --git a/hyperdbg/ScriptEngine/input.txt b/hyperdbg/ScriptEngine/input.txt
new file mode 100644
index 00000000..9f5dde05
--- /dev/null
+++ b/hyperdbg/ScriptEngine/input.txt
@@ -0,0 +1,27 @@
+//x1 = poi(poi((poi(($proc&neg(1000`0000))+10)^poi(poi(poi(poi(poi(poi(poi(poi($prcb+18)+220)+648)+8)-240)+2a0)))^neg(0n6708588087252463955)^($proc&neg(100000)))-8)-1080);
+test= poi(2 + 5 * 1);
+//a2= poi((01)+ 2 * 3) * poi(2); // Binary
+//test=dw(@rcx+($proc|3+poi(poi(@rax))));
+/*
+ //test=dq(@rcx)
+ //test=$proc+@rdx
+ //ad1= b2;A
+ //a3 = $rsc34;
+ //a2= 0y0101`1010`1; // Binary
+ //a10 = 0n34331; //
+ Decimal
+ //a10 = 0o770; // Octal
+ //test=poi(@rax+a0);
+ //test1=str(poi($proc+10));mytest=str(poi($proc+10));test3=str(poi($proc+10));
+ //test=dw(NtCreateFile+10)
+ //test=dw(NtCreateFile+@rcx+($proc|3+poi(poi(@rax))))
+ //
+ //
+ //$proc = 0xfffff801`42600000
+ //
+ //
+ //csc=0y101010`010101*934;
+ //tsc = 10.032;
+ //
+ //test = 343
+*/
\ No newline at end of file
diff --git a/hyperdbg/ScriptEngine/pch.cpp b/hyperdbg/ScriptEngine/pch.cpp
new file mode 100644
index 00000000..64b7eef6
--- /dev/null
+++ b/hyperdbg/ScriptEngine/pch.cpp
@@ -0,0 +1,5 @@
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
diff --git a/hyperdbg/ScriptEngine/pch.h b/hyperdbg/ScriptEngine/pch.h
new file mode 100644
index 00000000..885d5d62
--- /dev/null
+++ b/hyperdbg/ScriptEngine/pch.h
@@ -0,0 +1,13 @@
+// pch.h: This is a precompiled header file.
+// Files listed below are compiled only once, improving build performance for future builds.
+// This also affects IntelliSense performance, including code completion and many code browsing features.
+// However, files listed here are ALL re-compiled if any one of them is updated between builds.
+// Do not add files here that you will be updating frequently as this negates the performance advantage.
+
+#ifndef PCH_H
+#define PCH_H
+
+// add headers that you want to pre-compile here
+#include "framework.h"
+
+#endif //PCH_H
diff --git a/hyperdbg/ScriptEngine/python/Grammer.txt b/hyperdbg/ScriptEngine/python/Grammer.txt
new file mode 100644
index 00000000..2a124003
--- /dev/null
+++ b/hyperdbg/ScriptEngine/python/Grammer.txt
@@ -0,0 +1,75 @@
+S->C ; S'
+S'->C ; S'
+S'->eps
+C->@PUSH _id = E0 @MOV C'
+C'->eps
+#
+E0->E1 E0'
+E0'->| E1 @OR E0'
+E0'->eps
+
+E1->E2 E1'
+E1'->^ E2 @XOR E1'
+E1'->eps
+
+E2->E3 E2'
+E2'->& E3 @AND E2'
+E2'->eps
+
+E3->E4 E3'
+E3'->>> E4 @ASR E3'
+E3'->eps
+
+E4->E5 E4'
+E4'-><< E5 @ASL E4'
+E4'->eps
+
+E5->E6 E5'
+E5'->+ E6 @ADD E5'
+E5'->eps
+
+E6->E7 E6'
+E6'->- E7 @SUB E6'
+E6'->eps
+
+E7->E8 E7'
+E7'->* E8 @MUL E7'
+E7'->eps
+
+E8->E9 E8'
+E8'->/ E9 @DIV E8'
+E8'->eps
+
+
+E9->E10 E9'
+E9'->% E10 @MOD E9'
+E9'->eps
+
+E10->poi ( E0 @POI )
+E10->db ( E0 @DB )
+E10->dd ( E0 @DD )
+E10->dw ( E0 @DW )
+E10->dq ( E0 @DQ )
+E10->str ( E0 @STR )
+E10->wstr ( E0 @WSTR )
+E10->sizeof ( E0 @SIZEOF )
+E10->not ( E0 @NOT )
+E10->neg ( E0 @NEG )
+E10->hi ( E0 @HI )
+E10->low ( E0 @LOW )
+
+
+E10->( E0 )
+
+E10->@PUSH _register
+
+# numbers
+E10->@PUSH _hex
+E10->@PUSH _decimal
+E10->@PUSH _octal
+E10->@PUSH _binary
+
+
+E10->@PUSH func
+E10->@PUSH _pseudo_register
+
diff --git a/hyperdbg/ScriptEngine/python/parse_table_generator.py b/hyperdbg/ScriptEngine/python/parse_table_generator.py
new file mode 100644
index 00000000..f1320be6
--- /dev/null
+++ b/hyperdbg/ScriptEngine/python/parse_table_generator.py
@@ -0,0 +1,593 @@
+import re
+
+# Util functions
+def get_top(l):
+ return l[len(l)-1]
+
+def read(tokens):
+ x = tokens[0]
+ tokens = tokens[1:]
+ return tokens, x
+
+
+
+
+
+
+class Parser:
+ def __init__(self):
+ self.grammer_file = open("Grammer.txt", "r")
+ self.output_file = open("..\src\parse_table.h", "w")
+ self.rhs_list = []
+ self.lhs_list = []
+ self.terminal_set = set()
+ self.nonterminal_set = set()
+ self.start = ""
+ self.maximum_rhs_len = 0
+
+
+ self.SPECIAL_TOKENS = ['%', '++', '+=', '+', '--', '-=', '-', '*=', "*", "/=", "/", "=", ",", ";", "(", ")", "{", "}", "|", ">>", "<<", "&", "^"]
+
+ self.first_dict = dict()
+ self.follow_dict = dict()
+
+ self.INVALID = -1
+
+ def run(self):
+ self.read_grammer()
+
+ self.find_all_firsts()
+ print("Firsts:")
+ self.print_firsts()
+ print("________________________________________________________________________________")
+
+ self.find_all_follows()
+ print("Follows:")
+ self.print_follows()
+ print("________________________________________________________________________________")
+
+
+ self.find_all_perdicts()
+ print("Predicts:")
+ self.print_predicts()
+ print("________________________________________________________________________________")
+
+
+ self.fill_parse_table()
+ print("Parse Table:")
+ self.print_parse_table()
+ print()
+
+
+ self.output_file.write("#ifndef PARSE_TABLE_H\n")
+ self.output_file.write("#define PARSE_TABLE_H\n")
+ self.output_file.write("#include \"scanner.h\"\n")
+ self.output_file.write("#define RULES_COUNT " + str(len(self.lhs_list)) + "\n")
+ self.output_file.write("#define TERMINAL_COUNT " + str(len(list(self.terminal_set))) + "\n")
+ self.output_file.write("#define NONETERMINAL_COUNT " + str(len(list(self.nonterminal_list))) + "\n")
+ self.output_file.write("#define START_VARIABLE " + "\"" + self.start +"\"\n")
+ self.output_file.write("#define MAX_RHS_LEN " + str(self.maximum_rhs_len) +"\n")
+
+
+ self.write_lhs_list()
+ self.write_rhs_list()
+ self.write_rhs_size()
+ self.write_noneterminal_list()
+ self.write_terminal_list()
+ self.write_parse_table()
+
+
+ self.output_file.write("#endif\n")
+
+ self.grammer_file.close()
+ self.output_file.close()
+
+
+ def parse(self, tokens):
+ stack = []
+ matched_stack = []
+ stack.append("$")
+ stack.append(self.start)
+ top = ""
+ tokens, current_in = read(tokens)
+ t_counter = 0
+
+ while top != "$":
+ top = get_top(stack)
+
+ # print(stack)
+
+ if self.isNoneTerminal(top):
+ id = self.parse_table[self.get_noneterminal_id(top)][self.get_terminal_id(current_in)]
+
+ # Error Handling
+ if id == -1:
+ print("1)Error in input!")
+ exit()
+
+ stack.pop()
+
+
+ rhs = self.rhs_list[id]
+ if rhs != ["eps"]:
+ for symbol in reversed(rhs):
+ stack.append(symbol)
+
+
+ elif self.isSemanticRule(top):
+ # TODO: Handle Semantic rules
+ if top == "@PUSH":
+ stack.pop()
+ top = get_top(stack)
+ if top == current_in:
+ matched_stack.append(top)
+ current_in = tokens[0]
+ tokens = tokens[1:]
+ else:
+ print("2)Error in input!")
+ exit()
+
+ else:
+
+
+
+ op0 = matched_stack.pop()
+
+ op1 = matched_stack.pop()
+
+ if top == "@MOV":
+ print(top,"\t", op1, ", ", op0 )
+ else:
+ matched_stack.append("t" + str(t_counter))
+ print(top, "\t", "t"+ str(t_counter), ", ", op1, ",", op0 )
+ t_counter += 1
+
+ # print("matched stack :", end ="")
+ # print(matched_stack)
+
+ stack.pop()
+
+ else: # Terminal
+ # TODO: Handle Error
+ current_in = tokens[0]
+ if (len(tokens) > 1):
+ tokens = tokens[1:]
+ stack.pop()
+ # print(top)
+
+ return matched_stack
+
+ # def code_gen(self, input_stack):
+ # print("input stack:", input_stack)
+ # if len(input_stack) < 3:
+ # return input_stack
+ # top_idx = len(input_stack) - 1
+ # first_op_idx = len(input_stack) - 2
+ # second_op_idx = len(input_stack) - 3
+
+ # output_stack = []
+
+ # if not self.isSemanticRule(input_stack[top_idx]):
+ # print("Error!")
+ # exit()
+ # else:
+ # output_stack.append(input_stack.pop())
+ # if not self.isSemanticRule(input_stack[first_op_idx]): # Operand
+ # output_stack.append(input_stack.pop())
+ # else: # Operator
+ # output_stack.extend(self.code_gen(input_stack))
+
+ # if not self.isSemanticRule(input_stack[second_op_idx]): # Operand
+ # output_stack.append(input_stack.pop())
+ # else: #Operator
+ # output_stack.extend(self.code_gen(input_stack))
+ # print("output stack:", output_stack)
+ # return output_stack
+
+
+
+ def read_grammer(self):
+ flag = 1
+ counter = 0
+ for line in self.grammer_file:
+ line = line.strip()
+ if line == "" or line[0] == "#":
+ continue
+ l = line.split("->")
+ lhs = l[0]
+ self.nonterminal_set.add(lhs)
+ self.lhs_list.append(lhs)
+
+
+ rhs = l[1].split(" ")
+ self.rhs_list.append(rhs)
+ for x in rhs:
+ if not self.isNoneTerminal(x) and not self.isSemanticRule(x) and not x=="eps":
+ self.terminal_set.add(x)
+
+
+
+
+ if flag:
+ flag = 0
+ self.start = lhs
+ self.maximum_rhs_len = max(self.maximum_rhs_len, len(rhs))
+
+ counter += 1
+
+ self.terminal_set.add("$")
+
+ self.nonterminal_list = list(self.nonterminal_set)
+ self.terminal_list = list(self.terminal_set)
+
+
+
+
+
+
+ def write_lhs_list(self):
+
+ self.output_file.write("const struct _TOKEN Lhs[RULES_COUNT]= \n{\n")
+ counter = 0
+ for lhs in self.lhs_list:
+ if counter == len(self.lhs_list)-1:
+ self.output_file.write("\t{NON_TERMINAL, " + "\"" + lhs + "\"}" + "\n")
+ else:
+ self.output_file.write("\t{NON_TERMINAL, " + "\"" + lhs + "\"}" + ",\n")
+ counter +=1
+ self.output_file.write("};\n")
+
+ def get_type(self,var):
+ if self.isNoneTerminal(var):
+ return "NON_TERMINAL"
+ elif self.isSemanticRule(var):
+ return "SEMANTIC_RULE"
+
+ elif var == "eps":
+ return "EPSILON"
+
+ elif var in self.SPECIAL_TOKENS:
+ return "SPECIAL_TOKEN"
+ elif var[0] == "_":
+ return var[1:].upper()
+ else:
+ return "KEYWORD"
+
+
+ def write_rhs_list(self):
+ self.output_file.write("const struct _TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN]= \n{\n")
+ counter =0
+ for rhs in self.rhs_list:
+ self.output_file.write("\t{")
+
+ c = 0
+ for var in rhs:
+ if c == len(rhs) -1:
+ self.output_file.write("{"+self.get_type(var) +", "+"\"" + var + "\"}" )
+ else:
+ self.output_file.write("{"+self.get_type(var) +", "+"\"" + var + "\"}," )
+ c += 1
+
+ if counter == len(self.rhs_list)-1:
+ self.output_file.write("}\n")
+ else:
+ self.output_file.write("},\n")
+ counter+= 1
+
+ self.output_file.write("};\n")
+
+ def write_rhs_size(self):
+ self.output_file.write("const unsigned int RhsSize[RULES_COUNT]= \n{\n")
+ counter =0
+ for rhs in self.rhs_list:
+ if counter == len(self.rhs_list)-1:
+ self.output_file.write( str(len(rhs)) + "\n" )
+ else:
+ self.output_file.write( str(len(rhs)) + ",\n" )
+ counter+= 1
+
+ self.output_file.write("};\n")
+
+ def write_terminal_list(self):
+ self.output_file.write("const char* TerminalMap[TERMINAL_COUNT]= \n{\n")
+ counter = 0
+ for x in self.terminal_list:
+ if counter == len(self.terminal_list)-1:
+ self.output_file.write("\"" + x + "\"" + "\n")
+ else:
+ self.output_file.write("\"" + x + "\"" + ",\n")
+ counter +=1
+ self.output_file.write("};\n")
+
+ def write_noneterminal_list(self):
+ self.output_file.write("const char* NoneTerminalMap[NONETERMINAL_COUNT]= \n{\n")
+ counter = 0
+ for x in self.nonterminal_list:
+ if counter == len(self.nonterminal_list)-1:
+ self.output_file.write("\"" + x + "\"" + "\n")
+ else:
+ self.output_file.write("\"" + x + "\"" + ",\n")
+ counter +=1
+ self.output_file.write("};\n")
+
+ def write_parse_table(self):
+ self.output_file.write("const int ParseTable[NONETERMINAL_COUNT][TERMINAL_COUNT]= \n{\n")
+ i = 0
+ for x in self.nonterminal_list:
+ j = 0
+ self.output_file.write("\t{")
+ for y in self.terminal_list:
+ self.output_file.write(str(self.parse_table[i][j]))
+ if j != len(self.terminal_list)-1:
+ self.output_file.write("\t\t,")
+ j += 1
+
+ if i == len(self.nonterminal_list)-1:
+ self.output_file.write("\t}\n")
+
+ else:
+ self.output_file.write("\t},\n")
+ i +=1
+ self.output_file.write("};\n")
+
+
+
+ def find_all_firsts(self):
+
+ self.first_dict = {}
+ for symbol in self.nonterminal_list:
+ self.first_dict[symbol] = set()
+
+ t = 0
+ while True:
+ updated = False
+ i = 0
+ for lhs in self.lhs_list:
+ rhs = self.rhs_list[i]
+ temp = set(self.first_dict[lhs])
+
+
+ if rhs[0] == "eps":
+ pass
+ elif self.isNoneTerminal(rhs[0]):
+ self.first_dict[lhs] = self.first_dict[lhs].union(self.first_dict[rhs[0]])
+ p = 0
+ while self.isnullable(rhs[p]):
+ self.first_dict[lhs] = self.first_dict[lhs].union(self.first_dict[rhs[p+1]])
+ p += 1
+ elif self.isSemanticRule(rhs[0]):
+ if self.isNoneTerminal(rhs[0]):
+ self.first_dict[lhs] = self.first_dict[lhs].union(self.first_dict[rhs[1]])
+ else:
+ self.first_dict[lhs].add(rhs[1])
+ else:
+ self.first_dict[lhs].add(rhs[0])
+ i += 1
+
+ if temp != self.first_dict[lhs]:
+ updated = True
+ p += 1
+ if not updated:
+ break;
+
+
+
+ def print_firsts(self):
+ for id in self.first_dict:
+ print(id, end=": ")
+ for x in self.first_dict[id]:
+ print(x,end = " ")
+ print()
+
+ def get_noneterminal_id(self, nonterminal):
+ for i in range(len(self.nonterminal_list)):
+ if nonterminal == self.nonterminal_list[i]:
+ return i
+
+ return -1
+ def get_terminal_id(self, terminal):
+ for i in range(len(self.terminal_list)):
+ if terminal == self.terminal_list[i]:
+ return i
+
+ return -1
+
+
+ def fill_parse_table(self):
+ self.parse_table = [[self.INVALID for y in range(len(self.terminal_list))] for x in range(len(self.nonterminal_list))]
+
+ rule_id = 0
+ for lhs in self.lhs_list:
+ i = self.get_noneterminal_id(lhs)
+
+ j = 0
+ for terminal in self.terminal_list:
+ if terminal in self.predict_dict[rule_id]:
+ if self.parse_table[i][j] == self.INVALID:
+ self.parse_table[i][j] = rule_id
+
+ else:
+ print("Error! Input grammer is not LL1.")
+ exit()
+
+ j += 1
+
+ rule_id += 1
+
+ def print_parse_table(self):
+ print("\t", end = "")
+ for j in range(len(self.terminal_list)):
+ print(self.terminal_list[j], end= "\t ")
+ print()
+ for i in range(len(self.nonterminal_list)):
+ print(self.nonterminal_list[i], end= "\t")
+ for j in range(len(self.terminal_list)):
+ if self.parse_table[i][j] == self.INVALID:
+ print(".", end= "\t ")
+ else:
+ print(self.parse_table[i][j], end= "\t ")
+ print()
+
+
+ def find_all_perdicts(self):
+ self.predict_dict = {}
+ for i in range(len(self.lhs_list)):
+ self.predict_dict[i] = set()
+
+ i = 0
+ for lhs in self.lhs_list:
+ rhs = self.rhs_list[i]
+ is_right_nullable = True
+ # print(lhs, end= ": ")
+ # print(rhs)
+
+ # if rhs[0] == "eps":
+ # pass
+ for symbol in rhs:
+ if self.isSemanticRule(symbol):
+ pass
+
+ elif symbol == "eps":
+ is_right_nullable = True
+ break
+ elif self.isNoneTerminal(symbol):
+ self.predict_dict[i] |= self.first_dict[symbol]
+ if not self.isnullable(symbol):
+ is_right_nullable = False
+ break
+ else:
+ self.predict_dict[i].add(symbol)
+ is_right_nullable = False
+ break
+
+ if is_right_nullable:
+ self.predict_dict[i] |= self.follow_dict[lhs]
+ i += 1
+
+
+ def print_predicts(self):
+ for key in self.predict_dict:
+ print(key, end=": ")
+ for x in self.predict_dict[key]:
+ print(x,end = " ")
+ print()
+
+
+
+ def find_all_follows(self):
+ self.follow_dict = {}
+ for symbol in self.nonterminal_list:
+ self.follow_dict[symbol] = set()
+ if symbol == self.start:
+ self.follow_dict[symbol].add('$')
+
+ t = 0
+ while True:
+ updated = False
+
+ i = 0
+ for lhs in self.lhs_list:
+ rhs = self.rhs_list[i]
+
+ p = 0
+ for symbol in rhs:
+
+ if self.isNoneTerminal(symbol):
+
+ temp = set(self.follow_dict[symbol])
+ if p == len(rhs)-1:
+ self.follow_dict[symbol] = self.follow_dict[symbol].union(self.follow_dict[lhs])
+
+
+
+ else:
+
+ next_var = self.get_next_var(rhs, p)
+ if self.isNoneTerminal(next_var):
+ self.follow_dict[symbol] = self.follow_dict[symbol].union(self.first_dict[next_var])
+ if self.isnullable(next_var):
+ self.follow_dict[symbol] = self.follow_dict[symbol].union(self.follow_dict[next_var])
+ elif self.isSemanticRule(next_var):
+ pass
+ else:
+ self.follow_dict[symbol].add(next_var)
+
+ if p == len(rhs)-2:
+ next_var = self.get_next_var(rhs, p)
+
+ if self.isnullable(next_var):
+ self.follow_dict[symbol] = self.follow_dict[symbol].union(self.follow_dict[lhs])
+ self.follow_dict[lhs] = self.follow_dict[lhs].union(self.follow_dict[next_var])
+
+
+
+ if temp != self.follow_dict[symbol]:
+ updated = True
+ p += 1
+ i += 1
+ t += 1
+
+ if not updated:
+ break
+ def get_next_var(self, rhs, p):
+ if p == len(rhs)-1:
+ return None
+
+ x = p +1
+ while self.isSemanticRule(rhs[x]):
+ x+=1
+ return rhs[x]
+
+ def print_follows(self):
+ for key in self.follow_dict:
+ print(key, end=": ")
+ for x in self.follow_dict[key]:
+ print(x,end = " ")
+ print()
+
+ def isNoneTerminal(self,x):
+ if x[0].isupper():
+ return True
+ else:
+ return False
+
+ def isSemanticRule(self, x):
+ if x[0] == '@':
+ return True
+ else:
+ return False
+
+ def isnullable(self, s):
+
+ if not s[0].isupper():
+ return False
+ i = 0
+ for lhs in self.lhs_list:
+ rhs = self.rhs_list[i]
+
+ if lhs == s:
+
+ if rhs[0] == "eps":
+ return True
+
+ p = 0
+ while True:
+ if self.isnullable(rhs[p]):
+ return True
+ else:
+ break
+ p += 1
+ i +=1
+
+ return False
+
+parser = Parser()
+parser.run()
+tokens = ['_id', '=', '(', '_hex', '*', '_hex', ')', '*', '_hex', '*', '_decimal', '*', '_octal', ';', '$']
+stack = parser.parse(tokens)
+print(stack)
+# parser.code_gen(stack)
+
+
+
+
diff --git a/hyperdbg/ScriptEngine/src/ScriptEngine.c b/hyperdbg/ScriptEngine/src/ScriptEngine.c
new file mode 100644
index 00000000..cb53eee3
--- /dev/null
+++ b/hyperdbg/ScriptEngine/src/ScriptEngine.c
@@ -0,0 +1,798 @@
+#include
+#include
+#include
+#include
+#include "ScriptEngine.h"
+#include "scanner.h"
+#include "parse_table.h"
+
+/**
+*
+*
+*/
+PSYMBOL_BUFFER ScriptEngineParse(char *str)
+{
+ TOKEN_LIST Stack = NewTokenList();
+ TOKEN_LIST MatchedStack = NewTokenList();
+ PSYMBOL_BUFFER CodeBuffer = NewSymbolBuffer();
+
+ TOKEN CurrentIn;
+ TOKEN TopToken;
+
+
+ int NonTerminalId;
+ int TerminalId;
+ int RuleId;
+ char c;
+ char t;
+
+
+
+ //
+ // End of File Token
+ //
+ TOKEN EndToken = NewToken();
+ EndToken->Type = END_OF_STACK;
+ strcpy(EndToken->Value, "$");
+
+ //
+ // Start Token
+ //
+ TOKEN StartToken = NewToken();
+ strcpy(StartToken->Value, START_VARIABLE);
+ StartToken->Type = NON_TERMINAL;
+
+ Push(Stack, EndToken);
+ Push(Stack, StartToken);
+
+ c = sgetc(str);
+ CurrentIn = Scan(str, &c);
+
+ do
+ {
+
+ TopToken = Pop(Stack);
+
+#ifdef _SCRIPT_ENGINE_DBG_EN
+ printf("\nTop Token :\n");
+ PrintToken(TopToken);
+ printf("\nCurrent Input :\n");
+ PrintToken(CurrentIn);
+ printf("\n");
+#endif
+
+
+ if (TopToken->Type == NON_TERMINAL)
+ {
+ NonTerminalId = GetNonTerminalId(TopToken);
+ if (NonTerminalId == -1)
+ {
+ printf("Error in Nonterminal ID\n");
+ return;
+ }
+ TerminalId = GetTerminalId(CurrentIn);
+ if (TerminalId == -1)
+ {
+ printf("Error in Terminal ID\n");
+ return;
+ }
+ RuleId = ParseTable[NonTerminalId][TerminalId];
+ if (RuleId == -1)
+ {
+ printf("Error in Parse Table\n");
+ return;
+ }
+
+ // printf("Rule ID = %d\n", RuleId);
+
+ // Push RHS Reversely into stack
+ for (int i = RhsSize[RuleId] - 1; i >= 0; i--)
+ {
+ TOKEN Token = &Rhs[RuleId][i];
+
+ if (Token->Type == EPSILON)
+ break;
+ Push(Stack, Token);
+ }
+ }
+ else if (TopToken->Type == SEMANTIC_RULE)
+ {
+ if (!strcmp(TopToken->Value, "@PUSH"))
+ {
+ TopToken = Pop(Stack);
+ Push(MatchedStack, CurrentIn);
+ CurrentIn = Scan(str, &c);
+
+ // char t = getchar();
+ }
+ else
+ {
+ CodeGen(MatchedStack, CodeBuffer, TopToken);
+
+ }
+ }
+ else
+ {
+ if (!IsEqual(TopToken, CurrentIn))
+ {
+ printf("Error: Not Matched\n");
+ return;
+ }
+ else
+ {
+ CurrentIn = Scan(str, &c);
+ /* printf("\nCurrent Input :\n");
+ PrintToken(CurrentIn);
+ printf("\n");*/
+
+#ifdef _SCRIPT_ENGINE_DBG_EN
+ printf("matched...\n");
+#endif
+ }
+ }
+#ifdef _SCRIPT_ENGINE_DBG_EN
+ PrintTokenList(Stack);
+ printf("\n");
+#endif
+
+ } while (TopToken->Type != END_OF_STACK);
+
+ return CodeBuffer;
+}
+
+TOKEN NewTemp(void)
+{
+ static unsigned int TempID = 0;
+ int i;
+ for (i = 0; i < MAX_TEMP_COUNT; i++)
+ {
+ if (TempMap[i] == 0)
+ {
+ TempID = i;
+ TempMap[i] = 1;
+ break;
+ }
+ }
+ if (i == MAX_TEMP_COUNT)
+ {
+ // TODO: Handle Error
+ printf("Error: Not enough tempporary variables to allocate. \n");
+ }
+ TOKEN Temp = NewToken();
+ char TempValue[8];
+ sprintf(TempValue, "%d", TempID);
+ strcpy(Temp->Value, TempValue);
+ Temp->Type = TEMP;
+ return Temp;
+
+}
+void FreeTemp(TOKEN Temp)
+{
+ int id = DecimalToInt(Temp->Value);
+ if (Temp->Type == TEMP)
+ {
+ TempMap[id] = 0;
+ }
+ free(Temp);
+
+}
+void CodeGen(TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, TOKEN Operator)
+{
+
+ TOKEN Op0;
+ TOKEN Op1;
+ TOKEN Temp;
+
+ PSYMBOL OperatorSymbol;
+ PSYMBOL Op0Symbol;
+ PSYMBOL Op1Symbol;
+ PSYMBOL TempSymbol;
+
+ OperatorSymbol = ToSymbol(Operator);
+ PushSymbol(CodeBuffer, OperatorSymbol);
+
+ Op0 = Pop(MatchedStack);
+ Op0Symbol = ToSymbol(Op0);
+ PushSymbol(CodeBuffer, Op0Symbol);
+
+
+
+ if (!strcmp(Operator->Value, "@MOV"))
+ {
+ Op1 = Pop(MatchedStack);
+ Op1Symbol = ToSymbol(Op1);
+ PushSymbol(CodeBuffer, Op1Symbol);
+
+
+ printf("%s\t%s,\t%s\n", Operator->Value, Op1->Value, Op0->Value);
+ PrintSymbol(OperatorSymbol);
+ PrintSymbol(Op1Symbol);
+ PrintSymbol(Op0Symbol);
+ printf("_____________\n");
+
+ // Free the operand if it is a temp value
+ FreeTemp(Op0);
+ FreeTemp(Op1);
+ }
+ else if (HasTwoOperand(Operator))
+ {
+
+ Op1 = Pop(MatchedStack);
+ Op1Symbol = ToSymbol(Op1);
+ PushSymbol(CodeBuffer, Op1Symbol);
+
+
+
+ Temp = NewTemp();
+ Push(MatchedStack, Temp);
+ TempSymbol = ToSymbol(Temp);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+
+
+
+
+
+ printf("%s\t%s,\t%s,\t%s\n", Operator->Value, Temp->Value, Op0->Value, Op1->Value);
+ PrintSymbol(OperatorSymbol);
+ PrintSymbol(TempSymbol);
+ PrintSymbol(Op1Symbol);
+ PrintSymbol(Op0Symbol);
+ printf("_____________\n");
+
+ // Free the operand if it is a temp value
+ FreeTemp(Op0);
+ FreeTemp(Op1);
+ }
+ else
+ {
+
+ Temp = NewTemp();
+ Push(MatchedStack, Temp);
+ TempSymbol = ToSymbol(Temp);
+ PushSymbol(CodeBuffer, TempSymbol);
+
+
+
+
+
+ printf("%s\t%s,\t%s\n", Operator->Value, Temp->Value, Op0->Value);
+ PrintSymbol(OperatorSymbol);
+ PrintSymbol(TempSymbol);
+ PrintSymbol(Op0Symbol);
+ printf("_____________\n");
+
+ // Free the operand if it is a temp value
+ FreeTemp(Op0);
+ }
+
+
+}
+
+
+char HasTwoOperand(TOKEN Operator)
+{
+ unsigned int n = sizeof(OneOperandSemanticRules) / sizeof(char*);
+ for (int i = 0; i < n; i++)
+ {
+ if (!strcmp(Operator->Value, OneOperandSemanticRules[i]))
+ {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/**
+*
+*
+*
+*/
+char IsNoneTerminal(TOKEN Token)
+{
+ if (Token->Value[0] >= 'A' && Token->Value[0] <= 'Z')
+ return 1;
+ else
+ return 0;
+}
+
+/**
+*
+*
+*
+*/
+char IsSemanticRule(TOKEN Token)
+{
+ if (Token->Value[0] == '@')
+ return 1;
+ else
+ return 0;
+}
+
+/**
+*
+*
+*
+*/
+int GetNonTerminalId(TOKEN Token)
+{
+ for (int i = 0; i < NONETERMINAL_COUNT; i++)
+ {
+ if (!strcmp(Token->Value, NoneTerminalMap[i]))
+ return i;
+ }
+ return -1;
+}
+
+/**
+*
+*
+*
+*/
+int GetTerminalId(TOKEN Token)
+{
+
+ for (int i = 0; i < TERMINAL_COUNT; i++)
+ {
+ if (Token->Type == HEX)
+ {
+ if (!strcmp("_hex", TerminalMap[i]))
+ return i;
+ }
+ else if (Token->Type == ID)
+ {
+ if (!strcmp("_id", TerminalMap[i]))
+ {
+ return i;
+ }
+ }
+ else if (Token->Type == REGISTER)
+ {
+ if (!strcmp("_register", TerminalMap[i]))
+ {
+ return i;
+ }
+ }
+ else if (Token->Type == PSEUDO_REGISTER)
+ {
+ if (!strcmp("_pseudo_register", TerminalMap[i]))
+ {
+ return i;
+ }
+ }
+ else if (Token->Type == DECIMAL)
+ {
+ if (!strcmp("_decimal", TerminalMap[i]))
+ {
+ return i;
+ }
+ }
+ else if (Token->Type == BINARY)
+ {
+ if (!strcmp("_binary", TerminalMap[i]))
+ {
+ return i;
+ }
+ }
+ else if (Token->Type == OCTAL)
+ {
+ if (!strcmp("_octal", TerminalMap[i]))
+ {
+ return i;
+ }
+ }
+
+ else // Keyword
+ {
+ if (!strcmp(Token->Value, TerminalMap[i]))
+ return i;
+ }
+ }
+ return -1;
+
+}
+
+/**
+*
+*
+*
+*/
+char IsEqual(const TOKEN Token1, const TOKEN Token2)
+{
+ if (Token1->Type == Token2->Type)
+ {
+ if (Token1->Type == SPECIAL_TOKEN)
+ {
+ if (!strcmp(Token1->Value, Token2->Value))
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/**
+*
+*
+*
+*/
+PSYMBOL NewSymbol(void)
+{
+ PSYMBOL Symbol;
+ Symbol = (PSYMBOL)malloc(sizeof(*Symbol));
+ Symbol->Value = 0;
+ Symbol->Type = 0;
+ return Symbol;
+}
+
+/**
+*
+*
+*
+*/
+void RemoveSymbol(PSYMBOL Symbol)
+{
+ free(Symbol);
+ return;
+}
+
+
+/**
+*
+*
+*
+*/
+void PrintSymbol(PSYMBOL Symbol)
+{
+ printf("Type:%llx, Value:0x%llx\n", Symbol->Type, Symbol->Value);
+}
+
+
+PSYMBOL ToSymbol(TOKEN Token)
+{
+ PSYMBOL Symbol = NewSymbol();
+ switch (Token->Type)
+ {
+ case ID:
+ Symbol->Value = IdCounter++;
+ SetType(&Symbol->Type, SYMBOL_ID_TYPE);
+ return Symbol;
+ case DECIMAL:
+ Symbol->Value = DecimalToInt(Token->Value);
+ SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
+ return Symbol;
+ case HEX:
+ Symbol->Value = HexToInt(Token->Value);
+ SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
+ return Symbol;
+ case OCTAL:
+ Symbol->Value = OctalToInt(Token->Value);
+ SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
+ return Symbol;
+ case BINARY:
+ Symbol->Value = BinaryToInt(Token->Value);
+ SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
+ return Symbol;
+
+ case REGISTER:
+ Symbol->Value = RegisterToInt(Token->Value); // TODO: Implement RegisterToInt(char* str)
+ SetType(&Symbol->Type, SYMBOL_REGISTER_TYPE);
+ return Symbol;
+
+ case PSEUDO_REGISTER:
+ Symbol->Value = PseudoRegToInt(Token->Value); // TODO: Implement PseudoRegToInt(char* str)
+ SetType(&Symbol->Type, SYMBOL_PSEUDO_REG_TYPE);
+ return Symbol;
+
+ case SEMANTIC_RULE:
+ Symbol->Value = SemanticRuleToInt(Token->Value); // TODO: Implement SemanticRuleToInt(char* str)
+ SetType(&Symbol->Type, SYMBOL_SEMANTIC_RULE_TYPE);
+ return Symbol;
+ case TEMP:
+ Symbol->Value = DecimalToInt(Token->Value); // TODO: Convert String to int
+ SetType(&Symbol->Type, SYMBOL_TEMP);
+ return Symbol;
+
+ default:
+ // Raise Error
+ printf("Error in Converting Token with type %d to Symbol!\n",Token->Type); // TODO: Handle Error in a Error Handler Funtion
+ }
+}
+void SetType(unsigned long long *Val, unsigned char Type)
+{
+ *Val = (unsigned long long int)Type;
+}
+
+unsigned long long int DecimalToInt(char *str)
+{
+ unsigned long long int acc = 0;
+ for (int i = 0; i < strlen(str); i++)
+ {
+ acc *= 10;
+ acc += (str[i] - '0');
+ }
+ return acc;
+}
+unsigned long long int HexToInt(char *str)
+{
+ char temp;
+ unsigned long long int acc = 0;
+ for (int i = 0 ; i < strlen(str); i++)
+ {
+ acc <<= 4;
+ if (str[i] >= '0' && str[i] <= '9')
+ {
+ temp = str[i] - '0';
+ }
+ else if (str[i] >= 'a' && str[i] <= 'f')
+ {
+ temp = str[i] - 'a' + 10;
+ }
+ else
+ {
+ temp = str[i] - 'A' + 10;
+ }
+ acc += temp;
+ }
+
+ return acc;
+}
+unsigned long long int OctalToInt(char *str)
+{
+ unsigned long long int acc = 0;
+ for (int i = 0; i < strlen(str); i++)
+ {
+ acc <<= 3;
+ acc += (str[i] - '0');
+ }
+ return acc;
+}
+unsigned long long int BinaryToInt(char *str)
+{
+ unsigned long long int acc = 0;
+ for (int i = 0; i < strlen(str); i++)
+ {
+ acc <<= 1;
+ acc += (str[i] - '0');
+ }
+ return acc;
+}
+
+unsigned long long int RegisterToInt(char *str)
+{
+
+ if (!strcmp(str, "rcx"))
+ {
+ return RCX_MNEMONIC;
+ }
+ else if (!strcmp(str, "r10"))
+ {
+ return R10_MNEMONIC;
+ }
+ // ...
+ // TODO: Handle all Registers
+ return INVALID;
+}
+unsigned long long int PseudoRegToInt(char *str)
+{
+ // ...
+ // TODO: Handle all Pseudo Registers
+ return INVALID;
+}
+unsigned long long int SemanticRuleToInt(char *str)
+{
+ if (!strcmp(str, "@OR"))
+ {
+ return (unsigned long long int)FUNC_OR;
+ }
+ else if (!strcmp(str, "@XOR"))
+ {
+ return (unsigned long long int)FUNC_XOR;
+ }
+ else if (!strcmp(str, "@AND"))
+ {
+ return (unsigned long long int)FUNC_OR;
+ }
+ else if (!strcmp(str, "@ASR"))
+ {
+ return (unsigned long long int)FUNC_ASR;
+ }
+ else if (!strcmp(str, "@ASL"))
+ {
+ return (unsigned long long int)FUNC_ASR;
+ }
+ else if (!strcmp(str, "@ADD"))
+ {
+ return (unsigned long long int)FUNC_ADD;
+ }
+ else if (!strcmp(str, "@SUB"))
+ {
+ return (unsigned long long int)FUNC_SUB;
+ }
+ else if (!strcmp(str, "@MUL"))
+ {
+ return (unsigned long long int)FUNC_MUL;
+ }
+ else if (!strcmp(str, "@DIV"))
+ {
+ return (unsigned long long int)FUNC_DIV;
+ }
+ else if (!strcmp(str, "@MOD"))
+ {
+ return (unsigned long long int)FUNC_MOD;
+ }
+ else if (!strcmp(str, "@POI"))
+ {
+ return (unsigned long long int)FUNC_POI;
+ }
+ else if (!strcmp(str, "@DB"))
+ {
+ return (unsigned long long int)FUNC_DB;
+ }
+ else if (!strcmp(str, "@DD"))
+ {
+ return (unsigned long long int)FUNC_DD;
+ }
+ else if (!strcmp(str, "@DW"))
+ {
+ return (unsigned long long int)FUNC_DW;
+ }
+ else if (!strcmp(str, "@DQ"))
+ {
+ return (unsigned long long int)FUNC_DQ;
+ }
+ else if (!strcmp(str, "@STR"))
+ {
+ return (unsigned long long int)FUNC_STR;
+ }
+ else if (!strcmp(str, "@WSTR"))
+ {
+ return (unsigned long long int)FUNC_WSTR;
+ }
+ else if (!strcmp(str, "@SIZEOF"))
+ {
+ return (unsigned long long int)FUNC_SIZEOF;
+ }
+ else if (!strcmp(str, "@NOT"))
+ {
+ return (unsigned long long int)FUNC_NOT;
+ }
+ else if (!strcmp(str, "@NEG"))
+ {
+ return (unsigned long long int)FUNC_NEG;
+ }
+ else if (!strcmp(str, "@HI"))
+ {
+ return (unsigned long long int)FUNC_HI;
+ }
+ else if (!strcmp(str, "@LOW"))
+ {
+ return (unsigned long long int)FUNC_LOW;
+ }
+ else if (!strcmp(str, "@MOV"))
+ {
+ return (unsigned long long int)FUNC_MOV;
+ }
+ return -1;
+}
+
+/**
+*
+*
+*
+*/
+PSYMBOL_BUFFER NewSymbolBuffer(void)
+{
+ PSYMBOL_BUFFER SymbolBuffer;
+ SymbolBuffer = (PSYMBOL_BUFFER)malloc(sizeof(*SymbolBuffer));
+ SymbolBuffer->Pointer = 0;
+ SymbolBuffer->Size = SYMBOL_BUFFER_INIT_SIZE;
+ SymbolBuffer->Head = (PSYMBOL)malloc(SymbolBuffer->Size * sizeof(SYMBOL));
+ return SymbolBuffer;
+}
+
+/**
+*
+*
+*
+*/
+void RemoveSymbolBuffer(PSYMBOL_BUFFER SymbolBuffer)
+{
+ // TODO: When size of SymbolBuffer is more than 0, it must be freed
+ free(SymbolBuffer);
+ return;
+}
+
+/**
+*
+*
+*
+*/
+PSYMBOL_BUFFER PushSymbol(PSYMBOL_BUFFER SymbolBuffer, const PSYMBOL Symbol)
+{
+ //
+ // Calculate address to write new token
+ //
+ uintptr_t Head = (uintptr_t)SymbolBuffer->Head;
+ uintptr_t Pointer = (uintptr_t)SymbolBuffer->Pointer;
+ PSYMBOL WriteAddr = (PSYMBOL)(Head + Pointer * sizeof(SYMBOL));
+
+ //
+ // Write input to the appropriate address in SymbolBuffer
+ //
+ *WriteAddr = *Symbol;
+
+ //
+ // Update Pointer
+ //
+ SymbolBuffer->Pointer++;
+
+ //
+ // Handle Overflow
+ //
+ if (Pointer == SymbolBuffer->Size - 1)
+ {
+ //
+ // Allocate a new buffer for string list with doubled length
+ //
+ PSYMBOL NewHead = (PSYMBOL)malloc(2 * SymbolBuffer->Size * sizeof(SYMBOL));
+
+ //
+ // Copy old Buffer to new buffer
+ //
+ memcpy(NewHead, SymbolBuffer->Head, SymbolBuffer->Size * sizeof(SYMBOL));
+
+ //
+ // Free Old buffer
+ //
+ free(SymbolBuffer->Head);
+
+ //
+ // Upadate Head and size of SymbolBuffer
+ //
+ SymbolBuffer->Size *= 2;
+ SymbolBuffer->Head = NewHead;
+ }
+
+ return SymbolBuffer;
+}
+
+/**
+*
+*
+*
+*/
+PSYMBOL PopSymbol(PSYMBOL_BUFFER SymbolBuffer)
+{
+ if (SymbolBuffer->Pointer > 0)
+ {
+ SymbolBuffer->Pointer--;
+ }
+ uintptr_t Head = SymbolBuffer->Head;
+ uintptr_t Pointer = SymbolBuffer->Pointer;
+ PSYMBOL ReadAddr = (PSYMBOL)(Head + Pointer * sizeof(SYMBOL));
+
+ return ReadAddr;
+}
+
+
+
+/**
+*
+*
+*
+*/
+void PrintSymbolBuffer(const PSYMBOL_BUFFER SymbolBuffer)
+{
+ PSYMBOL Symbol;
+ for (int i = 0; i < SymbolBuffer->Pointer; i++)
+ {
+ Symbol = SymbolBuffer->Head + i;
+ PrintSymbol(Symbol);
+ }
+}
\ No newline at end of file
diff --git a/hyperdbg/ScriptEngine/src/ScriptEngine.h b/hyperdbg/ScriptEngine/src/ScriptEngine.h
new file mode 100644
index 00000000..0e183dc4
--- /dev/null
+++ b/hyperdbg/ScriptEngine/src/ScriptEngine.h
@@ -0,0 +1,138 @@
+#ifndef SCRIPT_ENGINE_H
+#define SCRIPT_ENGINE_H
+
+
+#include
+#include "scanner.h"
+
+ //#define _SCRIPT_ENGINE_DBG_EN
+
+#define SYMBOL_ID_TYPE 0
+#define SYMBOL_NUM_TYPE 1
+#define SYMBOL_REGISTER_TYPE 2
+#define SYMBOL_PSEUDO_REG_TYPE 3
+#define SYMBOL_SEMANTIC_RULE_TYPE 4
+#define SYMBOL_TEMP 5
+
+
+#define R10_MNEMONIC 0
+#define RCX_MNEMONIC 16
+
+#define INVALID -1
+
+
+#define FUNC_OR 0
+#define FUNC_XOR 1
+#define FUNC_AND 2
+#define FUNC_ASR 3
+#define FUNC_ASL 4
+#define FUNC_ADD 5
+#define FUNC_SUB 6
+#define FUNC_MUL 7
+#define FUNC_DIV 8
+#define FUNC_MOD 9
+#define FUNC_POI 10
+#define FUNC_DB 11
+#define FUNC_DD 12
+#define FUNC_DW 13
+#define FUNC_DQ 14
+#define FUNC_STR 15
+#define FUNC_WSTR 16
+#define FUNC_SIZEOF 17
+#define FUNC_NOT 18
+#define FUNC_NEG 19
+#define FUNC_HI 20
+#define FUNC_LOW 21
+#define FUNC_MOV 22
+
+
+#define SYMBOL_BUFFER_INIT_SIZE 1024
+#define MAX_TEMP_COUNT 32
+
+// TODO : Automate generating this array
+const char* OneOperandSemanticRules[] =
+{
+ "@POI",
+ "@DB",
+ "@DD",
+ "@DW",
+ "@DQ",
+ "@STR",
+ "@WSTR",
+ "@SIZEOF",
+ "@NOT",
+ "@NEG",
+ "@HI",
+ "@LOW"
+};
+
+typedef struct SYMBOL
+{
+ long long unsigned Type;
+ long long unsigned Value;
+}SYMBOL, * PSYMBOL;
+
+typedef struct SYMBOL_BUFFER
+{
+ PSYMBOL Head;
+ unsigned int Pointer;
+ unsigned int Size;
+ unsigned int IdsCount;
+
+}SYMBOL_BUFFER, * PSYMBOL_BUFFER;
+
+
+char TempMap[MAX_TEMP_COUNT] = { 0 };
+unsigned int IdCounter = 0;
+
+
+char IsNoneTerminal(TOKEN Token);
+char IsSemanticRule(TOKEN Token);
+char IsEqual(const TOKEN Token1, const TOKEN Token2);
+
+int GetNonTerminalId(TOKEN Token);
+int GetTerminalId(TOKEN Token);
+
+
+PSYMBOL NewSymbol(void);
+void RemoveSymbol(PSYMBOL Symbol);
+__declspec(dllexport) void PrintSymbol(PSYMBOL Symbol);
+
+PSYMBOL_BUFFER NewSymbolBuffer(void);
+void RemoveSymbolBuffer(PSYMBOL_BUFFER SymbolBuffer);
+PSYMBOL_BUFFER PushSymbol(PSYMBOL_BUFFER SymbolBuffer, const PSYMBOL Symbol);
+PSYMBOL PopSymbol(PSYMBOL_BUFFER SymbolBuffer);
+
+__declspec(dllexport) void PrintSymbolBuffer(const PSYMBOL_BUFFER SymbolBuffer);
+
+PSYMBOL ToSymbol(TOKEN Token);
+
+
+
+
+
+
+
+// Util Functions:
+void SetType(unsigned long long* Val, unsigned char Type);
+unsigned long long int DecimalToInt(char* str);
+unsigned long long int HexToInt(char* str);
+unsigned long long int OctalToInt(char* str);
+unsigned long long int BinaryToInt(char* str);
+
+unsigned long long int RegisterToInt(char* str);
+unsigned long long int PseudoRegToInt(char* str);
+unsigned long long int SemanticRuleToInt(char* str);
+
+TOKEN NewTemp(void);
+void FreeTemp(TOKEN Temp);
+
+
+
+
+__declspec(dllexport) PSYMBOL_BUFFER ScriptEngineParse(char* str);
+
+void CodeGen(TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, TOKEN Operator);
+char HasTwoOperand(TOKEN Operator);
+
+#endif // !SCRIPT_ENGINE_H
\ No newline at end of file
diff --git a/hyperdbg/ScriptEngine/src/input.txt b/hyperdbg/ScriptEngine/src/input.txt
new file mode 100644
index 00000000..a171613e
--- /dev/null
+++ b/hyperdbg/ScriptEngine/src/input.txt
@@ -0,0 +1,29 @@
+
+
+x1 = poi(poi((poi(($proc&neg(1000`0000))+10)^poi(poi(poi(poi(poi(poi(poi(poi($prcb+18)+220)+648)+8)-240)+2a0)))^neg(0n6708588087252463955)^($proc&neg(100000)))-8)-1080);
+//test= poi(2);
+//a2= poi((01)+ 2 * 3) * poi(2); // Binary
+//test=dw(@rcx+($proc|3+poi(poi(@rax))));
+/*
+ //test=dq(@rcx)
+ //test=$proc+@rdx
+ //ad1= b2;A
+ //a3 = $rsc34;
+ //a2= 0y0101`1010`1; // Binary
+ //a10 = 0n34331; //
+ Decimal
+ //a10 = 0o770; // Octal
+ //test=poi(@rax+a0);
+ //test1=str(poi($proc+10));mytest=str(poi($proc+10));test3=str(poi($proc+10));
+ //test=dw(NtCreateFile+10)
+ //test=dw(NtCreateFile+@rcx+($proc|3+poi(poi(@rax))))
+ //
+ //
+ //$proc = 0xfffff801`42600000
+ //
+ //
+ //csc=0y101010`010101*934;
+ //tsc = 10.032;
+ //
+ //test = 343
+*/
\ No newline at end of file
diff --git a/hyperdbg/ScriptEngine/src/parse_table.h b/hyperdbg/ScriptEngine/src/parse_table.h
new file mode 100644
index 00000000..3975df6f
--- /dev/null
+++ b/hyperdbg/ScriptEngine/src/parse_table.h
@@ -0,0 +1,277 @@
+#ifndef PARSE_TABLE_H
+#define PARSE_TABLE_H
+#include "scanner.h"
+#define RULES_COUNT 55
+#define TERMINAL_COUNT 35
+#define NONETERMINAL_COUNT 25
+#define START_VARIABLE "S"
+#define MAX_RHS_LEN 6
+const struct _TOKEN Lhs[RULES_COUNT]=
+{
+ {NON_TERMINAL, "S"},
+ {NON_TERMINAL, "S'"},
+ {NON_TERMINAL, "S'"},
+ {NON_TERMINAL, "C"},
+ {NON_TERMINAL, "C'"},
+ {NON_TERMINAL, "E0"},
+ {NON_TERMINAL, "E0'"},
+ {NON_TERMINAL, "E0'"},
+ {NON_TERMINAL, "E1"},
+ {NON_TERMINAL, "E1'"},
+ {NON_TERMINAL, "E1'"},
+ {NON_TERMINAL, "E2"},
+ {NON_TERMINAL, "E2'"},
+ {NON_TERMINAL, "E2'"},
+ {NON_TERMINAL, "E3"},
+ {NON_TERMINAL, "E3'"},
+ {NON_TERMINAL, "E3'"},
+ {NON_TERMINAL, "E4"},
+ {NON_TERMINAL, "E4'"},
+ {NON_TERMINAL, "E4'"},
+ {NON_TERMINAL, "E5"},
+ {NON_TERMINAL, "E5'"},
+ {NON_TERMINAL, "E5'"},
+ {NON_TERMINAL, "E6"},
+ {NON_TERMINAL, "E6'"},
+ {NON_TERMINAL, "E6'"},
+ {NON_TERMINAL, "E7"},
+ {NON_TERMINAL, "E7'"},
+ {NON_TERMINAL, "E7'"},
+ {NON_TERMINAL, "E8"},
+ {NON_TERMINAL, "E8'"},
+ {NON_TERMINAL, "E8'"},
+ {NON_TERMINAL, "E9"},
+ {NON_TERMINAL, "E9'"},
+ {NON_TERMINAL, "E9'"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"},
+ {NON_TERMINAL, "E10"}
+};
+const struct _TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN]=
+{
+ {{NON_TERMINAL, "C"},{SPECIAL_TOKEN, ";"},{NON_TERMINAL, "S'"}},
+ {{NON_TERMINAL, "C"},{SPECIAL_TOKEN, ";"},{NON_TERMINAL, "S'"}},
+ {{EPSILON, "eps"}},
+ {{SEMANTIC_RULE, "@PUSH"},{ID, "_id"},{SPECIAL_TOKEN, "="},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@MOV"},{NON_TERMINAL, "C'"}},
+ {{EPSILON, "eps"}},
+ {{NON_TERMINAL, "E1"},{NON_TERMINAL, "E0'"}},
+ {{SPECIAL_TOKEN, "|"},{NON_TERMINAL, "E1"},{SEMANTIC_RULE, "@OR"},{NON_TERMINAL, "E0'"}},
+ {{EPSILON, "eps"}},
+ {{NON_TERMINAL, "E2"},{NON_TERMINAL, "E1'"}},
+ {{SPECIAL_TOKEN, "^"},{NON_TERMINAL, "E2"},{SEMANTIC_RULE, "@XOR"},{NON_TERMINAL, "E1'"}},
+ {{EPSILON, "eps"}},
+ {{NON_TERMINAL, "E3"},{NON_TERMINAL, "E2'"}},
+ {{SPECIAL_TOKEN, "&"},{NON_TERMINAL, "E3"},{SEMANTIC_RULE, "@AND"},{NON_TERMINAL, "E2'"}},
+ {{EPSILON, "eps"}},
+ {{NON_TERMINAL, "E4"},{NON_TERMINAL, "E3'"}},
+ {{SPECIAL_TOKEN, ">>"},{NON_TERMINAL, "E4"},{SEMANTIC_RULE, "@ASR"},{NON_TERMINAL, "E3'"}},
+ {{EPSILON, "eps"}},
+ {{NON_TERMINAL, "E5"},{NON_TERMINAL, "E4'"}},
+ {{SPECIAL_TOKEN, "<<"},{NON_TERMINAL, "E5"},{SEMANTIC_RULE, "@ASL"},{NON_TERMINAL, "E4'"}},
+ {{EPSILON, "eps"}},
+ {{NON_TERMINAL, "E6"},{NON_TERMINAL, "E5'"}},
+ {{SPECIAL_TOKEN, "+"},{NON_TERMINAL, "E6"},{SEMANTIC_RULE, "@ADD"},{NON_TERMINAL, "E5'"}},
+ {{EPSILON, "eps"}},
+ {{NON_TERMINAL, "E7"},{NON_TERMINAL, "E6'"}},
+ {{SPECIAL_TOKEN, "-"},{NON_TERMINAL, "E7"},{SEMANTIC_RULE, "@SUB"},{NON_TERMINAL, "E6'"}},
+ {{EPSILON, "eps"}},
+ {{NON_TERMINAL, "E8"},{NON_TERMINAL, "E7'"}},
+ {{SPECIAL_TOKEN, "*"},{NON_TERMINAL, "E8"},{SEMANTIC_RULE, "@MUL"},{NON_TERMINAL, "E7'"}},
+ {{EPSILON, "eps"}},
+ {{NON_TERMINAL, "E9"},{NON_TERMINAL, "E8'"}},
+ {{SPECIAL_TOKEN, "/"},{NON_TERMINAL, "E9"},{SEMANTIC_RULE, "@DIV"},{NON_TERMINAL, "E8'"}},
+ {{EPSILON, "eps"}},
+ {{NON_TERMINAL, "E10"},{NON_TERMINAL, "E9'"}},
+ {{SPECIAL_TOKEN, "%"},{NON_TERMINAL, "E10"},{SEMANTIC_RULE, "@MOD"},{NON_TERMINAL, "E9'"}},
+ {{EPSILON, "eps"}},
+ {{KEYWORD, "poi"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@POI"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "db"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@DB"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "dd"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@DD"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "dw"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@DW"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "dq"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@DQ"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "str"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@STR"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "wstr"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@WSTR"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "sizeof"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@SIZEOF"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "not"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@NOT"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "neg"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@NEG"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "hi"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@HI"},{SPECIAL_TOKEN, ")"}},
+ {{KEYWORD, "low"},{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SEMANTIC_RULE, "@LOW"},{SPECIAL_TOKEN, ")"}},
+ {{SPECIAL_TOKEN, "("},{NON_TERMINAL, "E0"},{SPECIAL_TOKEN, ")"}},
+ {{SEMANTIC_RULE, "@PUSH"},{REGISTER, "_register"}},
+ {{SEMANTIC_RULE, "@PUSH"},{HEX, "_hex"}},
+ {{SEMANTIC_RULE, "@PUSH"},{DECIMAL, "_decimal"}},
+ {{SEMANTIC_RULE, "@PUSH"},{OCTAL, "_octal"}},
+ {{SEMANTIC_RULE, "@PUSH"},{BINARY, "_binary"}},
+ {{SEMANTIC_RULE, "@PUSH"},{KEYWORD, "func"}},
+ {{SEMANTIC_RULE, "@PUSH"},{PSEUDO_REGISTER, "_pseudo_register"}}
+};
+const unsigned int RhsSize[RULES_COUNT]=
+{
+3,
+3,
+1,
+6,
+1,
+2,
+4,
+1,
+2,
+4,
+1,
+2,
+4,
+1,
+2,
+4,
+1,
+2,
+4,
+1,
+2,
+4,
+1,
+2,
+4,
+1,
+2,
+4,
+1,
+2,
+4,
+1,
+2,
+4,
+1,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+5,
+3,
+2,
+2,
+2,
+2,
+2,
+2,
+2
+};
+const char* NoneTerminalMap[NONETERMINAL_COUNT]=
+{
+"E8",
+"E5'",
+"E6'",
+"S",
+"E3",
+"E3'",
+"E1",
+"E4'",
+"E5",
+"E2'",
+"E6",
+"E10",
+"E9'",
+"E1'",
+"E0",
+"E9",
+"C'",
+"E7'",
+"C",
+"E8'",
+"E2",
+"E7",
+"S'",
+"E0'",
+"E4"
+};
+const char* TerminalMap[TERMINAL_COUNT]=
+{
+"_id",
+";",
+"str",
+"&",
+"/",
+"low",
+"_binary",
+"_pseudo_register",
+"poi",
+"<<",
+"db",
+"_octal",
+"dq",
+"|",
+"%",
+"=",
+"_decimal",
+"*",
+"(",
+"dw",
+"+",
+">>",
+"_hex",
+"not",
+"dd",
+"^",
+"-",
+"func",
+"wstr",
+"sizeof",
+"$",
+"neg",
+")",
+"hi",
+"_register"
+};
+const int ParseTable[NONETERMINAL_COUNT][TERMINAL_COUNT]=
+{
+ {-1 ,-1 ,29 ,-1 ,-1 ,29 ,29 ,29 ,29 ,-1 ,29 ,29 ,29 ,-1 ,-1 ,-1 ,29 ,-1 ,29 ,29 ,-1 ,-1 ,29 ,29 ,29 ,-1 ,-1 ,29 ,29 ,29 ,-1 ,29 ,-1 ,29 ,29 },
+ {-1 ,22 ,-1 ,22 ,-1 ,-1 ,-1 ,-1 ,-1 ,22 ,-1 ,-1 ,-1 ,22 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,21 ,22 ,-1 ,-1 ,-1 ,22 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,22 ,-1 ,-1 },
+ {-1 ,25 ,-1 ,25 ,-1 ,-1 ,-1 ,-1 ,-1 ,25 ,-1 ,-1 ,-1 ,25 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,25 ,25 ,-1 ,-1 ,-1 ,25 ,24 ,-1 ,-1 ,-1 ,-1 ,-1 ,25 ,-1 ,-1 },
+ {0 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 },
+ {-1 ,-1 ,14 ,-1 ,-1 ,14 ,14 ,14 ,14 ,-1 ,14 ,14 ,14 ,-1 ,-1 ,-1 ,14 ,-1 ,14 ,14 ,-1 ,-1 ,14 ,14 ,14 ,-1 ,-1 ,14 ,14 ,14 ,-1 ,14 ,-1 ,14 ,14 },
+ {-1 ,16 ,-1 ,16 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,16 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,15 ,-1 ,-1 ,-1 ,16 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,16 ,-1 ,-1 },
+ {-1 ,-1 ,8 ,-1 ,-1 ,8 ,8 ,8 ,8 ,-1 ,8 ,8 ,8 ,-1 ,-1 ,-1 ,8 ,-1 ,8 ,8 ,-1 ,-1 ,8 ,8 ,8 ,-1 ,-1 ,8 ,8 ,8 ,-1 ,8 ,-1 ,8 ,8 },
+ {-1 ,19 ,-1 ,19 ,-1 ,-1 ,-1 ,-1 ,-1 ,18 ,-1 ,-1 ,-1 ,19 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,19 ,-1 ,-1 ,-1 ,19 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,19 ,-1 ,-1 },
+ {-1 ,-1 ,20 ,-1 ,-1 ,20 ,20 ,20 ,20 ,-1 ,20 ,20 ,20 ,-1 ,-1 ,-1 ,20 ,-1 ,20 ,20 ,-1 ,-1 ,20 ,20 ,20 ,-1 ,-1 ,20 ,20 ,20 ,-1 ,20 ,-1 ,20 ,20 },
+ {-1 ,13 ,-1 ,12 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,13 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,13 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,13 ,-1 ,-1 },
+ {-1 ,-1 ,23 ,-1 ,-1 ,23 ,23 ,23 ,23 ,-1 ,23 ,23 ,23 ,-1 ,-1 ,-1 ,23 ,-1 ,23 ,23 ,-1 ,-1 ,23 ,23 ,23 ,-1 ,-1 ,23 ,23 ,23 ,-1 ,23 ,-1 ,23 ,23 },
+ {-1 ,-1 ,40 ,-1 ,-1 ,46 ,52 ,54 ,35 ,-1 ,36 ,51 ,39 ,-1 ,-1 ,-1 ,50 ,-1 ,47 ,38 ,-1 ,-1 ,49 ,43 ,37 ,-1 ,-1 ,53 ,41 ,42 ,-1 ,44 ,-1 ,45 ,48 },
+ {-1 ,34 ,-1 ,34 ,34 ,-1 ,-1 ,-1 ,-1 ,34 ,-1 ,-1 ,-1 ,34 ,33 ,-1 ,-1 ,34 ,-1 ,-1 ,34 ,34 ,-1 ,-1 ,-1 ,34 ,34 ,-1 ,-1 ,-1 ,-1 ,-1 ,34 ,-1 ,-1 },
+ {-1 ,10 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,10 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,9 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,10 ,-1 ,-1 },
+ {-1 ,-1 ,5 ,-1 ,-1 ,5 ,5 ,5 ,5 ,-1 ,5 ,5 ,5 ,-1 ,-1 ,-1 ,5 ,-1 ,5 ,5 ,-1 ,-1 ,5 ,5 ,5 ,-1 ,-1 ,5 ,5 ,5 ,-1 ,5 ,-1 ,5 ,5 },
+ {-1 ,-1 ,32 ,-1 ,-1 ,32 ,32 ,32 ,32 ,-1 ,32 ,32 ,32 ,-1 ,-1 ,-1 ,32 ,-1 ,32 ,32 ,-1 ,-1 ,32 ,32 ,32 ,-1 ,-1 ,32 ,32 ,32 ,-1 ,32 ,-1 ,32 ,32 },
+ {-1 ,4 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 },
+ {-1 ,28 ,-1 ,28 ,-1 ,-1 ,-1 ,-1 ,-1 ,28 ,-1 ,-1 ,-1 ,28 ,-1 ,-1 ,-1 ,27 ,-1 ,-1 ,28 ,28 ,-1 ,-1 ,-1 ,28 ,28 ,-1 ,-1 ,-1 ,-1 ,-1 ,28 ,-1 ,-1 },
+ {3 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 },
+ {-1 ,31 ,-1 ,31 ,30 ,-1 ,-1 ,-1 ,-1 ,31 ,-1 ,-1 ,-1 ,31 ,-1 ,-1 ,-1 ,31 ,-1 ,-1 ,31 ,31 ,-1 ,-1 ,-1 ,31 ,31 ,-1 ,-1 ,-1 ,-1 ,-1 ,31 ,-1 ,-1 },
+ {-1 ,-1 ,11 ,-1 ,-1 ,11 ,11 ,11 ,11 ,-1 ,11 ,11 ,11 ,-1 ,-1 ,-1 ,11 ,-1 ,11 ,11 ,-1 ,-1 ,11 ,11 ,11 ,-1 ,-1 ,11 ,11 ,11 ,-1 ,11 ,-1 ,11 ,11 },
+ {-1 ,-1 ,26 ,-1 ,-1 ,26 ,26 ,26 ,26 ,-1 ,26 ,26 ,26 ,-1 ,-1 ,-1 ,26 ,-1 ,26 ,26 ,-1 ,-1 ,26 ,26 ,26 ,-1 ,-1 ,26 ,26 ,26 ,-1 ,26 ,-1 ,26 ,26 },
+ {1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,2 ,-1 ,-1 ,-1 ,-1 },
+ {-1 ,7 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,6 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,7 ,-1 ,-1 },
+ {-1 ,-1 ,17 ,-1 ,-1 ,17 ,17 ,17 ,17 ,-1 ,17 ,17 ,17 ,-1 ,-1 ,-1 ,17 ,-1 ,17 ,17 ,-1 ,-1 ,17 ,17 ,17 ,-1 ,-1 ,17 ,17 ,17 ,-1 ,17 ,-1 ,17 ,17 }
+};
+#endif
diff --git a/hyperdbg/ScriptEngine/src/scanner.c b/hyperdbg/ScriptEngine/src/scanner.c
new file mode 100644
index 00000000..c5a5c868
--- /dev/null
+++ b/hyperdbg/ScriptEngine/src/scanner.c
@@ -0,0 +1,679 @@
+#include "scanner.h"
+#include
+#include
+#include
+#include
+
+const char* KeywordList[] =
+{
+ "str",
+ "low",
+ "poi",
+ "db",
+ "dq",
+ "dw",
+ "not",
+ "dd",
+ "func",
+ "wstr",
+ "sizeof",
+ "neg",
+ "hi"
+};
+
+/**
+ *
+ */
+TOKEN NewToken()
+{
+ TOKEN Token;
+ Token = (TOKEN)malloc(sizeof(*Token));
+ Token->Value = (char *)calloc(TOKEN_VALUE_MAX_LEN, sizeof(char));
+ strcpy(Token->Value, "");
+ Token->Type = UNKNOWN;
+ return Token;
+}
+
+/**
+ *
+ */
+TOKEN_LIST NewTokenList(void)
+{
+ TOKEN_LIST TokenList;
+ TokenList = (TOKEN_LIST)malloc(sizeof(*TokenList));
+ TokenList->Pointer = 0;
+ TokenList->Size = TOKEN_LIST_INIT_SIZE;
+ TokenList->Head = (TOKEN *)malloc(TokenList->Size * sizeof(TOKEN));
+ return TokenList;
+}
+
+/**
+ *
+ */
+TOKEN_LIST Push(TOKEN_LIST TokenList, TOKEN Token)
+{
+ //
+ // Calculate address to write new token
+ //
+ uintptr_t Head = (uintptr_t)TokenList->Head;
+ uintptr_t Pointer = (uintptr_t)TokenList->Pointer;
+ TOKEN *WriteAddr = (TOKEN *)(Head + Pointer * sizeof(TOKEN));
+
+ //
+ // Write Token to appropriate address in TokenList
+ //
+ *WriteAddr = Token;
+
+ //
+ // Update Pointer
+ //
+ TokenList->Pointer++;
+
+ //
+ // Handle overflow
+ //
+ if (Pointer == TokenList->Size - 1)
+ {
+ //
+ // Allocate a new buffer for string list with doubled length
+ //
+ TOKEN *NewHead = (TOKEN *)malloc(2 * TokenList->Size * sizeof(TOKEN));
+
+ //
+ // Copy old buffer to new buffer
+ //
+ memcpy(NewHead, TokenList->Head, TokenList->Size * sizeof(TOKEN));
+
+ //
+ // Free old buffer
+ //
+ free(TokenList->Head);
+
+ //
+ // Update Head and size of TokenList
+ //
+ TokenList->Size = TokenList->Size * 2;
+ TokenList->Head = NewHead;
+ }
+
+ return TokenList;
+}
+/**
+ *
+ */
+
+TOKEN Pop(TOKEN_LIST TokenList)
+{
+ //
+ // Calculate address to read most recent token
+ //
+ if (TokenList->Pointer > 0)
+ TokenList->Pointer--;
+ uintptr_t Head = (uintptr_t)TokenList->Head;
+ uintptr_t Pointer = (uintptr_t)TokenList->Pointer;
+ TOKEN *ReadAddr = (TOKEN *)(Head + Pointer * sizeof(TOKEN));
+
+
+ return *ReadAddr;
+}
+
+TOKEN Top(TOKEN_LIST TokenList)
+{
+ //
+ // Calculate address to read most recent token
+ //
+ uintptr_t Head = (uintptr_t)TokenList->Head;
+ uintptr_t Pointer = (uintptr_t)TokenList->Pointer-1;
+ TOKEN *ReadAddr = (TOKEN *)(Head + Pointer * sizeof(TOKEN));
+
+ return *ReadAddr;
+}
+/**
+ *
+ */
+void PrintTokenList(TOKEN_LIST TokenList)
+{
+ TOKEN Token = NewToken();
+ for (uintptr_t i = 0; i < TokenList->Pointer; i++)
+ {
+ Token = *(TokenList->Head + i);
+ PrintToken(Token);
+ }
+}
+
+/**
+ *
+ *
+ */
+void PrintToken(TOKEN Token)
+{
+ if (Token->Type == WHITE_SPACE)
+ {
+ printf("< :");
+ }
+ else
+ {
+ printf("<'%s' : ", Token->Value);
+ }
+
+ switch (Token->Type)
+ {
+ case ID:
+ printf(" ID>\n");
+ break;
+ case DECIMAL:
+ printf(" DECIMAL>\n");
+ break;
+ case HEX:
+ printf(" HEX>\n");
+ break;
+ case OCTAL:
+ printf(" OCTAL>\n");
+ break;
+ case BINARY:
+ printf(" BINARY>\n");
+ break;
+ case SPECIAL_TOKEN:
+ printf(" SPECIAL_TOKEN>\n");
+ break;
+ case KEYWORD:
+ printf(" KEYWORD>\n");
+ break;
+ case WHITE_SPACE:
+ printf(" WHITE_SPACE>\n");
+ break;
+ case COMMENT:
+ printf(" COMMENT>\n");
+ break;
+ case REGISTER:
+ printf(" REGISTER>\n");
+ break;
+ case PSEUDO_REGISTER:
+ printf(" PSEUDO_REGISTER>\n");
+ break;
+ case SEMANTIC_RULE:
+ printf(" SEMANTIC_RULE>\n");
+ break;
+ case NON_TERMINAL:
+ printf(" NON_TERMINAL>\n");
+ break;
+ case END_OF_STACK:
+ printf(" END_OF_STACK>\n");
+ break;
+ case UNKNOWN:
+ printf(" UNKNOWN>\n");
+ break;
+
+ default:
+ printf(" ERROR>\n");
+ break;
+ }
+}
+/**
+ *
+ */
+void Append(TOKEN Token, char c)
+{
+ strncat(Token->Value, &c, 1);
+}
+/**
+ *
+ */
+TOKEN GetToken(char *c, char* str)
+{
+ static unsigned char WaitForID = 1;
+ TOKEN Token = NewToken();
+
+ switch (*c)
+ {
+ case '+':
+ *c = sgetc(str);
+ if (*c == '+')
+ {
+ strcpy(Token->Value, "++");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ }
+ else if (*c == '=')
+ {
+ strcpy(Token->Value, "+=");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ }
+ else
+ {
+ strcpy(Token->Value, "+");
+ Token->Type = SPECIAL_TOKEN;
+ return Token;
+ }
+ case '-':
+ *c = sgetc(str);
+ if (*c == '-')
+ {
+ strcpy(Token->Value, "--");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ }
+ else if (*c == '=')
+ {
+ strcpy(Token->Value, "-=");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ }
+ else
+ {
+ strcpy(Token->Value, "-");
+ Token->Type = SPECIAL_TOKEN;
+ return Token;
+ }
+ case '*':
+ *c = sgetc(str);
+ if (*c == '=')
+ {
+ strcpy(Token->Value, "*=");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ }
+ else
+ {
+ strcpy(Token->Value, "*");
+ Token->Type = SPECIAL_TOKEN;
+ return Token;
+ }
+ case '>':
+ *c = sgetc(str);
+ if (*c == '>')
+ {
+ strcpy(Token->Value, ">>");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ }
+ else
+ {
+ strcpy(Token->Value, ">");
+ Token->Type = SPECIAL_TOKEN;
+ return Token;
+ }
+ case '<':
+ *c = sgetc(str);
+ if (*c == '<')
+ {
+ strcpy(Token->Value, "<<");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ }
+ else
+ {
+ strcpy(Token->Value, "<");
+ Token->Type = SPECIAL_TOKEN;
+ return Token;
+ }
+ case '/':
+ *c = sgetc(str);
+ if (*c == '=')
+ {
+ strcpy(Token->Value, "/=");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+
+ return Token;
+ }
+ else if (*c == '/')
+ {
+ do
+ {
+ *c = sgetc(str);
+ } while (*c != '\n' && *c != EOF);
+
+ Token->Type = COMMENT;
+ *c = sgetc(str);
+ return Token;
+ }
+ else if (*c == '*')
+ {
+ do
+ {
+ *c = sgetc(str);
+ if (*c == '*')
+ {
+ *c = sgetc(str);
+ if (*c == '/')
+ {
+ Token->Type = COMMENT;
+ *c = sgetc(str);
+ return Token;
+ }
+ }
+ if (*c == EOF)
+ break;
+ } while (1);
+
+ Token->Type = UNKNOWN;
+ *c = sgetc(str);
+ return Token;
+ }
+ else
+ {
+ strcpy(Token->Value, "/");
+ Token->Type = SPECIAL_TOKEN;
+ return Token;
+ }
+
+ case '=':
+ strcpy(Token->Value, "=");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ case '%':
+ strcpy(Token->Value, "%");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+
+ case ',':
+ strcpy(Token->Value, ",");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+
+ case ';':
+ strcpy(Token->Value, ";");
+ Token->Type = SPECIAL_TOKEN;
+ WaitForID = 1;
+ *c = sgetc(str);
+ return Token;
+
+ case ':':
+ strcpy(Token->Value, ":");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+
+ case '(':
+ strcpy(Token->Value, "(");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ case ')':
+ strcpy(Token->Value, ")");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ case '{':
+ strcpy(Token->Value, "{");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ case '}':
+ strcpy(Token->Value, "}");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ case '|':
+ strcpy(Token->Value, "|");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ case '&':
+ strcpy(Token->Value, "&");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ case '^':
+ strcpy(Token->Value, "^");
+ Token->Type = SPECIAL_TOKEN;
+ *c = sgetc(str);
+ return Token;
+ case '@':
+ *c = sgetc(str);
+ if (IsLetter(*c))
+ {
+ while (IsLetter(*c) || IsDecimal(*c))
+ {
+ Append(Token, *c);
+ *c = sgetc(str);
+ }
+ Token->Type = REGISTER;
+ return Token;
+ }
+
+ case '$':
+ *c = sgetc(str);
+ if (IsLetter(*c))
+ {
+ while (IsLetter(*c) || IsDecimal(*c))
+ {
+ Append(Token, *c);
+ *c = sgetc(str);
+ }
+ Token->Type = PSEUDO_REGISTER;
+ return Token;
+ }
+
+ case '.':
+ *c = sgetc(str);
+ if (IsHex(*c))
+ {
+ }
+ else
+ {
+ }
+
+ case ' ':
+ case '\t':
+ strcpy(Token->Value, "");
+ Token->Type = WHITE_SPACE;
+ *c = sgetc(str);
+ return Token;
+ case '\n':
+ strcpy(Token->Value, "");
+ Token->Type = WHITE_SPACE;
+ *c = sgetc(str);
+ WaitForID = 1;
+ return Token;
+
+ case '0':
+ *c = sgetc(str);
+ if (*c == 'x')
+ {
+ *c = sgetc(str);
+ while (IsHex(*c) || *c == '`')
+ {
+ if (*c != '`')
+ Append(Token, *c);
+ *c = sgetc(str);
+ }
+ Token->Type = HEX;
+ return Token;
+ }
+ else if (*c == 'o')
+ {
+ *c = sgetc(str);
+ while (IsOctal(*c) || *c == '`')
+ {
+ if (*c != '`')
+ Append(Token, *c);
+ *c = sgetc(str);
+ }
+ Token->Type = OCTAL;
+ return Token;
+ }
+ else if (*c == 'n')
+ {
+ *c = sgetc(str);
+ while (IsDecimal(*c) || *c == '`')
+ {
+ if (*c != '`')
+ Append(Token, *c);
+ *c = sgetc(str);
+ }
+ Token->Type = DECIMAL;
+ return Token;
+ }
+ else if (*c == 'y')
+ {
+ *c = sgetc(str);
+ while (IsBinary(*c) || *c == '`')
+ {
+ if (*c != '`')
+ Append(Token, *c);
+ *c = sgetc(str);
+ }
+ Token->Type = BINARY;
+ return Token;
+ }
+
+ else if (IsHex(*c))
+ {
+ do
+ {
+ if (*c != '`')
+ Append(Token, *c);
+ *c = sgetc(str);
+ } while (IsHex(*c) || *c == '`');
+ Token->Type = HEX;
+ return Token;
+ }
+ else
+ {
+ strcpy(Token->Value, "0");
+ Token->Type = HEX;
+ return Token;
+ }
+
+ default:
+ if (IsHex(*c))
+ {
+ do
+ {
+ if (*c != '`')
+ Append(Token, *c);
+ *c = sgetc(str);
+ } while (IsHex(*c) || *c == '`');
+ int n = sizeof(KeywordList) / sizeof(char*);
+ for (int i = 0; i < n; i++)
+ {
+ if (!strcmp(Token->Value, KeywordList[i]))
+ {
+ Token->Type = KEYWORD;
+ return Token;
+ }
+ }
+ Token->Type = HEX;
+ return Token;
+ }
+ else if (IsLetter(*c) || *c == '_')
+ {
+ while (IsLetter(*c) || *c == '_' || IsDecimal(*c))
+ {
+ Append(Token, *c);
+ *c = sgetc(str);
+ }
+
+ if (WaitForID)
+ {
+ Token->Type = ID;
+ WaitForID = 0;
+ }
+ else
+ {
+ Token->Type = KEYWORD;
+ }
+
+ return Token;
+ }
+
+
+ Token->Type = UNKNOWN;
+ *c = sgetc(str);
+ return Token;
+ }
+ return Token;
+}
+/**
+ *
+ */
+TOKEN Scan(char* str, char* c)
+{
+ TOKEN Token = NewToken();
+
+ while (1)
+ {
+
+ Token = GetToken(c, str);
+ if (*c == EOF)
+ {
+ Token->Type = END_OF_STACK;
+ strcpy(Token->Value,"$");
+ return Token;
+ }
+
+ else if (Token->Type == WHITE_SPACE || Token->Type == COMMENT)
+ {
+ continue;
+ }
+ return Token;
+ }
+}
+
+char IsHex(char c)
+{
+ if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
+ return 1;
+ else
+ return 0;
+}
+char IsDecimal(char c)
+{
+ if (c >= '0' && c <= '9')
+ return 1;
+ else
+ return 0;
+}
+char IsLetter(char c)
+{
+ if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
+ return 1;
+ else
+ {
+ return 0;
+ }
+}
+char IsBinary(char c)
+{
+ if (c == '0' || c == '1')
+ return 1;
+ else
+ {
+ return 0;
+ }
+}
+char IsOctal(char c)
+{
+ if (c >= '0' && c <= '7')
+ return 1;
+ else
+ return 0;
+}
+
+char sgetc(char* str)
+{
+ static int idx = 0;
+ char c = str[idx];
+ if (c)
+ {
+ idx++;
+ return c;
+ }
+ else
+ {
+ return EOF;
+ }
+}
\ No newline at end of file
diff --git a/hyperdbg/ScriptEngine/src/scanner.h b/hyperdbg/ScriptEngine/src/scanner.h
new file mode 100644
index 00000000..061a03d9
--- /dev/null
+++ b/hyperdbg/ScriptEngine/src/scanner.h
@@ -0,0 +1,64 @@
+#ifndef SCANNER_H
+#define SCANNER_H
+#include
+
+//#define SCRIPTENGINE_EXPORTS
+#define TOKEN_VALUE_MAX_LEN 100
+#define TOKEN_LIST_INIT_SIZE 16
+typedef enum TOKEN_TYPE
+{
+ ID,
+ DECIMAL,
+ HEX,
+ OCTAL,
+ BINARY,
+ SPECIAL_TOKEN,
+ KEYWORD,
+ WHITE_SPACE,
+ COMMENT,
+ REGISTER,
+ PSEUDO_REGISTER,
+ NON_TERMINAL,
+ SEMANTIC_RULE,
+ END_OF_STACK,
+ EPSILON,
+ TEMP,
+ UNKNOWN
+} TOKEN_TYPE;
+
+
+
+struct _TOKEN
+{
+ TOKEN_TYPE Type;
+ char *Value;
+};
+
+typedef struct _TOKEN *TOKEN;
+
+typedef struct _TOKEN_LIST
+{
+ TOKEN *Head;
+ unsigned int Pointer;
+ unsigned int Size;
+} * TOKEN_LIST;
+
+TOKEN NewToken(void);
+TOKEN_LIST NewTokenList(void);
+void PrintTokenList(TOKEN_LIST TokenList);
+void PrintToken(TOKEN Token);
+TOKEN_LIST Push(TOKEN_LIST TokenList, TOKEN Token);
+TOKEN Pop(TOKEN_LIST TokenList);
+TOKEN Top(TOKEN_LIST TokenList);
+void Append(TOKEN Token, char c);
+TOKEN GetToken(char *c, char* str);
+TOKEN Scan(char* str, char* c);
+char IsHex(char c);
+char IsDecimal(char c);
+char IsLetter(char c);
+char IsBinary(char c);
+char IsOctal(char c);
+
+char sgetc(char* str);
+
+#endif
\ No newline at end of file
diff --git a/hyperdbg/hprdbghv/hprdbghv.vcxproj b/hyperdbg/hprdbghv/hprdbghv.vcxproj
index 0de985e0..8c2d1c0e 100644
--- a/hyperdbg/hprdbghv/hprdbghv.vcxproj
+++ b/hyperdbg/hprdbghv/hprdbghv.vcxproj
@@ -30,6 +30,7 @@
KMDF
Universal
false
+ false
Windows10
diff --git a/hyperdbg/hyperdbg.sln b/hyperdbg/hyperdbg.sln
index 3faef099..34349a8d 100644
--- a/hyperdbg/hyperdbg.sln
+++ b/hyperdbg/hyperdbg.sln
@@ -20,9 +20,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "include", "include", "{1997
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hprdbgctrl", "hprdbgctrl\hprdbgctrl.vcxproj", "{809C3AD5-3211-4992-A472-9D81D124C5FA}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C2D44C60-3F23-4972-8F60-21083B9FB112} = {C2D44C60-3F23-4972-8F60-21083B9FB112}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg-test", "hyperdbg-test\hyperdbg-test.vcxproj", "{C3DC85E1-0559-4B58-9792-DE421472DFE9}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ScriptEngine", "ScriptEngine\ScriptEngine.vcxproj", "{C2D44C60-3F23-4972-8F60-21083B9FB112}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -57,6 +62,14 @@ Global
{C3DC85E1-0559-4B58-9792-DE421472DFE9}.Release|x64.Build.0 = Release|x64
{C3DC85E1-0559-4B58-9792-DE421472DFE9}.Release|x86.ActiveCfg = Release|Win32
{C3DC85E1-0559-4B58-9792-DE421472DFE9}.Release|x86.Build.0 = Release|Win32
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Debug|x64.ActiveCfg = Debug|x64
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Debug|x64.Build.0 = Debug|x64
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Debug|x86.ActiveCfg = Debug|Win32
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Debug|x86.Build.0 = Debug|Win32
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Release|x64.ActiveCfg = Release|x64
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Release|x64.Build.0 = Release|x64
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Release|x86.ActiveCfg = Release|Win32
+ {C2D44C60-3F23-4972-8F60-21083B9FB112}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE