2929# - License: GPL 3.0
3030
3131import questionary
32+ import sys
3233
3334
35+ is_dev_mode = False
36+
37+ if len (sys .argv ) != 1 :
38+ if sys .argv [1 ] == "--dev" :
39+ is_dev_mode = True
3440
3541
3642class options :
@@ -60,120 +66,195 @@ def __init__(self, enum_name, file_path, function_name, cross_platform, is_linux
6066
6167def prompt ():
6268 # 1: enum name
63- enum_answer = questionary .text ("What's the name of the enum? (i.e. VBOX_REG or HYPERVISOR_STR)" ).ask ()
64- enum_answer = enum_answer .upper ()
69+ enum_answer = ""
70+ if is_dev_mode :
71+ enum_answer = "TEST"
72+ else :
73+ enum_answer = questionary .text ("What's the name of the enum? (i.e. VBOX_REG or HYPERVISOR_STR)" ).ask ()
74+ enum_answer = enum_answer .upper ()
6575
6676
6777 # 2: technique file
68- file_path = questionary .path ("What's the path to the technique file?" ).ask ()
69- if not file_path .endswith (".cpp" ) and not file_path .endswith (".cc" ):
70- raise ValueError ("file input MUST be a .cpp file" )
71- with open (file_path , 'r' ) as file :
72- is_static = False
73- for line in file :
74- if "#include" in line .lower ():
75- raise ValueError ("The cpp file will be directly copied to the lib verbatim, do not add #include as this will end up in vmaware.hpp" )
76- if "static" in line :
77- is_static = True
78-
79- if not is_static :
80- raise ValueError ("The function must be set as static" )
78+ file_path = ""
79+ if is_dev_mode :
80+ file_path = "../archive/techniques/test.cpp"
81+ else :
82+ while True :
83+ file_path = questionary .path ("What's the path to the technique file?" ).ask ()
84+ if not file_path .endswith (".cpp" ) and not file_path .endswith (".cc" ):
85+ print ("file input MUST be a .cpp file" )
86+ continue
87+
88+ with open (file_path , 'r' ) as file :
89+ is_static = False
90+ for line in file :
91+ if "#include" in line .lower ():
92+ print ("The cpp file will be directly copied to the lib verbatim, so do not add #include as this will mess up include orders." )
93+ continue
94+
95+ if "static" in line :
96+ is_static = True
97+
98+ if not is_static :
99+ print ("The function must be set as static" )
100+ continue
101+
102+ break
103+
81104
82105 # 3: function name
83- function_name = questionary .text ("What's the name of the technqiue function in your .cpp file?" ).ask ()
84- function_name = function_name .lower ()
85- if "(" in function_name or ")" in function_name :
86- function_name = function_name .replace ("(" , "" ).replace (")" , "" )
106+ function_name = ""
107+ if is_dev_mode :
108+ function_name = "test"
109+ else :
110+ function_name = questionary .text ("What's the name of the function in your .cpp file? example: new_technique()" ).ask ()
111+ function_name = function_name .lower ()
112+ if "(" in function_name or ")" in function_name :
113+ function_name = function_name .replace ("(" , "" ).replace (")" , "" )
87114
88115
89116 # 4: is it cross-platform?
90- cross_platform = questionary .confirm ("Is it cross-platform?" ).ask ()
91- is_linux = False
92- is_win = False
93- is_mac = False
94- if cross_platform == True :
117+ cross_platform = False
118+
119+ if is_dev_mode :
120+ cross_platform = False
95121 is_linux = True
96- is_win = True
97- is_mac = True
122+ is_win = False
123+ is_mac = False
98124 else :
99- choices = questionary .checkbox (
100- "Which OS does this technique support?" ,
101- choices = [
102- "Linux" ,
103- "Windows" ,
104- "MacOS"
105- ]
106- ).ask ()
107- if "Linux" in choices :
125+ cross_platform = questionary .confirm ("Is it cross-platform?" ).ask ()
126+ is_linux = False
127+ is_win = False
128+ is_mac = False
129+ if cross_platform == True :
108130 is_linux = True
109- if "Windows" in choices :
110131 is_win = True
111- if "MacOS" in choices :
112132 is_mac = True
133+ else :
134+ choices = questionary .checkbox (
135+ "Which OS does this technique support?" ,
136+ choices = [
137+ "Linux" ,
138+ "Windows" ,
139+ "MacOS"
140+ ]
141+ ).ask ()
142+ if "Linux" in choices :
143+ is_linux = True
144+ if "Windows" in choices :
145+ is_win = True
146+ if "MacOS" in choices :
147+ is_mac = True
113148
114149
115150 # 5: certainty score
116- certainty = questionary .text ("What's the score of your technique?" ).ask ()
117- if certainty == "" :
118- raise ValueError ("A score is mandatory (0 to 100)" )
151+ if is_dev_mode :
152+ score = 50
153+ else :
154+ certainty = ""
155+ while True :
156+ certainty = questionary .text ("What's the score of your technique? (0-100)" ).ask ()
157+ if certainty == "" :
158+ print ("A score is mandatory, try again" )
159+ continue
160+
161+ if 0 <= int (certainty ) <= 100 :
162+ break
163+ else :
164+ print ("Score must be between 0 and 100, try again" )
165+ continue
119166
167+ score = int (certainty )
120168
121- score = int (certainty )
122169
123170
124171 # 6: description
125172 description = ""
126- while True :
127- text = questionary .text ("What's the description of your technique? (30-100 characters)" ).ask ()
128- if len (text ) < 30 :
129- print ("Too short, try again\n " )
130- continue
131- if len (text ) > 100 :
132- print ("Too long, try again\n " )
133- continue
134- description = text
135- break
173+ if is_dev_mode :
174+ description = "testing, this is a boilerplate technique"
175+ else :
176+ while True :
177+ text = questionary .text ("What's the description of your technique? (30-100 characters)" ).ask ()
178+ if len (text ) < 30 :
179+ print ("Too short, try again\n " )
180+ continue
181+ if len (text ) > 100 :
182+ print ("Too long, try again\n " )
183+ continue
184+ description = text
185+ break
136186
137187 # 7: short description
138188 short_description = ""
139- while True :
140- text = questionary .text ("What is your technique checking for? This will appear in the CLI, so be as minimal as you can (max 30 characters)" ).ask ()
141- if len (text ) > 30 :
142- print ("Too long, try again\n " )
143- continue
144- if len (text ) > len (description ):
145- print ("The answer cannot be longer than the actual description from the previous question\n " )
146- continue
147- short_description = text
148- break
189+ if is_dev_mode :
190+ short_description = "testing, ignore"
191+ else :
192+ while True :
193+ text = questionary .text ("What is your technique checking for? This will appear in the CLI, so be as minimal as you can (max 25 characters)" ).ask ()
194+ if len (text ) > 25 :
195+ print ("Too long, try again\n " )
196+ continue
197+ if len (text ) > len (description ):
198+ print ("The answer cannot be longer than the actual description from the previous question\n " )
199+ continue
200+ short_description = text
201+ break
149202
150203
151204 # 8: author
152- author = questionary .text ("Who is the author? (optional, can be left empty)" ).ask ()
205+ author = ""
206+ if is_dev_mode :
207+ author = ""
208+ else :
209+ author = questionary .text ("Who is the author? (optional, can be left empty)" ).ask ()
153210
154211
155212 # 9: link
156- link = questionary .text ("If there's a source for the technique's origin, paste the link here (optional, can be left empty)" ).ask ()
213+ link = ""
214+ if is_dev_mode :
215+ link = ""
216+ else :
217+ link = questionary .text ("If there's a source for the technique's origin, paste the link here (optional, can be left empty)" ).ask ()
157218
158219
159220 # 10: permissions
160- is_admin = questionary .confirm ("Does it require admin permissions?" ).ask ()
221+ is_admin = False
222+ if is_dev_mode :
223+ is_admin = False
224+ else :
225+ is_admin = questionary .confirm ("Does it require admin permissions?" ).ask ()
161226
162227
163228 # 11: GPL
164- is_gpl = questionary .confirm ("Is it GPL?" ).ask ()
229+ is_gpl = False
230+ if is_dev_mode :
231+ is_gpl = True
232+ else :
233+ is_gpl = questionary .confirm ("Is it GPL?" ).ask ()
165234
166235
167236 # 12: 32-bit
168- only_32_bit = questionary .confirm ("Is it 32-bit only? (no support for 64-bit systems)" ).ask ()
237+ only_32_bit = False
238+ if is_dev_mode :
239+ only_32_bit = False
240+ else :
241+ only_32_bit = questionary .confirm ("Is it 32-bit only? (no support for 64-bit systems)" ).ask ()
169242
170243
171244 # 13: x86
172- is_x86 = questionary .confirm ("Is it x86 only? (no support for ARM for example)" ).ask ()
245+ is_x86 = False
246+ if is_dev_mode :
247+ is_x86 = True
248+ else :
249+ is_x86 = questionary .confirm ("Is it x86 only? (no support for ARM for example)" ).ask ()
173250
174251
175252 # 14: notes
176- notes = questionary .text ("Are there any extra notes you want to add? (leave this empty if it's unnecessary)" ).ask ()
253+ notes = ""
254+ if is_dev_mode :
255+ notes = ""
256+ else :
257+ notes = questionary .text ("Are there any extra notes you want to add? (leave this empty if it's unnecessary)" ).ask ()
177258
178259
179260 return options (
@@ -197,13 +278,15 @@ def prompt():
197278 )
198279
199280
200- def write_header (options ):
201- with open ('../src/vmaware.hpp' , 'r' ) as file :
281+ def write_header (options , header_file ):
282+ with open (header_file , 'r' ) as file :
202283 lines = file .readlines ()
203284
204285 new_code = []
205286 update_count = 0
206287
288+ if options .is_gpl and header_file == "../src/vmaware_MIT.hpp" :
289+ return
207290
208291 for line in lines :
209292 # if the line is empty, skip
@@ -304,28 +387,21 @@ def write_header(options):
304387
305388 # modify the technique table with the new technique appended
306389 if "// ADD NEW TECHNIQUE STRUCTURE HERE" in line :
390+ code_str = (
391+ "std::make_pair(VM::" +
392+ options .enum_name +
393+ ", VM::core::technique(" +
394+ str (options .score ) +
395+ ", VM::" +
396+ options .function_name +
397+ ")),\n "
398+ )
399+
307400 if options .is_gpl :
308- new_code .append (
309- "/* GPL */ " +
310- "{ VM::" +
311- options .enum_name +
312- ", { " +
313- str (options .score ) +
314- ", VM::" +
315- options .function_name +
316- " } },\n "
317- )
401+ new_code .append ("/* GPL */ " + code_str )
318402 else :
319- new_code .append (
320- tab +
321- "{ VM::" +
322- options .enum_name +
323- ", { " +
324- str (options .score ) +
325- ", VM::" +
326- options .function_name +
327- " } },\n "
328- )
403+ new_code .append (tab + code_str )
404+
329405 update_count += 1
330406
331407
@@ -349,7 +425,7 @@ def write_header(options):
349425
350426
351427 # commit the new changes from the buffer array
352- with open ("../src/vmaware.hpp" , "w" ) as file :
428+ with open (header_file , "w" ) as file :
353429 for line in new_code :
354430 file .write (line )
355431
@@ -480,6 +556,7 @@ def write_docs(options):
480556if __name__ == "__main__" :
481557 options_object = prompt ()
482558
483- write_header (options_object )
559+ write_header (options_object , "../src/vmaware.hpp" )
560+ write_header (options_object , "../src/vmaware_MIT.hpp" )
484561 write_cli (options_object )
485562 write_docs (options_object )
0 commit comments