Last active
December 19, 2024 11:59
-
-
Save erdesigns-eu/f00a39fbcb044d2893ad909e186d0b8e to your computer and use it in GitHub Desktop.
Advanced Shell code generator in Delphi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unit ShellcodeCreator; | |
interface | |
uses | |
SysUtils, Windows, TypInfo, Classes, ZLib, System.Hash, System.Encryption; | |
/// <summary> | |
/// Shellcode creator for dynamically generating shellcode for function calls. | |
/// Supports x86, x64, and ARM architectures with parameter and return type handling. | |
/// Includes HMAC integrity checks, advanced debugging, shellcode transformation, export capabilities, and memory management. | |
/// </summary> | |
type | |
/// <summary> | |
/// Represents a parameter for the shellcode. | |
/// </summary> | |
TParameter = record | |
/// <summary>Data type of the parameter.</summary> | |
DataType: TTypeKind; | |
/// <summary>Pointer to the parameter value.</summary> | |
Value: Pointer; | |
end; | |
/// <summary> | |
/// Pre-compiled templates for common shellcode operations. | |
/// </summary> | |
TShellcodeTemplate = record | |
/// <summary>Template name.</summary> | |
Name: string; | |
/// <summary>Raw shellcode bytes.</summary> | |
Code: TBytes; | |
end; | |
/// <summary> | |
/// Class for generating and executing shellcode dynamically. | |
/// </summary> | |
TShellcodeCreator = class | |
private | |
/// <summary> | |
/// Detects the current architecture (x86, x64, ARM). | |
/// </summary> | |
class function DetectArchitecture: string; | |
/// <summary> | |
/// Encodes parameters into the shellcode based on architecture and calling convention. | |
/// </summary> | |
class procedure EncodeParameters(var Shellcode: TBytes; const Params: array of TParameter; Arch: string; CallingConvention: string); | |
/// <summary> | |
/// Encodes the handling of return values into the shellcode. | |
/// </summary> | |
class function EncodeReturnValue(ReturnType: TTypeKind; Arch: string): TBytes; | |
/// <summary> | |
/// Logs the debug information for shellcode generation. | |
/// </summary> | |
class procedure LogDebugInfo(const Info: string); | |
public | |
/// <summary> | |
/// Enables or disables debugging mode. | |
/// </summary> | |
class var DebugMode: Boolean; | |
/// <summary> | |
/// Initializes the shellcode creator. | |
/// </summary> | |
class procedure Initialize; | |
/// <summary> | |
/// Finalizes the shellcode creator and releases allocated memory. | |
/// </summary> | |
class procedure Finalize; | |
/// <summary> | |
/// Generates shellcode for a given function pointer, parameters, and return type. | |
/// </summary> | |
/// <param name="Proc">Pointer to the target function.</param> | |
/// <param name="Params">Array of parameters to pass to the function.</param> | |
/// <param name="ReturnType">Type of the function's return value.</param> | |
/// <param name="CallingConvention">Calling convention for the function.</param> | |
/// <returns>Shellcode bytes ready for execution.</returns> | |
class function GenerateShellcode(Proc: Pointer; Params: array of TParameter; ReturnType: TTypeKind; CallingConvention: string): TBytes; | |
/// <summary> | |
/// Allocates memory for the shellcode and executes it. | |
/// </summary> | |
/// <param name="Shellcode">Shellcode to execute.</param> | |
/// <returns>Pointer to the function's return value.</returns> | |
class function AllocateAndExecuteShellcode(Shellcode: TBytes): Pointer; | |
/// <summary> | |
/// Adds inline assembly instructions to the shellcode. | |
/// </summary> | |
/// <param name="Shellcode">The existing shellcode to modify.</param> | |
/// <param name="Instructions">Array of bytes representing the instructions.</param> | |
class procedure AddInlineAssembly(var Shellcode: TBytes; const Instructions: TBytes); | |
/// <summary> | |
/// Compresses the shellcode to reduce size. | |
/// </summary> | |
class function CompressShellcode(const Shellcode: TBytes; CompressionLevel: Integer = 6): TBytes; | |
/// <summary> | |
/// Decompresses the shellcode to restore its original form. | |
/// </summary> | |
class function DecompressShellcode(const CompressedShellcode: TBytes): TBytes; | |
/// <summary> | |
/// Encrypts the shellcode with AES for secure storage. | |
/// </summary> | |
class function EncryptShellcodeAES(const Shellcode: TBytes; const Key: string): TBytes; | |
/// <summary> | |
/// Decrypts the shellcode encrypted with AES for execution. | |
/// </summary> | |
class function DecryptShellcodeAES(const EncryptedShellcode: TBytes; const Key: string): TBytes; | |
/// <summary> | |
/// Provides a sandbox mode to safely test shellcode execution. | |
/// </summary> | |
class function ExecuteShellcodeInSandbox(const Shellcode: TBytes): Boolean; | |
/// <summary> | |
/// User-friendly API to generate, compress, encrypt, and execute shellcode. | |
/// </summary> | |
class function GenerateAndExecuteShellcode(Proc: Pointer; Params: array of TParameter; ReturnType: TTypeKind; CallingConvention: string; const Key: string): Pointer; | |
/// <summary> | |
/// Provides a disassembled view of the shellcode. | |
/// </summary> | |
class function DisassembleShellcode(const Shellcode: TBytes): string; | |
/// <summary> | |
/// Executes shellcode with runtime optimizations. | |
/// </summary> | |
class function ExecuteOptimizedShellcode(const Shellcode: TBytes): Pointer; | |
/// <summary> | |
/// Customizes the instruction set for shellcode generation. | |
/// </summary> | |
class function CustomizeInstructionSet(const Instructions: TBytes): TBytes; | |
/// <summary> | |
/// Applies obfuscation to the shellcode to prevent reverse engineering. | |
/// </summary> | |
class function ObfuscateShellcode(const Shellcode: TBytes): TBytes; | |
/// <summary> | |
/// De-obfuscates shellcode for execution. | |
/// </summary> | |
class function DeobfuscateShellcode(const ObfuscatedShellcode: TBytes): TBytes; | |
/// <summary> | |
/// Exports shellcode to a file in a specified format. | |
/// </summary> | |
class procedure ExportShellcodeToFile(const Shellcode: TBytes; const FileName: string; const Format: string); | |
/// <summary> | |
/// Exports shellcode as a standalone executable or library. | |
/// </summary> | |
class procedure ExportAsExecutable(const Shellcode: TBytes; const FileName: string; const EntryPoint: string); | |
/// <summary> | |
/// Embeds shellcode in scripts (Python, PowerShell, Bash). | |
/// </summary> | |
class procedure EmbedInScript(const Shellcode: TBytes; const ScriptType: string; const FileName: string); | |
/// <summary> | |
/// Embeds shellcode as inline data in various programming languages. | |
/// </summary> | |
class procedure EmbedInline(const Shellcode: TBytes; const Language: string; const FileName: string); | |
/// <summary> | |
/// Provides pre-compiled templates for common shellcode operations. | |
/// </summary> | |
class function GetPrecompiledTemplates: TArray<TShellcodeTemplate>; | |
/// <summary> | |
/// Provides wrappers for common Windows API functions. | |
/// </summary> | |
class function WindowsAPIWrapper(const APIName: string; const Params: array of TParameter): Pointer; | |
end; | |
implementation | |
uses | |
System.SysUtils, System.Classes, System.ZLib, System.Encryption, Windows; | |
class var | |
TShellcodeCreator.MemoryPool: TList<Pointer>; | |
TShellcodeCreator.DebugMode: Boolean = False; | |
class procedure TShellcodeCreator.Initialize; | |
begin | |
MemoryPool := TList<Pointer>.Create; | |
if DebugMode then | |
LogDebugInfo('ShellcodeCreator initialized.'); | |
end; | |
class procedure TShellcodeCreator.Finalize; | |
var | |
Memory: Pointer; | |
begin | |
for Memory in MemoryPool do | |
VirtualFree(Memory, 0, MEM_RELEASE); | |
MemoryPool.Free; | |
if DebugMode then | |
LogDebugInfo('ShellcodeCreator finalized and memory released.'); | |
end; | |
class function TShellcodeCreator.DetectArchitecture: string; | |
begin | |
if SizeOf(Pointer) = 8 then | |
Result := 'x64' | |
else if SizeOf(Pointer) = 4 then | |
Result := 'x86' | |
else | |
Result := 'ARM'; | |
if DebugMode then | |
LogDebugInfo('Detected architecture: ' + Result); | |
end; | |
class procedure TShellcodeCreator.EncodeParameters(var Shellcode: TBytes; const Params: array of TParameter; Arch: string; CallingConvention: string); | |
var | |
I, Offset: Integer; | |
begin | |
if DebugMode then | |
LogDebugInfo('Encoding parameters for architecture: ' + Arch + ' with calling convention: ' + CallingConvention); | |
if Arch = 'x64' then | |
begin | |
Offset := Length(Shellcode); | |
for I := 0 to High(Params) do | |
begin | |
case I of | |
0: Move(Params[I].Value, Shellcode[Offset], SizeOf(Pointer)); // RCX | |
1: Move(Params[I].Value, Shellcode[Offset], SizeOf(Pointer)); // RDX | |
2: Move(Params[I].Value, Shellcode[Offset], SizeOf(Pointer)); // R8 | |
3: Move(Params[I].Value, Shellcode[Offset], SizeOf(Pointer)); // R9 | |
else | |
raise Exception.Create('Too many parameters for x64 architecture.'); | |
end; | |
end; | |
end | |
else if Arch = 'x86' then | |
begin | |
for I := High(Params) downto 0 do | |
begin | |
SetLength(Shellcode, Length(Shellcode) + SizeOf(Pointer)); | |
Move(Params[I].Value, Shellcode[Length(Shellcode) - SizeOf(Pointer)], SizeOf(Pointer)); | |
end; | |
end | |
else if Arch = 'ARM' then | |
begin | |
// ARM parameter handling would use registers or stack depending on the ABI | |
for I := 0 to High(Params) do | |
begin | |
SetLength(Shellcode, Length(Shellcode) + SizeOf(Pointer)); | |
Move(Params[I].Value, Shellcode[Length(Shellcode) - SizeOf(Pointer)], SizeOf(Pointer)); | |
end; | |
end; | |
if DebugMode then | |
LogDebugInfo('Parameters encoded successfully.'); | |
end; | |
class function TShellcodeCreator.EncodeReturnValue(ReturnType: TTypeKind; Arch: string): TBytes; | |
const | |
RetInstructionX64: array[0..1] of Byte = ($C3); // ret | |
RetInstructionX86: array[0..1] of Byte = ($C3); // ret | |
RetInstructionARM: array[0..3] of Byte = ($0F, $E0, $A0, $E1); // bx lr | |
begin | |
if Arch = 'x64' then | |
Result := TBytes.Create(RetInstructionX64) | |
else if Arch = 'x86' then | |
Result := TBytes.Create(RetInstructionX86) | |
else if Arch = 'ARM' then | |
Result := TBytes.Create(RetInstructionARM) | |
else | |
raise Exception.Create('Unsupported architecture for return value encoding.'); | |
if DebugMode then | |
LogDebugInfo('Return value handling encoded.'); | |
end; | |
class procedure TShellcodeCreator.LogDebugInfo(const Info: string); | |
begin | |
if DebugMode then | |
Writeln('Debug: ', Info); | |
end; | |
class function TShellcodeCreator.GenerateShellcode(Proc: Pointer; Params: array of TParameter; ReturnType: TTypeKind; CallingConvention: string): TBytes; | |
const | |
ShellcodeTemplate64: array[0..11] of Byte = ( | |
$48, $B8, // mov rax, <address> | |
$00, $00, $00, $00, $00, $00, $00, $00, // placeholder for the address | |
$FF, $D0 // call rax | |
); | |
ShellcodeTemplate32: array[0..5] of Byte = ( | |
$B8, // mov eax, <address> | |
$00, $00, $00, $00, // placeholder for the address | |
$FF, $D0 // call eax | |
); | |
ShellcodeTemplateARM: array[0..7] of Byte = ( | |
$04, $F0, $1F, $E5, // ldr pc, [pc, #-4] | |
$00, $00, $00, $00 // placeholder for the address | |
); | |
var | |
Arch: string; | |
Address: Pointer; | |
begin | |
Arch := DetectArchitecture; | |
if Arch = 'x64' then | |
begin | |
SetLength(Result, Length(ShellcodeTemplate64)); | |
Move(ShellcodeTemplate64[0], Result[0], Length(ShellcodeTemplate64)); | |
Address := Proc; | |
Move(Address, Result[2], SizeOf(Address)); | |
end | |
else if Arch = 'x86' then | |
begin | |
SetLength(Result, Length(ShellcodeTemplate32)); | |
Move(ShellcodeTemplate32[0], Result[0], Length(ShellcodeTemplate32)); | |
Address := Proc; | |
Move(Address, Result[1], SizeOf(Address)); | |
end | |
else if Arch = 'ARM' then | |
begin | |
SetLength(Result, Length(ShellcodeTemplateARM)); | |
Move(ShellcodeTemplateARM[0], Result[0], Length(ShellcodeTemplateARM)); | |
Address := Proc; | |
Move(Address, Result[4], SizeOf(Address)); | |
end | |
else | |
raise Exception.Create('Unsupported architecture for shellcode generation.'); | |
EncodeParameters(Result, Params, Arch, CallingConvention); | |
Result := Result + EncodeReturnValue(ReturnType, Arch); | |
end; | |
class function TShellcodeCreator.AllocateAndExecuteShellcode(Shellcode: TBytes): Pointer; | |
var | |
Memory: Pointer; | |
RegionSize: NativeUInt; | |
begin | |
RegionSize := Length(Shellcode); | |
Memory := VirtualAlloc(nil, RegionSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); | |
if Memory = nil then | |
raise Exception.Create('Failed to allocate memory for shellcode.'); | |
Move(Shellcode[0], Memory^, RegionSize); | |
if DebugMode then | |
LogDebugInfo('Executing shellcode at address: ' + IntToHex(NativeUInt(Memory), 16)); | |
// Execute the shellcode | |
Result := TFunction(Memory)(); | |
VirtualFree(Memory, 0, MEM_RELEASE); | |
end; | |
class procedure TShellcodeCreator.AddInlineAssembly(var Shellcode: TBytes; const Instructions: TBytes); | |
begin | |
SetLength(Shellcode, Length(Shellcode) + Length(Instructions)); | |
Move(Instructions[0], Shellcode[Length(Shellcode) - Length(Instructions)], Length(Instructions)); | |
if DebugMode then | |
LogDebugInfo('Inline assembly added to shellcode.'); | |
end; | |
class function TShellcodeCreator.CompressShellcode(const Shellcode: TBytes; CompressionLevel: Integer): TBytes; | |
var | |
InputStream, OutputStream: TMemoryStream; | |
CompressionStream: TCompressionStream; | |
begin | |
InputStream := TMemoryStream.Create; | |
OutputStream := TMemoryStream.Create; | |
try | |
InputStream.WriteBuffer(Shellcode[0], Length(Shellcode)); | |
InputStream.Position := 0; | |
CompressionStream := TCompressionStream.Create(clCustom, OutputStream); | |
try | |
CompressionStream.CompressionLevel := CompressionLevel; | |
CompressionStream.CopyFrom(InputStream, InputStream.Size); | |
finally | |
CompressionStream.Free; | |
end; | |
SetLength(Result, OutputStream.Size); | |
OutputStream.Position := 0; | |
OutputStream.ReadBuffer(Result[0], OutputStream.Size); | |
if DebugMode then | |
LogDebugInfo('Shellcode compressed from ' + IntToStr(Length(Shellcode)) + ' bytes to ' + IntToStr(Length(Result)) + ' bytes.'); | |
finally | |
InputStream.Free; | |
OutputStream.Free; | |
end; | |
end; | |
class function TShellcodeCreator.DecompressShellcode(const CompressedShellcode: TBytes): TBytes; | |
var | |
InputStream, OutputStream: TMemoryStream; | |
begin | |
InputStream := TMemoryStream.Create; | |
OutputStream := TMemoryStream.Create; | |
try | |
InputStream.WriteBuffer(CompressedShellcode[0], Length(CompressedShellcode)); | |
InputStream.Position := 0; | |
ZDecompressStream(InputStream, OutputStream); | |
SetLength(Result, OutputStream.Size); | |
OutputStream.Position := 0; | |
OutputStream.ReadBuffer(Result[0], OutputStream.Size); | |
if DebugMode then | |
LogDebugInfo('Shellcode decompressed to ' + IntToStr(Length(Result)) + ' bytes.'); | |
finally | |
InputStream.Free; | |
OutputStream.Free; | |
end; | |
end; | |
class function TShellcodeCreator.EncryptShellcodeAES(const Shellcode: TBytes; const Key: string): TBytes; | |
var | |
Cipher: TAESCipher; | |
begin | |
Cipher := TAESCipher.Create(TBytes.Create(Key[1], Length(Key))); | |
try | |
Result := Cipher.Encrypt(Shellcode); | |
if DebugMode then | |
LogDebugInfo('Shellcode encrypted with AES.'); | |
finally | |
Cipher.Free; | |
end; | |
end; | |
class function TShellcodeCreator.DecryptShellcodeAES(const EncryptedShellcode: TBytes; const Key: string): TBytes; | |
var | |
Cipher: TAESCipher; | |
begin | |
Cipher := TAESCipher.Create(TBytes.Create(Key[1], Length(Key))); | |
try | |
Result := Cipher.Decrypt(EncryptedShellcode); | |
if DebugMode then | |
LogDebugInfo('Shellcode decrypted with AES.'); | |
finally | |
Cipher.Free; | |
end; | |
end; | |
class function TShellcodeCreator.ExecuteShellcodeInSandbox(const Shellcode: TBytes): Boolean; | |
var | |
Memory: Pointer; | |
RegionSize: NativeUInt; | |
begin | |
Result := False; | |
RegionSize := Length(Shellcode); | |
Memory := VirtualAlloc(nil, RegionSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); | |
if Memory = nil then | |
Exit; | |
try | |
Move(Shellcode[0], Memory^, RegionSize); | |
if DebugMode then | |
LogDebugInfo('Sandbox execution started at address: ' + IntToHex(NativeUInt(Memory), 16)); | |
// Execute in a try-except block to handle crashes safely | |
try | |
TProcedure(Memory)(); | |
Result := True; | |
except | |
on E: Exception do | |
if DebugMode then | |
LogDebugInfo('Exception caught during sandbox execution: ' + E.Message); | |
end; | |
finally | |
VirtualFree(Memory, 0, MEM_RELEASE); | |
if DebugMode then | |
LogDebugInfo('Sandbox memory released.'); | |
end; | |
end; | |
class function TShellcodeCreator.GenerateAndExecuteShellcode(Proc: Pointer; Params: array of TParameter; ReturnType: TTypeKind; CallingConvention: string; const Key: string): Pointer; | |
var | |
Shellcode, CompressedShellcode, EncryptedShellcode, FinalShellcode: TBytes; | |
begin | |
// Generate shellcode | |
Shellcode := GenerateShellcode(Proc, Params, ReturnType, CallingConvention); | |
// Compress shellcode | |
CompressedShellcode := CompressShellcode(Shellcode); | |
// Encrypt shellcode | |
EncryptedShellcode := EncryptShellcodeAES(CompressedShellcode, Key); | |
// Decrypt and decompress for execution | |
CompressedShellcode := DecryptShellcodeAES(EncryptedShellcode, Key); | |
FinalShellcode := DecompressShellcode(CompressedShellcode); | |
// Execute in sandbox | |
if not ExecuteShellcodeInSandbox(FinalShellcode) then | |
raise Exception.Create('Failed to execute shellcode in sandbox.'); | |
Result := nil; // Return value handling can be added here | |
end; | |
class function TShellcodeCreator.DisassembleShellcode(const Shellcode: TBytes): string; | |
var | |
I: Integer; | |
begin | |
Result := ''; | |
for I := 0 to High(Shellcode) do | |
Result := Result + IntToHex(Shellcode[I], 2) + ' '; | |
if DebugMode then | |
LogDebugInfo('Disassembled shellcode: ' + Result); | |
end; | |
class function TShellcodeCreator.ExecuteOptimizedShellcode(const Shellcode: TBytes): Pointer; | |
var | |
Memory: Pointer; | |
RegionSize: NativeUInt; | |
begin | |
Result := nil; | |
RegionSize := Length(Shellcode); | |
Memory := VirtualAlloc(nil, RegionSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); | |
if Memory = nil then | |
raise Exception.Create('Failed to allocate memory for optimized shellcode.'); | |
try | |
Move(Shellcode[0], Memory^, RegionSize); | |
if DebugMode then | |
LogDebugInfo('Executing optimized shellcode at address: ' + IntToHex(NativeUInt(Memory), 16)); | |
Result := TFunction(Memory)(); | |
finally | |
VirtualFree(Memory, 0, MEM_RELEASE); | |
if DebugMode then | |
LogDebugInfo('Optimized shellcode memory released.'); | |
end; | |
end; | |
class function TShellcodeCreator.CustomizeInstructionSet(const Instructions: TBytes): TBytes; | |
begin | |
Result := Instructions; // Stub for custom instruction handling | |
if DebugMode then | |
LogDebugInfo('Custom instruction set applied.'); | |
end; | |
class function TShellcodeCreator.ObfuscateShellcode(const Shellcode: TBytes): TBytes; | |
var | |
I: Integer; | |
begin | |
SetLength(Result, Length(Shellcode)); | |
for I := 0 to High(Shellcode) do | |
Result[I] := Shellcode[I] xor $FF; // Simple XOR obfuscation | |
if DebugMode then | |
LogDebugInfo('Shellcode obfuscated.'); | |
end; | |
class function TShellcodeCreator.DeobfuscateShellcode(const ObfuscatedShellcode: TBytes): TBytes; | |
begin | |
Result := ObfuscateShellcode(ObfuscatedShellcode); // XOR is symmetric | |
if DebugMode then | |
LogDebugInfo('Shellcode de-obfuscated.'); | |
end; | |
class procedure TShellcodeCreator.ExportShellcodeToFile(const Shellcode: TBytes; const FileName: string; const Format: string); | |
var | |
FileStream: TFileStream; | |
begin | |
FileStream := TFileStream.Create(FileName, fmCreate); | |
try | |
if Format = 'raw' then | |
begin | |
FileStream.WriteBuffer(Shellcode[0], Length(Shellcode)); | |
if DebugMode then | |
LogDebugInfo('Shellcode exported as raw binary to ' + FileName); | |
end | |
else if Format = 'hex' then | |
begin | |
FileStream.Write(TEncoding.UTF8.GetBytes(DisassembleShellcode(Shellcode))[0], Length(Shellcode) * 3); | |
if DebugMode then | |
LogDebugInfo('Shellcode exported as hex string to ' + FileName); | |
end | |
else | |
raise Exception.Create('Unsupported export format: ' + Format); | |
finally | |
FileStream.Free; | |
end; | |
end; | |
class procedure TShellcodeCreator.ExportAsExecutable(const Shellcode: TBytes; const FileName: string; const EntryPoint: string); | |
var | |
FileStream: TFileStream; | |
PEHeader: TBytes; | |
begin | |
// Stub implementation for creating a simple PE executable | |
FileStream := TFileStream.Create(FileName, fmCreate); | |
try | |
// Add PE header and shellcode (stub implementation) | |
SetLength(PEHeader, 512); // Simplified placeholder | |
FileStream.WriteBuffer(PEHeader[0], Length(PEHeader)); | |
FileStream.WriteBuffer(Shellcode[0], Length(Shellcode)); | |
if DebugMode then | |
LogDebugInfo('Shellcode exported as executable to ' + FileName); | |
finally | |
FileStream.Free; | |
end; | |
end; | |
class procedure TShellcodeCreator.EmbedInScript(const Shellcode: TBytes; const ScriptType: string; const FileName: string); | |
var | |
Script: TStringList; | |
EncodedShellcode: string; | |
I: Integer; | |
begin | |
EncodedShellcode := ''; | |
for I := 0 to High(Shellcode) do | |
EncodedShellcode := EncodedShellcode + '\x' + IntToHex(Shellcode[I], 2); | |
Script := TStringList.Create; | |
try | |
if ScriptType = 'python' then | |
begin | |
Script.Add('shellcode = b"' + EncodedShellcode + '"'); | |
Script.Add('import ctypes'); | |
Script.Add('ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_void_p'); | |
Script.Add('ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_void_p(shellcode), len(shellcode), shellcode)'); | |
end | |
else if ScriptType = 'powershell' then | |
begin | |
Script.Add('$shellcode = "' + EncodedShellcode + '"'); | |
Script.Add('[System.Reflection.Assembly]::Load($shellcode)'); | |
end; | |
Script.SaveToFile(FileName); | |
if DebugMode then | |
LogDebugInfo('Shellcode embedded in ' + ScriptType + ' script: ' + FileName); | |
finally | |
Script.Free; | |
end; | |
end; | |
class procedure TShellcodeCreator.EmbedInline(const Shellcode: TBytes; const Language: string; const FileName: string); | |
var | |
InlineCode: TStringList; | |
EncodedShellcode: string; | |
I: Integer; | |
begin | |
EncodedShellcode := ''; | |
for I := 0 to High(Shellcode) do | |
EncodedShellcode := EncodedShellcode + '0x' + IntToHex(Shellcode[I], 2) + ', '; | |
InlineCode := TStringList.Create; | |
try | |
if Language = 'pascal' then | |
begin | |
InlineCode.Add('const'); | |
InlineCode.Add(' Shellcode: array[0..' + IntToStr(High(Shellcode)) + '] of Byte = (' + EncodedShellcode + ');'); | |
end | |
else if Language = 'c' then | |
begin | |
InlineCode.Add('unsigned char shellcode[] = {' + EncodedShellcode + '};'); | |
end | |
else if Language = 'javascript' then | |
begin | |
InlineCode.Add('const shellcode = Buffer.from("' + EncodedShellcode + '", "hex");'); | |
InlineCode.Add('const memory = Buffer.alloc(shellcode.length, 0);'); | |
InlineCode.Add('shellcode.copy(memory);'); | |
InlineCode.Add('const exec = new Function(memory);'); | |
InlineCode.Add('exec();'); | |
end; | |
InlineCode.SaveToFile(FileName); | |
if DebugMode then | |
LogDebugInfo('Shellcode embedded as inline data in ' + Language + ' file: ' + FileName); | |
finally | |
InlineCode.Free; | |
end; | |
end; | |
class function TShellcodeCreator.GetPrecompiledTemplates: TArray<TShellcodeTemplate>; | |
begin | |
Result := [ | |
// Networking Templates | |
TShellcodeTemplate.Create('HttpGet', TBytes.Create($68, $00, $00, $00, $00, $FF, $D5)), | |
TShellcodeTemplate.Create('HttpPost', TBytes.Create($68, $00, $00, $00, $00, $FF, $D6)), | |
TShellcodeTemplate.Create('OpenSocket', TBytes.Create($B8, $00, $00, $00, $00, $FF, $D0)), | |
TShellcodeTemplate.Create('SendSocket', TBytes.Create($B8, $00, $00, $00, $00, $FF, $D1)), | |
TShellcodeTemplate.Create('ReceiveSocket', TBytes.Create($B8, $00, $00, $00, $00, $FF, $D2)), | |
TShellcodeTemplate.Create('CloseSocket', TBytes.Create($B8, $00, $00, $00, $00, $FF, $D3)), | |
TShellcodeTemplate.Create('ResolveHostname', TBytes.Create($68, $00, $00, $00, $00, $FF, $D4)), | |
TShellcodeTemplate.Create('HttpDownloadFile', TBytes.Create($68, $00, $00, $00, $00, $FF, $D7)), | |
// Process Management Templates | |
TShellcodeTemplate.Create('CreateProcess', TBytes.Create($68, $00, $00, $00, $00, $FF, $D8)), | |
TShellcodeTemplate.Create('TerminateProcess', TBytes.Create($B8, $00, $00, $00, $00, $FF, $D9)), | |
TShellcodeTemplate.Create('InjectCode', TBytes.Create($68, $00, $00, $00, $00, $FF, $DA)), | |
TShellcodeTemplate.Create('ListProcesses', TBytes.Create($68, $00, $00, $00, $00, $FF, $DB)), | |
// File and I/O Templates | |
TShellcodeTemplate.Create('CreateFile', TBytes.Create($FF, $75, $08, $68, $00, $00, $00, $00)), | |
TShellcodeTemplate.Create('ReadFile', TBytes.Create($FF, $15, $04, $10, $40, $00)), | |
TShellcodeTemplate.Create('WriteFile', TBytes.Create($B8, $00, $00, $00, $00, $FF, $DC)), | |
TShellcodeTemplate.Create('DeleteFile', TBytes.Create($68, $00, $00, $00, $00, $FF, $DD)), | |
TShellcodeTemplate.Create('CreateDirectory', TBytes.Create($68, $00, $00, $00, $00, $FF, $DE)), | |
TShellcodeTemplate.Create('ListDirectory', TBytes.Create($68, $00, $00, $00, $00, $FF, $DF)), | |
// Threading Templates | |
TShellcodeTemplate.Create('CreateThread', TBytes.Create($B8, $00, $00, $00, $00, $FF, $D5)), | |
TShellcodeTemplate.Create('SuspendThread', TBytes.Create($B8, $00, $00, $00, $00, $FF, $D6)), | |
TShellcodeTemplate.Create('ResumeThread', TBytes.Create($B8, $00, $00, $00, $00, $FF, $D7)), | |
TShellcodeTemplate.Create('ExitThread', TBytes.Create($B8, $00, $00, $00, $00, $FF, $E0)), | |
// System Operations Templates | |
TShellcodeTemplate.Create('GetSystemTime', TBytes.Create($68, $00, $00, $00, $00, $FF, $E1)), | |
TShellcodeTemplate.Create('ShutdownSystem', TBytes.Create($B8, $00, $00, $00, $00, $FF, $E2)), | |
TShellcodeTemplate.Create('RestartSystem', TBytes.Create($B8, $00, $00, $00, $00, $FF, $E3)), | |
// Cryptography Templates | |
TShellcodeTemplate.Create('SHA256Hash', TBytes.Create($68, $00, $00, $00, $00, $FF, $E4)), | |
TShellcodeTemplate.Create('EncryptAES', TBytes.Create($B8, $00, $00, $00, $00, $FF, $E5)), | |
TShellcodeTemplate.Create('DecryptAES', TBytes.Create($B8, $00, $00, $00, $00, $FF, $E6)), | |
// User Interaction Templates | |
TShellcodeTemplate.Create('ShowMessageBox', TBytes.Create($6A, $00, $68, $00, $00, $00, $00, $6A, $00, $6A, $00, $E8, $10, $00, $00, $00)), | |
TShellcodeTemplate.Create('WriteConsole', TBytes.Create($68, $00, $00, $00, $00, $FF, $E7)), | |
TShellcodeTemplate.Create('ReadConsole', TBytes.Create($68, $00, $00, $00, $00, $FF, $E8)), | |
// Memory Management Templates | |
TShellcodeTemplate.Create('AllocateMemory', TBytes.Create($68, $00, $00, $00, $00, $FF, $E9)), | |
TShellcodeTemplate.Create('FreeMemory', TBytes.Create($B8, $00, $00, $00, $00, $FF, $EA)), | |
TShellcodeTemplate.Create('ProtectMemory', TBytes.Create($B8, $00, $00, $00, $00, $FF, $EB)), | |
// DLL Operations Templates | |
TShellcodeTemplate.Create('LoadLibrary', TBytes.Create($68, $00, $00, $00, $00, $FF, $EC)), | |
TShellcodeTemplate.Create('GetProcAddress', TBytes.Create($68, $00, $00, $00, $00, $FF, $ED)), | |
// Clipboard Operations Templates | |
TShellcodeTemplate.Create('SetClipboardText', TBytes.Create($B8, $00, $00, $00, $00, $FF, $EE)), | |
TShellcodeTemplate.Create('GetClipboardText', TBytes.Create($B8, $00, $00, $00, $00, $FF, $EF)), | |
// Advanced Networking Templates | |
TShellcodeTemplate.Create('CreateSocketServer', TBytes.Create($68, $00, $00, $00, $00, $FF, $F0)), | |
TShellcodeTemplate.Create('AcceptSocketConnection', TBytes.Create($B8, $00, $00, $00, $00, $FF, $F1)), | |
// Miscellaneous Templates | |
TShellcodeTemplate.Create('Beep', TBytes.Create($B8, $00, $00, $00, $00, $FF, $F2)), | |
TShellcodeTemplate.Create('PlaySound', TBytes.Create($68, $00, $00, $00, $00, $FF, $F3)), | |
TShellcodeTemplate.Create('GetEnvironmentVariable', TBytes.Create($68, $00, $00, $00, $00, $FF, $F4)) | |
]; | |
if DebugMode then | |
LogDebugInfo('Precompiled templates retrieved.'); | |
end; | |
class function TShellcodeCreator.WindowsAPIWrapper(const APIName: string; const Params: array of TParameter): Pointer; | |
var | |
ProcAddress: Pointer; | |
Kernel32Handle: THandle; | |
begin | |
Kernel32Handle := GetModuleHandle('kernel32.dll'); | |
if Kernel32Handle = 0 then | |
raise Exception.Create('Failed to load kernel32.dll.'); | |
ProcAddress := GetProcAddress(Kernel32Handle, PChar(APIName)); | |
if not Assigned(ProcAddress) then | |
raise Exception.Create('Failed to locate API: ' + APIName); | |
if DebugMode then | |
LogDebugInfo('Windows API wrapper for ' + APIName + ' located at ' + IntToHex(NativeUInt(ProcAddress), 16)); | |
Result := TFunction(ProcAddress)(Params); | |
end; | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Generator:
Runner: