Initial commit

This commit is contained in:
Alukym
2023-05-12 20:16:10 +08:00
commit a8433f06ee
1167 changed files with 1036549 additions and 0 deletions

View File

@ -0,0 +1,303 @@
/* Arrays of asctime-date day and month strs, rfc1123-date day and month strs, and rfc850-date day and month strs. */
static const char* kDayStrs[] = {
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday",
"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
static const char* kMonthStrs[] = {
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December",
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
/* NOTE that these are ordered this way on purpose. */
static const char* kUSTimeZones[] = {"PST", "PDT", "MST", "MDT", "CST", "CDT", "EST", "EDT"};
/* extern */ const UInt8*
_CFGregorianDateCreateWithBytes(CFAllocatorRef alloc, const UInt8* bytes, CFIndex length, CFGregorianDate* date, CFTimeZoneRef* tz) {
UInt8 buffer[256]; /* Any dates longer than this are not understood. */
length = (length == 256) ? 255 : length;
memmove(buffer, bytes, length);
buffer[length] = '\0'; /* Guarantees every compare will fail if trying to index off the end. */
memset(date, 0, sizeof(date[0]));
if (tz) *tz = NULL;
do {
size_t i;
CFIndex scan = 0;
UInt8 c = buffer[scan];
/* Skip leading whitespace */
while (isspace(c))
c = buffer[++scan];
/* Check to see if there is a weekday up front. */
if (!isdigit(c)) {
for (i = 0; i < (sizeof(kDayStrs) / sizeof(kDayStrs[0])); i++) {
if (!memcmp(kDayStrs[i], &buffer[scan], strlen(kDayStrs[i])))
break;
}
if (i >=(sizeof(kDayStrs) / sizeof(kDayStrs[0])))
break;
scan += strlen(kDayStrs[i]);
c = buffer[scan];
while (isspace(c) || c == ',')
c = buffer[++scan];
}
/* check for asctime where month comes first */
if (!isdigit(c)) {
for (i = 0; i < (sizeof(kMonthStrs) / sizeof(kMonthStrs[0])); i++) {
if (!memcmp(kMonthStrs[i], &buffer[scan], strlen(kMonthStrs[i])))
break;
}
if (i >= (sizeof(kMonthStrs) / sizeof(kMonthStrs[0])))
break;
date->month = (i % 12) + 1;
scan += strlen(kMonthStrs[i]);
c = buffer[scan];
while (isspace(c))
c = buffer[++scan];
if (!isdigit(c))
break;
}
/* Read the day of month */
for (i = 0; isdigit(c) && (i < 2); i++) {
date->day *= 10;
date->day += c - '0';
c = buffer[++scan];
}
while (isspace(c) || c == '-')
c = buffer[++scan];
/* Not asctime so now comes the month. */
if (date->month == 0) {
if (isdigit(c)) {
for (i = 0; isdigit(c) && (i < 2); i++) {
date->month *= 10;
date->month += c - '0';
c = buffer[++scan];
}
}
else {
for (i = 0; i < (sizeof(kMonthStrs) / sizeof(kMonthStrs[0])); i++) {
if (!memcmp(kMonthStrs[i], &buffer[scan], strlen(kMonthStrs[i])))
break;
}
if (i >= (sizeof(kMonthStrs) / sizeof(kMonthStrs[0])))
break;
date->month = (i % 12) + 1;
scan += strlen(kMonthStrs[i]);
c = buffer[scan];
}
while (isspace(c) || c == '-')
c = buffer[++scan];
/* Read the year */
for (i = 0; isdigit(c) && (i < 4); i++) {
date->year *= 10;
date->year += c - '0';
c = buffer[++scan];
}
while (isspace(c))
c = buffer[++scan];
}
/* Read the hours */
for (i = 0; isdigit(c) && (i < 2); i++) {
date->hour *= 10;
date->hour += c - '0';
c = buffer[++scan];
}
if (c != ':')
break;
c = buffer[++scan];
/* Read the minutes */
for (i = 0; isdigit(c) && (i < 2); i++) {
date->minute *= 10;
date->minute += c - '0';
c = buffer[++scan];
}
if (c == ':') {
c = buffer[++scan];
/* Read the seconds */
for (i = 0; isdigit(c) && (i < 2); i++) {
date->second *= 10;
date->second += c - '0';
c = buffer[++scan];
}
c = buffer[++scan];
}
/* If haven't read the year yet, now is the time. */
if (date->year == 0) {
while (isspace(c))
c = buffer[++scan];
/* Read the year */
for (i = 0; isdigit(c) && (i < 4); i++) {
date->year *= 10;
date->year += c - '0';
c = buffer[++scan];
}
}
if (date->year && date->year < 100) {
if (date->year < 70)
date->year += 2000; /* My CC is still using 2-digit years! */
else
date->year += 1900; /* Bad 2 byte clients */
}
while (isspace(c))
c = buffer[++scan];
if (c && tz) {
/* If it has absolute offset, read the hours and minutes. */
if ((c == '+') || (c == '-')) {
char sign = c;
CFTimeInterval minutes = 0, offset = 0;
c = buffer[++scan];
/* Read the hours */
for (i = 0; isdigit(c) && (i < 2); i++) {
offset *= 10;
offset += c - '0';
c = buffer[++scan];
}
/* Read the minutes */
for (i = 0; isdigit(c) && (i < 2); i++) {
minutes *= 10;
minutes += c - '0';
c = buffer[++scan];
}
offset *= 60;
offset += minutes;
if (sign == '-') offset *= -60;
else offset *= 60;
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, offset);
}
/* If it's not GMT/UT time, need to parse the alpha offset. */
else if (!strncmp((const char*)(&buffer[scan]), "UT", 2)) {
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, 0);
scan += 2;
}
else if (!strncmp((const char*)(&buffer[scan]), "GMT", 3)) {
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, 0);
scan += 3;
}
else if (isalpha(c)) {
UInt8 next = buffer[scan + 1];
/* Check for military time. */
if ((c != 'J') && (!next || isspace(next) || (next == '*'))) {
if (c == 'Z')
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, 0);
else {
CFTimeInterval offset = (c < 'N') ? (c - 'A' + 1) : ('M' - c);
offset *= 60;
if (next == '*') {
scan++;
offset = (offset < 0) ? offset - 30 : offset + 30;
}
offset *= 60;
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, 0);
}
}
else {
for (i = 0; i < (sizeof(kUSTimeZones) / sizeof(kUSTimeZones[0])); i++) {
if (!memcmp(kUSTimeZones[i], &buffer[scan], strlen(kUSTimeZones[i]))) {
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, (-8 + (i >> 2) + (i & 0x1)) * 3600);
scan += strlen(kUSTimeZones[i]);
break;
}
}
}
}
}
if (!CFGregorianDateIsValid(*date, kCFGregorianAllUnits))
break;
return bytes + scan;
} while (1);
memset(date, 0, sizeof(date[0]));
if (tz) {
if (*tz) CFRelease(*tz);
*tz = NULL;
}
return bytes;
}
/* extern */ CFIndex
_CFGregorianDateCreateWithString(CFAllocatorRef alloc, CFStringRef str, CFGregorianDate* date, CFTimeZoneRef* tz) {
UInt8 buffer[256]; /* Any dates longer than this are not understood. */
CFIndex length = CFStringGetLength(str);
CFIndex result = 0;
CFStringGetBytes(str, CFRangeMake(0, length), kCFStringEncodingASCII, 0, FALSE, buffer, sizeof(buffer), &length);
if (length)
result = _CFGregorianDateCreateWithBytes(alloc, buffer, length, date, tz) - buffer;
else {
memset(date, 0, sizeof(date[0]));
if (tz) *tz = NULL;
}
return result;
}

View File

@ -0,0 +1,526 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Diagnostics;
using System.Threading;
using System.Collections.Generic;
using System.Text;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedParameter.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable once CheckNamespace
[assembly: SuppressIldasmAttribute()]
[assembly: Obfuscation(Feature = "renaming", Exclude = true)]
namespace VMProtect
{
/// <summary>
/// Serial number status flags
/// </summary>
[Flags]
public enum SerialState
{
/// <summary>
/// No problems.
/// </summary>
Success = 0x00000000,
/// <summary>
/// Licensing module is corrupted. This may be caused by cracking attempts. Usually you will never get this flag.
/// </summary>
Corrupted = 0x00000001,
/// <summary>
/// Serial number is invalid. You will get this flag if licensing module will be unable to decrypt serial number or
/// if the serial number is not yet set or it is empty.
/// </summary>
Invalid = 0x00000002,
/// <summary>
/// Serial number is correct, but it was blacklisted in VMProtect.
/// </summary>
Blacklisted = 0x00000004,
/// <summary>
/// Serial number is expired. You will get this flag if serial number has expiration date chunk and this date is in the past.
/// You may read the expiration date by calling GetSerialNumberData() function.
/// </summary>
DateExpired = 0x00000008,
/// <summary>
/// Running time limit for this session is over. You may read limit value by calling GetSerialNumberData() function.
/// </summary>
RunningTimeOver = 0x00000010,
/// <summary>
/// Serial number is locked to another hardware identifier.
/// </summary>
BadHwid = 0x00000020,
/// <summary>
/// Serial number will not work with this version of application, because it has "Max Build Date" block and the application was
/// build after those date. You may read maximal build date by calling GetSerialNumberData() function.
/// </summary>
MaxBuildExpired = 0x00000040,
};
/// <summary>
/// Serial number contents
/// </summary>
public class SerialNumberData
{
/// <summary>
/// Serial number status
/// </summary>
public SerialState State;
/// <summary>
/// End user name
/// </summary>
public string UserName;
/// <summary>
/// End user E-Mail
/// </summary>
public string EMail;
/// <summary>
/// Serial number expiration date.
/// </summary>
public DateTime Expires;
/// <summary>
/// Max date of build, that will accept this key
/// </summary>
public DateTime MaxBuild;
/// <summary>
/// Running time in minutes
/// </summary>
public int RunningTime;
/// <summary>
/// Up to 255 bytes of user data
/// </summary>
public byte[] UserData;
public SerialNumberData()
{
State = SerialState.Invalid;
Expires = DateTime.MaxValue;
MaxBuild = DateTime.MaxValue;
RunningTime = 0;
UserData = new byte[0];
UserName = "";
EMail = "";
}
};
/// <summary>
/// Activation API status codes
/// </summary>
public enum ActivationStatus
{
/// <summary>
/// Activation successful, the serial field contains a serial number.
/// </summary>
Ok,
/// <summary>
/// The activation module was unable to connect the Web License Manager.
/// </summary>
NoConnection,
/// <summary>
/// The server returned unexpected reply. This means configuration problems or probably a cracking attempt.
/// </summary>
BadReply,
/// <summary>
/// The activation code is blocked on the server. This doesn't mean that the number of possible activations is exceeded,
/// this means that this exactly code is banned by the vendor, so the user is trying to cheat you.
/// </summary>
Banned,
/// <summary>
/// Something goes really wrong here. The error means that the internal activation stuff is not working,
/// it is not safe to continue with the activation, registration and so on.
/// </summary>
Corrupted,
/// <summary>
/// The code has been successfully passed to the server and it was unable to find it in the database.
/// Probably the user made a mistake, so it is worth asking the user to check the entered code for mistakes.
/// </summary>
BadCode,
/// <summary>
/// The code has been used too many times and cannot be used more. This doesn't mean the code is bad or banned, it is OK.
/// The user may contact vendor to ask/purchase more activations, or the user may deactivate some installations to increase
/// the number of activations available for that code.
/// </summary>
AlreadyUsed,
/// <summary>
/// This is the deactivation error code that means that the server can't find the serial number that the user tries to deactivate.
/// </summary>
SerialUnknown,
/// <summary>
/// The code is expired.
/// </summary>
Expired,
/// <summary>
/// Activation/deactivation features are not available.
/// </summary>
NotAvailable
};
[Flags]
[VMProtect.DeleteOnCompilation]
enum CoreOption
{
MEMORY_PROTECTION = 0x1,
CHECK_DEBUGGER = 0x2
}
public class Core
{
public static bool IsProtected() { return true; }
public static bool IsDebuggerPresent(bool checkKernelMode)
{
if (GlobalData.IsDebuggerDetected())
return true;
if (Debugger.IsAttached || Debugger.IsLogging())
return true;
if (Win32.IsDebuggerPresent() || Win32.CheckRemoteDebuggerPresent())
return true;
return false;
}
internal static bool FindFirmwareVendor(byte[] data)
{
for (var i = 0; i < data.Length; i++)
{
if (i + 3 < data.Length && data[i + 0] == 'Q' && data[i + 1] == 'E' && data[i + 2] == 'M' && data[i + 3] == 'U')
return true;
if (i + 8 < data.Length && data[i + 0] == 'M' && data[i + 1] == 'i' && data[i + 2] == 'c' && data[i + 3] == 'r' && data[i + 4] == 'o' && data[i + 5] == 's' && data[i + 6] == 'o' && data[i + 7] == 'f' && data[i + 8] == 't')
return true;
if (i + 6 < data.Length && data[i + 0] == 'i' && data[i + 1] == 'n' && data[i + 2] == 'n' && data[i + 3] == 'o' && data[i + 4] == 't' && data[i + 5] == 'e' && data[i + 6] == 'k')
return true;
if (i + 9 < data.Length && data[i + 0] == 'V' && data[i + 1] == 'i' && data[i + 2] == 'r' && data[i + 3] == 't' && data[i + 4] == 'u' && data[i + 5] == 'a' && data[i + 6] == 'l' && data[i + 7] == 'B' && data[i + 8] == 'o' && data[i + 9] == 'x')
return true;
if (i + 5 < data.Length && data[i + 0] == 'V' && data[i + 1] == 'M' && data[i + 2] == 'w' && data[i + 3] == 'a' && data[i + 4] == 'r' && data[i + 5] == 'e')
return true;
if (i + 8 < data.Length && data[i + 0] == 'P' && data[i + 1] == 'a' && data[i + 2] == 'r' && data[i + 3] == 'a' && data[i + 4] == 'l' && data[i + 5] == 'l' && data[i + 6] == 'e' && data[i + 7] == 'l' && data[i + 8] == 's')
return true;
}
return false;
}
public static bool IsVirtualMachinePresent()
{
var info = CpuId.Invoke(1);
if (((info[2] >> 31) & 1) != 0)
{
// check Hyper-V root partition
info = CpuId.Invoke(0x40000000);
if (info[1] == 0x7263694d && info[2] == 0x666f736f && info[3] == 0x76482074) // "Microsoft Hv"
{
info = CpuId.Invoke(0x40000003);
if ((info[1] & 1) != 0)
return false;
}
return true;
}
else
{
int size;
uint tableSignature = (byte)'R' << 24 | (byte)'S' << 16 | (byte)'M' << 8 | (byte)'B';
try
{
size = (int)Win32.EnumSystemFirmwareTables(tableSignature, IntPtr.Zero, 0);
}
catch (EntryPointNotFoundException) { size = 0; }
if (size > 0)
{
IntPtr nativeBuffer = Marshal.AllocHGlobal(size);
Win32.EnumSystemFirmwareTables(tableSignature, nativeBuffer, (uint)size);
byte[] buffer = new byte[size];
Marshal.Copy(nativeBuffer, buffer, 0, size);
Marshal.FreeHGlobal(nativeBuffer);
for (var i = 0; i < size / sizeof(uint); i += sizeof(uint))
{
uint tableId = BitConverter.ToUInt32(buffer, i);
int dataSize = (int)Win32.GetSystemFirmwareTable(tableSignature, tableId, IntPtr.Zero, 0);
if (dataSize > 0)
{
nativeBuffer = Marshal.AllocHGlobal(dataSize);
Win32.GetSystemFirmwareTable(tableSignature, tableId, nativeBuffer, (uint)dataSize);
byte[] data = new byte[dataSize];
Marshal.Copy(nativeBuffer, data, 0, dataSize);
Marshal.FreeHGlobal(nativeBuffer);
if (FindFirmwareVendor(data))
return true;
}
}
}
}
return false;
}
public static bool IsValidImageCRC()
{
if (GlobalData.IsPatchDetected())
return false;
long instance = Marshal.GetHINSTANCE(typeof(Core).Module).ToInt64();
// check memory CRC
var crcSize = (uint)Marshal.ReadInt32(new IntPtr(instance + (uint)Faces.CRC_TABLE_SIZE));
var crcPosition = (uint)Faces.CRC_TABLE_ENTRY;
bool isValid = true;
var crcInfo = new byte[12];
var crc32 = new CRC32();
var crcHash = (uint)Marshal.ReadInt32(new IntPtr(instance + (uint)Faces.CRC_TABLE_HASH));
if (crcHash != crc32.Hash(new IntPtr(instance + crcPosition), crcSize))
isValid = false;
{
var crcCryptor = new CRCValueCryptor();
for (var i = 0; i < crcSize; i += crcInfo.Length)
{
Marshal.Copy(new IntPtr(instance + crcPosition + i), crcInfo, 0, crcInfo.Length);
uint address = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 0));
uint size = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 4));
uint hash = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 8));
if (crc32.Hash(new IntPtr(instance + address), size) != hash)
isValid = false;
}
}
// check header and loader CRC
crcSize = (uint)Marshal.ReadInt32(new IntPtr(instance + GlobalData.LoaderCrcSize()));
crcPosition = GlobalData.LoaderCrcInfo();
crcHash = (uint)Marshal.ReadInt32(new IntPtr(instance + GlobalData.LoaderCrcHash()));
if (crcHash != crc32.Hash(new IntPtr(instance + crcPosition), crcSize))
isValid = false;
{
var crcCryptor = new CRCValueCryptor();
for (var i = 0; i < crcSize; i += crcInfo.Length)
{
Marshal.Copy(new IntPtr(instance + crcPosition + i), crcInfo, 0, crcInfo.Length);
uint address = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 0));
uint size = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 4));
uint hash = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 8));
if (crc32.Hash(new IntPtr(instance + address), size) != hash)
isValid = false;
}
}
return isValid;
}
public static string DecryptString() { return DecryptString((uint)Faces.STORAGE_INFO); }
public static bool FreeString(ref string value) { value = null; return true; }
public static SerialState SetSerialNumber(string serial)
{
LicensingManager licensing_manager = Instance.LicensingManager;
return licensing_manager != null ? licensing_manager.SetSerialNumber(serial) : SerialState.Corrupted;
}
public static SerialState GetSerialNumberState()
{
LicensingManager licensing_manager = Instance.LicensingManager;
return licensing_manager != null ? licensing_manager.GetSerialNumberState() : SerialState.Corrupted;
}
public static bool GetSerialNumberData(out SerialNumberData data)
{
data = new SerialNumberData();
LicensingManager licensing_manager = Instance.LicensingManager;
return licensing_manager != null ? licensing_manager.GetSerialNumberData(data) : false;
}
public static string GetCurrentHWID() { return Instance.HWID.ToString(); }
public static ActivationStatus ActivateLicense(string code, out string serial)
{
serial = string.Empty;
LicensingManager licensing_manager = Instance.LicensingManager;
return licensing_manager != null ? licensing_manager.ActivateLicense(code, out serial) : ActivationStatus.NotAvailable;
}
public static ActivationStatus DeactivateLicense(string serial)
{
LicensingManager licensing_manager = Instance.LicensingManager;
return licensing_manager != null ? licensing_manager.DeactivateLicense(serial) : ActivationStatus.NotAvailable;
}
public static ActivationStatus GetOfflineActivationString(string code, out string buf)
{
buf = string.Empty;
LicensingManager licensing_manager = Instance.LicensingManager;
return licensing_manager != null ? licensing_manager.GetOfflineActivationString(code, out buf) : ActivationStatus.NotAvailable;
}
public static ActivationStatus GetOfflineDeactivationString(string serial, out string buf)
{
buf = string.Empty;
LicensingManager licensing_manager = Instance.LicensingManager;
return licensing_manager != null ? licensing_manager.GetOfflineDeactivationString(serial, out buf) : ActivationStatus.NotAvailable;
}
public static readonly Core Instance = new Core();
public HardwareID HWID { get; private set; }
public StringManager StringManager { get; private set; }
public LicensingManager LicensingManager { get; private set; }
public ResourceManager ResourceManager { get; private set; }
private static string DecryptString(uint stringId) { return Instance.StringManager.DecryptString(stringId); }
public static void ShowMessage(string message) { Win32.ShowMessage(message, Assembly.GetExecutingAssembly().GetName().Name, MessageBoxButtons.OK, MessageBoxIcon.Error); }
private static void AntidebugThread()
{
Win32.NtSetInformationThread(Win32.CurrentThread, Win32.THREADINFOCLASS.ThreadHideFromDebugger, IntPtr.Zero, 0);
while (true)
{
if (Debugger.IsAttached || Debugger.IsLogging())
Environment.FailFast("");
if (Win32.IsDebuggerPresent() || Win32.CheckRemoteDebuggerPresent())
Environment.FailFast("");
Thread.Sleep(1000);
}
}
public bool Init(long instance)
{
var options = (uint)Faces.CORE_OPTIONS;
if ((options & (uint)CoreOption.CHECK_DEBUGGER) != 0)
{
var thread = new Thread(AntidebugThread);
thread.IsBackground = true;
thread.Start();
}
HWID = new HardwareID();
var pos = (uint)Faces.STRING_INFO;
if (pos != 0)
StringManager = new StringManager(instance);
pos = (uint)Faces.LICENSE_INFO;
if (pos != 0)
LicensingManager = new LicensingManager(instance);
pos = (uint)Faces.TRIAL_HWID;
if (pos != 0) {
var key = new byte[8];
Marshal.Copy(new IntPtr(instance + (uint)Faces.KEY_INFO), key, 0, key.Length);
var entry = new byte[64];
Marshal.Copy(new IntPtr(instance + pos), entry, 0, entry.Length);
CipherRC5 cipher = new CipherRC5(key);
entry = cipher.Decrypt(entry);
var value = new byte[(uint)Faces.TRIAL_HWID_SIZE];
Array.Copy(entry, 0, value, 0, value.Length);
if (!HWID.IsCorrect(value))
{
ShowMessage("This application cannot be executed on this computer.");
return false;
}
}
pos = (uint)Faces.RESOURCE_INFO;
if (pos != 0)
ResourceManager = new ResourceManager(instance);
return true;
}
public static uint DecryptBuffer(uint p3, uint p2, uint p1, uint p0)
{
return Instance.LicensingManager.DecryptBuffer(p3, p2, p1, p0);
}
#if !RUNTIME
public readonly Random RndGenerator = new Random();
public uint Rand32()
{
var a4 = new byte[4];
RndGenerator.NextBytes(a4);
return BitConverter.ToUInt32(a4, 0);
}
public ulong Rand64()
{
return (Rand32() << 32) | Rand32();
}
#endif
}
public class ResourceManager
{
public ResourceManager(long instance)
{
_instance = instance;
var key = new byte[8];
Marshal.Copy(new IntPtr(instance + (uint)Faces.KEY_INFO), key, 0, key.Length);
_cipher = new CipherRC5(key);
var resourceInfo = new byte[16];
var pos = (uint)Faces.RESOURCE_INFO;
var buffer = new byte[1024];
for (var i = 0; ;i += resourceInfo.Length)
{
Marshal.Copy(new IntPtr(instance + pos + i), resourceInfo, 0, resourceInfo.Length);
byte[] entry = _cipher.Decrypt(resourceInfo);
uint nameOffset = BitConverter.ToUInt32(entry, 0);
if (nameOffset == 0)
break;
for (var j = 0; j < buffer.Length / 2; j++)
{
var c = (ushort)(Marshal.ReadInt16(new IntPtr(instance + nameOffset + j * 2)) ^ (BitRotate.Left((uint)Faces.STRING_DECRYPT_KEY, j) + j));
if (c == 0)
{
_entries.Add(Encoding.Unicode.GetString(buffer, 0, j * 2), (uint)(pos + i));
break;
}
buffer[j * 2] = (byte)c;
buffer[j * 2 + 1] = (byte)(c >> 8);
}
}
AppDomain.CurrentDomain.AssemblyResolve += Handler;
}
private void DecryptData(ref byte[] data, uint key)
{
for (var c = 0; c < data.Length; c++)
{
data[c] = (byte)(data[c] ^ BitRotate.Left(key, c) + c);
}
}
private Assembly Handler(object sender, ResolveEventArgs args)
{
uint pos;
if (_entries.TryGetValue(args.Name, out pos))
{
var resourceInfo = new byte[16];
Marshal.Copy(new IntPtr(_instance + pos), resourceInfo, 0, resourceInfo.Length);
byte[] entry = _cipher.Decrypt(resourceInfo);
uint dataOffset = BitConverter.ToUInt32(entry, 4);
var data = new byte[BitConverter.ToUInt32(entry, 8)];
Marshal.Copy(new IntPtr(_instance + dataOffset), data, 0, data.Length);
DecryptData(ref data, (uint)Faces.STRING_DECRYPT_KEY);
try
{
var assembly = Assembly.Load(data);
return assembly;
}
catch (Exception)
{
}
}
return null;
}
private long _instance;
private CipherRC5 _cipher;
private readonly Dictionary<string, uint> _entries = new Dictionary<string, uint>();
}
}

View File

@ -0,0 +1,87 @@
using System;
using System.Runtime.InteropServices;
// ReSharper disable once CheckNamespace
namespace VMProtect
{
public static class CpuId
{
public static int[] Invoke(int level)
{
var codePointer = IntPtr.Zero;
try
{
// compile
byte[] codeBytes;
if (IntPtr.Size == 4)
{
codeBytes = new byte[30];
codeBytes[0] = 0x55; // push ebp
codeBytes[1] = 0x8B; codeBytes[2] = 0xEC; // mov ebp,esp
codeBytes[3] = 0x53; // push ebx
codeBytes[4] = 0x57; // push edi
codeBytes[5] = 0x8B; codeBytes[6] = 0x45; codeBytes[7] = 0x08; // mov eax, dword ptr [ebp+8] (move level into eax)
codeBytes[8] = 0x0F; codeBytes[9] = 0xA2; // cpuid
codeBytes[10] = 0x8B; codeBytes[11] = 0x7D; codeBytes[12] = 0x0C; // mov edi, dword ptr [ebp+12] (move address of buffer into edi)
codeBytes[13] = 0x89; codeBytes[14] = 0x07; // mov dword ptr [edi+0], eax (write eax, ... to buffer)
codeBytes[15] = 0x89; codeBytes[16] = 0x5F; codeBytes[17] = 0x04; // mov dword ptr [edi+4], ebx
codeBytes[18] = 0x89; codeBytes[19] = 0x4F; codeBytes[20] = 0x08; // mov dword ptr [edi+8], ecx
codeBytes[21] = 0x89; codeBytes[22] = 0x57; codeBytes[23] = 0x0C; // mov dword ptr [edi+12],edx
codeBytes[24] = 0x5F; // pop edi
codeBytes[25] = 0x5B; // pop ebx
codeBytes[26] = 0x8B; codeBytes[27] = 0xE5; // mov esp,ebp
codeBytes[28] = 0x5D; // pop ebp
codeBytes[29] = 0xc3; // ret
} else
{
codeBytes = new byte[26];
codeBytes[0] = 0x53; // push rbx this gets clobbered by cpuid
codeBytes[1] = 0x49; codeBytes[2] = 0x89; codeBytes[3] = 0xd0; // mov r8, rdx
codeBytes[4] = 0x89; codeBytes[5] = 0xc8; // mov eax, ecx
codeBytes[6] = 0x0F; codeBytes[7] = 0xA2; // cpuid
codeBytes[8] = 0x41; codeBytes[9] = 0x89; codeBytes[10] = 0x40; codeBytes[11] = 0x00; // mov dword ptr [r8+0], eax
codeBytes[12] = 0x41; codeBytes[13] = 0x89; codeBytes[14] = 0x58; codeBytes[15] = 0x04; // mov dword ptr [r8+4], ebx
codeBytes[16] = 0x41; codeBytes[17] = 0x89; codeBytes[18] = 0x48; codeBytes[19] = 0x08; // mov dword ptr [r8+8], ecx
codeBytes[20] = 0x41; codeBytes[21] = 0x89; codeBytes[22] = 0x50; codeBytes[23] = 0x0c; // mov dword ptr [r8+12], edx
codeBytes[24] = 0x5b; // pop rbx
codeBytes[25] = 0xc3; // ret
}
codePointer = Win32.VirtualAlloc(
IntPtr.Zero,
new UIntPtr((uint)codeBytes.Length),
Win32.AllocationType.Commit | Win32.AllocationType.Reserve,
Win32.MemoryProtection.ExecuteReadWrite
);
Marshal.Copy(codeBytes, 0, codePointer, codeBytes.Length);
var cpuIdDelg = (CpuIdDelegate)Marshal.GetDelegateForFunctionPointer(codePointer, typeof(CpuIdDelegate));
// invoke
var buffer = new int[4];
var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try
{
cpuIdDelg(level, buffer);
}
finally
{
handle.Free();
}
return buffer;
}
finally
{
if (codePointer != IntPtr.Zero)
{
Win32.VirtualFree(codePointer, UIntPtr.Zero, Win32.FreeType.Release);
}
}
}
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
private delegate void CpuIdDelegate(int level, int []buffer);
}
}

View File

@ -0,0 +1,195 @@
using System;
using System.Runtime.InteropServices;
// ReSharper disable once CheckNamespace
namespace VMProtect
{
public class CipherRC5
{
private const int R = 15; // number of rounds
private const int B = 8; // number of bytes in key
private const int C = 8 * B / BitRotate.W; // 16 - number u32s in key = ceil(8*B/W)
private const int T = 2 * (R + 1); // 34 - size of table _s = 2*(R+1) u32s
private readonly uint[] _s; // expanded key table
#if RUNTIME
private const uint P = (uint)Faces.RC5_P;
private const uint Q = (uint)Faces.RC5_Q;
#else
private static readonly uint P = Core.Instance.Rand32();
private static readonly uint Q = Core.Instance.Rand32();
public static byte[] CreateRandomKey()
{
var ret = new byte[B];
Core.Instance.RndGenerator.NextBytes(ret);
return ret;
}
#endif
public CipherRC5(byte[] key)
{
uint i, j, k, u = BitRotate.W / 8, a, b;
var l = new uint[C];
_s = new uint[T];
for (i = B - 1, l[C - 1] = 0; i != uint.MaxValue; i--)
l[i / u] = (l[i / u] << 8) + key[i];
for (_s[0] = P, i = 1; i < T; i++)
_s[i] = _s[i - 1] + Q;
for (a = b = i = j = k = 0; k < 3 * T; k++, i = (i + 1) % T, j = (j + 1) % C) // 3*T > 3*C
{
a = _s[i] = BitRotate.Left(_s[i] + a + b, 3);
b = l[j] = BitRotate.Left(l[j] + a + b, (int)(a + b));
}
}
[StructLayout(LayoutKind.Explicit)]
private struct Dword
{
[FieldOffset(0)]
public ulong dw;
[FieldOffset(0)]
public uint w0;
[FieldOffset(4)]
public uint w1;
}
private void Encrypt(ref Dword io)
{
uint i, a = io.w0 + _s[0], b = io.w1 + _s[1];
for (i = 1; i <= R; i++)
{
a = BitRotate.Left(a ^ b, (int)b) + _s[2 * i];
b = BitRotate.Left(b ^ a, (int)a) + _s[2 * i + 1];
}
io.w0 = a;
io.w1 = b;
}
private void Decrypt(ref Dword io)
{
uint i, b = io.w1, a = io.w0;
for (i = R; i > 0; i--)
{
b = BitRotate.Right(b - _s[2 * i + 1], (int)a) ^ a;
a = BitRotate.Right(a - _s[2 * i], (int)b) ^ b;
}
io.w1 = b - _s[1];
io.w0 = a - _s[0];
}
public byte[] Encrypt(byte[] ain)
{
var aout = new byte[ain.Length];
Encrypt(ain, aout);
return aout;
}
public byte[] Decrypt(byte[] ain)
{
var aout = new byte[ain.Length];
Decrypt(ain, aout);
return aout;
}
public void Encrypt(byte[] ain, byte[] aout)
{
var block = new Dword();
for (var i = 0; i < ain.Length; i += 8)
{
block.dw = BitConverter.ToUInt64(ain, i);
Encrypt(ref block);
BitConverter.GetBytes(block.dw).CopyTo(aout, i);
}
}
public void Decrypt(byte[] ain, byte[] aout)
{
var block = new Dword();
for (var i = 0; i < ain.Length; i += 8)
{
block.dw = BitConverter.ToUInt64(ain, i);
Decrypt(ref block);
BitConverter.GetBytes(block.dw).CopyTo(aout, i);
}
}
}
public class CRC32
{
static uint[] _table;
public CRC32()
{
if (_table == null)
{
_table = new uint[256];
for (var i = 0; i < 256; i++)
{
var entry = (uint)i;
for (var j = 0; j < 8; j++)
if ((entry & 1) == 1)
entry = (entry >> 1) ^ 0xedb88320u;
else
entry = entry >> 1;
_table[i] = entry;
}
}
}
public uint Hash(IntPtr ptr, uint size)
{
uint crc = 0;
for (var i = 0; i < size; i++)
crc = _table[(Marshal.ReadByte(new IntPtr(ptr.ToInt64() + i)) ^ crc) & 0xff] ^ (crc >> 8);
return ~crc;
}
}
public class CRCValueCryptor
{
private uint _key;
public CRCValueCryptor()
{
_key = (uint)Faces.CRC_INFO_SALT;
}
public uint Decrypt(uint value)
{
uint res = value ^ _key;
_key = BitRotate.Left(_key, 7) ^ res;
return res;
}
}
public class BitRotate
{
public const int W = 32; // u32 size in bits
public static uint Left(uint a, int offset)
{
var r1 = a << offset;
var r2 = a >> (W - offset);
return r1 | r2;
}
public static uint Right(uint a, int offset)
{
var r1 = a >> offset;
var r2 = a << (W - offset);
return r1 | r2;
}
public static uint Swap(uint value)
{
uint mask_xx_zz = (value & 0x00FF00FFU);
uint mask_ww_yy = (value & 0xFF00FF00U);
return ((mask_xx_zz >> 8) | (mask_xx_zz << 24)) +
((mask_ww_yy << 8) | (mask_ww_yy >> 24));
}
}
}

View File

@ -0,0 +1,170 @@
using System;
// ReSharper disable once CheckNamespace
// ReSharper disable InconsistentNaming
namespace VMProtect
{
[AttributeUsage(AttributeTargets.Enum)]
public sealed class DeleteOnCompilation : Attribute { }
[VMProtect.DeleteOnCompilation]
public enum Variables : uint
{
IS_PATCH_DETECTED,
IS_DEBUGGER_DETECTED,
LOADER_CRC_INFO,
LOADER_CRC_INFO_SIZE,
LOADER_CRC_INFO_HASH,
SESSION_KEY,
DRIVER_UNLOAD,
CRC_IMAGE_SIZE,
LOADER_STATUS,
SERVER_DATE,
RESERVED,
CPU_COUNT,
CPU_HASH,
COUNT = CPU_HASH + 32
}
[VMProtect.DeleteOnCompilation]
public enum Faces : uint
{
MASK = 0xFACE0000U,
RC5_P,
RC5_Q,
STRING_INFO,
RESOURCE_INFO,
STORAGE_INFO,
REGISTRY_INFO,
LICENSE_INFO,
LICENSE_INFO_SIZE,
KEY_INFO,
RUNTIME_ENTRY,
CRC_INFO_SALT,
CRC_TABLE_ENTRY,
CRC_TABLE_SIZE,
CRC_TABLE_HASH,
TRIAL_HWID,
TRIAL_HWID_SIZE,
CORE_OPTIONS,
IMAGE_BASE,
FILE_BASE,
NTOSKRNL_NAME,
HAL_NAME,
USER32_NAME,
MESSAGE_BOX_NAME,
KERNEL32_NAME,
CREATE_FILE_NAME,
CLOSE_HANDLE_NAME,
INITIALIZATION_ERROR,
PROC_NOT_FOUND,
ORDINAL_NOT_FOUND,
STRING_DECRYPT_KEY,
DRIVER_FORMAT_VALUE,
FILE_CORRUPTED,
LOADER_OPTIONS,
LOADER_DATA,
DEBUGGER_FOUND,
NT_SET_INFORMATION_PROCESS_NAME,
NT_RAISE_HARD_ERROR_NAME,
IS_WOW64_PROCESS_NAME,
WINE_GET_VERSION_NAME,
MACOSX_FORMAT_VALUE,
GNU_PTRACE,
UNREGISTERED_VERSION,
WTSAPI32_NAME,
WTS_SEND_MESSAGE_NAME,
NTDLL_NAME,
NT_QUERY_INFORMATION_NAME,
NT_SET_INFORMATION_THREAD_NAME,
SICE_NAME,
SIWVID_NAME,
NTICE_NAME,
ICEEXT_NAME,
SYSER_NAME,
VIRTUAL_MACHINE_FOUND,
SBIEDLL_NAME,
QUERY_VIRTUAL_MEMORY_NAME,
ENUM_SYSTEM_FIRMWARE_NAME,
GET_SYSTEM_FIRMWARE_NAME,
NT_QUERY_INFORMATION_PROCESS_NAME,
NT_VIRTUAL_PROTECT_NAME,
NT_OPEN_FILE_NAME,
NT_CREATE_SECTION_NAME,
NT_OPEN_SECTION_NAME,
NT_MAP_VIEW_OF_SECTION,
NT_UNMAP_VIEW_OF_SECTION,
NT_CLOSE,
SYSCALL,
NT_ALLOCATE_VIRTUAL_MEMORY_NAME,
NT_FREE_VIRTUAL_MEMORY_NAME,
PACKER_INFO = 0xFACE0100U,
PACKER_INFO_SIZE,
FILE_CRC_INFO,
FILE_CRC_INFO_SIZE,
LOADER_CRC_INFO,
LOADER_CRC_INFO_SIZE,
SECTION_INFO,
SECTION_INFO_SIZE,
FIXUP_INFO,
FIXUP_INFO_SIZE,
RELOCATION_INFO,
RELOCATION_INFO_SIZE,
IAT_INFO,
IAT_INFO_SIZE,
IMPORT_INFO,
IMPORT_INFO_SIZE,
INTERNAL_IMPORT_INFO,
INTERNAL_IMPORT_INFO_SIZE,
MEMORY_CRC_INFO,
MEMORY_CRC_INFO_SIZE,
DELAY_IMPORT_INFO,
DELAY_IMPORT_INFO_SIZE,
LOADER_CRC_INFO_HASH,
MEMORY_CRC_INFO_HASH,
TLS_INDEX_INFO,
VAR = 0xFACE0200U,
VAR_IS_PATCH_DETECTED = VAR | (Variables.IS_PATCH_DETECTED << 4),
VAR_IS_DEBUGGER_DETECTED = VAR | (Variables.IS_DEBUGGER_DETECTED << 4),
VAR_LOADER_CRC_INFO = VAR | (Variables.LOADER_CRC_INFO << 4),
VAR_LOADER_CRC_INFO_SIZE = VAR | (Variables.LOADER_CRC_INFO_SIZE << 4),
VAR_LOADER_CRC_INFO_HASH = VAR | (Variables.LOADER_CRC_INFO_HASH << 4),
VAR_SESSION_KEY = VAR | (Variables.SESSION_KEY << 4),
VAR_LOADER_STATUS = VAR | (Variables.LOADER_STATUS << 4),
VAR_SERVER_DATE = VAR | (Variables.SERVER_DATE << 4),
VAR_SALT = 0xFACE0300U,
VAR_IS_PATCH_DETECTED_SALT = VAR_SALT | Variables.IS_PATCH_DETECTED,
VAR_IS_DEBUGGER_DETECTED_SALT = VAR_SALT | Variables.IS_DEBUGGER_DETECTED,
VAR_LOADER_CRC_INFO_SALT = VAR_SALT | Variables.LOADER_CRC_INFO,
VAR_LOADER_CRC_INFO_SIZE_SALT = VAR_SALT | Variables.LOADER_CRC_INFO_SIZE,
VAR_LOADER_CRC_INFO_HASH_SALT = VAR_SALT | Variables.LOADER_CRC_INFO_HASH,
VAR_SERVER_DATE_SALT = VAR_SALT | Variables.SERVER_DATE,
}
public static class GlobalData
{
private static uint[] _v = new uint[(uint)Variables.COUNT];
public static bool IsPatchDetected() { return (_v[(uint)Faces.VAR_IS_PATCH_DETECTED] ^ (uint)Faces.VAR_IS_PATCH_DETECTED_SALT) != 0; }
public static bool IsDebuggerDetected() { return (_v[(uint)Faces.VAR_IS_DEBUGGER_DETECTED] ^ (uint)Faces.VAR_IS_DEBUGGER_DETECTED_SALT) != 0; }
public static uint LoaderCrcInfo() { return _v[(uint)Faces.VAR_LOADER_CRC_INFO] ^ (uint)Faces.VAR_LOADER_CRC_INFO_SALT; }
public static uint LoaderCrcSize() { return _v[(uint)Faces.VAR_LOADER_CRC_INFO_SIZE] ^ (uint)Faces.VAR_LOADER_CRC_INFO_SIZE_SALT; }
public static uint LoaderCrcHash() { return _v[(uint)Faces.VAR_LOADER_CRC_INFO_HASH] ^ (uint)Faces.VAR_LOADER_CRC_INFO_HASH_SALT; }
public static uint SessionKey() { return _v[(uint)Faces.VAR_SESSION_KEY]; }
public static uint LoaderStatus() { return _v[(uint)Faces.VAR_LOADER_STATUS]; }
public static uint ServerDate() { return _v[(uint)Faces.VAR_SERVER_DATE] ^ (uint)Faces.VAR_SERVER_DATE_SALT; }
public static void SetIsPatchDetected(bool value) { _v[(uint)Faces.VAR_IS_PATCH_DETECTED] = (uint)(value ? 1 : 0) ^ (uint)Faces.VAR_IS_PATCH_DETECTED_SALT; }
public static void SetIsDebuggerDetected(bool value) { _v[(uint)Faces.VAR_IS_DEBUGGER_DETECTED] = (uint)(value ? 1 : 0) ^ (uint)Faces.VAR_IS_DEBUGGER_DETECTED_SALT; }
public static void SetLoaderCrcInfo(uint value) { _v[(uint)Faces.VAR_LOADER_CRC_INFO] = value ^ (uint)Faces.VAR_LOADER_CRC_INFO_SALT; }
public static void SetLoaderCrcSize(uint value) { _v[(uint)Faces.VAR_LOADER_CRC_INFO_SIZE] = value ^ (uint)Faces.VAR_LOADER_CRC_INFO_SIZE_SALT; }
public static void SetLoaderCrcHash(uint value) { _v[(uint)Faces.VAR_LOADER_CRC_INFO_HASH] = value ^ (uint)Faces.VAR_LOADER_CRC_INFO_HASH_SALT; }
public static void SetSessionKey(uint value) { _v[(uint)Faces.VAR_SESSION_KEY] = value; }
public static void SetLoaderStatus(uint value) { _v[(uint)Faces.VAR_LOADER_STATUS] = value; }
public static void SetServerDate(uint value) { _v[(uint)Faces.VAR_SERVER_DATE] = value ^ (uint)Faces.VAR_SERVER_DATE_SALT; }
}
}

View File

@ -0,0 +1,266 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
// ReSharper disable once CheckNamespace
namespace VMProtect
{
public class HardwareID
{
private const int OldMethodBlocks = 8;
private const int MaxBlocks = 16 + OldMethodBlocks;
private const uint TypeMask = 3;
private enum BlockType {
Cpu,
Host,
Mac,
Hdd
};
private readonly int _startBlock;
private readonly List<uint> _blocks = new List<uint>();
public HardwareID()
{
// old methods
GetCpu(0);
GetCpu(1);
_startBlock = _blocks.Count;
// new methods, we'll return HWID starting from this DWORD
GetCpu(2);
GetMachineName();
GetHdd();
GetMacAddresses();
}
private void AddBlock(byte[] p, BlockType type)
{
if (_blocks.Count == MaxBlocks) return; // no free space
if (p.Length == 0) return;
using (var hash = new SHA1Managed())
{
var h = hash.ComputeHash(p);
var block = (uint)((h[0] << 24) | (h[1] << 16) | (h[2] << 8) | h[3]);
block &= ~TypeMask; // zero two lower bits
block |= (uint)type & TypeMask; // set type bits
// check existing blocks
for (var i = _blocks.Count; i > _startBlock; i--) {
var prevBlock = _blocks[i - 1];
if (prevBlock == block)
return;
if ((prevBlock & TypeMask) != (block & TypeMask))
break;
}
_blocks.Add(block);
}
}
private void GetCpu(int method)
{
//TODO: foreach cpu:
var info = CpuId.Invoke(1);
if ((info[0] & 0xFF0) == 0xFE0)
info[0] ^= 0x20; // fix Athlon bug
info[1] &= 0x00FFFFFF; // mask out APIC Physical ID
if (method == 2) {
info[2] = 0;
} else if (method == 1) {
info[2] &= ~(1 << 27);
}
var infob = new byte[16];
Buffer.BlockCopy(info, 0, infob, 0, infob.Length);
AddBlock(infob, BlockType.Cpu);
}
private void GetMachineName()
{
try
{
var hn = Encoding.Unicode.GetBytes(Dns.GetHostName().ToUpperInvariant());
AddBlock(hn, BlockType.Host);
}
catch (SocketException)
{
}
}
private void ProcessMac(byte[] p)
{
// this big IF construction allows to put constants to the code, not to the data segment
// it is harder to find them in the code after virtualisation
var dw = (p[0] << 16) + (p[1] << 8) + p[2];
if (dw == 0x000569 || dw == 0x000C29 || dw == 0x001C14 || dw == 0x005056 || // vmware
dw == 0x0003FF || dw == 0x000D3A || dw == 0x00125A || dw == 0x00155D || dw == 0x0017FA || dw == 0x001DD8 || dw == 0x002248 || dw == 0x0025AE || dw == 0x0050F2 || // microsoft
dw == 0x001C42 || // parallels
dw == 0x0021F6) // virtual iron
return;
AddBlock(p, BlockType.Mac);
}
private void GetMacAddresses()
{
var blockCountNoMac = _blocks.Count;
byte[] paBytes = null;
foreach (var nic in NetworkInterface.GetAllNetworkInterfaces())
{
if(nic.NetworkInterfaceType != NetworkInterfaceType.Ethernet)
continue;
paBytes = nic.GetPhysicalAddress().GetAddressBytes();
if (paBytes.Length >= 3)
ProcessMac(paBytes);
}
if (blockCountNoMac == _blocks.Count && paBytes != null && paBytes.Length >= 3)
AddBlock(paBytes, BlockType.Mac);
}
private void GetHdd()
{
try
{
switch (Environment.OSVersion.Platform)
{
case PlatformID.MacOSX:
//TODO
/*
DASessionRef session = DASessionCreate(NULL);
if (session) {
struct statfs statFS;
statfs ("/", &statFS);
DADiskRef disk = DADiskCreateFromBSDName(NULL, session, statFS.f_mntfromname);
if (disk) {
CFDictionaryRef descDict = DADiskCopyDescription(disk);
if (descDict) {
CFUUIDRef value = (CFUUIDRef)CFDictionaryGetValue(descDict, CFSTR("DAVolumeUUID"));
CFUUIDBytes bytes = CFUUIDGetUUIDBytes(value);
AddBlock(&bytes, sizeof(bytes), BLOCK_HDD);
CFRelease(descDict);
}
CFRelease(disk);
}
CFRelease(session);
}
*/
break;
case PlatformID.Unix:
//TODO: нет ли здесь лишних дисков?
var rootUuids = new DirectoryInfo ("/dev/disk/by-uuid");
var uuids = new StringBuilder();
foreach (var f in rootUuids.GetFiles("*"))
{
uuids.Append(f.Name);
}
if(uuids.Length > 0)
AddBlock(Encoding.UTF8.GetBytes(uuids.ToString()), BlockType.Hdd);
break;
default:
/*
* mono for windows: unimplemented
*
* var moType = Assembly.Load("System.Management, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a").
GetType("System.Management.ManagementObject");
var disk = Activator.CreateInstance(moType,
BindingFlags.CreateInstance, null,
new object[] { string.Format("Win32_LogicalDisk.DeviceID='{0}:'", Environment.SystemDirectory[0]) },
CultureInfo.InvariantCulture);
var props = moType.InvokeMember("Properties", BindingFlags.GetProperty, null, disk, null);
var sn = props.GetType().GetMethod("get_Item").Invoke(props, new object[] { "volumeSerialNumber" });
var snv = sn.GetType().GetMethod("get_Value").Invoke(sn, null).ToString();
Console.WriteLine("GetHdd volumeSerialNumber = {0}", snv);
var bytes = BitConverter.GetBytes(Convert.ToUInt32(snv, 16));*/
var driveLetter = Path.GetPathRoot(Environment.SystemDirectory);
uint serialNumber = 0;
uint maxComponentLength = 0, fileSystemFlags = 0;
if (Win32.GetVolumeInformation(driveLetter, null,
0, ref serialNumber, ref maxComponentLength,
ref fileSystemFlags, null, 0) && serialNumber != 0)
{
AddBlock(BitConverter.GetBytes(serialNumber), BlockType.Hdd);
}
break;
}
}
catch (Exception)
{
// ignored
}
}
public byte[] GetBytes()
{
var ms = new MemoryStream();
for (var i = _startBlock; i < _blocks.Count; i++)
{
ms.Write(BitConverter.GetBytes(_blocks[i]), 0, 4);
}
return ms.ToArray();
}
public override string ToString()
{
return Convert.ToBase64String(GetBytes());
}
public bool IsCorrect(byte[] p)
{
if (p.Length == 0 || (p.Length & 3) != 0)
return false;
var equals = new bool[4];
var found = new bool[4];
foreach (var id1 in _blocks)
{
found[id1 & 3] = true;
for (var i = 0; i < p.Length; i += 4) {
var id2 = BitConverter.ToUInt32(p, i);
if (id1 == id2) {
equals[id1 & 3] = true;
break;
}
}
}
// 1. check CPU
if (!equals[0])
return false;
// 2. check if at least 2 of 3 items are OK
var n = 0;
var c = 0;
for (var i = 0; i < 4; i++) {
if (found[i])
c++;
if (equals[i])
n++;
}
return n == c || n >= 3;
}
/*public bool IsCorrect(CryptoContainer &cont, size_t offset, size_t size)
{
if (size == 0 || (size & 3) || size > MAX_BLOCKS * sizeof(uint32_t))
return false;
uint32_t buff[MAX_BLOCKS];
for (size_t i = 0; i < size / sizeof(uint32_t); i++) {
buff[i] = cont.GetDWord(offset + i * sizeof(uint32_t));
}
return IsCorrect(reinterpret_cast<uint8_t *>(buff), size);
}*/
}
}

View File

@ -0,0 +1,664 @@
using System;
using System.Globalization;
using System.Net;
using System.Net.Cache;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using Numerics;
// ReSharper disable once CheckNamespace
namespace VMProtect
{
public class LicensingManager
{
public class BaseRequest
{
protected bool BuildUrl(byte[] licenseData)
{
var urlSize = BitConverter.ToInt32(licenseData, (int)Fields.ActivationUrlSize * sizeof(uint));
if (urlSize == 0)
return false;
var urlOffset = BitConverter.ToInt32(licenseData, (int)Fields.ActivationUrlOffset * sizeof(uint));
Url = Encoding.UTF8.GetString(licenseData, urlOffset, urlSize);
if (Url[Url.Length - 1] != '/')
Url += '/';
return true;
}
protected void EncodeUrl()
{
Url = Convert.ToBase64String(Encoding.UTF8.GetBytes(Url));
}
protected void AppendUrlParam(string param, string value)
{
AppendUrl(param, false);
AppendUrl(value, true);
}
private void AppendUrl(string str, bool escape)
{
if (escape)
{
var sb = new StringBuilder(Url);
foreach (var c in str)
{
switch (c)
{
case '+':
sb.Append("%2B");
break;
case '/':
sb.Append("%2F");
break;
case '=':
sb.Append("%3D");
break;
default:
sb.Append(c);
break;
}
}
Url = sb.ToString();
} else
{
Url += str;
}
}
public bool Send()
{
try
{
using (var wc = new WebClient())
{
ServicePointManager.ServerCertificateValidationCallback +=
(sender, certificate, chain, sslPolicyErrors) => true;
wc.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
wc.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
Response = wc.DownloadString(Url);
try
{
var strDt = wc.ResponseHeaders.Get("Date");
var dt = DateTime.ParseExact(strDt, "ddd, dd MMM yyyy HH:mm:ss 'GMT'",
CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal);
GlobalData.SetServerDate((uint)((dt.Year << 16) + (dt.Month << 8) + dt.Day));
}
catch (Exception)
{
//не смогли вытащить дату из заголовков - прощаем?
}
return true;
}
}
catch (Exception)
{
return false;
}
}
public string Url { get; private set; }
public string Response { get; private set; }
}
public class ActivationRequest : BaseRequest
{
public ActivationStatus Process(byte[] licenseData, string code, bool offline)
{
if (!VerifyCode(code))
return ActivationStatus.BadCode;
if (!BuildUrl(licenseData, code, offline))
return ActivationStatus.NotAvailable;
if (offline)
return ActivationStatus.Ok;
if (!Send())
return ActivationStatus.NoConnection;
var res = Response;
if (string.IsNullOrEmpty(res))
return ActivationStatus.BadReply;
// possible answers: OK, BAD, BANNED, USED, EXPIRED
// if OK - see the Serial number below
if (res == "BAD")
return ActivationStatus.BadCode;
if (res == "BANNED")
return ActivationStatus.Banned;
if (res == "USED")
return ActivationStatus.AlreadyUsed;
if (res == "EXPIRED")
return ActivationStatus.Expired;
var crPos = res.IndexOf('\n');
if (crPos != 2)
return ActivationStatus.BadReply;
if (res[0] != 'O' || res[1] != 'K')
return ActivationStatus.BadReply;
if (res.Length - 3 < 64)
return ActivationStatus.BadReply;
Serial = res.Substring(3);
return ActivationStatus.Ok;
}
public string Serial
{
get; private set;
}
private bool VerifyCode(string code)
{
if (string.IsNullOrEmpty(code) || code.Length > 32)
return false;
return code.ToLower().TrimEnd("0123456789abcdefghijklmnopqrstuvwxyz-".ToCharArray()).Length == 0;
}
private bool BuildUrl(byte[] licenseData, string code, bool offline)
{
if (!offline) {
if (!base.BuildUrl(licenseData))
return false;
}
// hwid -> base64
var hwid = Convert.ToBase64String(Core.Instance.HWID.GetBytes());
// hash -> base64
var modSize = BitConverter.ToInt32(licenseData, (int)Fields.ModulusSize * sizeof(uint));
var modOffset = BitConverter.ToInt32(licenseData, (int)Fields.ModulusOffset * sizeof(uint));
using (var sha = new SHA1Managed())
{
var modulus = sha.ComputeHash(licenseData, modOffset, modSize);
var hash = Convert.ToBase64String(modulus, 0, 20);
// build Url
AppendUrlParam(offline ? "type=activation&code=" : "activation.php?code=", code);
AppendUrlParam("&hwid=", hwid);
AppendUrlParam("&hash=", hash);
}
if (offline)
EncodeUrl();
return true;
}
}
public class DeactivationRequest : BaseRequest
{
public ActivationStatus Process(byte[] licenseData, string serial, bool offline)
{
if (!VerifySerial(serial))
return ActivationStatus.BadCode;
if (!BuildUrl(licenseData, serial, offline))
return ActivationStatus.NotAvailable;
if (offline)
return ActivationStatus.Ok;
if (!Send())
return ActivationStatus.NoConnection;
var res = Response;
if (string.IsNullOrEmpty(res))
return ActivationStatus.BadReply;
if (res == "OK")
return ActivationStatus.Ok;
if (res == "ERROR")
return ActivationStatus.Corrupted;
if (res == "UNKNOWN")
return ActivationStatus.SerialUnknown;
return ActivationStatus.BadReply;
}
private bool VerifySerial(string serial)
{
return !string.IsNullOrEmpty(serial);
}
private bool BuildUrl(byte[] licenseData, string serial, bool offline)
{
if (!offline) {
if (!base.BuildUrl(licenseData))
return false;
}
try
{
var serialBytes = Convert.FromBase64String(serial);
using (var sha = new SHA1Managed())
{
var serialHash = sha.ComputeHash(serialBytes);
var hash = Convert.ToBase64String(serialHash, 0, 20);
AppendUrlParam(offline ? "type=deactivation&hash=" : "deactivation.php?hash=", hash);
}
}
catch (FormatException)
{
return false;
}
if (offline)
EncodeUrl();
return true;
}
}
public LicensingManager(long instance)
{
_sessionKey = 0 - GlobalData.SessionKey();
_licenseData = new byte[(uint)Faces.LICENSE_INFO_SIZE];
Marshal.Copy(new IntPtr(instance + (uint)Faces.LICENSE_INFO), _licenseData, 0, _licenseData.Length);
_startTickCount = Environment.TickCount;
}
public LicensingManager(byte [] licenseData)
{
_licenseData = licenseData;
}
public SerialState GetSerialNumberState()
{
lock (_lock)
{
return (_state & (SerialState.Corrupted | SerialState.Invalid | SerialState.BadHwid | SerialState.Blacklisted)) != 0 ? _state : ParseSerial(null);
}
}
public ActivationStatus ActivateLicense(string code, out string serial)
{
serial = string.Empty;
if (!CheckLicenseDataCRC())
return ActivationStatus.Corrupted;
var request = new ActivationRequest();
var res = request.Process(_licenseData, code, false);
if (res == ActivationStatus.Ok)
{
serial = request.Serial;
}
return res;
}
public ActivationStatus DeactivateLicense(string serial)
{
return CheckLicenseDataCRC() ?
new DeactivationRequest().Process(_licenseData, serial, false) :
ActivationStatus.Corrupted;
}
public ActivationStatus GetOfflineActivationString(string code, out string buf)
{
buf = string.Empty;
if (!CheckLicenseDataCRC())
return ActivationStatus.Corrupted;
var request = new ActivationRequest();
var res = request.Process(_licenseData, code, true);
if (res == ActivationStatus.Ok)
{
buf = request.Url;
}
return res;
}
public ActivationStatus GetOfflineDeactivationString(string serial, out string buf)
{
buf = string.Empty;
if (!CheckLicenseDataCRC())
return ActivationStatus.Corrupted;
var request = new DeactivationRequest();
var res = request.Process(_licenseData, serial, true);
if (res == ActivationStatus.Ok)
{
buf = request.Url;
}
return res;
}
private static BigInteger B2Bi(byte[] b) //reverse & make positive
{
Array.Reverse(b);
var b2 = new byte[b.Length + 1];
Array.Copy(b, b2, b.Length);
return new BigInteger(b2);
}
public SerialState SetSerialNumber(string serial)
{
lock (_lock)
{
SaveState(SerialState.Invalid);
if (string.IsNullOrEmpty(serial))
return SerialState.Invalid; // the key is empty
// decode serial number from base64
byte[] binarySerial;
try
{
binarySerial = Convert.FromBase64String(serial);
if (binarySerial.Length < 16)
return SerialState.Invalid;
}
catch (Exception)
{
return SerialState.Invalid;
}
// check license data integrity
if (!CheckLicenseDataCRC()) {
return SaveState(SerialState.Corrupted);
}
// check serial by black list
var blackListSize = BitConverter.ToInt32(_licenseData, (int)Fields.BlacklistSize * sizeof(uint));
if (blackListSize != 0) {
var blackListOffset = BitConverter.ToInt32(_licenseData, (int)Fields.BlacklistOffset * sizeof(uint));
using (var hash = new SHA1Managed())
{
var p = hash.ComputeHash(binarySerial);
int min = 0;
int max = blackListSize / 20 - 1;
while (min <= max)
{
int i = (min + max) / 2;
var blocked = true;
for (var j = 0; j < 20 / sizeof(uint); j++) {
var dw = BitConverter.ToUInt32(_licenseData, blackListOffset + i * 20 + j * sizeof(uint));
var v = BitConverter.ToUInt32(p, j * sizeof(uint));
if (dw == v)
continue;
if (BitRotate.Swap(dw) > BitRotate.Swap(v))
{
max = i - 1;
}
else
{
min = i + 1;
}
blocked = false;
break;
}
if (blocked) {
return SaveState(SerialState.Blacklisted);
}
}
}
}
// decode serial number
var ebytes = new byte[BitConverter.ToInt32(_licenseData, (int)Fields.PublicExpSize * sizeof(uint))];
Array.Copy(_licenseData, BitConverter.ToInt32(_licenseData, (int)Fields.PublicExpOffset * sizeof(uint)), ebytes, 0, ebytes.Length);
var e = B2Bi(ebytes);
var nbytes = new byte[BitConverter.ToInt32(_licenseData, (int)Fields.ModulusSize * sizeof(uint))];
Array.Copy(_licenseData, BitConverter.ToInt32(_licenseData, (int)Fields.ModulusOffset * sizeof(uint)), nbytes, 0, nbytes.Length);
var n = B2Bi(nbytes);
var x = B2Bi(binarySerial);
if (n < x) {
// data is too long to crypt
return SerialState.Invalid;
}
_serial = BigInteger.ModPow(x, e, n).ToByteArray();
Array.Reverse(_serial);
if (_serial[0] != 0 || _serial[1] != 2)
return SerialState.Invalid;
int pos;
for (pos = 2; pos < _serial.Length; pos++) {
if (_serial[pos] == 0) {
pos++;
break;
}
}
if (pos == _serial.Length)
return SerialState.Invalid;
_start = pos;
return ParseSerial(null);
}
}
public bool GetSerialNumberData(SerialNumberData data)
{
lock (_lock)
{
if (_state == SerialState.Corrupted)
return false;
data.State = (_state & (SerialState.Invalid | SerialState.Blacklisted | SerialState.BadHwid)) != 0 ? _state : ParseSerial(data);
return true;
}
}
public uint DecryptBuffer(uint p3, uint p2, uint p1, uint p0)
{
uint key0 = (uint)_productCode;
uint key1 = (uint)(_productCode >> 32) + _sessionKey;
p0 = BitRotate.Left((p0 + _sessionKey) ^ key0, 7) + key1;
p1 = BitRotate.Left((p1 + _sessionKey) ^ key0, 11) + key1;
p2 = BitRotate.Left((p2 + _sessionKey) ^ key0, 17) + key1;
p3 = BitRotate.Left((p3 + _sessionKey) ^ key0, 23) + key1;
if (p0 + p1 + p2 + p3 != _sessionKey * 4)
{
Core.ShowMessage("This code requires valid serial number to run.\nProgram will be terminated.");
Environment.Exit(1);
}
return p3;
}
[VMProtect.DeleteOnCompilation]
private enum ChunkType
{
Version = 0x01, // 1 byte of data - version
UserName = 0x02, // 1 + N bytes - length + N bytes of customer's name (without enging \0).
Email = 0x03, // 1 + N bytes - length + N bytes of customer's email (without ending \0).
HWID = 0x04, // 1 + N bytes - length + N bytes of hardware id (N % 4 == 0)
ExpDate = 0x05, // 4 bytes - (year << 16) + (month << 8) + (day)
RunningTimeLimit = 0x06, // 1 byte - number of minutes
ProductCode = 0x07, // 8 bytes - used for decrypting some parts of exe-file
UserData = 0x08, // 1 + N bytes - length + N bytes of user data
MaxBuild = 0x09, // 4 bytes - (year << 16) + (month << 8) + (day)
End = 0xFF // 4 bytes - checksum: the first four bytes of sha-1 hash from the data before that chunk
}
private SerialState SaveState(SerialState state)
{
_state = state;
if ((_state & (SerialState.Invalid | SerialState.BadHwid)) != 0)
{
_serial = null;
_productCode = 0;
}
return _state;
}
private SerialState ParseSerial(SerialNumberData data)
{
if (_serial == null)
return SerialState.Invalid;
var newState = _state & (SerialState.MaxBuildExpired | SerialState.DateExpired | SerialState.RunningTimeOver);
var pos = _start;
while (pos < _serial.Length) {
var b = _serial[pos++];
byte s;
switch (b) {
case (byte)ChunkType.Version:
if (_serial[pos] != 1)
return SaveState(SerialState.Invalid);
pos += 1;
break;
case (byte)ChunkType.ExpDate:
var expDate = BitConverter.ToUInt32(_serial, pos);
if ((newState & SerialState.DateExpired) == 0) {
if (BitConverter.ToUInt32(_licenseData, (int)Fields.BuildDate * sizeof(uint)) > expDate || GetCurrentDate() > expDate)
newState |= SerialState.DateExpired;
}
if (data != null) {
data.Expires = new DateTime((int)(expDate >> 16), (byte)(expDate >> 8), (byte)expDate);
}
pos += 4;
break;
case (byte)ChunkType.RunningTimeLimit:
s = _serial[pos];
if ((newState & SerialState.RunningTimeOver) == 0) {
var curTime = (Environment.TickCount - _startTickCount) / 1000 / 60;
if (curTime > s)
newState |= SerialState.RunningTimeOver;
}
if (data != null)
data.RunningTime = s;
pos += 1;
break;
case (byte)ChunkType.ProductCode:
if ((_state & SerialState.Invalid) != 0)
_productCode = BitConverter.ToInt64(_serial, pos);
pos += 8;
break;
case (byte)ChunkType.MaxBuild:
var maxBuildDate = BitConverter.ToUInt32(_serial, pos);
if ((newState & SerialState.MaxBuildExpired) == 0) {
if (BitConverter.ToUInt32(_licenseData, (int)Fields.BuildDate * sizeof(uint)) > maxBuildDate)
newState |= SerialState.MaxBuildExpired;
}
if (data != null)
{
data.MaxBuild = new DateTime((int)(maxBuildDate >> 16), (byte)(maxBuildDate >> 8), (byte)maxBuildDate);
}
pos += 4;
break;
case (byte)ChunkType.UserName:
s = _serial[pos++];
if (data != null)
data.UserName = Encoding.UTF8.GetString(_serial, pos, s);
pos += s;
break;
case (byte)ChunkType.Email:
s = _serial[pos++];
if (data != null)
data.EMail = Encoding.UTF8.GetString(_serial, pos, s);
pos += s;
break;
case (byte)ChunkType.HWID:
s = _serial[pos++];
if ((_state & SerialState.Invalid) != 0)
{
var shwid = new byte[s];
Array.Copy(_serial, pos, shwid, 0, s);
if (!Core.Instance.HWID.IsCorrect(shwid))
return SaveState(SerialState.BadHwid);
}
pos += s;
break;
case (byte)ChunkType.UserData:
s = _serial[pos++];
if (data != null) {
data.UserData = new byte[s];
for (var i = 0; i < s; i++) {
data.UserData[i] = _serial[pos + i];
}
}
pos += s;
break;
case (byte)ChunkType.End:
if (pos + 4 > _serial.Length)
return SaveState(SerialState.Invalid);
if ((_state & SerialState.Invalid) != 0) {
// calc hash without last chunk
using (var hash = new SHA1Managed())
{
var p = hash.ComputeHash(_serial, _start, pos - _start - 1);
// check CRC
for (var i = 0; i < 4; i++) {
if (_serial[pos + i] != p[3 - i])
return SaveState(SerialState.Invalid);
}
}
}
return SaveState(newState);
}
}
// SERIAL_CHUNK_END not found
return SaveState(SerialState.Invalid);
}
[VMProtect.DeleteOnCompilation]
internal enum Fields
{
BuildDate,
PublicExpOffset,
PublicExpSize,
ModulusOffset,
ModulusSize,
BlacklistOffset,
BlacklistSize,
ActivationUrlOffset,
ActivationUrlSize,
CRCOffset,
Count
}
private bool CheckLicenseDataCRC()
{
var crcPos = BitConverter.ToInt32(_licenseData, (int)Fields.CRCOffset * sizeof(uint));
var size = crcPos + 16;
if (size != _licenseData.Length)
return false; // bad key size
// CRC check
using (var hash = new SHA1Managed())
{
var h = hash.ComputeHash(_licenseData, 0, crcPos);
for (var i = crcPos; i < size; i++)
{
if (_licenseData[i] != h[i - crcPos])
return false;
}
}
return true;
}
internal static uint GetCurrentDate()
{
var dt = DateTime.Now;
var curDate = (uint)((dt.Year << 16) + (dt.Month << 8) + dt.Day);
var serverDate = GlobalData.ServerDate();
return serverDate > curDate ? serverDate : curDate;
}
private readonly byte[] _licenseData;
private byte[] _serial;
private readonly object _lock = new object();
private SerialState _state = SerialState.Invalid;
//TODO
//ReSharper disable once NotAccessedField.Local
private long _productCode;
private readonly int _startTickCount;
private int _start;
private uint _sessionKey;
/*
CryptoContainer *_serial;
*/
}
}

View File

@ -0,0 +1,703 @@
using System;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using System.Reflection.Emit;
// ReSharper disable once CheckNamespace
namespace VMProtect
{
[VMProtect.DeleteOnCompilation]
enum MessageType
{
InitializationError,
ProcNotFound,
OrdinalNotFound,
FileCorrupted,
DebuggerFound,
UnregisteredVersion,
VirtualMachineFound
}
[VMProtect.DeleteOnCompilation]
enum ErrorType
{
VIRTUAL_PROTECT_ERROR = 1,
UNPACKER_ERROR = 2
}
[VMProtect.DeleteOnCompilation]
enum LoaderOption
{
CHECK_PATCH = 0x1,
CHECK_DEBUGGER = 0x2,
CHECK_KERNEL_DEBUGGER = 0x4,
EXIT_PROCESS = 0x8,
CHECK_VIRTUAL_MACHINE = 0x10
}
[VMProtect.DeleteOnCompilation]
enum FixupType
{
Absolute = 0,
High = 1,
Low = 2,
HighLow = 3,
Dir64 = 10
}
public static class Loader
{
public static object[] IAT;
internal static bool FindFirmwareVendor(byte[] data)
{
for (var i = 0; i < data.Length; i++)
{
if (i + 3 < data.Length && data[i + 0] == 'Q' && data[i + 1] == 'E' && data[i + 2] == 'M' && data[i + 3] == 'U')
return true;
if (i + 8 < data.Length && data[i + 0] == 'M' && data[i + 1] == 'i' && data[i + 2] == 'c' && data[i + 3] == 'r' && data[i + 4] == 'o' && data[i + 5] == 's' && data[i + 6] == 'o' && data[i + 7] == 'f' && data[i + 8] == 't')
return true;
if (i + 6 < data.Length && data[i + 0] == 'i' && data[i + 1] == 'n' && data[i + 2] == 'n' && data[i + 3] == 'o' && data[i + 4] == 't' && data[i + 5] == 'e' && data[i + 6] == 'k')
return true;
if (i + 9 < data.Length && data[i + 0] == 'V' && data[i + 1] == 'i' && data[i + 2] == 'r' && data[i + 3] == 't' && data[i + 4] == 'u' && data[i + 5] == 'a' && data[i + 6] == 'l' && data[i + 7] == 'B' && data[i + 8] == 'o' && data[i + 9] == 'x')
return true;
if (i + 5 < data.Length && data[i + 0] == 'V' && data[i + 1] == 'M' && data[i + 2] == 'w' && data[i + 3] == 'a' && data[i + 4] == 'r' && data[i + 5] == 'e')
return true;
if (i + 8 < data.Length && data[i + 0] == 'P' && data[i + 1] == 'a' && data[i + 2] == 'r' && data[i + 3] == 'a' && data[i + 4] == 'l' && data[i + 5] == 'l' && data[i + 6] == 'e' && data[i + 7] == 'l' && data[i + 8] == 's')
return true;
}
return false;
}
private static void ShowMessage(uint type, uint param = 0)
{
uint position;
switch (type)
{
case (uint)MessageType.DebuggerFound:
position = (uint)Faces.DEBUGGER_FOUND;
break;
case (uint)MessageType.VirtualMachineFound:
position = (uint)Faces.VIRTUAL_MACHINE_FOUND;
break;
case (uint)MessageType.FileCorrupted:
position = (uint)Faces.FILE_CORRUPTED;
break;
case (uint)MessageType.UnregisteredVersion:
position = (uint)Faces.UNREGISTERED_VERSION;
break;
case (uint)MessageType.InitializationError:
position = (uint)Faces.INITIALIZATION_ERROR;
break;
default:
return;
}
long instance = Marshal.GetHINSTANCE(typeof(Loader).Module).ToInt64();
String message = null;
var buffer = new byte[1024];
for (var pos = 0; pos < 512; pos++)
{
var c = (ushort)(Marshal.ReadInt16(new IntPtr(instance + position + pos * 2)) ^ (BitRotate.Left((uint)Faces.STRING_DECRYPT_KEY, pos) + pos));
if (c == 0)
{
if (pos > 0)
message = Encoding.Unicode.GetString(buffer, 0, pos * 2);
break;
}
buffer[pos * 2] = (byte)c;
buffer[pos * 2 + 1] = (byte)(c >> 8);
}
if (message != null)
{
if (type == (uint)MessageType.InitializationError)
message = String.Format(message, param);
Win32.ShowMessage(message, Assembly.GetExecutingAssembly().GetName().Name, MessageBoxButtons.OK, type == (uint)MessageType.UnregisteredVersion ? MessageBoxIcon.Warning : MessageBoxIcon.Error);
}
}
internal static bool LzmaDecode(IntPtr dst, IntPtr src, byte[] properties, ref uint dstSize, out uint srcSize)
{
srcSize = 0;
unsafe
{
using (
var srcStream = new UnmanagedMemoryStream((byte*)src.ToPointer(), int.MaxValue, int.MaxValue, FileAccess.Read)
)
{
using (
var dstStream = new UnmanagedMemoryStream((byte*) dst.ToPointer(), dstSize, dstSize,
FileAccess.Write))
{
try
{
var coder = new SevenZip.Compression.LZMA.Decoder();
coder.SetDecoderProperties(properties);
coder.Code(srcStream, dstStream, dstSize);
dstStream.Flush();
srcSize = (uint)srcStream.Position;
dstSize = (uint)dstStream.Position;
}
catch (Exception)
{
return false;
}
return true;
}
}
}
}
public static void Main()
{
if (GlobalData.LoaderStatus() != 0)
return;
var module = typeof(Loader).Module;
long instance = Marshal.GetHINSTANCE(module).ToInt64();
var options = (uint)Faces.LOADER_OPTIONS;
GlobalData.SetIsPatchDetected(false);
GlobalData.SetIsDebuggerDetected(false);
GlobalData.SetLoaderCrcInfo((uint)Faces.LOADER_CRC_INFO);
GlobalData.SetLoaderCrcSize((uint)Faces.LOADER_CRC_INFO_SIZE);
GlobalData.SetLoaderCrcHash((uint)Faces.LOADER_CRC_INFO_HASH);
GlobalData.SetServerDate(0);
// detect a debugger
if ((options & (uint)LoaderOption.CHECK_DEBUGGER) != 0)
{
if (Debugger.IsAttached || Debugger.IsLogging())
{
ShowMessage((uint)MessageType.DebuggerFound);
Environment.Exit(1);
return;
}
if (Win32.IsDebuggerPresent() || Win32.CheckRemoteDebuggerPresent())
{
ShowMessage((uint)MessageType.DebuggerFound);
Environment.Exit(1);
return;
}
Win32.NtSetInformationThread(Win32.CurrentThread, Win32.THREADINFOCLASS.ThreadHideFromDebugger, IntPtr.Zero, 0);
}
// check header and loader CRC
var crcSize = (uint)Faces.LOADER_CRC_INFO_SIZE;
if (crcSize != 0)
{
crcSize = (uint)Marshal.ReadInt32(new IntPtr(instance + crcSize));
var crcPosition = (uint)Faces.LOADER_CRC_INFO;
var crcCryptor = new CRCValueCryptor();
bool isValid = true;
var crcInfo = new byte[12];
var crc32 = new CRC32();
var crcHash = (uint)Marshal.ReadInt32(new IntPtr(instance + (uint)Faces.LOADER_CRC_INFO_HASH));
if (crcHash != crc32.Hash(new IntPtr(instance + crcPosition), crcSize))
isValid = false;
for (var i = 0; i < crcSize; i += crcInfo.Length)
{
Marshal.Copy(new IntPtr(instance + crcPosition + i), crcInfo, 0, crcInfo.Length);
uint address = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 0));
uint size = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 4));
uint hash = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 8));
if (crc32.Hash(new IntPtr(instance + address), size) != hash)
isValid = false;
}
if (!isValid)
{
if ((options & (uint)LoaderOption.CHECK_PATCH) != 0)
{
ShowMessage((uint)MessageType.FileCorrupted);
Environment.Exit(1);
return;
}
GlobalData.SetIsPatchDetected(true);
}
}
// check file CRC
crcSize = (uint)Faces.FILE_CRC_INFO_SIZE;
if (crcSize != 0) //-V3022
{
crcSize = (uint)Marshal.ReadInt32(new IntPtr(instance + crcSize));
var crcPosition = (uint)Faces.FILE_CRC_INFO;
bool isValid = true;
var file = Win32.OpenFile(Assembly.GetExecutingAssembly().Location, (uint)Win32.Values.GENERIC_READ, (uint)Win32.Values.FILE_SHARE_READ | (uint)Win32.Values.FILE_SHARE_WRITE);
if (file != Win32.InvalidHandleValue)
{
var fileSize = Win32.GetFileSize(file, IntPtr.Zero);
if (fileSize < (uint)Marshal.ReadInt32(new IntPtr(instance + crcPosition)))
isValid = false;
else
{
var map = Win32.CreateFileMapping(file, IntPtr.Zero, Win32.MemoryProtection.ReadOnly, 0, 0, null);
if (map != Win32.NullHandle)
{
IntPtr baseAddress = Win32.MapViewOfFile(map, Win32.MapAccess.Read, 0, 0, IntPtr.Zero);
if (baseAddress != IntPtr.Zero)
{
var crcInfo = new byte[12];
var crc32 = new CRC32();
var crcCryptor = new CRCValueCryptor();
for (var i = 4; i < crcSize; i += crcInfo.Length)
{
Marshal.Copy(new IntPtr(instance + crcPosition + i), crcInfo, 0, crcInfo.Length);
uint address = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 0));
uint size = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 4));
uint hash = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 8));
if (crc32.Hash(new IntPtr(baseAddress.ToInt64() + address), size) != hash)
isValid = false;
}
Win32.UnmapViewOfFile(baseAddress);
}
Win32.CloseHandle(map);
}
}
Win32.CloseHandle(file);
}
if (!isValid)
{
if ((options & (uint)LoaderOption.CHECK_PATCH) != 0)
{
ShowMessage((uint)MessageType.FileCorrupted);
Environment.Exit(1);
return;
}
GlobalData.SetIsPatchDetected(true);
}
}
// setup WRITABLE flag for memory pages
var sectionSize = (uint)Faces.SECTION_INFO_SIZE;
if (sectionSize != 0)
{
var sectionPos = (uint)Faces.SECTION_INFO;
var sectionInfo = new byte[12];
for (var i = 0; i < sectionSize; i += sectionInfo.Length) //-V3022
{
Marshal.Copy(new IntPtr(instance + sectionPos + i), sectionInfo, 0, sectionInfo.Length);
uint address = BitConverter.ToUInt32(sectionInfo, 0);
uint size = BitConverter.ToUInt32(sectionInfo, 4);
uint type = BitConverter.ToUInt32(sectionInfo, 8);
Win32.MemoryProtection protect, old_protect;
protect = ((type & (uint)Win32.SectionType.Execute) != 0) ? Win32.MemoryProtection.ExecuteReadWrite : Win32.MemoryProtection.ReadWrite;
if (!Win32.VirtualProtect(new IntPtr(instance + address), new UIntPtr(size), protect, out old_protect))
{
ShowMessage((uint)MessageType.InitializationError, (uint)ErrorType.VIRTUAL_PROTECT_ERROR);
Environment.Exit(1);
return;
}
if (((uint)old_protect & ((uint)Win32.MemoryProtection.NoAccess | (uint)Win32.MemoryProtection.Guard)) != 0)
{
if ((options & (uint)LoaderOption.CHECK_DEBUGGER) != 0)
{
ShowMessage((uint)MessageType.DebuggerFound);
Environment.Exit(1);
return;
}
GlobalData.SetIsDebuggerDetected(true);
}
}
}
// unpack regions
var packerSize = (uint)Faces.PACKER_INFO_SIZE;
if (packerSize != 0)
{
int tlsIndex = 0;
var tlsIndexPos = (uint)Faces.TLS_INDEX_INFO;
if (tlsIndexPos != 0)
tlsIndex = Marshal.ReadInt32(new IntPtr(instance + tlsIndexPos));
var packerPos = (uint)Faces.PACKER_INFO;
var packerInfo = new byte[8];
Marshal.Copy(new IntPtr(instance + packerPos), packerInfo, 0, packerInfo.Length);
uint src = BitConverter.ToUInt32(packerInfo, 0);
uint dst = BitConverter.ToUInt32(packerInfo, 4);
var properties = new byte[dst];
Marshal.Copy(new IntPtr(instance + src), properties, 0, properties.Length);
for (var i = packerInfo.Length; i < packerSize; i += packerInfo.Length) //-V3022
{
Marshal.Copy(new IntPtr(instance + packerPos + i), packerInfo, 0, packerInfo.Length);
src = BitConverter.ToUInt32(packerInfo, 0);
dst = BitConverter.ToUInt32(packerInfo, 4);
uint dstSize = int.MaxValue, srcSize;
if (!LzmaDecode(new IntPtr(instance + dst), new IntPtr(instance + src), properties, ref dstSize, out srcSize))
{
ShowMessage((uint)MessageType.InitializationError, (uint)ErrorType.UNPACKER_ERROR);
Environment.Exit(1);
return;
}
}
if (tlsIndexPos != 0)
Marshal.WriteInt32(new IntPtr(instance + tlsIndexPos), tlsIndex);
}
// setup fixups
long fileBase = (uint)Faces.FILE_BASE;
long deltaBase = instance - fileBase;
if (deltaBase != 0)
{
var fixupSize = (uint)Faces.FIXUP_INFO_SIZE;
if (fixupSize != 0)
{
var fixupPos = (uint)Faces.FIXUP_INFO;
var fixupInfo = new byte[8];
uint blockSize = 0;
for (uint i = 0; i < fixupSize; i += blockSize)
{
Marshal.Copy(new IntPtr(instance + fixupPos + i), fixupInfo, 0, fixupInfo.Length);
uint address = BitConverter.ToUInt32(fixupInfo, 0);
blockSize = BitConverter.ToUInt32(fixupInfo, 4);
if (blockSize < fixupInfo.Length)
break;
var c = blockSize - fixupInfo.Length;
var block = new byte[c];
Marshal.Copy(new IntPtr(instance + fixupPos + i + fixupInfo.Length), block, 0, block.Length);
for (var j = 0; j < c; j += 2)
{
ushort typeOffset = BitConverter.ToUInt16(block, j);
var type = (typeOffset & 0xf);
var ptr = new IntPtr(instance + address + (typeOffset >> 4));
if (type == (uint)FixupType.HighLow)
{
int value = Marshal.ReadInt32(ptr);
value += (int)deltaBase;
Marshal.WriteInt32(ptr, value);
}
else if (type == (uint)FixupType.Dir64)
{
long value = Marshal.ReadInt64(ptr);
value += deltaBase;
Marshal.WriteInt64(ptr, value);
}
else if (type == (uint)FixupType.High)
{
short value = Marshal.ReadInt16(ptr);
value += (short)(deltaBase >> 16);
Marshal.WriteInt16(ptr, value);
}
else if (type == (uint)FixupType.Low)
{
short value = Marshal.ReadInt16(ptr);
value += (short)deltaBase;
Marshal.WriteInt16(ptr, value);
}
}
}
}
}
// setup IAT
var iatSize = (uint)Faces.IAT_INFO_SIZE;
if (iatSize != 0)
{
var iatPos = (uint)Faces.IAT_INFO;
var iatInfo = new byte[12];
for (var i = 0; i < iatSize; i += iatInfo.Length) //-V3022
{
Marshal.Copy(new IntPtr(instance + iatPos + i), iatInfo, 0, iatInfo.Length);
uint src = BitConverter.ToUInt32(iatInfo, 0);
uint dst = BitConverter.ToUInt32(iatInfo, 4);
uint size = BitConverter.ToUInt32(iatInfo, 8);
var data = new byte[size];
Marshal.Copy(new IntPtr(instance + src), data, 0, data.Length);
Marshal.Copy(data, 0, new IntPtr(instance + dst), data.Length);
}
}
// reset WRITABLE flag for memory pages
if (sectionSize != 0) //-V3022
{
var sectionPos = (uint)Faces.SECTION_INFO;
var sectionInfo = new byte[12];
for (var i = 0; i < sectionSize; i += sectionInfo.Length) //-V3022
{
Marshal.Copy(new IntPtr(instance + sectionPos + i), sectionInfo, 0, sectionInfo.Length);
uint address = BitConverter.ToUInt32(sectionInfo, 0);
uint size = BitConverter.ToUInt32(sectionInfo, 4);
uint type = BitConverter.ToUInt32(sectionInfo, 8);
Win32.MemoryProtection protect, old_protect;
if ((type & (uint)Win32.SectionType.Read) != 0)
{
if ((type & (uint)Win32.SectionType.Write) != 0)
protect = ((type & (uint)Win32.SectionType.Execute) != 0) ? Win32.MemoryProtection.ExecuteReadWrite : Win32.MemoryProtection.ReadWrite;
else
protect = ((type & (uint)Win32.SectionType.Execute) != 0) ? Win32.MemoryProtection.ExecuteRead : Win32.MemoryProtection.ReadOnly;
}
else
{
protect = ((type & (uint)Win32.SectionType.Execute) != 0) ? Win32.MemoryProtection.Execute : Win32.MemoryProtection.NoAccess;
}
if (!Win32.VirtualProtect(new IntPtr(instance + address), new UIntPtr(size), protect, out old_protect))
{
ShowMessage((uint)MessageType.InitializationError, (uint)ErrorType.VIRTUAL_PROTECT_ERROR);
Environment.Exit(1);
}
if (((uint)old_protect & ((uint)Win32.MemoryProtection.NoAccess | (uint)Win32.MemoryProtection.Guard)) != 0)
{
if ((options & (uint)LoaderOption.CHECK_DEBUGGER) != 0)
{
ShowMessage((uint)MessageType.DebuggerFound);
Environment.Exit(1);
return;
}
GlobalData.SetIsDebuggerDetected(true);
}
}
}
// detect a virtual machine
if ((options & (uint)LoaderOption.CHECK_VIRTUAL_MACHINE) != 0)
{
var info = CpuId.Invoke(1);
if (((info[2] >> 31) & 1) != 0)
{
// hypervisor found
bool isFound = true;
// check Hyper-V root partition
info = CpuId.Invoke(0x40000000);
if (info[1] == 0x7263694d && info[2] == 0x666f736f && info[3] == 0x76482074) // "Microsoft Hv"
{
info = CpuId.Invoke(0x40000003);
if ((info[1] & 1) != 0)
isFound = false;
}
if (isFound)
{
ShowMessage((uint)MessageType.VirtualMachineFound);
Environment.Exit(1);
return;
}
}
else
{
int size;
uint tableSignature = (byte)'R' << 24 | (byte)'S' << 16 | (byte)'M' << 8 | (byte)'B';
try
{
size = (int)Win32.EnumSystemFirmwareTables(tableSignature, IntPtr.Zero, 0);
}
catch (EntryPointNotFoundException) { size = 0; }
if (size > 0)
{
IntPtr nativeBuffer = Marshal.AllocHGlobal(size);
Win32.EnumSystemFirmwareTables(tableSignature, nativeBuffer, (uint)size);
byte[] buffer = new byte[size];
Marshal.Copy(nativeBuffer, buffer, 0, size);
Marshal.FreeHGlobal(nativeBuffer);
for (var i = 0; i < size / sizeof(uint); i += sizeof(uint))
{
uint tableId = BitConverter.ToUInt32(buffer, i);
int dataSize = (int)Win32.GetSystemFirmwareTable(tableSignature, tableId, IntPtr.Zero, 0);
if (dataSize > 0)
{
nativeBuffer = Marshal.AllocHGlobal(dataSize);
Win32.GetSystemFirmwareTable(tableSignature, tableId, nativeBuffer, (uint)dataSize);
byte[] data = new byte[dataSize];
Marshal.Copy(nativeBuffer, data, 0, dataSize);
Marshal.FreeHGlobal(nativeBuffer);
if (FindFirmwareVendor(data))
{
ShowMessage((uint)MessageType.VirtualMachineFound);
Environment.Exit(1);
return;
}
}
}
}
}
}
// check memory CRC
crcSize = (uint)Faces.MEMORY_CRC_INFO_SIZE;
if (crcSize != 0) //-V3022
{
var crcPosition = (uint)Faces.MEMORY_CRC_INFO;
var crcCryptor = new CRCValueCryptor();
bool isValid = true;
var crcInfo = new byte[12];
var crc32 = new CRC32();
var crcHash = (uint)Faces.MEMORY_CRC_INFO_HASH;
if (crcHash != crc32.Hash(new IntPtr(instance + crcPosition), crcSize))
isValid = false;
for (var i = 0; i < crcSize; i += crcInfo.Length) //-V3022
{
Marshal.Copy(new IntPtr(instance + crcPosition + i), crcInfo, 0, crcInfo.Length);
uint address = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 0));
uint size = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 4));
uint hash = crcCryptor.Decrypt(BitConverter.ToUInt32(crcInfo, 8));
if (crc32.Hash(new IntPtr(instance + address), size) != hash)
isValid = false;
}
if (!isValid)
{
if ((options & (uint)LoaderOption.CHECK_PATCH) != 0)
{
ShowMessage((uint)MessageType.FileCorrupted);
Environment.Exit(1);
return;
}
GlobalData.SetIsPatchDetected(true);
}
}
GlobalData.SetSessionKey((uint)new Random().Next());
if (!Core.Instance.Init(instance))
{
Environment.Exit(1);
return;
}
// setup Import
var importSize = (uint)Faces.IMPORT_INFO_SIZE;
if (importSize != 0)
{
var importPos = (uint)Faces.IMPORT_INFO;
var key = (uint)Faces.STRING_DECRYPT_KEY;
var importInfo = new byte[12];
object[] iat = new object[importSize / importInfo.Length];
uint index = 0;
for (var i = 0; i < importSize; i += importInfo.Length) //-V3022
{
Marshal.Copy(new IntPtr(instance + importPos + i), importInfo, 0, importInfo.Length);
uint token = BitConverter.ToUInt32(importInfo, 0) ^ key;
uint delegateToken = BitConverter.ToUInt32(importInfo, 4) ^ key;
uint callType = BitConverter.ToUInt32(importInfo, 8);
MethodBase method = null;
FieldInfo field = null;
try
{
if ((callType & 8) != 0)
field = module.ResolveField((int)token);
else
method = module.ResolveMethod((int)token);
}
catch (Exception e)
{
Win32.ShowMessage(e.InnerException.Message, Assembly.GetExecutingAssembly().GetName().Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
Environment.Exit(1);
return;
}
var invoke = (MethodInfo)module.ResolveMethod((int)delegateToken);
var delegateType = invoke.DeclaringType;
object delegateObject;
if (callType == 0 && method.IsStatic)
delegateObject = Delegate.CreateDelegate(delegateType, (MethodInfo)method);
else
{
ParameterInfo[] parameters = invoke.GetParameters();
Type[] paramTypes = new Type[parameters.Length];
for (var j = 0; j < paramTypes.Length; j++)
paramTypes[j] = parameters[j].ParameterType;
Type declType = (method != null) ? method.DeclaringType : field.DeclaringType;
DynamicMethod dynamicMethod = new DynamicMethod("", invoke.ReturnType, paramTypes, (declType.IsInterface || declType.IsArray) ? delegateType : declType, true);
DynamicILInfo dynamicInfo = dynamicMethod.GetDynamicILInfo();
dynamicInfo.SetLocalSignature(new byte[] { 0x7, 0x0 });
if (method != null)
{
parameters = method.GetParameters();
int s = 0;
if (paramTypes.Length > parameters.Length)
{
paramTypes[0] = method.DeclaringType;
s = 1;
}
for (var j = 0; j < parameters.Length; j++)
paramTypes[s + j] = parameters[j].ParameterType;
}
else
{
if (paramTypes.Length > 0)
paramTypes[0] = field.DeclaringType;
}
var code = new byte[7 * paramTypes.Length + 6];
int codePos = 0;
int dynamicToken;
for (var j = 0; j < paramTypes.Length; j++)
{
code[codePos++] = 0x0e; // Ldarg_s
code[codePos++] = (byte)j;
Type type = paramTypes[j];
if ((type.IsClass || type.IsInterface) && !type.IsPointer && !type.IsByRef)
{
code[codePos++] = 0x74; // Castclass
dynamicToken = dynamicInfo.GetTokenFor(type.TypeHandle);
code[codePos++] = (byte)dynamicToken;
code[codePos++] = (byte)(dynamicToken >> 8);
code[codePos++] = (byte)(dynamicToken >> 16);
code[codePos++] = (byte)(dynamicToken >> 24);
}
else
codePos += 5;
}
switch (callType)
{
case 1:
code[codePos++] = 0x73; // Newobj
break;
case 2:
code[codePos++] = 0x6f; // Callvirt
break;
case 8:
code[codePos++] = 0x7e; // Ldsfld
break;
case 9:
code[codePos++] = 0x7b; // Ldfld
break;
default:
code[codePos++] = 0x28; // Call
break;
}
dynamicToken = (method != null) ? dynamicInfo.GetTokenFor(method.MethodHandle) : dynamicInfo.GetTokenFor(field.FieldHandle);
code[codePos++] = (byte)dynamicToken;
code[codePos++] = (byte)(dynamicToken >> 8);
code[codePos++] = (byte)(dynamicToken >> 16);
code[codePos++] = (byte)(dynamicToken >> 24);
code[codePos] = 0x2a; // Ret
dynamicInfo.SetCode(code, paramTypes.Length + 1);
delegateObject = dynamicMethod.CreateDelegate(delegateType);
}
iat[index++] = delegateObject;
}
IAT = iat;
}
ShowMessage((uint)MessageType.UnregisteredVersion);
GlobalData.SetLoaderStatus(1);
}
}
}

View File

@ -0,0 +1,651 @@
// LzmaDecoder.cs
using System;
using System.IO;
using SevenZip.Compression.RangeCoder;
#pragma warning disable 414
namespace SevenZip.Compression.LZ
{
public class OutWindow
{
byte[] _buffer;
uint _pos;
uint _windowSize;
uint _streamPos;
Stream _stream;
uint _id = 1;
public uint TrainSize;
public void Create(uint windowSize)
{
if (_windowSize != windowSize)
{
_buffer = new byte[windowSize];
}
_windowSize = windowSize;
_pos = 0;
_streamPos = 0;
}
public void Init(Stream stream, bool solid)
{
ReleaseStream();
_stream = stream;
if (!solid)
{
_streamPos = 0;
_pos = 0;
TrainSize = 0;
}
}
public void ReleaseStream()
{
Flush();
_stream = null;
}
public void Flush()
{
uint size = _pos - _streamPos;
if (size == 0)
return;
_stream.Write(_buffer, (int)_streamPos, (int)size);
if (_pos >= _windowSize)
_pos = 0;
_streamPos = _pos;
}
public void CopyBlock(uint distance, uint len)
{
uint pos = _pos - distance - 1;
if (pos >= _windowSize)
pos += _windowSize;
for (; len > 0; len--)
{
if (pos >= _windowSize)
pos = 0;
_buffer[_pos++] = _buffer[pos++];
if (_pos >= _windowSize)
Flush();
}
}
public void PutByte(byte b)
{
_buffer[_pos++] = b;
if (_pos >= _windowSize)
Flush();
}
public byte GetByte(uint distance)
{
uint pos = _pos - distance - 1;
if (pos >= _windowSize)
pos += _windowSize;
return _buffer[pos];
}
}
}
namespace SevenZip.Compression.RangeCoder
{
class Decoder
{
uint _id = 1;
public const uint KTopValue = (1 << 24);
public uint Range;
public uint Code;
public Stream Stream;
public void Init(Stream stream)
{
Stream = stream;
Code = 0;
Range = 0xFFFFFFFF;
for (int i = 0; i < 5; i++)
Code = (Code << 8) | (byte)Stream.ReadByte();
}
public void ReleaseStream()
{
Stream = null;
}
public uint DecodeDirectBits(int numTotalBits)
{
uint range = Range;
uint code = Code;
uint result = 0;
for (int i = numTotalBits; i > 0; i--)
{
range >>= 1;
uint t = (code - range) >> 31;
code -= range & (t - 1);
result = (result << 1) | (1 - t);
if (range < KTopValue)
{
code = (code << 8) | (byte)Stream.ReadByte();
range <<= 8;
}
}
Range = range;
Code = code;
return result;
}
}
struct BitDecoder
{
private const int KNumBitModelTotalBits = 11;
private const uint KBitModelTotal = (1 << KNumBitModelTotalBits);
const int KNumMoveBits = 5;
uint _prob;
public void Init() { _prob = KBitModelTotal >> 1; }
public uint Decode(Decoder rangeDecoder)
{
uint newBound = (rangeDecoder.Range >> KNumBitModelTotalBits) * _prob;
if (rangeDecoder.Code < newBound)
{
rangeDecoder.Range = newBound;
_prob += (KBitModelTotal - _prob) >> KNumMoveBits;
if (rangeDecoder.Range < Decoder.KTopValue)
{
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
rangeDecoder.Range <<= 8;
}
return 0;
}
else
{
rangeDecoder.Range -= newBound;
rangeDecoder.Code -= newBound;
_prob -= (_prob) >> KNumMoveBits;
if (rangeDecoder.Range < Decoder.KTopValue)
{
rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
rangeDecoder.Range <<= 8;
}
return 1;
}
}
}
struct BitTreeDecoder
{
private readonly BitDecoder[] _models;
private readonly int _numBitLevels;
public BitTreeDecoder(int numBitLevels)
{
_numBitLevels = numBitLevels;
_models = new BitDecoder[1 << numBitLevels];
}
public void Init()
{
for (uint i = 1; i < (1 << _numBitLevels); i++)
_models[i].Init();
}
public uint Decode(Decoder rangeDecoder)
{
uint m = 1;
for (int bitIndex = _numBitLevels; bitIndex > 0; bitIndex--)
m = (m << 1) + _models[m].Decode(rangeDecoder);
return m - ((uint)1 << _numBitLevels);
}
public uint ReverseDecode(Decoder rangeDecoder)
{
uint m = 1;
uint symbol = 0;
for (int bitIndex = 0; bitIndex < _numBitLevels; bitIndex++)
{
uint bit = _models[m].Decode(rangeDecoder);
m <<= 1;
m += bit;
symbol |= (bit << bitIndex);
}
return symbol;
}
public static uint ReverseDecode(BitDecoder[] models, UInt32 startIndex,
Decoder rangeDecoder, int numBitLevels)
{
uint m = 1;
uint symbol = 0;
for (int bitIndex = 0; bitIndex < numBitLevels; bitIndex++)
{
uint bit = models[startIndex + m].Decode(rangeDecoder);
m <<= 1;
m += bit;
symbol |= (bit << bitIndex);
}
return symbol;
}
}
}
namespace SevenZip.Compression.LZMA
{
internal abstract class Base
{
public const uint KNumStates = 12;
public struct State
{
public uint Index;
public void Init() { Index = 0; }
public void UpdateChar()
{
if (Index < 4) Index = 0;
else if (Index < 10) Index -= 3;
else Index -= 6;
}
public void UpdateMatch() { Index = (uint)(Index < 7 ? 7 : 10); }
public void UpdateRep() { Index = (uint)(Index < 7 ? 8 : 11); }
public void UpdateShortRep() { Index = (uint)(Index < 7 ? 9 : 11); }
public bool IsCharState() { return Index < 7; }
}
public const int KNumPosSlotBits = 6;
private const int KNumLenToPosStatesBits = 2; // it's for speed optimization
public const uint KNumLenToPosStates = 1 << KNumLenToPosStatesBits;
public const uint KMatchMinLen = 2;
public static uint GetLenToPosState(uint len)
{
len -= KMatchMinLen;
if (len < KNumLenToPosStates)
return len;
return KNumLenToPosStates - 1;
}
public const int KNumAlignBits = 4;
public const uint KStartPosModelIndex = 4;
public const uint KEndPosModelIndex = 14;
public const uint KNumFullDistances = 1 << ((int)KEndPosModelIndex / 2);
public const int KNumPosStatesBitsMax = 4;
public const uint KNumPosStatesMax = (1 << KNumPosStatesBitsMax);
public const int KNumLowLenBits = 3;
public const int KNumMidLenBits = 3;
public const int KNumHighLenBits = 8;
public const uint KNumLowLenSymbols = 1 << KNumLowLenBits;
public const uint KNumMidLenSymbols = 1 << KNumMidLenBits;
}
public class Decoder
{
uint _id = 1;
class LenDecoder
{
BitDecoder _mChoice = new BitDecoder();
BitDecoder _mChoice2 = new BitDecoder();
readonly BitTreeDecoder[] _mLowCoder = new BitTreeDecoder[Base.KNumPosStatesMax];
readonly BitTreeDecoder[] _mMidCoder = new BitTreeDecoder[Base.KNumPosStatesMax];
BitTreeDecoder _mHighCoder = new BitTreeDecoder(Base.KNumHighLenBits);
uint _mNumPosStates;
public void Create(uint numPosStates)
{
for (uint posState = _mNumPosStates; posState < numPosStates; posState++)
{
_mLowCoder[posState] = new BitTreeDecoder(Base.KNumLowLenBits);
_mMidCoder[posState] = new BitTreeDecoder(Base.KNumMidLenBits);
}
_mNumPosStates = numPosStates;
}
public void Init()
{
_mChoice.Init();
for (uint posState = 0; posState < _mNumPosStates; posState++)
{
_mLowCoder[posState].Init();
_mMidCoder[posState].Init();
}
_mChoice2.Init();
_mHighCoder.Init();
}
public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
{
if (_mChoice.Decode(rangeDecoder) == 0)
return _mLowCoder[posState].Decode(rangeDecoder);
else
{
uint symbol = Base.KNumLowLenSymbols;
if (_mChoice2.Decode(rangeDecoder) == 0)
symbol += _mMidCoder[posState].Decode(rangeDecoder);
else
{
symbol += Base.KNumMidLenSymbols;
symbol += _mHighCoder.Decode(rangeDecoder);
}
return symbol;
}
}
}
class LiteralDecoder
{
uint _id = 1;
struct Decoder2
{
BitDecoder[] _mDecoders;
public void Create() { _mDecoders = new BitDecoder[0x300]; }
public void Init() { for (int i = 0; i < 0x300; i++) _mDecoders[i].Init(); }
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
{
uint symbol = 1;
do
symbol = (symbol << 1) | _mDecoders[symbol].Decode(rangeDecoder);
while (symbol < 0x100);
return (byte)symbol;
}
public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
{
uint symbol = 1;
do
{
uint matchBit = (uint)(matchByte >> 7) & 1;
matchByte <<= 1;
uint bit = _mDecoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
symbol = (symbol << 1) | bit;
if (matchBit != bit)
{
while (symbol < 0x100)
symbol = (symbol << 1) | _mDecoders[symbol].Decode(rangeDecoder);
break;
}
}
while (symbol < 0x100);
return (byte)symbol;
}
}
Decoder2[] _mCoders;
int _mNumPrevBits;
int _mNumPosBits;
uint _mPosMask;
public void Create(int numPosBits, int numPrevBits)
{
if (_mCoders != null && _mNumPrevBits == numPrevBits &&
_mNumPosBits == numPosBits)
return;
_mNumPosBits = numPosBits;
_mPosMask = ((uint)1 << numPosBits) - 1;
_mNumPrevBits = numPrevBits;
uint numStates = (uint)1 << (_mNumPrevBits + _mNumPosBits);
_mCoders = new Decoder2[numStates];
for (uint i = 0; i < numStates; i++)
_mCoders[i].Create();
}
public void Init()
{
uint numStates = (uint)1 << (_mNumPrevBits + _mNumPosBits);
for (uint i = 0; i < numStates; i++)
_mCoders[i].Init();
}
uint GetState(uint pos, byte prevByte)
{ return ((pos & _mPosMask) << _mNumPrevBits) + (uint)(prevByte >> (8 - _mNumPrevBits)); }
public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
{ return _mCoders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
{ return _mCoders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
};
readonly LZ.OutWindow _mOutWindow = new LZ.OutWindow();
readonly RangeCoder.Decoder _mRangeDecoder = new RangeCoder.Decoder();
readonly BitDecoder[] _mIsMatchDecoders = new BitDecoder[Base.KNumStates << Base.KNumPosStatesBitsMax];
readonly BitDecoder[] _mIsRepDecoders = new BitDecoder[Base.KNumStates];
readonly BitDecoder[] _mIsRepG0Decoders = new BitDecoder[Base.KNumStates];
readonly BitDecoder[] _mIsRepG1Decoders = new BitDecoder[Base.KNumStates];
readonly BitDecoder[] _mIsRepG2Decoders = new BitDecoder[Base.KNumStates];
readonly BitDecoder[] _mIsRep0LongDecoders = new BitDecoder[Base.KNumStates << Base.KNumPosStatesBitsMax];
readonly BitTreeDecoder[] _mPosSlotDecoder = new BitTreeDecoder[Base.KNumLenToPosStates];
readonly BitDecoder[] _mPosDecoders = new BitDecoder[Base.KNumFullDistances - Base.KEndPosModelIndex];
BitTreeDecoder _mPosAlignDecoder = new BitTreeDecoder(Base.KNumAlignBits);
readonly LenDecoder _mLenDecoder = new LenDecoder();
readonly LenDecoder _mRepLenDecoder = new LenDecoder();
readonly LiteralDecoder _mLiteralDecoder = new LiteralDecoder();
uint _mDictionarySize;
uint _mDictionarySizeCheck;
uint _mPosStateMask;
public Decoder()
{
_mDictionarySize = 0xFFFFFFFF;
for (int i = 0; i < Base.KNumLenToPosStates; i++)
_mPosSlotDecoder[i] = new BitTreeDecoder(Base.KNumPosSlotBits);
}
void SetDictionarySize(uint dictionarySize)
{
if (_mDictionarySize != dictionarySize)
{
_mDictionarySize = dictionarySize;
_mDictionarySizeCheck = Math.Max(_mDictionarySize, 1);
uint blockSize = Math.Max(_mDictionarySizeCheck, (1 << 12));
_mOutWindow.Create(blockSize);
}
}
void SetLiteralProperties(int lp, int lc)
{
if (lp > 8)
throw new ArgumentException("lp > 8");
if (lc > 8)
throw new ArgumentException("lc > 8");
_mLiteralDecoder.Create(lp, lc);
}
void SetPosBitsProperties(int pb)
{
if (pb > Base.KNumPosStatesBitsMax)
throw new ArgumentException("pb > Base.KNumPosStatesBitsMax");
uint numPosStates = (uint)1 << pb;
_mLenDecoder.Create(numPosStates);
_mRepLenDecoder.Create(numPosStates);
_mPosStateMask = numPosStates - 1;
}
void Init(Stream inStream, Stream outStream)
{
_mRangeDecoder.Init(inStream);
_mOutWindow.Init(outStream, false);
uint i;
for (i = 0; i < Base.KNumStates; i++)
{
for (uint j = 0; j <= _mPosStateMask; j++)
{
uint index = (i << Base.KNumPosStatesBitsMax) + j;
_mIsMatchDecoders[index].Init();
_mIsRep0LongDecoders[index].Init();
}
_mIsRepDecoders[i].Init();
_mIsRepG0Decoders[i].Init();
_mIsRepG1Decoders[i].Init();
_mIsRepG2Decoders[i].Init();
}
_mLiteralDecoder.Init();
for (i = 0; i < Base.KNumLenToPosStates; i++)
_mPosSlotDecoder[i].Init();
for (i = 0; i < Base.KNumFullDistances - Base.KEndPosModelIndex; i++)
_mPosDecoders[i].Init();
_mLenDecoder.Init();
_mRepLenDecoder.Init();
_mPosAlignDecoder.Init();
}
public void Code(Stream inStream, Stream outStream, Int64 outSize)
{
Init(inStream, outStream);
Base.State state = new Base.State();
state.Init();
uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
UInt64 nowPos64 = 0;
UInt64 outSize64 = (UInt64)outSize;
if (nowPos64 < outSize64)
{
if (_mIsMatchDecoders[state.Index << Base.KNumPosStatesBitsMax].Decode(_mRangeDecoder) != 0)
throw new InvalidDataException("IsMatchDecoders");
state.UpdateChar();
byte b = _mLiteralDecoder.DecodeNormal(_mRangeDecoder, 0, 0);
_mOutWindow.PutByte(b);
nowPos64++;
}
while (nowPos64 < outSize64)
{
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
// while(nowPos64 < next)
{
uint posState = (uint)nowPos64 & _mPosStateMask;
if (_mIsMatchDecoders[(state.Index << Base.KNumPosStatesBitsMax) + posState].Decode(_mRangeDecoder) == 0)
{
byte b;
byte prevByte = _mOutWindow.GetByte(0);
if (!state.IsCharState())
b = _mLiteralDecoder.DecodeWithMatchByte(_mRangeDecoder,
(uint)nowPos64, prevByte, _mOutWindow.GetByte(rep0));
else
b = _mLiteralDecoder.DecodeNormal(_mRangeDecoder, (uint)nowPos64, prevByte);
_mOutWindow.PutByte(b);
state.UpdateChar();
nowPos64++;
}
else
{
uint len;
if (_mIsRepDecoders[state.Index].Decode(_mRangeDecoder) == 1)
{
if (_mIsRepG0Decoders[state.Index].Decode(_mRangeDecoder) == 0)
{
if (_mIsRep0LongDecoders[(state.Index << Base.KNumPosStatesBitsMax) + posState].Decode(_mRangeDecoder) == 0)
{
state.UpdateShortRep();
_mOutWindow.PutByte(_mOutWindow.GetByte(rep0));
nowPos64++;
continue;
}
}
else
{
UInt32 distance;
if (_mIsRepG1Decoders[state.Index].Decode(_mRangeDecoder) == 0)
{
distance = rep1;
}
else
{
if (_mIsRepG2Decoders[state.Index].Decode(_mRangeDecoder) == 0)
distance = rep2;
else
{
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
len = _mRepLenDecoder.Decode(_mRangeDecoder, posState) + Base.KMatchMinLen;
state.UpdateRep();
}
else
{
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
len = Base.KMatchMinLen + _mLenDecoder.Decode(_mRangeDecoder, posState);
state.UpdateMatch();
uint posSlot = _mPosSlotDecoder[Base.GetLenToPosState(len)].Decode(_mRangeDecoder);
if (posSlot >= Base.KStartPosModelIndex)
{
int numDirectBits = (int)((posSlot >> 1) - 1);
rep0 = ((2 | (posSlot & 1)) << numDirectBits);
if (posSlot < Base.KEndPosModelIndex)
rep0 += BitTreeDecoder.ReverseDecode(_mPosDecoders,
rep0 - posSlot - 1, _mRangeDecoder, numDirectBits);
else
{
rep0 += (_mRangeDecoder.DecodeDirectBits(
numDirectBits - Base.KNumAlignBits) << Base.KNumAlignBits);
rep0 += _mPosAlignDecoder.ReverseDecode(_mRangeDecoder);
}
}
else
rep0 = posSlot;
}
if (rep0 >= _mOutWindow.TrainSize + nowPos64 || rep0 >= _mDictionarySizeCheck)
{
if (rep0 == 0xFFFFFFFF)
break;
throw new InvalidDataException("rep0");
}
_mOutWindow.CopyBlock(rep0, len);
nowPos64 += len;
}
}
}
_mOutWindow.Flush();
_mOutWindow.ReleaseStream();
_mRangeDecoder.ReleaseStream();
}
public void SetDecoderProperties(byte[] properties)
{
if (properties.Length < 5)
throw new ArgumentException("properties.Length < 5");
int lc = properties[0] % 9;
int remainder = properties[0] / 9;
int lp = remainder % 5;
int pb = remainder / 5;
if (pb > Base.KNumPosStatesBitsMax)
throw new ArgumentException("pb > Base.kNumPosStatesBitsMax");
UInt32 dictionarySize = 0;
for (int i = 0; i < 4; i++)
dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
SetDictionarySize(dictionarySize);
SetLiteralProperties(lp, lc);
SetPosBitsProperties(pb);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,425 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
using System;
using Contracts = System.Diagnostics.Debug;
using Contract = System.Diagnostics.Debug;
//using System.Runtime.InteropServices;
// ReSharper disable once CheckNamespace
namespace Numerics
{
/*
[StructLayout(LayoutKind.Explicit)]
internal struct DoubleUlong
{
[FieldOffset(0)]
internal double dbl;
[FieldOffset(0)]
internal ulong uu;
}
*/
internal static class NumericsHelpers
{
private const int KcbitUint = 32;
/*internal static void GetDoubleParts(double dbl, out int sign, out int exp, out ulong man, out bool fFinite)
{
//Contract.Ensures(Contract.ValueAtReturn(out sign) == +1 || Contract.ValueAtReturn(out sign) == -1);
DoubleUlong du;
du.uu = 0;
du.dbl = dbl;
sign = 1 - ((int)(du.uu >> 62) & 2);
man = du.uu & 0x000FFFFFFFFFFFFF;
exp = (int)(du.uu >> 52) & 0x7FF;
if (exp == 0)
{
// Denormalized number.
fFinite = true;
if (man != 0)
exp = -1074;
}
else if (exp == 0x7FF)
{
// NaN or Inifite.
fFinite = false;
exp = int.MaxValue;
}
else
{
fFinite = true;
man |= 0x0010000000000000;
exp -= 1075;
}
}
internal static double GetDoubleFromParts(int sign, int exp, ulong man)
{
DoubleUlong du;
du.dbl = 0;
if (man == 0)
du.uu = 0;
else
{
// Normalize so that 0x0010 0000 0000 0000 is the highest bit set.
int cbitShift = CbitHighZero(man) - 11;
if (cbitShift < 0)
man >>= -cbitShift;
else
man <<= cbitShift;
exp -= cbitShift;
Contract.Assert((man & 0xFFF0000000000000) == 0x0010000000000000);
// Move the point to just behind the leading 1: 0x001.0 0000 0000 0000
// (52 bits) and skew the exponent (by 0x3FF == 1023).
exp += 1075;
if (exp >= 0x7FF)
{
// Infinity.
du.uu = 0x7FF0000000000000;
}
else if (exp <= 0)
{
// Denormalized.
exp--;
if (exp < -52)
{
// Underflow to zero.
du.uu = 0;
}
else
{
du.uu = man >> -exp;
Contract.Assert(du.uu != 0);
}
}
else
{
// Mask off the implicit high bit.
du.uu = (man & 0x000FFFFFFFFFFFFF) | ((ulong)exp << 52);
}
}
if (sign < 0)
du.uu |= 0x8000000000000000;
return du.dbl;
}
*/
// Do an in-place twos complement of d and also return the result.
// "Dangerous" because it causes a mutation and needs to be used
// with care for immutable types
internal static void DangerousMakeTwosComplement(uint[] d)
{
// first do complement and +1 as long as carry is needed
int i = 0;
uint v = 0;
for (; i < d.Length; i++)
{
v = ~d[i] + 1;
d[i] = v;
if (v != 0) { i++; break; }
}
if (v != 0)
{
// now ones complement is sufficient
for (; i < d.Length; i++)
{
d[i] = ~d[i];
}
}
else
{
//??? this is weird
d = resize(d, d.Length + 1);
d[d.Length - 1] = 1;
}
}
// ReSharper disable once InconsistentNaming
private static uint[] resize(uint[] v, int len)
{
if (v.Length == len) return v;
uint[] ret = new uint[len];
int n = Math.Min(v.Length, len);
for (int i = 0; i < n; i++)
{
ret[i] = v[i];
}
return ret;
}
internal static void Swap<T>(ref T a, ref T b)
{
T tmp = a;
a = b;
b = tmp;
}
// ReSharper disable once InconsistentNaming
/*
internal static uint GCD(uint u1, uint u2)
{
const int cvMax = 32;
if (u1 < u2)
goto LOther;
LTop:
Contract.Assert(u2 <= u1);
if (u2 == 0)
return u1;
for (int cv = cvMax; ; )
{
u1 -= u2;
if (u1 < u2)
break;
if (--cv == 0)
{
u1 %= u2;
break;
}
}
LOther:
Contract.Assert(u1 < u2);
if (u1 == 0)
return u2;
for (int cv = cvMax; ; )
{
u2 -= u1;
if (u2 < u1)
break;
if (--cv == 0)
{
u2 %= u1;
break;
}
}
goto LTop;
}
*/
// ReSharper disable once InconsistentNaming
/*
internal static ulong GCD(ulong uu1, ulong uu2)
{
const int cvMax = 32;
if (uu1 < uu2)
goto LOther;
LTop:
Contract.Assert(uu2 <= uu1);
if (uu1 <= uint.MaxValue)
goto LSmall;
if (uu2 == 0)
return uu1;
for (int cv = cvMax; ; )
{
uu1 -= uu2;
if (uu1 < uu2)
break;
if (--cv == 0)
{
uu1 %= uu2;
break;
}
}
LOther:
Contract.Assert(uu1 < uu2);
if (uu2 <= uint.MaxValue)
goto LSmall;
if (uu1 == 0)
return uu2;
for (int cv = cvMax; ; )
{
uu2 -= uu1;
if (uu2 < uu1)
break;
if (--cv == 0)
{
uu2 %= uu1;
break;
}
}
goto LTop;
LSmall:
uint u1 = (uint)uu1;
uint u2 = (uint)uu2;
if (u1 < u2)
goto LOtherSmall;
LTopSmall:
Contract.Assert(u2 <= u1);
if (u2 == 0)
return u1;
for (int cv = cvMax; ; )
{
u1 -= u2;
if (u1 < u2)
break;
if (--cv == 0)
{
u1 %= u2;
break;
}
}
LOtherSmall:
Contract.Assert(u1 < u2);
if (u1 == 0)
return u2;
for (int cv = cvMax; ; )
{
u2 -= u1;
if (u2 < u1)
break;
if (--cv == 0)
{
u2 %= u1;
break;
}
}
goto LTopSmall;
}
*/
internal static ulong MakeUlong(uint uHi, uint uLo)
{
return ((ulong)uHi << KcbitUint) | uLo;
}
internal static uint GetLo(ulong uu)
{
return (uint)uu;
}
internal static uint GetHi(ulong uu)
{
return (uint)(uu >> KcbitUint);
}
/*
internal static uint Abs(int a)
{
uint mask = (uint)(a >> 31);
return ((uint)a ^ mask) - mask;
}
*/
// internal static ulong Abs(long a) {
// ulong mask = (ulong)(a >> 63);
// return ((ulong)a ^ mask) - mask;
// }
private static uint CombineHash(uint u1, uint u2)
{
return ((u1 << 7) | (u1 >> 25)) ^ u2;
}
internal static int CombineHash(int n1, int n2)
{
return (int)CombineHash((uint)n1, (uint)n2);
}
internal static int CbitHighZero(uint u)
{
if (u == 0)
return 32;
int cbit = 0;
if ((u & 0xFFFF0000) == 0)
{
cbit += 16;
u <<= 16;
}
if ((u & 0xFF000000) == 0)
{
cbit += 8;
u <<= 8;
}
if ((u & 0xF0000000) == 0)
{
cbit += 4;
u <<= 4;
}
if ((u & 0xC0000000) == 0)
{
cbit += 2;
u <<= 2;
}
if ((u & 0x80000000) == 0)
cbit += 1;
return cbit;
}
/*internal static int CbitLowZero(uint u)
{
if (u == 0)
return 32;
int cbit = 0;
if ((u & 0x0000FFFF) == 0)
{
cbit += 16;
u >>= 16;
}
if ((u & 0x000000FF) == 0)
{
cbit += 8;
u >>= 8;
}
if ((u & 0x0000000F) == 0)
{
cbit += 4;
u >>= 4;
}
if ((u & 0x00000003) == 0)
{
cbit += 2;
u >>= 2;
}
if ((u & 0x00000001) == 0)
cbit += 1;
return cbit;
}
internal static int CbitHighZero(ulong uu)
{
if ((uu & 0xFFFFFFFF00000000) == 0)
return 32 + CbitHighZero((uint)uu);
return CbitHighZero((uint)(uu >> 32));
}*/
// internal static int CbitLowZero(ulong uu) {
// if ((uint)uu == 0)
// return 32 + CbitLowZero((uint)(uu >> 32));
// return CbitLowZero((uint)uu);
// }
//
// internal static int Cbit(uint u) {
// u = (u & 0x55555555) + ((u >> 1) & 0x55555555);
// u = (u & 0x33333333) + ((u >> 2) & 0x33333333);
// u = (u & 0x0F0F0F0F) + ((u >> 4) & 0x0F0F0F0F);
// u = (u & 0x00FF00FF) + ((u >> 8) & 0x00FF00FF);
// return (int)((ushort)u + (ushort)(u >> 16));
// }
//
// static int Cbit(ulong uu) {
// uu = (uu & 0x5555555555555555) + ((uu >> 1) & 0x5555555555555555);
// uu = (uu & 0x3333333333333333) + ((uu >> 2) & 0x3333333333333333);
// uu = (uu & 0x0F0F0F0F0F0F0F0F) + ((uu >> 4) & 0x0F0F0F0F0F0F0F0F);
// uu = (uu & 0x00FF00FF00FF00FF) + ((uu >> 8) & 0x00FF00FF00FF00FF);
// uu = (uu & 0x0000FFFF0000FFFF) + ((uu >> 16) & 0x0000FFFF0000FFFF);
// return (int)((uint)uu + (uint)(uu >> 32));
// }
}
}

View File

@ -0,0 +1,35 @@
using System.Reflection;
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("VMProtect.Runtime")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VMProtect.Runtime")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[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("544f194e-b3a9-40a8-8f75-bd12b10868bf")]
// 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")]

View File

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
// ReSharper disable once CheckNamespace
namespace VMProtect
{
public class StringManager
{
public StringManager(long instance)
{
_instance = instance;
var key = new byte[8];
Marshal.Copy(new IntPtr(_instance + (uint)Faces.KEY_INFO), key, 0, key.Length);
_cipher = new CipherRC5(key);
_entries = new Dictionary<uint, uint>();
_key = BitConverter.ToUInt32(key, 0);
var startPosition = (uint)Faces.STRING_INFO;
// DecryptDirectory
var directory = new byte[8];
Marshal.Copy(new IntPtr(_instance + startPosition), directory, 0, directory.Length);
directory = _cipher.Decrypt(directory);
var numberOfEntries = BitConverter.ToUInt32(directory, 0);
var entry = new byte[16];
for (uint i = 0; i < numberOfEntries; i++)
{
// DecryptEntry
uint pos = startPosition + 8 + i * 16;
Marshal.Copy(new IntPtr(_instance + pos), entry, 0, 16);
entry = _cipher.Decrypt(entry);
_entries.Add(BitConverter.ToUInt32(entry, 0), pos);
}
}
public string DecryptString(uint stringId)
{
uint pos;
if (_entries.TryGetValue(stringId, out pos))
{
var entry = new byte[16];
Marshal.Copy(new IntPtr(_instance + pos), entry, 0, 16);
entry = _cipher.Decrypt(entry);
var size = BitConverter.ToInt32(entry, 8);
var stringData = new byte[size];
Marshal.Copy(new IntPtr(_instance + BitConverter.ToUInt32(entry, 4)), stringData, 0, size);
for (var c = 0; c < size; c++)
{
stringData[c] = (byte)(stringData[c] ^ BitRotate.Left(_key, c) + c);
}
return Encoding.Unicode.GetString(stringData);
}
return null;
}
private readonly long _instance;
private readonly CipherRC5 _cipher;
private readonly Dictionary<uint, uint> _entries;
private readonly uint _key;
}
}

View File

@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using VMProtect;
namespace UnitTestProject
{
[TestClass]
public class LicensingManagerTests
{
private class Data
{
public void PushByte(byte b) { _data.Add(b); }
//void PushDWord(int d) { PushBuff(BitConverter.GetBytes(d)); }
/*void PushQWord(ulong q) { PushBuff(&q, sizeof(q)); }
void PushWord(ushort w) { PushBuff(&w, sizeof(w)); }*/
public void PushBuff(byte[] buff)
{
_data.AddRange(buff);
}
/*public void InsertByte(int position, byte value)
{
_data.Insert(position, value);
}*/
/*uint32_t ReadDWord(size_t nPosition) const
{
return *reinterpret_cast<const uint32_t *>(&m_vData[nPosition]);
}*/
public void WriteDWord(int position, int value)
{
foreach (var b in BitConverter.GetBytes(value))
{
_data[position++] = b;
}
}
public int Size => _data.Count;
//public void clear() { _data.Clear(); }
//public bool empty() { return _data.Count == 0; }
//void resize(int size) { _data.resize(size); }
//void resize(int size, uint8_t value) { m_vData.resize(size, value); }
public byte[] ToArray() { return _data.ToArray(); }
private readonly List<byte> _data;
public Data(int sz)
{
_data = new List<byte>(new byte[sz]);
}
}
[TestMethod]
public void ParseSerial()
{
//var key = new byte[] {1, 2, 3, 4, 5, 6, 7, 8};
var data = new Data(sizeof(uint) * (int)LicensingManager.Fields.Count);
var publicExp = Convert.FromBase64String("AAEAAQ==");
var modulus = Convert.FromBase64String("pwUqwaM8IOukyx06Lvi5YNQ70JE7pwg7K+pmM/vCe1CUseHKFM1v1m11geDjVsAt38AnaiFs3JhtTs80ySCIxOSyvMw6Cd52k6N6dn7LAx1mxQLJLhYeMMJYbplMHnMLwYN0+IO58OVbEqRyaJV2ExolnK2EYZL7QRXujGY7/sOoOMF3p6GsWJK6kkBJICIoL9hHWBQMO6/9rmls/+EhaWuP80Vx0+H2OlrQ58K+TJeyE393cvb4QufiEPpCNaB50Klee9QUnsjSW/bTnmGn4Bi5+cowRbawUY73Q5I58fMAXiH9ueDPuNMR9YKDgW9GxunLmYkbuwqIp/v7kw3cfMBM0ihhB0B8UhjyAMAGLzJWX3H/H6Zrz41g9PbPjTAxfsTaCrxoqjaTaO4zk9YsI//VX9Fhivcy913SevBpNandziGfYH/oHW2xDy9AfwkE1wuIBlLj7c/k8U1YmmRAmkoCzlmB7EU4ClNltboh1uARUQ6wW30upppnuYhGkTy7");
var black = Convert.FromBase64String("A7zybXsboP8UVQ4x8mCSPVlm4W8G2gMbKOiLDFIX28dpdl6AzdqGCxIeiXRfaPBgeGeyL1BB+3pLVJ9SGkjc/BXy1hYkjJCwacADVEWoR14blpa3hdx+R/WHe8uhS9ShV1hxviIKRt4UJbIjyqH7tMu2p8KuVbB0IwM0dFPnVujgNmNN2/BeOQl/RFMmD+TpLzFHetvt0Dx7rk8MKINv3SoyL97QWNvwCbL35JIZN5DtMdZ3MfO/fxz/1kSTNbccciqEljRiC74zMsNz2LNkf1hwxES96yGBsd2oOTe+DJx43j8iZ7UD75iwIGKoPxysOYnHTewT2ofK9d6SMl4rIyxt6TI+KzXppRyhVieHtEIo9/NIm7ABnkLTJvy4tjFftPocJP3E5v9ra8YBQ2y3PKz04BkesCeKiVPyBqy9phxHtjKpIimlm73GSfDMVZ+xgLsn/Ui6XSW8kB8ai+rEA1KFosfmsVPASiuXJAHJaNfY4ULKZWOfGcoPDh1KjhmFq7INiQaMy+rml/EiKv4p9k3vomv41ll5IoIVkxZaMY8Gtkl5UYWWJUMlJgphM9+LOkWCLX1fm7ZUiJbfHkmVTTFZ6SxhxoeO73yovFdt37I/17tbM0jjQjC1Q172ZPQmWPBP2NaPTXglJdkSKWYWw8pG6EJh+eRrfZ1USmdkU2TI0FUDSwJ2F2RSkObaDx4WFrBz0xddLmEl0XEJaQI/TTRZk5hQB/20NPzavgiAQ39p62LR7hZTqnR4zshiFv2sChe4x2p4XzBx4NKx1Zw6QaZrfwX47R3dc2K80jHIisj9Ltnr3qUgr5S0Nbp6+8BKB6RFcPuPAi24SVh7e5KgvoKNB/FzJqZnE9FCiryEeRbRwU26g3l+orZTM/jm1niFKlgrvdRweVqVza4JBnbeTGF2t8PstMH6Vx4+gpoJWyoQY6acm5MSFyl2DLXCcd6MmoRyp30Ge209zoOjj7c5PGRYxjiiUO04gaGhh7YyUp7VTHmd2llSQaKhsyw/7k3OqEKTinSRmdiDNsmfp8fOqtd388jGyhME6zzda8u1Ex6uvHkrk2arjVSeQk3XED4ZPqyRbLDZYGZcp9HheDdciX56rK39NTXetOWN8p4KW6aMa91EUTaCiafQVhO6dYzO+1ybRjOR7ND7nOnt9zUEerzNbIkCFT6uGTqtue0FZe4Zxunlv9D1mA4266xWfZfIPSzXD2cVAerBjr2BtYHOolDP1dRu1JcPwXGxOMiDL76x1NghovHsQxlwcfWT9CO+ywvhEkiwirt0UsTbACSslWD2sNLTdQ1aLNkqM9FjJzN7uKHk/J4OZtmNFRsxxZUvWYKYb/+q93FEsbMr5YfSPLlezvf6fL3k6tSKB5sFuk/rsgeBQYOwUGIKDRc8c0yNd8kEXOxvmzCGEv2/95Lh7XxXEUaHYKki7TR73v+H6pIiYmTOHg/Z9F4OjzHxb6HIUq6bzNywpzguJjBKqhnoRfJMwBr9P3NQ+CU5VaBXwxTlMWtW9Ihou7a+Hio34w2YGYdtr8BzMjT03VrAOtLH4V0HZj/UTAkTFaGDK/bdOAYXH/fz9GVBVU94hB86ii4e9ulYanZkiRJMDwTlNTup5jRVAR7/nM4H0Q0evDGRo7k4IP5CtLb6fg==");
data.WriteDWord((int)LicensingManager.Fields.PublicExpOffset * sizeof(uint), data.Size);
data.WriteDWord((int)LicensingManager.Fields.PublicExpSize * sizeof(uint), publicExp.Length);
data.PushBuff(publicExp);
data.WriteDWord((int)LicensingManager.Fields.ModulusOffset * sizeof(uint), data.Size);
data.WriteDWord((int)LicensingManager.Fields.ModulusSize * sizeof(uint), modulus.Length);
data.PushBuff(modulus);
data.WriteDWord((int)LicensingManager.Fields.BlacklistOffset * sizeof(uint), data.Size);
data.WriteDWord((int)LicensingManager.Fields.BlacklistSize * sizeof(uint), black.Length);
data.PushBuff(black);
var crcPos = data.Size;
data.WriteDWord((int)LicensingManager.Fields.CRCOffset * sizeof(uint), crcPos);
var size = crcPos + 16;
using (var hash = new SHA1Managed())
{
var p = hash.ComputeHash(data.ToArray());
for (var i = crcPos; i < size; i++)
{
data.PushByte(p[i - crcPos]);
}
}
var licensingManager = new LicensingManager(data.ToArray());
Assert.AreEqual(SerialState.Blacklisted, licensingManager.SetSerialNumber("H2GfYz579KQ5poUTxKRWsUd7o+1XSwaJrK7CmwG15rNuo3Wa+vy660rJkRaWTrELbyyIe2k15973P13WJvxDR8myQCMi8Pv9D9k9iblCTAZL9vOcX55g2Vk4i+x+DEDn601kjvkL7RvHug1SYq6GqKm4dnApwlGvbnSebSDwrhh0E5g9I/XA5pa7hQUQwcBoXq6A7e7Blj8FbJ1JBdYUJY7RavgFE9KYfTXn5ceCwPr0gR3A++W66amQdxWnFxyyOFwfCPuZDk+LCgqqAgMyj5PRPcLA3nanXLDLPGva1wa1EEP0qvx6yCSpDURP94GxQGY1xjPlZagbuLaYyWn7bb/sLsYNXVHE1a+YNFORn890tbZ1D6i+wTEa254oF3yKa5GYTQmRWJQR+OXqaTK/wNG4y8dAUisOmQpevrSrD7pQj7ZLGOChmw+KWB6SozSHtIMY665ji9tMP8mq8OUSVSZ9N9q3Zh/xnW0W8sGck5IzTr3JtT0a3iOXSYfijpmy"));
Assert.AreEqual(SerialState.Blacklisted, licensingManager.GetSerialNumberState());
var snd = new SerialNumberData();
Assert.IsTrue(licensingManager.GetSerialNumberData(snd));
Assert.AreEqual("", snd.EMail); //a20071234@163.com
Assert.AreEqual("", snd.UserName); //Su Ying
Assert.AreEqual(DateTime.MaxValue, snd.Expires);
Assert.AreEqual(DateTime.MaxValue, snd.MaxBuild);
Assert.AreEqual(0, snd.RunningTime);
Assert.AreEqual(SerialState.Blacklisted, snd.State);
Assert.AreEqual(0, snd.UserData.Length);
Assert.AreEqual(SerialState.Success, licensingManager.SetSerialNumber("V5z/4JRVkIhN/D7KkHUBfM2ww3VMxq4r7SgRViTG840294nBiqLer9QUyuX/oyS5sxwzgtMruYYK2n8PvrilVRhFj3rgoK67V + 0 / kJxNmypnWY + PbNurXbimp8KfTF6aOydLQyo26M2iRJhnPCXXInXB4QMi5dPNf41cdVelwt + C5hSfV7zPeJZRLbWv + AMScBJEmy1AW3AWUokfHUMSonq75LxBc3jLnDESz8UGTNWrIXSEiRjrueszSM7uGEmWemUjS + MzgL + F + DfsKNTc2KTEctprxQmxcJZsN4rZS0q8UJo3eA0HXgrrFlxYkLqgcq + 8 / 018W3l79nR17ZDQsUuJFfrElY8F6OGtbis2j9YyCszcWoKQLB3bSgWrKXPAlrEN4VuxMk0wbq + sYZLIt / npAmFheE7wHhnN1PubK84BpQFZKnkrIrsC43PJ2ss2WOQl / vqTxhTbbDyPEE69NW8R + fUanth5sglfableZjt4WH + hwgiGL + D8wHQlWgT7"));
Assert.AreEqual(SerialState.Success, licensingManager.GetSerialNumberState());
Assert.IsTrue(licensingManager.GetSerialNumberData(snd));
Assert.AreEqual("jleber@onvisionnetworks.com", snd.EMail);
Assert.AreEqual("Onvision Networks Limited", snd.UserName);
Assert.AreEqual(DateTime.MaxValue, snd.Expires);
Assert.AreEqual(new DateTime(2017, 4, 11), snd.MaxBuild);
Assert.AreEqual(0, snd.RunningTime);
Assert.AreEqual(SerialState.Success, snd.State);
Assert.AreEqual(1, snd.UserData.Length);
CollectionAssert.AreEqual(snd.UserData, new byte[] {4});
}
/*[TestMethod]
public void ParseSerialTimeLimitedHWID()
{
//TODO
}*/
}
}

View File

@ -0,0 +1,47 @@
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using VMProtect;
namespace UnitTestProject
{
[TestClass]
public class LoaderTests
{
[TestMethod]
public void LzmaDecode()
{
byte[] properties =
{
0x5d, 0, 0, 0, 1 // 5 bytes props
};
byte[] src =
{
0x00, 0x4e, 0x3a, 0x46, 0xeb, 0xe0, 0x06, 0x71, 0xc9, 0xe1,
0xe6, 0x37, 0xfd, 0x9b, 0xb6, 0xd0, 0x76, 0x3f, 0xc8, 0x73,
0xee, 0x11, 0xb6, 0x41, 0xaa, 0xb1, 0x7b, 0x7b, 0xef, 0xc6,
0x9f, 0xff, 0xf6, 0x1d, 0x28, 0x00 //36 bytes packed
};
byte [] dstExpected = { 0x9c, 0xe9, 0x57, 0xbe, 0x00, 0x00, 0xc3, 0xe9, 0x24, 0x2c, 0x01, 0x00, 0xe9, 0xef, 0x65, 0x00, 0x00, 0xe9, 0xc0, 0x41, 0x06, 0x00, 0xc3, 0x56, 0x57 };
var pinnedSrc = GCHandle.Alloc(src, GCHandleType.Pinned);
uint dstSize = 65536;
var dstPtr = Marshal.AllocHGlobal((int)dstSize);
try
{
dstSize = int.MaxValue;
uint srcSize /*= (uint)src.Length*/;
var res = Loader.LzmaDecode(dstPtr, pinnedSrc.AddrOfPinnedObject(), properties, ref dstSize, out srcSize);
Assert.AreEqual(true, res);
Assert.AreEqual(dstExpected.Length, (int)dstSize);
var dst = new byte[dstSize];
Marshal.Copy(dstPtr, dst, 0, (int)dstSize);
CollectionAssert.AreEqual(dstExpected, dst);
Assert.AreEqual(src.Length, (int)srcSize);
}
finally
{
pinnedSrc.Free();
Marshal.FreeHGlobal(dstPtr);
}
}
}
}

View File

@ -0,0 +1,100 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.ExceptionServices;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTestProject
{
public abstract class MsilToVmTestCompiler
{
public enum LongEnum : long { Eval1 = 1, Evalm1 = -1 }
public enum ULongEnum : ulong { Evalm1 = 0xFFFFFFFFFFFFFFFF }
public enum ByteEnum : byte {}
public enum SByteEnum : sbyte { }
public enum IntEnum /*: int*/ { }
public enum UIntEnum : uint { }
public enum ShortEnum : short { }
public enum UShortEnum : ushort { }
public static byte[] GetIlBytes(DynamicMethod dynamicMethod)
{
// ReSharper disable once PossibleNullReferenceException
var resolver = typeof(DynamicMethod).GetField("m_resolver", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(dynamicMethod);
if (resolver == null) throw new ArgumentException("The dynamic method's IL has not been finalized.");
// ReSharper disable once PossibleNullReferenceException
return (byte[])resolver.GetType().GetField("m_code", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(resolver);
}
public abstract Stream CreateVmStream(Type rt, ParameterInfo[] pi, Type[] locals, byte[] ilBytes);
public enum InvokeTestCombineError
{
NoError,
NoErrorByStdEx, // текущий стандарт ECMA-335 оставляет некоторые сценарии как "неопределенное поведение", но их можно определить
VmOtherExceptionExpected,
VmOtherTypeExpected,
VmOtherValueExpected,
Cnt
};
// dyn/vm обязаны что-то возвратить, либо выбросить исключение
// (в тестах не должно быть методов, возвращающих void, null или исключение в качестве retVal)
[HandleProcessCorruptedStateExceptions]
public InvokeTestCombineError InvokeTestCombine(DynamicMethod dyn, object[] parameters, out object dynRet, out object vmRet, out string err)
{
Type exceptionType = null;
err = "";
try
{
dynRet = dyn.Invoke(null, parameters);
Assert.IsNotNull(dynRet);
Assert.IsInstanceOfType(dynRet, dyn.ReturnType);
}
catch (Exception e)
{
Assert.IsInstanceOfType(e, typeof(TargetInvocationException));
Assert.IsNotNull(e.InnerException);
exceptionType = e.InnerException.GetType();
dynRet = e.InnerException;
}
var vmStream = CreateVmStream(dyn.ReturnType, dyn.GetBaseDefinition().GetParameters(),
//FIXME dyn.GetMethodBody().LocalVariables.Select(o => o.LocalType).ToArray(),
new Type[] {},
GetIlBytes(dyn));
try
{
vmRet = Invoke(parameters, vmStream);
if(exceptionType != null)
{
err = $"VmOtherExceptionExpected: {exceptionType.FullName}, actual: {vmRet}";
return InvokeTestCombineError.VmOtherExceptionExpected;
}
if (vmRet == null || vmRet.GetType() != dyn.ReturnType)
{
err = $"VmOtherTypeExpected: {dyn.ReturnType.FullName}, actual: {((vmRet != null) ? vmRet.GetType().FullName : "null")}";
return InvokeTestCombineError.VmOtherTypeExpected;
}
}
catch (Exception e)
{
vmRet = e;
if (e.GetType() != exceptionType)
{
err = $"VmOtherExceptionExpected: {((exceptionType != null) ? exceptionType.FullName : dynRet)}, actual: {e.GetType().FullName}";
return InvokeTestCombineError.VmOtherExceptionExpected;
}
return InvokeTestCombineError.NoError;
}
if (dynRet.Equals(vmRet))
{
return InvokeTestCombineError.NoError;
}
err = $"VmOtherValueExpected: {dynRet}, actual: {vmRet}";
return InvokeTestCombineError.VmOtherValueExpected;
}
public abstract object Invoke(object[] parameters, Stream vmStream);
}
}

View File

@ -0,0 +1,35 @@
using System.Reflection;
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("UnitTestProject")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UnitTestProject")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[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("aefca063-245a-4d50-a5a3-82188ce677fa")]
// 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")]

View File

@ -0,0 +1,172 @@
using System;
using System.Diagnostics;
namespace UnitTestProject.RefVm
{
// Token: 0x02000048 RID: 72
internal static class ElementedTypeHelper // \u0008\u2005
{
// Token: 0x06000307 RID: 775 RVA: 0x000148D8 File Offset: 0x00012AD8
public static Type TryGoToElementType(Type t) // \u0002
{
if (t.IsByRef || t.IsArray || t.IsPointer)
{
return TryGoToElementType(t.GetElementType());
}
return t;
}
// Token: 0x06000308 RID: 776 RVA: 0x00014900 File Offset: 0x00012B00
public static Type TryGoToPointerOrReferenceElementType(Type t) // \u0003
{
if (t.HasElementType && !t.IsArray)
{
t = t.GetElementType();
}
return t;
}
// Token: 0x06000309 RID: 777 RVA: 0x00014920 File Offset: 0x00012B20
public static MyCollection<ElementedTypeDescrItem> NestedElementTypes(Type type) // \u0002
{
var collection = new MyCollection<ElementedTypeDescrItem>();
while (true)
{
Debug.Assert(type != null, "type != null");
if(type == null) return collection;
if (type.IsArray)
{
collection.PushBack(new ElementedTypeDescrItem
{
K = ElementedTypeDescrItem.Kind.Array1,
ArrayRank = type.GetArrayRank()
});
}
else if (type.IsByRef)
{
collection.PushBack(new ElementedTypeDescrItem
{
K = ElementedTypeDescrItem.Kind.ByRef2
});
}
else
{
if (!type.IsPointer)
{
break;
}
collection.PushBack(new ElementedTypeDescrItem
{
K = ElementedTypeDescrItem.Kind.Ponter0
});
}
type = type.GetElementType();
}
return collection;
}
// Token: 0x0600030A RID: 778 RVA: 0x000149B0 File Offset: 0x00012BB0
public static MyCollection<ElementedTypeDescrItem> NestedElementTypes(string text) // \u0002
{
var collection = new MyCollection<ElementedTypeDescrItem>();
while (true)
{
if (text.EndsWith(StringDecryptor.GetString(-1550346966) /* & */, StringComparison.Ordinal))
{
collection.PushBack(new ElementedTypeDescrItem
{
K = ElementedTypeDescrItem.Kind.ByRef2
});
text = text.Substring(0, text.Length - 1);
}
else if (text.EndsWith(StringDecryptor.GetString(-1550346958) /* * */, StringComparison.Ordinal))
{
collection.PushBack(new ElementedTypeDescrItem
{
K = ElementedTypeDescrItem.Kind.Ponter0
});
text = text.Substring(0, text.Length - 1);
}
else if (text.EndsWith(StringDecryptor.GetString(-1550346950) /* [] */, StringComparison.Ordinal))
{
collection.PushBack(new ElementedTypeDescrItem
{
K = ElementedTypeDescrItem.Kind.Array1,
ArrayRank = 1
});
text = text.Substring(0, text.Length - 2);
}
else
{
if (!text.EndsWith(StringDecryptor.GetString(-1550346811) /* ,] */, StringComparison.Ordinal))
{
return collection;
}
var rank = 1;
var remainLen = -1;
for (var i = text.Length - 2; i >= 0; i--)
{
var c = text[i];
if (c != ',')
{
if (c != '[')
{
throw new InvalidOperationException(StringDecryptor.GetString(-1550346804) /* VM-3012 */);
}
remainLen = i;
i = -1;
}
else
{
rank++;
}
}
if (remainLen < 0)
{
throw new InvalidOperationException(StringDecryptor.GetString(-1550346790) /* VM-3014 */);
}
text = text.Substring(0, remainLen);
collection.PushBack(new ElementedTypeDescrItem
{
K = ElementedTypeDescrItem.Kind.Array1,
ArrayRank = rank
});
}
}
}
// Token: 0x0600030B RID: 779 RVA: 0x00014B30 File Offset: 0x00012D30
public static Type PopType(Type type, MyCollection<ElementedTypeDescrItem> descr) // \u0002
{
while (descr.Count > 0)
{
var p = descr.PopBack();
switch (p.K)
{
case ElementedTypeDescrItem.Kind.Ponter0:
type = type.MakePointerType();
break;
case ElementedTypeDescrItem.Kind.Array1:
type = (p.ArrayRank == 1) ? type.MakeArrayType() : type.MakeArrayType(p.ArrayRank);
break;
case ElementedTypeDescrItem.Kind.ByRef2:
type = type.MakeByRefType();
break;
}
}
return type;
}
}
// Token: 0x02000054 RID: 84
internal struct ElementedTypeDescrItem // \u000E\u2005
{
internal enum Kind { Ponter0, Array1, ByRef2 }
// Token: 0x04000183 RID: 387
public Kind K; // \u0002
// Token: 0x04000184 RID: 388
public int ArrayRank; // \u0003
}
}

View File

@ -0,0 +1,569 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace UnitTestProject.RefVm
{
// Token: 0x02000024 RID: 36
internal sealed class MyBuffer : IDisposable // \u0005\u2007
{
// Token: 0x060000F2 RID: 242 RVA: 0x000051C8 File begin: 0x000033C8
public MyBuffer() : this(0)
{
}
// Token: 0x060000F3 RID: 243 RVA: 0x000051D4 File begin: 0x000033D4
public MyBuffer(int sz)
{
if (sz < 0)
{
throw new ArgumentOutOfRangeException();
}
_data = new byte[sz];
_size = sz;
_internal = true;
_writable = true;
_begin = 0;
_valid = true;
}
// Token: 0x060000F4 RID: 244 RVA: 0x00005220 File begin: 0x00003420
public MyBuffer(byte[] src) : this(src, true)
{
}
// Token: 0x060000F5 RID: 245 RVA: 0x0000522C File begin: 0x0000342C
public MyBuffer(byte[] src, bool writable)
{
if (src == null)
{
throw new ArgumentNullException();
}
_data = src;
_end = (_size = src.Length);
_writable = writable;
_begin = 0;
_valid = true;
}
// Token: 0x060000F6 RID: 246 RVA: 0x00005278 File begin: 0x00003478
public MyBuffer(byte[] src, int begin, int count) : this(src, begin, count, true)
{
}
// Token: 0x060000F7 RID: 247 RVA: 0x00005284 File begin: 0x00003484
public MyBuffer(byte[] src, int begin, int count, bool writable)
{
if (src == null)
{
throw new ArgumentNullException();
}
if (begin < 0)
{
throw new ArgumentOutOfRangeException();
}
if (count < 0)
{
throw new ArgumentOutOfRangeException();
}
if (src.Length - begin < count)
{
throw new ArgumentException();
}
_data = src;
_cursor = begin;
_begin = begin;
_end = (_size = begin + count);
_writable = writable;
_internal = false;
_valid = true;
}
// Token: 0x060000F8 RID: 248 RVA: 0x00005304 File begin: 0x00003504
public bool IsValid() // \u0002
{
return _valid;
}
// Token: 0x060000F9 RID: 249 RVA: 0x0000530C File begin: 0x0000350C
public bool IsValid2() // \u0003
{
return _valid;
}
// Token: 0x060000FA RID: 250 RVA: 0x00005314 File begin: 0x00003514
public bool IsWritable() // \u0005
{
return _writable;
}
// Token: 0x060000FB RID: 251 RVA: 0x0000531C File begin: 0x0000351C
public void DoDispose() // \u0002
{
Dispose(true);
// ReSharper disable once GCSuppressFinalizeForTypeWithoutDestructor
GC.SuppressFinalize(this);
}
// Token: 0x060000FC RID: 252 RVA: 0x0000532C File begin: 0x0000352C
public void Dispose()
{
Dispose(false);
}
// Token: 0x060000FD RID: 253 RVA: 0x00005334 File begin: 0x00003534
private void Dispose(bool disposing) // \u0002
{
if (!_disposed)
{
if (disposing)
{
_valid = false;
_writable = false;
_internal = false;
}
_disposed = true;
}
}
// Token: 0x060000FE RID: 254 RVA: 0x00005360 File begin: 0x00003560
private bool Expand(int newSize) // \u0002
{
if (newSize < 0)
{
throw new IOException();
}
if (newSize > _size)
{
if (newSize < 256)
{
newSize = 256;
}
if (newSize < _size * 2)
{
newSize = _size * 2;
}
ExpandExact(newSize);
return true;
}
return false;
}
// Token: 0x060000FF RID: 255 RVA: 0x000053B0 File begin: 0x000035B0
public void DoNothing() // \u0003
{}
// Token: 0x06000100 RID: 256 RVA: 0x000053B4 File begin: 0x000035B4
internal byte[] Data() // \u0002
{
return _data;
}
// Token: 0x06000101 RID: 257 RVA: 0x000053BC File begin: 0x000035BC
internal void GetRanges(out int begin, out int end) // \u0002
{
if (!_valid)
{
throw new Exception();
}
begin = _begin;
end = _end;
}
// Token: 0x06000102 RID: 258 RVA: 0x000053DC File begin: 0x000035DC
internal int GetCursor() // \u0002
{
if (!_valid)
{
throw new Exception();
}
return _cursor;
}
// Token: 0x06000103 RID: 259 RVA: 0x000053F4 File begin: 0x000035F4
public int SkipBytes(int cnt) // \u0002
{
if (!_valid)
{
throw new Exception();
}
var num = _end - _cursor;
if (num > cnt)
{
num = cnt;
}
if (num < 0)
{
num = 0;
}
_cursor += num;
return num;
}
// Token: 0x06000104 RID: 260 RVA: 0x00005438 File begin: 0x00003638
public int Capacity() // \u0003
{
if (!_valid)
{
throw new Exception();
}
return _size - _begin;
}
// Token: 0x06000105 RID: 261 RVA: 0x00005458 File begin: 0x00003658
public void ExpandExact(int newSize) // \u0002
{
if (!_valid)
{
throw new Exception();
}
if (newSize != _size)
{
if (!_internal)
{
throw new Exception();
}
if (newSize < _end)
{
throw new ArgumentOutOfRangeException();
}
if (newSize > 0)
{
var dst = new byte[newSize];
if (_end > 0)
{
Buffer.BlockCopy(_data, 0, dst, 0, _end);
}
_data = dst;
}
else
{
_data = null;
}
_size = newSize;
}
}
// Token: 0x06000106 RID: 262 RVA: 0x000054D8 File begin: 0x000036D8
public long UsedSize() // \u0002
{
if (!_valid)
{
throw new Exception();
}
return _end - _begin;
}
// Token: 0x06000107 RID: 263 RVA: 0x000054F8 File begin: 0x000036F8
public long GetPos() // \u0003
{
if (!_valid)
{
throw new Exception();
}
return _cursor - _begin;
}
// Token: 0x06000108 RID: 264 RVA: 0x00005518 File begin: 0x00003718
public void SetPos(long newPos) // \u0002
{
if (!_valid)
{
throw new Exception();
}
if (newPos < 0L)
{
throw new ArgumentOutOfRangeException();
}
if (newPos > 2147483647L)
{
throw new ArgumentOutOfRangeException();
}
_cursor = _begin + (int)newPos;
}
// Token: 0x06000109 RID: 265 RVA: 0x00005554 File begin: 0x00003754
public int Read([In] [Out] byte[] dest, int offset, int cnt) // \u0002
{
if (!_valid)
{
throw new Exception();
}
if (dest == null)
{
throw new ArgumentNullException();
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException();
}
if (cnt < 0)
{
throw new ArgumentOutOfRangeException();
}
if (dest.Length - offset < cnt)
{
throw new ArgumentException();
}
var num = _end - _cursor;
if (num > cnt)
{
num = cnt;
}
if (num <= 0)
{
return 0;
}
if (num <= 8)
{
var num2 = num;
while (--num2 >= 0)
{
dest[offset + num2] = _data[_cursor + num2];
}
}
else
{
Buffer.BlockCopy(_data, _cursor, dest, offset, num);
}
_cursor += num;
return num;
}
// Token: 0x0600010A RID: 266 RVA: 0x00005600 File begin: 0x00003800
public int ReadByte() // \u0005
{
if (!_valid)
{
throw new Exception();
}
if (_cursor >= _end)
{
return -1;
}
var num = _cursor;
_cursor = num + 1;
return _data[num];
}
// Token: 0x0600010B RID: 267 RVA: 0x00005644 File begin: 0x00003844
public long Seek(long distance, SeekOrigin org) // \u0002
{
if (!_valid)
{
throw new Exception();
}
if (distance > 2147483647L)
{
throw new ArgumentOutOfRangeException();
}
switch (org)
{
case SeekOrigin.Begin:
if (distance < 0L)
{
throw new IOException();
}
_cursor = _begin + (int)distance;
break;
case SeekOrigin.Current:
if (distance + _cursor < _begin)
{
throw new IOException();
}
_cursor += (int)distance;
break;
case SeekOrigin.End:
if (_end + distance < _begin)
{
throw new IOException();
}
_cursor = _end + (int)distance;
break;
default:
throw new ArgumentException();
}
return _cursor;
}
// Token: 0x0600010C RID: 268 RVA: 0x00005700 File begin: 0x00003900
public void LazyShrink(long newCount) // \u0003
{
if (!_writable)
{
throw new Exception();
}
if (newCount > 2147483647L)
{
throw new ArgumentOutOfRangeException();
}
if (newCount < 0L || newCount > 2147483647 - _begin)
{
throw new ArgumentOutOfRangeException();
}
var num = _begin + (int)newCount;
if (!Expand(num) && num > _end)
{
Array.Clear(_data, _end, num - _end);
}
_end = num;
if (_cursor > num)
{
_cursor = num;
}
}
// Token: 0x0600010D RID: 269 RVA: 0x00005794 File begin: 0x00003994
public byte[] ToArray() // \u0003
{
var array = new byte[_end - _begin];
Buffer.BlockCopy(_data, _begin, array, 0, _end - _begin);
return array;
}
// Token: 0x0600010E RID: 270 RVA: 0x000057D8 File begin: 0x000039D8
public void Write(byte[] src, int offset, int cnt) // \u0002
{
if (!_valid)
{
throw new Exception();
}
if (!_writable)
{
throw new Exception();
}
if (src == null)
{
throw new ArgumentNullException();
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException();
}
if (cnt < 0)
{
throw new ArgumentOutOfRangeException();
}
if (src.Length - offset < cnt)
{
throw new ArgumentException();
}
var num = _cursor + cnt;
if (num < 0)
{
throw new IOException();
}
if (num > _end)
{
var flag = _cursor > _end;
if (num > _size && Expand(num))
{
flag = false;
}
if (flag)
{
Array.Clear(_data, _end, num - _end);
}
_end = num;
}
if (cnt <= 8)
{
while (--cnt >= 0)
{
_data[_cursor + cnt] = src[offset + cnt];
}
}
else
{
Buffer.BlockCopy(src, offset, _data, _cursor, cnt);
}
_cursor = num;
}
// Token: 0x0600010F RID: 271 RVA: 0x000058D0 File begin: 0x00003AD0
public void AppendByte(byte b) // \u0002
{
if (!_valid)
{
throw new Exception();
}
if (!_writable)
{
throw new Exception();
}
if (_cursor >= _end)
{
var num = _cursor + 1;
var flag = _cursor > _end;
if (num >= _size && Expand(num))
{
flag = false;
}
if (flag)
{
Array.Clear(_data, _end, _cursor - _end);
}
_end = num;
}
_data[_cursor] = b;
_cursor++;
}
// Token: 0x06000110 RID: 272 RVA: 0x00005974 File begin: 0x00003B74
public void WriteTo(Stream s) // \u0002
{
if (!_valid)
{
throw new Exception();
}
if (s == null)
{
throw new ArgumentNullException();
}
s.Write(_data, _begin, _end - _begin);
}
// Token: 0x06000111 RID: 273 RVA: 0x000059AC File begin: 0x00003BAC
internal int ReadInt32() // \u0008
{
if (!_valid)
{
throw new Exception();
}
var num = _cursor += 4;
if (num > _end)
{
_cursor = _end;
throw new Exception();
}
return _data[num - 2] | _data[num - 3] << 24 | _data[num - 1] << 8 | _data[num - 4] << 16;
}
// Token: 0x04000034 RID: 52
private byte[] _data; // \u0002
// Token: 0x04000035 RID: 53
private readonly int _begin; // \u0003
// Token: 0x04000036 RID: 54
private int _cursor; // \u0005
// Token: 0x04000037 RID: 55
private int _end; // \u0008
// Token: 0x04000038 RID: 56
private int _size; // \u0006
// Token: 0x04000039 RID: 57
private bool _internal; // \u000E
// Token: 0x0400003A RID: 58
private bool _writable; // \u000F
// Token: 0x0400003B RID: 59
private bool _valid; // \u0002\u2000
// Token: 0x0400003C RID: 60
private bool _disposed; // \u0003\u2000
}
}

View File

@ -0,0 +1,563 @@
using System;
using System.IO;
using System.Text;
using forms_cil;
namespace UnitTestProject.RefVm
{
// Token: 0x0200000A RID: 10
internal sealed class MyBufferReader : IDisposable // \u0002\u2007
{
// Token: 0x0400000C RID: 12
private MyBuffer _src; // \u0002
// Token: 0x0400000D RID: 13
private byte[] _inputRawBuf; // \u0003
// Token: 0x0400000E RID: 14
private Decoder _decoder; // \u0005
// Token: 0x0400000F RID: 15
private byte[] _inputCharRawBuf; // \u0008
// Token: 0x04000010 RID: 16
private char[] _inputCharsDecoded; // \u0006
// Token: 0x04000011 RID: 17
private char[] _stringChunk; // \u000E
// Token: 0x04000012 RID: 18
private readonly int _maxCharsIn128Bytes; // \u000F
// Token: 0x04000013 RID: 19
private readonly bool _isUnicode; // \u0002\u2000
// Token: 0x04000014 RID: 20
private readonly bool _alwaysTrue; // \u0003\u2000
// Token: 0x06000034 RID: 52 RVA: 0x000027C8 File Offset: 0x000009C8
public MyBufferReader(MyBuffer src) : this(src, new UTF8Encoding())
{
}
// Token: 0x06000035 RID: 53 RVA: 0x000027D8 File Offset: 0x000009D8
private MyBufferReader(MyBuffer src, Encoding encoding)
{
if (src == null)
{
throw new ArgumentNullException();
}
if (encoding == null)
{
throw new ArgumentNullException();
}
if (!src.IsValid())
{
throw new ArgumentException();
}
_src = src;
_decoder = encoding.GetDecoder();
_maxCharsIn128Bytes = encoding.GetMaxCharCount(128);
var num = encoding.GetMaxByteCount(1);
if (num < 16)
num = 16;
_inputRawBuf = new byte[num];
_stringChunk = null;
_inputCharRawBuf = null;
_isUnicode = (encoding is UnicodeEncoding);
_alwaysTrue = (_src != null);
}
// Token: 0x06000036 RID: 54 RVA: 0x00002878 File Offset: 0x00000A78
public MyBuffer GetBuffer() // \u0002
{
return _src;
}
// Token: 0x06000037 RID: 55 RVA: 0x00002880 File Offset: 0x00000A80
public void Dispose() // \u0002
{
DoDispose(true);
}
// Token: 0x06000038 RID: 56 RVA: 0x0000288C File Offset: 0x00000A8C
private void DoDispose(bool disposing) // \u0002
{
if (disposing)
_src?.DoDispose();
_src = null;
_inputRawBuf = null;
_decoder = null;
_inputCharRawBuf = null;
_inputCharsDecoded = null;
_stringChunk = null;
}
// Token: 0x06000039 RID: 57 RVA: 0x000028E0 File Offset: 0x00000AE0
void IDisposable.Dispose() // \u0002\u2007\u2008\u2000\u2002\u200A\u0003
{
DoDispose(true);
}
// Token: 0x0600003A RID: 58 RVA: 0x000028EC File Offset: 0x00000AEC
public int PeekUnicodeChar() // \u0002
{
SrcPrecondition();
if (!_src.IsValid2())
{
return -1;
}
var pos = _src.GetPos();
var ret = SafeReadUnicodeChar();
_src.SetPos(pos);
return ret;
}
// Token: 0x06000051 RID: 81 RVA: 0x00002FE8 File Offset: 0x000011E8
private void SrcPrecondition() // \u0005
{
if (_src == null)
{
throw new Exception();
}
}
// Token: 0x0600003B RID: 59 RVA: 0x0000292C File Offset: 0x00000B2C
public int SafeReadUnicodeChar() // \u0003
{
SrcPrecondition();
return ReadUnicodeChar();
}
// Token: 0x0600004E RID: 78 RVA: 0x00002E38 File Offset: 0x00001038
private int ReadUnicodeChar() // \u0005
{
var charCnt = 0;
var savedPos = 0L;
if (_src.IsValid2())
{
savedPos = _src.GetPos();
}
if (_inputCharRawBuf == null)
{
_inputCharRawBuf = new byte[128];
}
if (_inputCharsDecoded == null)
{
_inputCharsDecoded = new char[1];
}
while (charCnt == 0)
{
var bytesToRead = _isUnicode ? 2 : 1;
var b = _src.ReadByte();
_inputCharRawBuf[0] = (byte)b;
if (b == -1)
{
bytesToRead = 0;
}
if (bytesToRead == 2)
{
b = _src.ReadByte();
_inputCharRawBuf[1] = (byte)b;
if (b == -1)
{
bytesToRead = 1;
}
}
if (bytesToRead == 0)
{
return -1;
}
try
{
charCnt = _decoder.GetChars(_inputCharRawBuf, 0, bytesToRead, _inputCharsDecoded, 0);
}
catch
{
if (_src.IsValid2())
{
_src.Seek(savedPos - _src.GetPos(), SeekOrigin.Current);
}
throw;
}
}
if (charCnt == 0)
{
return -1;
}
return _inputCharsDecoded[0];
}
// Token: 0x06000053 RID: 83 RVA: 0x0000305C File Offset: 0x0000125C
private void ReadToRawBuf(int cnt) // \u0002
{
SrcPrecondition();
var offset = 0;
int bytesRead;
if (cnt != 1)
{
while (true)
{
bytesRead = _src.Read(_inputRawBuf, offset, cnt - offset);
if (bytesRead == 0)
break;
offset += bytesRead;
if (offset >= cnt)
return;
}
throw new Exception();
}
bytesRead = _src.ReadByte();
if (bytesRead == -1)
{
throw new Exception();
}
_inputRawBuf[0] = (byte)bytesRead;
}
// Token: 0x0600003C RID: 60 RVA: 0x0000293C File Offset: 0x00000B3C
public bool ReadByteInternal() // \u0002
{
ReadToRawBuf(1);
return _inputRawBuf[0] > 0;
}
// Token: 0x0600003D RID: 61 RVA: 0x00002950 File Offset: 0x00000B50
public byte ReadByte() // \u0002
{
SrcPrecondition();
var b = _src.ReadByte();
if (b == -1)
{
throw new Exception();
}
return (byte)b;
}
// Token: 0x0600003E RID: 62 RVA: 0x00002970 File Offset: 0x00000B70
public sbyte ReadSbyte() // \u0002
{
ReadToRawBuf(1);
return (sbyte)_inputRawBuf[0];
}
// Token: 0x0600003F RID: 63 RVA: 0x00002984 File Offset: 0x00000B84
public char ReadChar() // \u0002
{
var c = SafeReadUnicodeChar();
if (c == -1)
{
throw new Exception();
}
return (char)c;
}
// Token: 0x06000040 RID: 64 RVA: 0x00002998 File Offset: 0x00000B98
public short ReadShort() // \u0002
{
ReadToRawBuf(2);
return (short)(_inputRawBuf[0] | _inputRawBuf[1] << 8);
}
// Token: 0x06000041 RID: 65 RVA: 0x000029B8 File Offset: 0x00000BB8
public ushort ReadUshort() // \u0002
{
ReadToRawBuf(2);
return (ushort)(_inputRawBuf[0] | _inputRawBuf[1] << 8);
}
// Token: 0x06000042 RID: 66 RVA: 0x000029D8 File Offset: 0x00000BD8
public uint ReadUint() // \u0002
{
ReadToRawBuf(4);
return (uint)(_inputRawBuf[0] | _inputRawBuf[1] << 8 | _inputRawBuf[2] << 16 | _inputRawBuf[3] << 24);
}
// Token: 0x06000043 RID: 67 RVA: 0x00002A0C File Offset: 0x00000C0C
public long ReadLong() // \u0002
{
ReadToRawBuf(8);
var num = (uint)(_inputRawBuf[0] | _inputRawBuf[1] << 8 | _inputRawBuf[2] << 16 | _inputRawBuf[3] << 24);
return (long)((ulong)(_inputRawBuf[4] | _inputRawBuf[5] << 8 | _inputRawBuf[6] << 16 | _inputRawBuf[7] << 24) << 32 | num);
}
// Token: 0x06000044 RID: 68 RVA: 0x00002A80 File Offset: 0x00000C80
public ulong ReadUlong() // \u0002
{
ReadToRawBuf(8);
var num = (uint)(_inputRawBuf[0] | _inputRawBuf[1] << 8 | _inputRawBuf[2] << 16 | _inputRawBuf[3] << 24);
return (ulong)(_inputRawBuf[4] | _inputRawBuf[5] << 8 | _inputRawBuf[6] << 16 | _inputRawBuf[7] << 24) << 32 | num;
}
// Token: 0x06000045 RID: 69 RVA: 0x00002AF4 File Offset: 0x00000CF4
private BinaryReader ReaderFor(int cnt) // \u0002
{
ReadToRawBuf(cnt);
return new BinaryReader(new MemoryStream(_inputRawBuf, 0, cnt, false));
}
// Token: 0x06000046 RID: 70 RVA: 0x00002B10 File Offset: 0x00000D10
public float ReadFloat() // \u0002
{
var r = ReaderFor(4);
var result = r.ReadSingle();
r.Close();
return result;
}
// Token: 0x06000047 RID: 71 RVA: 0x00002B34 File Offset: 0x00000D34
public double ReadDouble() // \u0002
{
var r = ReaderFor(8);
var result = r.ReadDouble();
r.Close();
return result;
}
// Token: 0x06000048 RID: 72 RVA: 0x00002B58 File Offset: 0x00000D58
private static decimal CreateDecimal(int lo, int mid, int hi, int scaleNeg) // \u0002
{
var isNegative = (scaleNeg & -2147483648) != 0;
var scale = (byte)(scaleNeg >> 16);
return new decimal(lo, mid, hi, isNegative, scale);
}
// Token: 0x06000049 RID: 73 RVA: 0x00002B80 File Offset: 0x00000D80
internal static decimal CreateDecimal(byte[] b) // b
{
var lo = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
var mid = b[4] | b[5] << 8 | b[6] << 16 | b[7] << 24;
var hi = b[8] | b[9] << 8 | b[10] << 16 | b[11] << 24;
var scaleNeg = b[12] | b[13] << 8 | b[14] << 16 | b[15] << 24;
return CreateDecimal(lo, mid, hi, scaleNeg);
}
// Token: 0x0600004A RID: 74 RVA: 0x00002BFC File Offset: 0x00000DFC
public decimal ReadDecimal() // \u0002
{
ReadToRawBuf(16);
return CreateDecimal(_inputRawBuf);
}
// Token: 0x0600004B RID: 75 RVA: 0x00002C14 File Offset: 0x00000E14
public string ReadString() // \u0002
{
var totalRead = 0;
SrcPrecondition();
var strLen = Read28Bit();
if (strLen < 0)
{
throw new IOException();
}
if (strLen == 0)
{
return string.Empty;
}
if (_inputCharRawBuf == null)
{
_inputCharRawBuf = new byte[128];
}
if (_stringChunk == null)
{
_stringChunk = new char[_maxCharsIn128Bytes];
}
StringBuilder stringBuilder = null;
while (true)
{
var needChunkCnt = (strLen - totalRead > 128) ? 128 : (strLen - totalRead);
var realChunkRead = _src.Read(_inputCharRawBuf, 0, needChunkCnt);
if (realChunkRead == 0)
{
break;
}
var chars = _decoder.GetChars(_inputCharRawBuf, 0, realChunkRead, _stringChunk, 0);
if (totalRead == 0 && realChunkRead == strLen)
{
return new string(_stringChunk, 0, chars);
}
if (stringBuilder == null)
{
stringBuilder = new StringBuilder(strLen);
}
stringBuilder.Append(_stringChunk, 0, chars);
totalRead += realChunkRead;
if (totalRead >= strLen)
{
return stringBuilder.ToString();
}
}
throw new Exception();
}
// Token: 0x0600004C RID: 76 RVA: 0x00002D08 File Offset: 0x00000F08
public int Read(char[] dest, int offset, int cnt) // \u0002
{
if (dest == null)
{
throw new ArgumentNullException(StringDecryptor.GetString(-1550347170), /* \u0002 */
StringDecryptor.GetString(-1550347157) /* ArgumentNull_Buffer */);
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException();
}
if (cnt < 0)
{
throw new ArgumentOutOfRangeException();
}
if (dest.Length - offset < cnt)
{
throw new ArgumentException();
}
SrcPrecondition();
return DoRead(dest, offset, cnt);
}
// Token: 0x0600004D RID: 77 RVA: 0x00002D64 File Offset: 0x00000F64
private int DoRead(char[] dest, int offset, int cnt) // \u0003
{
var remainCharsToRead = cnt;
if (_inputCharRawBuf == null)
{
_inputCharRawBuf = new byte[128];
}
while (remainCharsToRead > 0)
{
var chunkSize = remainCharsToRead;
if (_isUnicode)
{
chunkSize <<= 1;
}
if (chunkSize > 128)
{
chunkSize = 128;
}
int chars;
if (_alwaysTrue)
{
var byteIndex = _src.GetCursor();
chunkSize = _src.SkipBytes(chunkSize);
if (chunkSize == 0)
{
return cnt - remainCharsToRead;
}
chars = _decoder.GetChars(_src.Data(), byteIndex, chunkSize, dest, offset);
}
else
{
chunkSize = _src.Read(_inputCharRawBuf, 0, chunkSize);
if (chunkSize == 0)
{
return cnt - remainCharsToRead;
}
chars = _decoder.GetChars(_inputCharRawBuf, 0, chunkSize, dest, offset);
}
remainCharsToRead -= chars;
offset += chars;
}
return cnt;
}
// Token: 0x0600004F RID: 79 RVA: 0x00002F54 File Offset: 0x00001154
public char[] ReadChars(int cnt) // \u0002
{
SrcPrecondition();
if (cnt < 0)
{
throw new ArgumentOutOfRangeException();
}
var ret = new char[cnt];
var realLength = DoRead(ret, 0, cnt);
if (realLength != cnt)
{
var shrinked = new char[realLength];
Buffer.BlockCopy(ret, 0, shrinked, 0, 2 * realLength);
ret = shrinked;
}
return ret;
}
// Token: 0x06000050 RID: 80 RVA: 0x00002F9C File Offset: 0x0000119C
public int Read(byte[] dest, int offset, int cnt) // dest
{
if (dest == null)
{
throw new ArgumentNullException();
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException();
}
if (cnt < 0)
{
throw new ArgumentOutOfRangeException();
}
if (dest.Length - offset < cnt)
{
throw new ArgumentException();
}
SrcPrecondition();
return _src.Read(dest, offset, cnt);
}
// Token: 0x06000052 RID: 82 RVA: 0x00002FF8 File Offset: 0x000011F8
public byte[] ReadBytes(int cnt) // \u0002
{
if (cnt < 0)
{
throw new ArgumentOutOfRangeException();
}
SrcPrecondition();
var ret = new byte[cnt];
var offset = 0;
do
{
var chunkSize = _src.Read(ret, offset, cnt);
if (chunkSize == 0)
{
break;
}
offset += chunkSize;
cnt -= chunkSize;
}
while (cnt > 0);
if (offset != ret.Length)
{
var shrinked = new byte[offset];
Buffer.BlockCopy(ret, 0, shrinked, 0, offset);
ret = shrinked;
}
return ret;
}
// Token: 0x06000054 RID: 84 RVA: 0x000030C0 File Offset: 0x000012C0
internal int Read28Bit() // \u0008
{
var ret = 0;
var bitCnt = 0;
while (bitCnt != 35)
{
var b = ReadByte();
ret |= (b & 127) << bitCnt;
bitCnt += 7;
if ((b & 128) == 0)
{
return ret;
}
}
throw new FormatException();
}
// Token: 0x06000055 RID: 85 RVA: 0x00003100 File Offset: 0x00001300
public int ReadInt32() // \u0006
{
if (_alwaysTrue)
{
return _src.ReadInt32();
}
ReadToRawBuf(4);
return _inputRawBuf[3] << 8 | _inputRawBuf[1] << 24 | _inputRawBuf[0] << 16 | _inputRawBuf[2];
}
}
}

View File

@ -0,0 +1,361 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
namespace UnitTestProject.RefVm
{
// Token: 0x02000006 RID: 6
internal static class EmptyArray<T> // \u0002\u2003
{
// Token: 0x04000004 RID: 4
public static readonly T[] Data = new T[0];
}
// Token: 0x02000022 RID: 34
internal sealed class MyCollection<T> : IEnumerable<T>, ICollection // \u0005\u2006
{
// Token: 0x0400002C RID: 44
internal T[] Data; // \u0002
// Token: 0x0400002E RID: 46
internal int ChangeCounter; // \u0005
// Token: 0x0400002F RID: 47
private object _sync; // \u0008
// Token: 0x060000DA RID: 218 RVA: 0x00004B9C File Offset: 0x00002D9C
public MyCollection()
{
Data = EmptyArray<T>.Data;
Count = 0;
ChangeCounter = 0;
}
// Token: 0x060000DB RID: 219 RVA: 0x00004BC0 File Offset: 0x00002DC0
public MyCollection(int capacity)
{
if (capacity < 0)
{
throw new ArgumentOutOfRangeException();
}
Data = new T[capacity];
Count = 0;
ChangeCounter = 0;
}
// Token: 0x060000DC RID: 220 RVA: 0x00004BEC File Offset: 0x00002DEC
public MyCollection(IEnumerable<T> src)
{
if (src == null)
{
throw new ArgumentNullException();
}
var collection = src as ICollection<T>;
if (collection != null)
{
var count = collection.Count;
Data = new T[count];
collection.CopyTo(Data, 0);
Count = count;
return;
}
Count = 0;
Data = new T[4];
foreach (var i in Data)
{
PushBack(i);
}
}
// Token: 0x0400002D RID: 45
// Token: 0x17000006 RID: 6
// (get) Token: 0x060000DD RID: 221 RVA: 0x00004C88 File Offset: 0x00002E88
public int Count { get; private set; } // \u0003
// Token: 0x060000DE RID: 222 RVA: 0x00004C90 File Offset: 0x00002E90
bool ICollection.IsSynchronized => false; // \u0005\u2006\u2008\u2000\u2002\u200A\u0002
// Token: 0x060000DF RID: 223 RVA: 0x00004C94 File Offset: 0x00002E94
object ICollection.SyncRoot // \u0005\u2006\u2008\u2000\u2002\u200A\u0002
{
get
{
if (_sync == null)
{
Interlocked.CompareExchange(ref _sync, new object(), null);
}
return _sync;
}
}
// Token: 0x060000E0 RID: 224 RVA: 0x00004CB8 File Offset: 0x00002EB8
public void Clear() // \u0002
{
Array.Clear(Data, 0, Count);
Count = 0;
ChangeCounter++;
}
// Token: 0x060000E1 RID: 225 RVA: 0x00004CE4 File Offset: 0x00002EE4
public bool Contains(T what) // \u0002
{
var num = Count;
var @default = EqualityComparer<T>.Default;
while (num-- > 0)
{
if (what == null)
{
if (Data[num] == null)
{
return true;
}
}
else if (Data[num] != null && @default.Equals(Data[num], what))
{
return true;
}
}
return false;
}
// Token: 0x060000E2 RID: 226 RVA: 0x00004D50 File Offset: 0x00002F50
public void CopyTo(T[] dest, int offset) // \u0003
{
if (dest == null)
{
throw new ArgumentNullException(StringDecryptor.GetString(-1550346880) /* \u0002 */);
}
if (offset < 0 || offset > dest.Length)
{
throw new ArgumentOutOfRangeException(StringDecryptor.GetString(-1550346867) /* \u0003 */,
StringDecryptor.GetString(-1550346858) /* arrayIndex < 0 || arrayIndex > array.Length */);
}
if (dest.Length - offset < Count)
{
throw new ArgumentException(StringDecryptor.GetString(-1550347192) /* Invalid Off Len */);
}
Array.Copy(Data, 0, dest, offset, Count);
Array.Reverse(dest, offset, Count);
}
// Token: 0x060000E3 RID: 227 RVA: 0x00004DD4 File Offset: 0x00002FD4
void ICollection.CopyTo(Array dest, int offset) // \u0005\u2006\u2008\u2000\u2002\u200A\u0002
{
if (dest == null)
{
throw new ArgumentNullException();
}
if (dest.Rank != 1)
{
throw new ArgumentException();
}
if (dest.GetLowerBound(0) != 0)
{
throw new ArgumentException();
}
if (offset < 0 || offset > dest.Length)
{
throw new ArgumentOutOfRangeException();
}
if (dest.Length - offset < Count)
{
throw new ArgumentException();
}
try
{
Array.Copy(Data, 0, dest, offset, Count);
Array.Reverse(dest, offset, Count);
}
catch (ArrayTypeMismatchException)
{
throw new ArgumentException();
}
}
// Token: 0x060000E4 RID: 228 RVA: 0x00004E6C File Offset: 0x0000306C
public MyEnumerator<T> GetEnumerator() // \u0005
{
return new MyEnumerator<T>(this);
}
// Token: 0x060000E5 RID: 229 RVA: 0x00004E74 File Offset: 0x00003074
IEnumerator<T> IEnumerable<T>.GetEnumerator() // \u0005\u2006\u2008\u2000\u2002\u200A\u0008
{
return new MyEnumerator<T>(this);
}
// Token: 0x060000E6 RID: 230 RVA: 0x00004E84 File Offset: 0x00003084
IEnumerator IEnumerable.GetEnumerator() // \u0005\u2006\u2008\u2000\u2002\u200A\u0002
{
return new MyEnumerator<T>(this);
}
// Token: 0x060000E7 RID: 231 RVA: 0x00004E94 File Offset: 0x00003094
public void Shrink() // \u0003
{
var num = (int)(Data.Length * 0.9);
if (Count < num)
{
var destinationArray = new T[Count];
Array.Copy(Data, 0, destinationArray, 0, Count);
Data = destinationArray;
ChangeCounter++;
}
}
// Token: 0x060000E8 RID: 232 RVA: 0x00004EF4 File Offset: 0x000030F4
public T PeekBack() // \u0006
{
if (Count == 0)
{
throw new InvalidOperationException();
}
return Data[Count - 1];
}
// Token: 0x060000E9 RID: 233 RVA: 0x00004F18 File Offset: 0x00003118
public T PopBack() // \u000E
{
if (Count == 0)
{
throw new InvalidOperationException();
}
ChangeCounter++;
var ret = Data[--Count];
Data[Count] = default(T);
return ret;
}
// Token: 0x060000EA RID: 234 RVA: 0x00004F78 File Offset: 0x00003178
public void PushBack(T obj) // \u000F
{
if (Count == Data.Length)
{
var destinationArray = new T[(Data.Length == 0) ? 4 : (2 * Data.Length)];
Array.Copy(Data, 0, destinationArray, 0, Count);
Data = destinationArray;
}
var num = Count;
Count = num + 1;
Data[num] = obj;
ChangeCounter++;
}
// Token: 0x060000EB RID: 235 RVA: 0x00004FF8 File Offset: 0x000031F8
public T[] Reverse() // \u0002\u2000
{
var array = new T[Count];
for (var i = 0; i < Count; i++)
{
array[i] = Data[Count - i - 1];
}
return array;
}
// Token: 0x02000023 RID: 35
public struct MyEnumerator<T1> : IEnumerator<T1> // \u0002
{
// Token: 0x060000EC RID: 236 RVA: 0x00005040 File Offset: 0x00003240
internal MyEnumerator(MyCollection<T1> src)
{
_src = src;
_changeCounter = _src.ChangeCounter;
_curPos = -2;
_current = default(T1);
}
// Token: 0x060000ED RID: 237 RVA: 0x00005070 File Offset: 0x00003270
public void Dispose()
{
_curPos = -1;
}
// Token: 0x060000EE RID: 238 RVA: 0x0000507C File Offset: 0x0000327C
public bool MoveNext()
{
if (_changeCounter != _src.ChangeCounter)
{
throw new InvalidOperationException(StringDecryptor.GetString(-1550346776) /* EnumFailedVersion */);
}
if (_curPos == -2)
{
_curPos = _src.Count - 1;
if (_curPos < 0) return false;
_current = _src.Data[_curPos];
return true;
}
if (_curPos == -1)
{
return false;
}
if (--_curPos >= 0)
{
_current = _src.Data[_curPos];
return true;
}
_current = default(T1);
return false;
}
// Token: 0x17000007 RID: 7
// (get) Token: 0x060000EF RID: 239 RVA: 0x00005144 File Offset: 0x00003344
public T1 Current
{
get
{
if (_curPos == -2)
{
throw new InvalidOperationException();
}
if (_curPos == -1)
{
throw new InvalidOperationException();
}
return _current;
}
}
// Token: 0x060000F0 RID: 240 RVA: 0x0000516C File Offset: 0x0000336C
object IEnumerator.Current // \u0002\u2008\u2000\u2002\u200A\u0002
{
get
{
if (_curPos == -2)
{
throw new InvalidOperationException();
}
if (_curPos == -1)
{
throw new InvalidOperationException();
}
return _current;
}
}
// Token: 0x060000F1 RID: 241 RVA: 0x00005198 File Offset: 0x00003398
void IEnumerator.Reset() // \u0002\u2008\u2000\u2002\u200A\u0002
{
if (_changeCounter != _src.ChangeCounter)
{
throw new InvalidOperationException();
}
_curPos = -2;
_current = default(T1);
}
// Token: 0x04000030 RID: 48
private readonly MyCollection<T1> _src; // \u0002
// Token: 0x04000031 RID: 49
private int _curPos; // \u0003
// Token: 0x04000032 RID: 50
private readonly int _changeCounter; // \u0005
// Token: 0x04000033 RID: 51
private T1 _current; // \u0008
}
}
}

View File

@ -0,0 +1,288 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
namespace UnitTestProject.RefVm
{
// Token: 0x02000063 RID: 99
internal static class SdMetadataTokens // \u000F\u2009
{
// Token: 0x06000399 RID: 921 RVA: 0x00015D18 File Offset: 0x00013F18
[MethodImpl(MethodImplOptions.NoInlining)]
internal static long GetLong() // \u0002
{
if (Assembly.GetCallingAssembly() != typeof(SdMetadataTokens).Assembly || !CheckStack())
{
return 0L;
}
long result;
lock (Obj)
{
var num = Obj.GetLong7();
if (num == 0L)
{
var executingAssembly = Assembly.GetExecutingAssembly();
var list = new List<byte>();
AssemblyName assemblyName;
try
{
assemblyName = executingAssembly.GetName();
}
catch
{
assemblyName = new AssemblyName(executingAssembly.FullName);
}
var array = assemblyName.GetPublicKeyToken();
if (array != null && array.Length == 0)
{
array = null;
}
if (array != null)
{
list.AddRange(array);
}
list.AddRange(Encoding.Unicode.GetBytes(assemblyName.Name));
var num2 = 0x02000063; //GetMdt(typeof(SdMetadataTokens));
var num3 = Class1.M();
list.Add((byte)(num2 >> 24));
list.Add((byte)(num3 >> 16));
list.Add((byte)(num2 >> 8));
list.Add((byte)num3);
list.Add((byte)(num2 >> 16));
list.Add((byte)(num3 >> 8));
list.Add((byte)num2);
list.Add((byte)(num3 >> 24));
var count = list.Count;
var num4 = 0uL;
for (var num5 = 0; num5 != count; num5++)
{
num4 += list[num5];
num4 += num4 << 20;
num4 ^= num4 >> 12;
list[num5] = 0;
}
num4 += num4 << 6;
num4 ^= num4 >> 22;
num4 += num4 << 30;
num = (long)num4;
num ^= 7895633081549295753L;
Obj.SetLong(num);
}
result = num;
}
return result;
}
// Token: 0x0600039A RID: 922 RVA: 0x00015EE0 File Offset: 0x000140E0
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool CheckStack() // \u0002
{
return CheckStackImpl();
}
// Token: 0x0600039B RID: 923 RVA: 0x00015EEC File Offset: 0x000140EC
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool CheckStackImpl() // \u0003
{
var stackTrace = new StackTrace();
var frame = stackTrace.GetFrame(3);
var methodBase = frame?.GetMethod();
var type = methodBase?.DeclaringType;
return type != typeof(RuntimeMethodHandle) && type != null && type.Assembly == typeof(SdMetadataTokens).Assembly;
}
// Token: 0x0600039C RID: 924 RVA: 0x00015F50 File Offset: 0x00014150
// ReSharper disable once UnusedMember.Local
private static int GetMdt(Type t) // \u0002
{
return t.MetadataToken;
}
// Token: 0x0400019A RID: 410
// \u0002
private static readonly Class7 Obj = new Class7();
// Token: 0x02000064 RID: 100
public sealed class Class1 // \u0002\u2007\u2007\u2009\u2002\u2006\u2003\u2003\u2002\u2004\u2007\u200A\u2009\u200A\u2008\u200A\u2000\u2003\u200B\u2007\u200A\u2008\u200A\u2003\u2006\u200B
{
// Token: 0x0600039E RID: 926 RVA: 0x00015F60 File Offset: 0x00014160
[MethodImpl(MethodImplOptions.NoInlining)]
internal static int M()
{
return Class2.M3(Class2.M2(0x02000067 /*GetMdt(typeof(Class4))*/, Class2.M3(0x02000064 /*GetMdt(typeof(Class1))*/, 0x02000066 /*GetMdt(typeof(Class3))*/)), Class5.M1());
}
}
// Token: 0x02000065 RID: 101
private static class Class2 // \u0002\u200A\u2003\u2000\u2002\u2000\u2007\u2008\u2004\u2006\u2007\u2003\u2007\u2004\u2000\u2003\u2009\u2007\u2003\u2006\u2007\u2008\u200A
{
// Token: 0x0600039F RID: 927 RVA: 0x00015FB0 File Offset: 0x000141B0
internal static int M1(int p1, int p2) // \u0002
{
return p1 ^ p2 - -~~- -~~- -~~-1683504797;
}
// Token: 0x060003A0 RID: 928 RVA: 0x00015FC8 File Offset: 0x000141C8
internal static int M2(int p1, int p2) // \u0003
{
return p1 - -~-~-~~- -~~-1670271084 ^ p2 + -~-~-~~-~-~699406271;
}
// Token: 0x060003A1 RID: 929 RVA: 0x00015FF0 File Offset: 0x000141F0
internal static int M3(int p1, int p2) // \u0005
{
return p1 ^ p2 - -~~-~-~- -~~-1466097638 ^ p1 - p2;
}
}
// Token: 0x02000066 RID: 102
public sealed class Class3 // \u0003\u2001\u2003\u2009\u2009\u2008\u2006\u2006\u2006\u200A\u2003\u2006\u2005\u2005\u2009\u200B\u2009\u200A\u2003\u2007
{
// Token: 0x060003A3 RID: 931 RVA: 0x00016014 File Offset: 0x00014214
[MethodImpl(MethodImplOptions.NoInlining)]
internal static int M1() // \u0002
{
return Class2.M2(Class2.M2(Class6.M1(), Class2.M1(0x02000066 /*GetMdt(typeof(Class3))*/, Class4.M1())), 0x02000068 /*GetMdt(typeof(Class5))*/);
}
}
// Token: 0x02000067 RID: 103
public sealed class Class4 // \u0003\u2007\u2006\u2000\u2001\u2003\u2006\u200B\u2003\u2009\u200B\u2008\u200A\u2008\u2004\u2005\u2006\u200A\u2008\u2000\u2000\u200B\u2008\u200A
{
// Token: 0x060003A5 RID: 933 RVA: 0x00016058 File Offset: 0x00014258
[MethodImpl(MethodImplOptions.NoInlining)]
internal static int M1() // \u0002
{
return Class2.M1(0x02000069 /*GetMdt(typeof(Class6))*/, 0x0200006B /*GetMdt(typeof(Class8))*/ ^ Class2.M2(0x02000067 /*GetMdt(typeof(Class4))*/, Class2.M3(0x02000068 /*GetMdt(typeof(Class5))*/, Class8.M1())));
}
}
// Token: 0x02000068 RID: 104
public sealed class Class5 // \u0005\u2006\u200A\u2004\u200B\u2005\u200B\u2004\u2005\u2002\u2000\u2001\u2002\u2004\u2000\u2002\u2007\u2003\u2009\u200B\u2007\u200A\u200B\u2000\u2008\u2002\u2003\u2002
{
// Token: 0x060003A7 RID: 935 RVA: 0x000160C0 File Offset: 0x000142C0
[MethodImpl(MethodImplOptions.NoInlining)]
internal static int M1() // \u0002
{
return Class2.M1(0x02000068 /*GetMdt(typeof(Class5))*/, Class2.M3(Class2.M2(0x02000066 /*GetMdt(typeof(Class3))*/, 0x02000064 /*GetMdt(typeof(Class1))*/), Class2.M3(0x02000069 /*GetMdt(typeof(Class6))*/ ^ -~-~~- -~~-1251689633, Class3.M1())));
}
}
// Token: 0x02000069 RID: 105
public sealed class Class6 // \u0008\u2007\u2007\u2004\u2006\u2006\u200A\u2009\u2005\u2006\u2008\u200A\u2000\u200A\u2008\u2002\u2009\u2003\u2006\u2008\u2000\u2005\u2004\u200A\u2004\u2008\u2008\u2001\u2004\u200B
{
// Token: 0x060003A9 RID: 937 RVA: 0x0001613C File Offset: 0x0001433C
[MethodImpl(MethodImplOptions.NoInlining)]
internal static int M1() // \u0002
{
return Class2.M3(Class2.M1(Class4.M1() ^ ~-~- -~~- -~~-527758448, 0x0200006B /*GetMdt(typeof(Class8))*/), Class2.M2(0x02000064 /*GetMdt(typeof(Class1))*/ ^ 0x02000068 /*GetMdt(typeof(Class5))*/, -~~- -~-~~1892236202));
}
}
// Token: 0x0200006A RID: 106
internal sealed class Class7 // \u000F\u2005\u2007\u2007\u2009\u2009\u2002\u2004\u2008\u2009\u2002\u2000\u2000\u2009\u2009\u200B\u2008\u2004\u2003\u200B\u200A\u2002\u2002\u2003\u2006\u2007\u2000\u2006\u2002\u2003
{
// Token: 0x060003AA RID: 938 RVA: 0x000161AC File Offset: 0x000143AC
internal Class7()
{
SetLong(0L);
}
// Token: 0x060003AB RID: 939 RVA: 0x000161BC File Offset: 0x000143BC
[MethodImpl(MethodImplOptions.NoInlining)]
public long GetLong7() // \u0002
{
if (Assembly.GetCallingAssembly() != typeof(Class7).Assembly)
{
return 2918384L;
}
if (!CheckStack())
{
return 2918384L;
}
var array = new[]
{
0,
0,
0,
-~~- -~-~~1688528055
};
array[1] = ~-~- -~~-~1937298816;
array[2] = ~-~- -~-~~-~-2131774929;
array[0] = ~-~-~- -~~-~859851913;
var num = _i1;
var num2 = _i2;
var num3 = -~-~-~~-~1640531528;
var num4 = -~-~~- -~~-~957401312;
for (var num5 = 0; num5 != 32; num5++)
{
num2 -= (num << 4 ^ num >> 5) + num ^ num4 + array[num4 >> 11 & 3];
num4 -= num3;
num -= (num2 << 4 ^ num2 >> 5) + num2 ^ num4 + array[num4 & 3];
}
for (var num6 = 0; num6 != 4; num6++)
{
array[num6] = 0;
}
var num7 = ((ulong)num2 << 32);
var n = (ulong)_i1;
return (long)(num7 | n);
}
// Token: 0x060003AC RID: 940 RVA: 0x000162D8 File Offset: 0x000144D8
[MethodImpl(MethodImplOptions.NoInlining)]
internal void SetLong(long p) // \u0002
{
if (Assembly.GetCallingAssembly() != typeof(Class7).Assembly)
{
return;
}
if (!CheckStack())
{
return;
}
var array = new int[4];
array[1] = -~~-~- -~~-~1937298817;
array[0] = -~~-~-~-~859851914;
array[2] = ~-~- -~~-~-2131774930;
array[3] = -~-~~-~- -~~1688528054;
var num = -~-~~- -~-~~1640531529;
var num2 = (int)p;
var num3 = (int)(p >> 32);
var num4 = 0;
for (var num5 = 0; num5 != 32; num5++)
{
num2 += (num3 << 4 ^ num3 >> 5) + num3 ^ num4 + array[num4 & 3];
num4 += num;
num3 += (num2 << 4 ^ num2 >> 5) + num2 ^ num4 + array[num4 >> 11 & 3];
}
for (var num6 = 0; num6 != 4; num6++)
{
array[num6] = 0;
}
_i1 = num2;
_i2 = num3;
}
// Token: 0x0400019B RID: 411
private int _i1; // \u0002
// Token: 0x0400019C RID: 412
private int _i2; // \u0003
}
// Token: 0x0200006B RID: 107
public sealed class Class8 // \u000F\u200A\u2002\u2009\u2000\u2009\u2003\u200A\u2005\u2001\u2002\u2002\u2003\u200B\u2000\u2009\u2003\u2009\u2009\u2001\u2002\u200B\u2000\u200A
{
// Token: 0x060003AE RID: 942 RVA: 0x000163DC File Offset: 0x000145DC
[MethodImpl(MethodImplOptions.NoInlining)]
internal static int M1()
{
return Class2.M3(0x0200006B /*GetMdt(typeof(Class8))*/, Class2.M1(0x02000064 /*GetMdt(typeof(Class1))*/, Class2.M2(0x02000067 /*GetMdt(typeof(Class4))*/, Class2.M3(0x02000069 /*GetMdt(typeof(Class6))*/, Class2.M1(0x02000066 /*GetMdt(typeof(Class3))*/, 0x02000068 /*GetMdt(typeof(Class5))*/)))));
}
}
}
}

View File

@ -0,0 +1,180 @@
using System;
using System.Threading;
namespace forms_cil
{
// Token: 0x02000057 RID: 87
internal interface I4 // \u000E\u2008
{
// Token: 0x06000346 RID: 838
bool I4M(); // \u000E\u2008\u2008\u2000\u2002\u200A\u0002
// Token: 0x06000347 RID: 839
object M2(); // \u000E\u2008\u2008\u2000\u2002\u200A\u0002
// Token: 0x06000348 RID: 840
void M3(); // \u000E\u2008\u2008\u2000\u2002\u200A\u0002
}
// Token: 0x02000062 RID: 98
internal interface I5 // \u000F\u2008
{
// Token: 0x06000397 RID: 919
void I5M(); // \u000F\u2008\u2008\u2000\u2002\u200A\u0002
}
// Token: 0x0200000C RID: 12
internal interface I1<out T> : I4, I5 // \u0002\u2009
{
// Token: 0x06000057 RID: 87
T I1M(); // \u000E\u2008\u2008\u2000\u2002\u200A\u0002
}
// Token: 0x0200004B RID: 75
internal interface I3 // \u0008\u2008
{
// Token: 0x0600031E RID: 798
I4 M1(); // \u0008\u2008\u2008\u2000\u2002\u200A\u0002
}
// Token: 0x0200003C RID: 60
internal interface I2<out T> : I3 // \u0006\u2008
{
// Token: 0x060002CD RID: 717
I1<T> I2M(); // \u0008\u2008\u2008\u2000\u2002\u200A\u0002
}
// Token: 0x02000025 RID: 37
internal static class SdTemplateStuff // \u0005\u2008
{
// Token: 0x02000026 RID: 38
internal sealed class C : I2<int>, I1<int> // \u0002
{
// Token: 0x06000112 RID: 274 RVA: 0x00005A28 File Offset: 0x00003C28
public C(int val)
{
_i2 = val;
_i5 = Thread.CurrentThread.ManagedThreadId;
}
// Token: 0x06000113 RID: 275 RVA: 0x00005A48 File Offset: 0x00003C48
void I5.I5M()
{
}
// Token: 0x06000114 RID: 276 RVA: 0x00005A4C File Offset: 0x00003C4C
bool I4.I4M()
{
switch (_i2)
{
case 0:
_i2 = -1;
_i3 = -1496196691;
_i2 = 1;
return true;
case 1:
_i2 = -1;
_i3 = _i8 ^ 70939052;
_i2 = 2;
return true;
case 2:
_i2 = -1;
_i3 = _i8 ^ -1812634754;
_i2 = 3;
return true;
case 3:
_i2 = -1;
_i3 = -5623460;
_i2 = 4;
return true;
case 4:
_i2 = -1;
_i3 = 401181880;
_i2 = 5;
return true;
case 5:
_i2 = -1;
_i3 = 2075948002;
_i2 = 6;
return true;
case 6:
_i2 = -1;
_i3 = _i8 ^ 70939052;
_i2 = 7;
return true;
case 7:
_i2 = -1;
_i3 = -783689628;
_i2 = 8;
return true;
case 8:
_i2 = -1;
_i3 = _i8 ^ 70939052;
_i2 = 9;
return true;
case 9:
_i2 = -1;
return false;
default:
return false;
}
}
// Token: 0x06000115 RID: 277 RVA: 0x00005BA8 File Offset: 0x00003DA8
int I1<int>.I1M()
{
return _i3;
}
// Token: 0x06000116 RID: 278 RVA: 0x00005BB0 File Offset: 0x00003DB0
void I4.M3()
{
throw new NotSupportedException();
}
// Token: 0x06000117 RID: 279 RVA: 0x00005BB8 File Offset: 0x00003DB8
object I4.M2()
{
return _i3;
}
// Token: 0x06000118 RID: 280 RVA: 0x00005BC8 File Offset: 0x00003DC8
I1<int> I2<int>.I2M()
{
C ret;
if (_i2 == -2 && _i5 == Thread.CurrentThread.ManagedThreadId)
{
_i2 = 0;
ret = this;
}
else
{
ret = new C(0);
}
ret._i8 = I6;
return ret;
}
// Token: 0x06000119 RID: 281 RVA: 0x00005C10 File Offset: 0x00003E10
I4 I3.M1()
{
return ((I2<int>)this).I2M();
}
// Token: 0x0400003D RID: 61
private int _i2; // \u0002
// Token: 0x0400003E RID: 62
private int _i3; // \u0003
// Token: 0x0400003F RID: 63
private readonly int _i5; // \u0005
// Token: 0x04000040 RID: 64
private int _i8; // \u0008
// Token: 0x04000041 RID: 65
public int I6; // \u0006
}
}
}

View File

@ -0,0 +1,26 @@
using System;
namespace UnitTestProject.RefVm
{
// Token: 0x02000009 RID: 9
static class SimpleTypeHelper // \u0002\u2006
{
// Token: 0x06000033 RID: 51 RVA: 0x000027AC File Offset: 0x000009AC
public static bool IsNullableGeneric(Type t) // \u0002
{
return t.IsGenericType && t.GetGenericTypeDefinition() == NullableType; // \u0003
}
// Token: 0x04000008 RID: 8
public static readonly Type ObjectType = typeof(object); // \u0002
// Token: 0x04000009 RID: 9
private static readonly Type NullableType = typeof(Nullable<>); // \u0003
// Token: 0x0400000A RID: 10
public static readonly Type TypedReferenceType = typeof(TypedReference); // \u0005
// Token: 0x0400000B RID: 11
public static readonly Type EnumType = typeof(Enum); // \u0008
}
}

View File

@ -0,0 +1,648 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using forms_cil;
// Token: 0x0200003D RID: 61
namespace UnitTestProject.RefVm
{
public static class StringDecryptor // \u0006\u2009
{
private static BinStreamReader _binStreamReader; // \u0003
private static readonly DecryptedStrings DecryptedStringsGlobal; // \u0002
private static byte[] _commonKey; // \u0005
private static short _keyLength; // \u0008
private static readonly Enum1 Enum1Dummy; // \u0003\u2000
private static int _int1Dummy; // \u0002\u2000
private static int _int2Dummy; // \u000F
private static int _int3Dummy; // \u0006
private static byte[] _pkt; // \u000E
// Token: 0x060002CE RID: 718 RVA: 0x00013060 File Offset: 0x00011260
[MethodImpl(MethodImplOptions.NoInlining)]
static StringDecryptor()
{
var num = -42518532;
var num2 = num ^ 1885636661;
DecryptedStringsGlobal = new DecryptedStrings(1970604170 + num + num2 /*9*/);
var num3 = 2;
var stackTrace = new StackTrace(num3, false);
num3 -= 2;
var frame = stackTrace.GetFrame(num3);
var index = num3;
if (frame == null)
{
stackTrace = new StackTrace();
index = 1;
frame = stackTrace.GetFrame(index);
}
var num4 = ~- -~~-~-~(1341405001 ^ num ^ num2) ^ -~~- -~-~~(2095196650 + num - num2);
var methodBase = frame?.GetMethod();
if (frame != null)
{
num4 ^= ~- -~~-~-~(num ^ -1658751032 ^ num2);
}
var type = methodBase?.DeclaringType;
if (type == typeof(RuntimeMethodHandle))
{
Enum1Dummy = (Enum1)(4 | (int)Enum1Dummy);
num4 ^= 1970604898 + num + num2 + num3;
}
else if (type == null)
{
if (CheckStack(stackTrace, index))
{
num4 ^= ~-~- -~~-~(-1970628130 - num - num2) - num3;
Enum1Dummy = (Enum1)(16 | (int)Enum1Dummy);
}
else
{
num4 ^= ~- -~~-~-~(num ^ -1885608078 ^ num2);
Enum1Dummy = (Enum1)(1 | (int)Enum1Dummy);
}
}
else
{
num4 ^= ~-~- -~~-~(1885542988 - num + num2) - num3;
Enum1Dummy = (Enum1)(16 | (int)Enum1Dummy);
}
_int1Dummy += num4;
}
// Token: 0x060002CF RID: 719 RVA: 0x000131D4 File Offset: 0x000113D4
public static string GetString(int id) // \u0002
{
lock (DecryptedStringsGlobal)
{
return DecryptedStringsGlobal[id] ?? DecryptString(id, true);
}
}
public static void SetString(int id, string val) // for unit tests
{
lock (DecryptedStringsGlobal)
{
DecryptedStringsGlobal[id] = val;
}
}
// Token: 0x060002D0 RID: 720 RVA: 0x00013224 File Offset: 0x00011424
[MethodImpl(MethodImplOptions.NoInlining)]
private static string DecryptString(int id, bool dummy) // \u0002
{
var num = 1500675437;
var num2 = 1065028357 - num;
byte[] key;
string str;
int num6;
if (_binStreamReader == null)
{
var executingAssembly = Assembly.GetExecutingAssembly();
_int3Dummy |= num ^ -1084071305 ^ num2;
var stringBuilder = new StringBuilder();
var num3 = -1821765671 - num + num2;
stringBuilder.Append((char)(num3 >> 16)).Append((char)num3);
num3 = 1822175277 + num ^ num2;
stringBuilder.Append((char)(num3 >> 16)).Append((char)num3);
num3 = (1619914499 ^ num) + num2;
stringBuilder.Append((char)num3).Append((char)(num3 >> 16));
num3 = 1602104074 - num - num2;
stringBuilder.Append((char)num3).Append((char)(num3 >> 16));
num3 = (num ^ 1619980037) + num2;
stringBuilder.Append((char)num3).Append((char)(num3 >> 16));
num3 = num + -1398984659 - num2;
stringBuilder.Append((char)num3).Append((char)(num3 >> 16));
var manifestResourceStream = executingAssembly.GetManifestResourceStream(/* added by ursoft */ "forms_cil." +
stringBuilder.ToString()
/* added by ursoft */.GetHashCode().ToString());
var num4 = 2;
var stackTrace = new StackTrace(num4, false);
_int3Dummy ^= (1082521283 ^ num) + num2 | num4;
num4 -= 2;
var frame = stackTrace.GetFrame(num4);
var index = num4;
if (frame == null)
{
stackTrace = new StackTrace();
index = 1;
frame = stackTrace.GetFrame(index);
}
var methodBase = frame?.GetMethod();
_int3Dummy ^= num4 + (num + -1936322645 ^ num2);
var type = methodBase?.DeclaringType;
if (frame == null)
{
_int3Dummy ^= 1065247672 - num - num2;
}
var flag = type == typeof(RuntimeMethodHandle);
_int3Dummy ^= (num ^ 1082461797) + num2;
if (!flag)
{
flag = type == null;
if (flag)
{
if (CheckStack(stackTrace, index))
{
flag = false;
}
else
{
_int3Dummy ^= 1065247640 - num - num2;
}
}
}
if (flag)
{
_int3Dummy ^= 32;
}
_int3Dummy ^= (num ^ 1082521251) + num2 | num4 + 1;
_binStreamReader = new BinStreamReader(manifestResourceStream);
var commonKeyLength = (short)(_binStreamReader.ReadHeaderInt16() ^ ~(short)-(short)-(short)~(short)~(short)-(short)~(short)-(short)~(short)-(short)~(short)(-1065050389 + num ^ num2));
if (commonKeyLength == 0)
{
_keyLength = (short)(_binStreamReader.ReadHeaderInt16() ^ -(short)~(short)~(short)-(short)-(short)~(short)~(short)-(short)-(short)~(short)~(short)((-1082482306 ^ num) - num2));
}
else
{
_commonKey = _binStreamReader.Read(commonKeyLength);
}
var assembly = executingAssembly;
var assemblyName = SafeAssemblyName(assembly);
_pkt = SafeAssemblyPkt(assemblyName);
num6 = _int1Dummy;
_int1Dummy = 0;
var num7 = SdMetadataTokens.GetLong();
num6 ^= (int)(uint)num7;
num6 ^= -888987382 - num + num2;
var num8 = num6;
var num9 = num8;
var num10 = 0;
var num11 = num9 ^ -1693408934 + num - num2;
var num12 = num11 * (1936327810 - num + num2) % ((num ^ -1092770072) - num2);
var num13 = num12;
var obj = ((I2<int>)new SdTemplateStuff.C(-1065028359 + num | num2)
{
I6 = num13
}).I2M();
try
{
while (obj.I4M())
{
var num14 = obj.I1M();
num12 ^= num10 - num14 << 2;
num10 += num12 >> 3;
}
}
finally
{
obj?.I5M();
}
num6 ^= ~- -~-~~- -~~(num ^ 1140387705 ^ num2);
var num15 = num12;
num6 = num15 + num6;
_int2Dummy = num6;
_int3Dummy = (_int3Dummy & -1667887203 + num - num2) ^ (num ^ 1082519937) + num2;
if ((Enum1Dummy & (Enum1)(-~~- -~-~~(1936322518 - num ^ num2))) == 0)
{
_int3Dummy = (-1082440641 ^ num) - num2;
}
}
else
{
num6 = _int2Dummy;
}
if (_int3Dummy == 1936366479 - num + num2)
{
return new string(new[] { (char)((-1082462051 ^ num) - num2), '0', (char)(num + -1065028269 + num2) });
}
var num16 = id ^ -1010833342 ^ num ^ num2 ^ num6;
num16 ^= -1459130838 - num + num2;
_binStreamReader.GetStream().Position = num16;
if (_commonKey != null)
{
key = _commonKey;
}
else
{
short keyLength;
if (_keyLength == -1)
{
keyLength = (short)(_binStreamReader.ReadHeaderInt32() ^ num + -1936293566 - num2 ^ num16);
}
else
{
keyLength = _keyLength;
}
if (keyLength == 0)
{
key = null;
}
else
{
key = _binStreamReader.Read(keyLength);
for (var i = 0; i != key.Length; i = 1 + i)
{
key[i] ^= (byte)(_int2Dummy >> ((3 & i) << 3));
}
}
}
var stringHeader = _binStreamReader.ReadHeaderInt32() ^ num16 ^ -~~-~-~-~((num ^ -1882046960) + num2) ^ num6;
if (stringHeader != (1936322515 - num | num2))
{
var flagAnsi = (stringHeader & 211161131 + num - num2) != 0;
var flagCompressed = (stringHeader & (-8713467 - num ^ num2)) != 0;
var flagSecure = (stringHeader & (1619332869 ^ num) + num2) != 0;
stringHeader &= num + -1870334726 ^ num2;
var packedStringBuf = _binStreamReader.Read(stringHeader);
// ReSharper disable once PossibleNullReferenceException
var key1 = key[1];
var length = packedStringBuf.Length;
var key1XorLen = (byte)(11 + length ^ 7 + key1);
var keysXorLen = (uint)((key[0] | key[2] << 8) + (key1XorLen << 3));
ushort keysXorLenLowWord = 0;
for (var index = 0; index < length; ++index)
{
if ((index & 1) == 0)
{
keysXorLen = keysXorLen * (uint)((num ^ -1082544904) - num2) + (uint)(num + -1933863442 ^ num2);
keysXorLenLowWord = (ushort)(keysXorLen >> 16);
}
var keysXorLenLowByte = (byte)keysXorLenLowWord;
keysXorLenLowWord = (ushort)(keysXorLenLowWord >> 8);
var inByte = packedStringBuf[index];
packedStringBuf[index] = (byte)(inByte ^ key1 ^ 3 + key1XorLen ^ keysXorLenLowByte);
key1XorLen = inByte;
}
if (_pkt != null != (_int3Dummy != (-1085052045 ^ num) - num2))
{
for (var j = 0; j < stringHeader; j = 1 + j)
{
// ReSharper disable once PossibleNullReferenceException
var b5 = _pkt[7 & j];
b5 = (byte)(b5 << 3 | b5 >> 5);
packedStringBuf[j] ^= b5;
}
}
var num23 = _int3Dummy - 12;
int unpackedLength;
byte[] unpackedStringBuf;
if (!flagCompressed)
{
unpackedLength = stringHeader;
unpackedStringBuf = packedStringBuf;
}
else
{
unpackedLength = packedStringBuf[2] | packedStringBuf[0] << 16 | packedStringBuf[3] << 8 | packedStringBuf[1] << 24;
unpackedStringBuf = new byte[unpackedLength];
Unpack(packedStringBuf, 4, unpackedStringBuf);
}
if (flagAnsi && num23 == (num + -1935832971 ^ num2))
{
var chArray = new char[unpackedLength];
for (var k = 0; k < unpackedLength; k++)
{
chArray[k] = (char)unpackedStringBuf[k];
}
str = new string(chArray);
}
else
{
str = Encoding.Unicode.GetString(unpackedStringBuf, 0, unpackedStringBuf.Length);
}
num23 += (-1082461318 ^ num) - num2 + (3 & num23) << 5;
if (num23 != (1065521775 - num ^ num2))
{
var num25 = stringHeader + id ^ -1935385949 + num - num2 ^ (num23 & (-1082460680 ^ num ^ num2));
var stringBuilder = new StringBuilder();
var num3 = 1065028445 - num - num2;
stringBuilder.Append((char)(byte)num3);
str = num25.ToString(stringBuilder.ToString());
}
if (!flagSecure & dummy)
{
str = string.Intern(str);
DecryptedStringsGlobal[id] = str;
if (DecryptedStringsGlobal.GetCachedPairs() == (num + -1936322454 ^ num2))
{
_binStreamReader.Close();
_binStreamReader = null;
_commonKey = null;
_pkt = null;
}
}
return str;
}
var refId = _binStreamReader.Read(4);
id = -64102883 ^ num ^ num2 ^ num6;
id = (refId[2] | refId[3] << 16 | refId[0] << 8 | refId[1] << 24) ^ -id;
str = DecryptedStringsGlobal[id];
return str;
}
// Token: 0x060002D1 RID: 721 RVA: 0x00013A28 File Offset: 0x00011C28
private static AssemblyName SafeAssemblyName(Assembly a) // \u0002
{
AssemblyName result;
try
{
result = a.GetName();
}
catch
{
result = new AssemblyName(a.FullName);
}
return result;
}
// Token: 0x060002D2 RID: 722 RVA: 0x00013A60 File Offset: 0x00011C60
private static byte[] SafeAssemblyPkt(AssemblyName an) // \u0002
{
var array = an.GetPublicKeyToken();
if (array != null && array.Length == 0)
{
array = null;
}
return array;
}
// Token: 0x060002D3 RID: 723 RVA: 0x00013A80 File Offset: 0x00011C80
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool CheckStack(StackTrace st, int idx) // \u0002
{
var a = st.GetFrame(idx + 1)?.GetMethod()?.DeclaringType?.Assembly;
if (a != null)
{
var assemblyName = SafeAssemblyName(a);
var array = SafeAssemblyPkt(assemblyName);
if (array != null && array.Length == 8 && array[0] == 183 && array[7] == 137)
{
return true;
}
}
return false;
}
// Token: 0x060002D4 RID: 724 RVA: 0x00013AF0 File Offset: 0x00011CF0
private static void Unpack(byte[] packedStringBuf, int idxPacked, byte[] unpackedStringBuf) // \u0002
{
var idxUnpacked = 0;
var packedBlockHeader = 0;
var byteMask = 0x80;
var unpackLen = unpackedStringBuf.Length;
while (idxUnpacked < unpackLen)
{
byteMask <<= 1;
if (byteMask == 0x100)
{
byteMask = 1;
packedBlockHeader = packedStringBuf[idxPacked++];
}
if ((packedBlockHeader & byteMask) == 0)
{
unpackedStringBuf[idxUnpacked++] = packedStringBuf[idxPacked++];
continue;
}
var knownWordLen = (packedStringBuf[idxPacked] >> 2) + 3;
var knownWordOffset = ((packedStringBuf[idxPacked] << 8) | packedStringBuf[idxPacked + 1]) & 0x3ff;
idxPacked += 2;
var knownWordIdx = idxUnpacked - knownWordOffset;
if (knownWordIdx < 0)
return;
while (--knownWordLen >= 0 && idxUnpacked < unpackLen)
{
unpackedStringBuf[idxUnpacked++] = unpackedStringBuf[knownWordIdx++];
}
}
}
// Token: 0x0200003E RID: 62
internal sealed class BinStreamReader // \u0003\u2002\u200A\u2008\u2008\u200B\u2002\u2006\u2002\u2009\u2009\u2006\u2004\u2006\u2002\u2007\u2006\u2003\u2001\u2007\u2003\u200A\u2009\u200B\u2003\u2001
{
private byte[] _header; // \u0003
private Stream _stream; // \u0002
// Token: 0x060002D5 RID: 725 RVA: 0x00013B94 File Offset: 0x00011D94
public BinStreamReader(Stream stream)
{
_stream = stream;
_header = new byte[4];
}
// Token: 0x060002D6 RID: 726 RVA: 0x00013BB0 File Offset: 0x00011DB0
public Stream GetStream() // \u0002
{
return _stream;
}
// Token: 0x060002D7 RID: 727 RVA: 0x00013BB8 File Offset: 0x00011DB8
public short ReadHeaderInt16() // \u0002
{
ReadHeader(2);
return (short) (_header[0] | (_header[1] << 8));
}
// Token: 0x060002D8 RID: 728 RVA: 0x00013BD8 File Offset: 0x00011DD8
public int ReadHeaderInt32() // \u0002
{
ReadHeader(4);
return _header[0] | (_header[1] << 8) | (_header[2] << 0x10) | (_header[3] << 0x18);
}
// Token: 0x060002D9 RID: 729 RVA: 0x00013C0C File Offset: 0x00011E0C
private void ThrowEOS() // \u0002
{
throw new EndOfStreamException();
}
// Token: 0x060002DA RID: 730 RVA: 0x00013C14 File Offset: 0x00011E14
private void ReadHeader(int headerSize) // \u0002
{
var offset = 0;
int read;
if (headerSize == 1)
{
read = _stream.ReadByte();
if (read == -1)
ThrowEOS();
_header[0] = (byte) read;
}
else
{
do
{
read = _stream.Read(_header, offset, headerSize - offset);
if (read == 0)
ThrowEOS();
offset += read;
} while (offset < headerSize);
}
}
// Token: 0x060002DB RID: 731 RVA: 0x00013C74 File Offset: 0x00011E74
public void Close() // \u0003
{
var stream = _stream;
_stream = null;
stream?.Close();
_header = null;
}
// Token: 0x060002DC RID: 732 RVA: 0x00013CA0 File Offset: 0x00011EA0
public byte[] Read(int bytesCount) // \u0002
{
if (bytesCount < 0)
throw new ArgumentOutOfRangeException();
var buffer = new byte[bytesCount];
var offset = 0;
do
{
var read = _stream.Read(buffer, offset, bytesCount);
if (read == 0)
break;
offset += read;
bytesCount -= read;
} while (bytesCount > 0);
if (offset != buffer.Length)
{
var dst = new byte[offset];
Buffer.BlockCopy(buffer, 0, dst, 0, offset);
buffer = dst;
}
return buffer;
}
}
// Token: 0x0200003F RID: 63
internal sealed class DecryptedStrings // \u0005\u2001\u2007\u200B\u2000\u2008\u2008\u2000\u2000\u2006\u2004\u2008\u200B\u2002\u2006\u200B\u2001\u200B\u2003\u2004\u2001\u2004
{
private int _cachedPairs; // \u0003
private Pair[] _arr; // \u0002
// Token: 0x060002DD RID: 733 RVA: 0x00013CFC File Offset: 0x00011EFC
public DecryptedStrings()
{
_arr = new Pair[0x10];
}
// Token: 0x060002DE RID: 734 RVA: 0x00013D14 File Offset: 0x00011F14
public DecryptedStrings(int capacityHint)
{
var capacity = 0x10;
capacityHint = capacityHint << 1;
while ((capacity < capacityHint) && (capacity > 0))
{
capacity = capacity << 1;
}
if (capacity < 0)
{
capacity = 0x10;
}
_arr = new Pair[capacity];
}
// Token: 0x060002DF RID: 735 RVA: 0x00013D54 File Offset: 0x00011F54
public int GetCachedPairs()
{
return _cachedPairs;
}
// Token: 0x060002E0 RID: 736 RVA: 0x00013D5C File Offset: 0x00011F5C
private void GrowCache() // \u0002
{
var length = _arr.Length;
var newLength = length * 2;
if (newLength > 0)
{
var newArr = new Pair[newLength];
var cnt = 0;
for (var i = 0; i < length; i++)
{
if (_arr[i].val != null)
{
var index = _arr[i].id & (newLength - 1);
while (true)
{
if (newArr[index].val == null)
{
newArr[index].val = _arr[i].val;
newArr[index].id = _arr[i].id;
cnt++;
break;
}
index++;
if (index >= newLength)
index = 0;
}
}
}
_arr = newArr;
_cachedPairs = cnt;
}
}
public string this[int id]
{
// Token: 0x060002E1 RID: 737 RVA: 0x00013E10 File Offset: 0x00012010
get // \u0002
{
var length = _arr.Length;
var index = id & (length - 1);
do
{
if (_arr[index].id == id || _arr[index].val == null)
return _arr[index].val;
index++;
if (index >= length)
index = 0;
} while (true);
}
// Token: 0x060002E2 RID: 738 RVA: 0x00013E6C File Offset: 0x0001206C
set // \u0002
{
var length = _arr.Length;
var halfLength = length >> 1;
var index = id & (length - 1);
do
{
var emptySlot = _arr[index].val == null;
if (_arr[index].id == id || emptySlot)
{
_arr[index].val = value;
if (emptySlot)
{
_arr[index].id = id;
_cachedPairs++;
if (_cachedPairs > halfLength)
GrowCache();
}
break;
}
index++;
if (index >= length)
index = 0;
} while (true);
}
}
// Token: 0x02000040 RID: 64
[StructLayout(LayoutKind.Sequential)]
private struct Pair // \u0002
{
public int id;
public string val;
}
}
// Token: 0x02000041 RID: 65
[Flags]
internal enum Enum1
{
}
}
}

View File

@ -0,0 +1,54 @@
using System;
namespace UnitTestProject.RefVm
{
// Token: 0x02000055 RID: 85
internal static class TypeCompatibility // \u000E\u2006
{
// Token: 0x06000341 RID: 833 RVA: 0x000152D4 File Offset: 0x000134D4
public static bool Check(Type t1, Type t2) // t1
{
if (t1 == t2)
{
return true;
}
if (t1 == null || t2 == null)
{
return false;
}
if (t1.IsByRef)
{
return t2.IsByRef && Check(t1.GetElementType(), t2.GetElementType());
}
if (t2.IsByRef)
{
return false;
}
if (t1.IsPointer)
{
return t2.IsPointer && Check(t1.GetElementType(), t2.GetElementType());
}
if (t2.IsPointer)
{
return false;
}
if (t1.IsArray)
{
return t2.IsArray && t1.GetArrayRank() == t2.GetArrayRank() && Check(t1.GetElementType(), t2.GetElementType());
}
if (t2.IsArray)
{
return false;
}
if (t1.IsGenericType && !t1.IsGenericTypeDefinition)
{
t1 = t1.GetGenericTypeDefinition();
}
if (t2.IsGenericType && !t2.IsGenericTypeDefinition)
{
t2 = t2.GetGenericTypeDefinition();
}
return t1 == t2;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,165 @@
using System;
using System.Runtime.Serialization;
namespace UnitTestProject.RefVm
{
// Token: 0x02000045 RID: 69
internal static class VariantFactory // \u0008\u2002
{
// Token: 0x060002F6 RID: 758 RVA: 0x000144E0 File Offset: 0x000126E0
private static bool IsDerivedFrom<T>(Type obj) // \u0002
{
var typeFromHandle = typeof(T);
return obj == typeFromHandle || obj.IsSubclassOf(typeFromHandle);
}
// Token: 0x060002F7 RID: 759 RVA: 0x00014508 File Offset: 0x00012708
public static VariantBase Convert(object src, Type t) // \u0002
{
var ret = src as VariantBase;
if (ret != null)
{
return ret;
}
if (t == null)
{
if (src == null)
{
return new ObjectVariant();
}
t = src.GetType();
}
t = ElementedTypeHelper.TryGoToPointerOrReferenceElementType(t);
if (t == SimpleTypeHelper.ObjectType)
{
ret = new ObjectVariant();
if (src != null && src.GetType() != SimpleTypeHelper.ObjectType)
{
ret.SetVariantType(src.GetType());
}
}
else if (IsDerivedFrom<Array>(t))
{
ret = new ArrayVariant();
}
else if (IsDerivedFrom<string>(t))
{
ret = new StringVariant();
}
else if (IsDerivedFrom<IntPtr>(t))
{
ret = new IntPtrVariant();
}
else if (IsDerivedFrom<UIntPtr>(t))
{
ret = new UIntPtrVariant();
}
else if (IsDerivedFrom<ulong>(t))
{
ret = new UlongVariant();
}
else if (IsDerivedFrom<uint>(t))
{
ret = new UintVariant();
}
else if (IsDerivedFrom<ushort>(t))
{
ret = new UshortVariant();
}
else if (IsDerivedFrom<long>(t))
{
ret = new LongVariant();
}
else if (IsDerivedFrom<int>(t))
{
ret = new IntVariant();
}
else if (IsDerivedFrom<short>(t))
{
ret = new ShortVariant();
}
else if (IsDerivedFrom<byte>(t))
{
ret = new ByteVariant();
}
else if (IsDerivedFrom<sbyte>(t))
{
ret = new SbyteVariant();
}
else if (IsDerivedFrom<double>(t))
{
ret = new DoubleVariant();
}
else if (IsDerivedFrom<float>(t))
{
ret = new FloatVariant();
}
else if (IsDerivedFrom<bool>(t))
{
ret = new BoolVariant();
}
else if (IsDerivedFrom<char>(t))
{
ret = new CharVariant();
}
else if (SimpleTypeHelper.IsNullableGeneric(t))
{
var ov = new ObjectVariant();
ov.SetVariantType(t);
ret = ov;
}
else
{
if (IsDerivedFrom<Enum>(t))
{
Enum e;
if (src == null)
{
e = (Enum)Activator.CreateInstance(t);
}
else if (t == SimpleTypeHelper.EnumType && src is Enum)
{
e = (Enum)src;
}
else
{
e = (Enum)Enum.ToObject(t, src);
}
return new EnumVariant(e);
}
if (IsDerivedFrom<ValueType>(t))
{
if (src == null)
{
var vt = (t == SimpleTypeHelper.TypedReferenceType) ?
FormatterServices.GetSafeUninitializedObject(SimpleTypeHelper.TypedReferenceType) :
Activator.CreateInstance(t);
ret = new ValueTypeVariant(vt);
}
else
{
if (src.GetType() != t)
{
try
{
src = System.Convert.ChangeType(src, t);
}
catch
{
// ignored
}
}
ret = new ValueTypeVariant(src);
}
return ret;
}
ret = new ObjectVariant();
}
if (src != null)
{
ret.SetValueAbstract(src);
}
return ret;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,899 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Threading;
// ReSharper disable UnusedMember.Global
namespace UnitTestProject.RefVm
{
// Token: 0x0200002E RID: 46
[SuppressMessage("ReSharper", "InconsistentNaming")]
public class VmInstrCodesDb // \u0006\u2005
{
// Token: 0x04000068 RID: 104
private VmInstrInfo[] _all;
// Token: 0x0400011D RID: 285
private bool _initialized;
// Token: 0x0600015B RID: 347 RVA: 0x000075B8 File Offset: 0x000057B8
public bool IsInitialized() // \u0002
{
return _initialized;
}
// Token: 0x0600015C RID: 348 RVA: 0x000075C0 File Offset: 0x000057C0
public void SetInitialized(bool val) // \u0002
{
_initialized = val;
}
// Token: 0x0600015A RID: 346 RVA: 0x000075A8 File Offset: 0x000057A8
public IEnumerable<VmInstrInfo> MyFieldsEnumerator() // \u0002
{
return new FieldsEnumerator(-2)
{
Source = this
};
}
// Token: 0x0600015D RID: 349 RVA: 0x000075CC File Offset: 0x000057CC
public VmInstrInfo[] ToSortedArray() // \u0002
{
if (_all == null)
{
lock (this)
{
if (_all == null)
{
var list = new List<VmInstrInfo>(256);
list.AddRange(MyFieldsEnumerator());
if (SortHelper.MyComparison == null)
{
SortHelper.MyComparison = SortHelper.MySortHelper.Compare;
}
list.Sort(SortHelper.MyComparison);
_all = list.ToArray();
}
}
}
return _all;
}
// Token: 0x0200002F RID: 47
[Serializable]
private sealed class SortHelper // \u0002
{
// Token: 0x06000160 RID: 352 RVA: 0x000076A0 File Offset: 0x000058A0
internal int Compare(VmInstrInfo v1, VmInstrInfo v2) // \u0002
{
return v1.Id.CompareTo(v2.Id);
}
// Token: 0x04000129 RID: 297
public static readonly SortHelper MySortHelper = new SortHelper(); // \u0002
// Token: 0x0400012A RID: 298
public static Comparison<VmInstrInfo> MyComparison; // \u0003
}
// Token: 0x02000030 RID: 48
private sealed class FieldsEnumerator : IEnumerable<VmInstrInfo>, IEnumerator<VmInstrInfo> // \u0003
{
// Token: 0x06000161 RID: 353 RVA: 0x000076C4 File Offset: 0x000058C4
public FieldsEnumerator(int st)
{
_state = st;
_threadId = Thread.CurrentThread.ManagedThreadId;
}
// Token: 0x06000162 RID: 354 RVA: 0x000076E4 File Offset: 0x000058E4
void IDisposable.Dispose() // \u0003\u2008\u2000\u2002\u200A\u0002
{
}
// Token: 0x06000163 RID: 355 RVA: 0x000076E8 File Offset: 0x000058E8
bool IEnumerator.MoveNext()
{
var num = _state;
if (num != 0)
{
if (num != 1)
{
return false;
}
_state = -1;
_index++;
}
else
{
_state = -1;
var fields = typeof(VmInstrCodesDb).GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
_data = fields;
_index = 0;
}
if (_index >= _data.Length)
{
_data = null;
return false;
}
var p = (VmInstrInfo)_data[_index].GetValue(Source);
_current = p;
_state = 1;
return true;
}
// Token: 0x06000164 RID: 356 RVA: 0x00007790 File Offset: 0x00005990
VmInstrInfo IEnumerator<VmInstrInfo>.Current // \u0003\u2008\u2000\u2002\u200A\u0002
=> _current;
// Token: 0x06000165 RID: 357 RVA: 0x00007798 File Offset: 0x00005998
[DebuggerHidden]
void IEnumerator.Reset() // \u0003\u2008\u2000\u2002\u200A\u0003
{
throw new NotSupportedException();
}
// Token: 0x06000166 RID: 358 RVA: 0x000077A0 File Offset: 0x000059A0
[DebuggerHidden]
object IEnumerator.Current // \u0003\u2008\u2000\u2002\u200A\u0002
=> _current;
// Token: 0x06000167 RID: 359 RVA: 0x000077A8 File Offset: 0x000059A8
[DebuggerHidden]
IEnumerator<VmInstrInfo> IEnumerable<VmInstrInfo>.GetEnumerator() // \u0003\u2008\u2000\u2002\u200A\u0002
{
FieldsEnumerator ret;
if (_state == -2 && _threadId == Thread.CurrentThread.ManagedThreadId)
{
_state = 0;
ret = this;
}
else
{
ret = new FieldsEnumerator(0) {Source = Source};
}
return ret;
}
// Token: 0x06000168 RID: 360 RVA: 0x000077F0 File Offset: 0x000059F0
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator() // \u0003\u2008\u2000\u2002\u200A\u0002
{
return ((IEnumerable<VmInstrInfo>)this).GetEnumerator();
}
// Token: 0x0400012B RID: 299
private int _state; // \u0002
// Token: 0x0400012C RID: 300
private VmInstrInfo _current; // \u0003
// Token: 0x0400012D RID: 301
private readonly int _threadId; // \u0005
// Token: 0x0400012E RID: 302
public VmInstrCodesDb Source; // \u0008
// Token: 0x0400012F RID: 303
private FieldInfo[] _data; // \u0006
// Token: 0x04000130 RID: 304
private int _index; // \u000E
}
#region all
/*
no. { typecheck, rangecheck, nullcheck } The specified fault check(s) normally performed as part of the execution of the subsequent instruction can/shall be skipped. Prefix to instruction
readonly. Specify that the subsequent array address operation performs no type check at runtime, and that it returns a controlled-mutability managed pointer Prefix to instruction
tail. Subsequent call terminates current method Prefix to instruction
unaligned. (alignment) Subsequent pointer instruction might be unaligned. Prefix to instruction
volatile. Subsequent pointer reference is volatile. Prefix to instruction
*/
// Token: 0x04000063 RID: 99
public readonly VmInstrInfo U0002U2000 = new VmInstrInfo(690984147, VmOperandType.Ot11Nope); // not implemented
// Token: 0x04000077 RID: 119
public readonly VmInstrInfo U0006U2001U2000 = new VmInstrInfo(733028785, VmOperandType.Ot11Nope); // not implemented
// Token: 0x0400007A RID: 122
public readonly VmInstrInfo U0006U2001 = new VmInstrInfo(701247957, VmOperandType.Ot11Nope); // not implemented
// Token: 0x04000086 RID: 134
public readonly VmInstrInfo U0006U2004 = new VmInstrInfo(-377358754, VmOperandType.Ot11Nope); // not implemented
// Token: 0x040000B0 RID: 176
public readonly VmInstrInfo U0006U2008U2000 = new VmInstrInfo(1026942272, VmOperandType.Ot11Nope); // empty impl
// Token: 0x040000B2 RID: 178
public readonly VmInstrInfo Endfilter_ = new VmInstrInfo(-1041717787, VmOperandType.Ot11Nope);
// Token: 0x040000C6 RID: 198
public readonly VmInstrInfo Mul_ovf_ = new VmInstrInfo(717697778, VmOperandType.Ot11Nope);
// Token: 0x040000CB RID: 203
public readonly VmInstrInfo Endfinally_ = new VmInstrInfo(-860175516, VmOperandType.Ot11Nope);
// Token: 0x040000E0 RID: 224
public readonly VmInstrInfo U0003U2009 = new VmInstrInfo(-1535884281, VmOperandType.Ot11Nope); // not implemented
// Token: 0x04000080 RID: 128
public readonly VmInstrInfo U000EU2006U2000 = new VmInstrInfo(1756761351, VmOperandType.Ot5Int); // ??? invoke some method
// Token: 0x04000082 RID: 130
public readonly VmInstrInfo Jmp_ = new VmInstrInfo(-512817309, VmOperandType.Ot12Int);
// Token: 0x040000CC RID: 204
public readonly VmInstrInfo Initobj_ = new VmInstrInfo(-647649665, VmOperandType.Ot5Int);
// Token: 0x04000065 RID: 101
public readonly VmInstrInfo Calli_ = new VmInstrInfo(1295283437, VmOperandType.Ot5Int);
// Token: 0x0400006F RID: 111
public readonly VmInstrInfo Constrained_ = new VmInstrInfo(1803463719, VmOperandType.Ot5Int);
// Token: 0x04000098 RID: 152
public readonly VmInstrInfo U000FU2001 = new VmInstrInfo(-1952417400, VmOperandType.Ot5Int); // empty impl
// Token: 0x040000E1 RID: 225
public readonly VmInstrInfo Box_ = new VmInstrInfo(1491096114, VmOperandType.Ot5Int);
// Token: 0x040000E4 RID: 228
public readonly VmInstrInfo U0006U200BU2000 = new VmInstrInfo(-1858492701, VmOperandType.Ot11Nope); // not implemented
// Token: 0x040000ED RID: 237
public readonly VmInstrInfo U0002U2002U2001 = new VmInstrInfo(113196648, VmOperandType.Ot11Nope); // not implemented
// Token: 0x040000EF RID: 239
public readonly VmInstrInfo Ldobj_ = new VmInstrInfo(-564585233, VmOperandType.Ot5Int);
// Token: 0x04000104 RID: 260
public readonly VmInstrInfo Rethrow_ = new VmInstrInfo(989001448, VmOperandType.Ot11Nope);
// Token: 0x04000125 RID: 293
public readonly VmInstrInfo U000EU2000U2000 = new VmInstrInfo(814546329, VmOperandType.Ot11Nope); // not implemented
// Token: 0x040000B8 RID: 184
public readonly VmInstrInfo Newobj_ = new VmInstrInfo(783240206, VmOperandType.Ot5Int);
// Token: 0x040000B9 RID: 185
public readonly VmInstrInfo U0006U2000U2000 = new VmInstrInfo(569679686, VmOperandType.Ot11Nope); // not implemented
// Token: 0x040000BD RID: 189
public readonly VmInstrInfo U0002U200B = new VmInstrInfo(578506051, VmOperandType.Ot6SByte); // leave.s not implemented
// Token: 0x040000BE RID: 190
public readonly VmInstrInfo Leave_ = new VmInstrInfo(182069479, VmOperandType.Ot0UInt);
// Token: 0x040000B3 RID: 179
//public readonly VmInstrInfo U0003U2008 = new VmInstrInfo(56035065, VmOperandType.Nope11);
// Token: 0x04000052 RID: 82
public readonly VmInstrInfo Ldnull_ = new VmInstrInfo(1672432034, VmOperandType.Ot11Nope);
// Token: 0x04000057 RID: 87
public readonly VmInstrInfo Pop_ = new VmInstrInfo(-423590017, VmOperandType.Ot11Nope);
// Token: 0x0400005B RID: 91
public readonly VmInstrInfo Ckfinite_ = new VmInstrInfo(-624596400, VmOperandType.Ot11Nope);
// Token: 0x0400005D RID: 93
public readonly VmInstrInfo Stind_i2_ = new VmInstrInfo(81292670, VmOperandType.Ot11Nope);
// Token: 0x0400006C RID: 108
public readonly VmInstrInfo Stind_r8_ = new VmInstrInfo(-239256528, VmOperandType.Ot11Nope);
// Token: 0x04000074 RID: 116
public readonly VmInstrInfo Ldftn_ = new VmInstrInfo(-204727488, VmOperandType.Ot5Int);
// Token: 0x04000076 RID: 118
public readonly VmInstrInfo Ldlen_ = new VmInstrInfo(-1528794514, VmOperandType.Ot11Nope);
// Token: 0x04000079 RID: 121
public readonly VmInstrInfo Isinst_ = new VmInstrInfo(-1879745689, VmOperandType.Ot5Int);
// Token: 0x04000081 RID: 129
public readonly VmInstrInfo Stind_i8_ = new VmInstrInfo(-279385973, VmOperandType.Ot11Nope);
// Token: 0x04000087 RID: 135
public readonly VmInstrInfo Newarr_ = new VmInstrInfo(1211659810, VmOperandType.Ot5Int);
// Token: 0x04000089 RID: 137
public readonly VmInstrInfo Callvirt_ = new VmInstrInfo(497685394, VmOperandType.Ot5Int);
// Token: 0x0400008A RID: 138
public readonly VmInstrInfo Ldc_i8_ = new VmInstrInfo(598097099, VmOperandType.Ot7Long);
// Token: 0x0400009A RID: 154
public readonly VmInstrInfo Castclass_ = new VmInstrInfo(1816382558, VmOperandType.Ot5Int);
// Token: 0x0400009C RID: 156
public readonly VmInstrInfo Stind_i_ = new VmInstrInfo(-774914583, VmOperandType.Ot11Nope);
// Token: 0x0400009D RID: 157
public readonly VmInstrInfo Ldc_i4_s_ = new VmInstrInfo(1440000960, VmOperandType.Ot6SByte);
// Token: 0x040000A7 RID: 167
public readonly VmInstrInfo Not_ = new VmInstrInfo(2044815068, VmOperandType.Ot11Nope);
// Token: 0x040000A8 RID: 168
public readonly VmInstrInfo Ldtoken_ = new VmInstrInfo(757747961, VmOperandType.Ot5Int);
// Token: 0x040000AD RID: 173
public readonly VmInstrInfo Stind_i4_ = new VmInstrInfo(-587303415, VmOperandType.Ot11Nope);
// Token: 0x040000B6 RID: 182
public readonly VmInstrInfo Ldvirtftn_ = new VmInstrInfo(-1088007919, VmOperandType.Ot5Int);
// Token: 0x040000BA RID: 186
public readonly VmInstrInfo Stind_i1_ = new VmInstrInfo(122987244, VmOperandType.Ot11Nope);
// Token: 0x040000BC RID: 188
public readonly VmInstrInfo Cgt_ = new VmInstrInfo(-290816002, VmOperandType.Ot11Nope);
// Token: 0x040000C4 RID: 196
public readonly VmInstrInfo Stobj_ = new VmInstrInfo(-18831398, VmOperandType.Ot5Int);
// Token: 0x040000C5 RID: 197
public readonly VmInstrInfo Clt_un_ = new VmInstrInfo(-377042092, VmOperandType.Ot11Nope);
// Token: 0x040000DD RID: 221
public readonly VmInstrInfo Cgt_un_ = new VmInstrInfo(-244421767, VmOperandType.Ot11Nope);
// Token: 0x040000D6 RID: 214
public readonly VmInstrInfo Stind_ref_ = new VmInstrInfo(-572078212, VmOperandType.Ot11Nope);
// Token: 0x040000DF RID: 223
public readonly VmInstrInfo Ldloca_ = new VmInstrInfo(-1112986259, VmOperandType.Ot1UShort);
// Token: 0x040000E9 RID: 233
public readonly VmInstrInfo Call_ = new VmInstrInfo(-1118186024, VmOperandType.Ot5Int);
// Token: 0x040000F9 RID: 249
public readonly VmInstrInfo Ldc_r8_ = new VmInstrInfo(-557730397, VmOperandType.Ot4Double);
// Token: 0x040000FD RID: 253
public readonly VmInstrInfo Clt_ = new VmInstrInfo(-1789431058, VmOperandType.Ot11Nope);
// Token: 0x04000107 RID: 263
public readonly VmInstrInfo Ldc_i4_ = new VmInstrInfo(-763377227, VmOperandType.Ot12Int);
// Token: 0x04000112 RID: 274
public readonly VmInstrInfo Ldc_r4_ = new VmInstrInfo(-976252990, VmOperandType.Ot10Float);
// Token: 0x04000116 RID: 278
public readonly VmInstrInfo Stind_r4_ = new VmInstrInfo(2036802079, VmOperandType.Ot11Nope);
// Token: 0x04000119 RID: 281
public readonly VmInstrInfo Nop_ = new VmInstrInfo(-724560934, VmOperandType.Ot11Nope);
// Token: 0x0400011E RID: 286
public readonly VmInstrInfo Ldloca_s_ = new VmInstrInfo(1851592203, VmOperandType.Ot8Byte);
// Token: 0x04000053 RID: 83
public readonly VmInstrInfo Sizeof_ = new VmInstrInfo(-1163259743, VmOperandType.Ot5Int);
// Token: 0x04000054 RID: 84
public readonly VmInstrInfo Ldind_r4_ = new VmInstrInfo(1144322863, VmOperandType.Ot11Nope);
// Token: 0x04000055 RID: 85
public readonly VmInstrInfo Ldelem_i1_ = new VmInstrInfo(322204500, VmOperandType.Ot11Nope);
// Token: 0x04000056 RID: 86
public readonly VmInstrInfo Conv_r8_ = new VmInstrInfo(-195608730, VmOperandType.Ot11Nope);
// Token: 0x04000058 RID: 88
public readonly VmInstrInfo Stelem_i1_ = new VmInstrInfo(-1560659480, VmOperandType.Ot11Nope);
// Token: 0x04000059 RID: 89
public readonly VmInstrInfo Ldstr_ = new VmInstrInfo(-883753595, VmOperandType.Ot5Int);
// Token: 0x0400005A RID: 90
public readonly VmInstrInfo Conv_i4_ = new VmInstrInfo(1738936149, VmOperandType.Ot11Nope);
// Token: 0x0400005C RID: 92
public readonly VmInstrInfo Ldarg_2_ = new VmInstrInfo(917707539, VmOperandType.Ot11Nope);
// Token: 0x0400005E RID: 94
public readonly VmInstrInfo Conv_i1_ = new VmInstrInfo(443736782, VmOperandType.Ot11Nope);
// Token: 0x0400005F RID: 95
public readonly VmInstrInfo Div_ = new VmInstrInfo(873071583, VmOperandType.Ot11Nope);
// Token: 0x04000060 RID: 96
public readonly VmInstrInfo Conv_i_ = new VmInstrInfo(863451657, VmOperandType.Ot11Nope);
// Token: 0x04000061 RID: 97
public readonly VmInstrInfo Stelem_ref_ = new VmInstrInfo(1243606418, VmOperandType.Ot11Nope);
// Token: 0x04000062 RID: 98
public readonly VmInstrInfo Shl_ = new VmInstrInfo(1269228253, VmOperandType.Ot11Nope);
// Token: 0x04000064 RID: 100
public readonly VmInstrInfo Conv_u4_ = new VmInstrInfo(-1046006878, VmOperandType.Ot11Nope);
// Token: 0x04000066 RID: 102
public readonly VmInstrInfo Break_ = new VmInstrInfo(-979485219, VmOperandType.Ot11Nope);
// Token: 0x04000067 RID: 103
public readonly VmInstrInfo Ldc_i4_1_ = new VmInstrInfo(-2108713475, VmOperandType.Ot11Nope);
// Token: 0x04000069 RID: 105
public readonly VmInstrInfo Or_ = new VmInstrInfo(1569462844, VmOperandType.Ot11Nope);
// Token: 0x0400006A RID: 106
public readonly VmInstrInfo Ldelem_ = new VmInstrInfo(-1705118555, VmOperandType.Ot5Int);
// Token: 0x0400006B RID: 107
public readonly VmInstrInfo Conv_u1_ = new VmInstrInfo(1055970854, VmOperandType.Ot11Nope);
// Token: 0x0400006D RID: 109
public readonly VmInstrInfo Ldind_i1_ = new VmInstrInfo(33169414, VmOperandType.Ot11Nope);
// Token: 0x0400006E RID: 110
public readonly VmInstrInfo Ldind_i_ = new VmInstrInfo(-1790442498, VmOperandType.Ot11Nope);
// Token: 0x04000070 RID: 112
public readonly VmInstrInfo Ldsfld_ = new VmInstrInfo(-1369658342, VmOperandType.Ot5Int);
// Token: 0x04000071 RID: 113
public readonly VmInstrInfo Ldloc_ = new VmInstrInfo(766115889, VmOperandType.Ot1UShort);
// Token: 0x04000072 RID: 114
public readonly VmInstrInfo Rem_un_ = new VmInstrInfo(-2121309775, VmOperandType.Ot11Nope);
// Token: 0x04000073 RID: 115
public readonly VmInstrInfo Conv_ovf_i8_ = new VmInstrInfo(-287049786, VmOperandType.Ot11Nope);
// Token: 0x04000075 RID: 117
public readonly VmInstrInfo Ldc_i4_0_ = new VmInstrInfo(89715609, VmOperandType.Ot11Nope);
// Token: 0x04000078 RID: 120
public readonly VmInstrInfo Ldloc_3_ = new VmInstrInfo(1790654656, VmOperandType.Ot11Nope);
// Token: 0x0400007B RID: 123
public readonly VmInstrInfo Ldsflda_ = new VmInstrInfo(-2097007575, VmOperandType.Ot5Int);
// Token: 0x0400007C RID: 124
public readonly VmInstrInfo Add_ovf_ = new VmInstrInfo(-545700640, VmOperandType.Ot11Nope);
// Token: 0x0400007D RID: 125
public readonly VmInstrInfo Refanytype_ = new VmInstrInfo(-971088331, VmOperandType.Ot11Nope);
// Token: 0x0400007E RID: 126
public readonly VmInstrInfo Blt_ = new VmInstrInfo(1978323310, VmOperandType.Ot0UInt);
// Token: 0x0400007F RID: 127
public readonly VmInstrInfo Conv_ovf_u8_un_ = new VmInstrInfo(1527584358, VmOperandType.Ot11Nope);
// Token: 0x04000083 RID: 131
public readonly VmInstrInfo Ldelem_i8_ = new VmInstrInfo(1272142104, VmOperandType.Ot11Nope);
// Token: 0x04000084 RID: 132
public readonly VmInstrInfo Ldc_i4_6_ = new VmInstrInfo(871172961, VmOperandType.Ot11Nope);
// Token: 0x04000085 RID: 133
public readonly VmInstrInfo Starg_s_ = new VmInstrInfo(-687376789, VmOperandType.Ot8Byte);
// Token: 0x04000088 RID: 136
public readonly VmInstrInfo Beq_ = new VmInstrInfo(352236975, VmOperandType.Ot0UInt);
// Token: 0x0400008B RID: 139
public readonly VmInstrInfo Ldfld_ = new VmInstrInfo(-688284774, VmOperandType.Ot5Int);
// Token: 0x0400008C RID: 140
public readonly VmInstrInfo Conv_ovf_i2_un_ = new VmInstrInfo(1663762471, VmOperandType.Ot11Nope);
// Token: 0x0400008D RID: 141
public readonly VmInstrInfo Conv_ovf_i_un_ = new VmInstrInfo(2093357171, VmOperandType.Ot11Nope);
// Token: 0x0400008E RID: 142
public readonly VmInstrInfo Ldelem_u4_ = new VmInstrInfo(896332376, VmOperandType.Ot11Nope);
// Token: 0x0400008F RID: 143
public readonly VmInstrInfo Conv_ovf_u4_un_ = new VmInstrInfo(-107488823, VmOperandType.Ot11Nope);
// Token: 0x04000090 RID: 144
public readonly VmInstrInfo Ldarga_ = new VmInstrInfo(2044160323, VmOperandType.Ot1UShort);
// Token: 0x04000091 RID: 145
public readonly VmInstrInfo Div_un_ = new VmInstrInfo(742839562, VmOperandType.Ot11Nope);
// Token: 0x04000092 RID: 146
public readonly VmInstrInfo Ldelem_r4_ = new VmInstrInfo(-1447311583, VmOperandType.Ot11Nope);
// Token: 0x04000093 RID: 147
public readonly VmInstrInfo And_ = new VmInstrInfo(1968373082, VmOperandType.Ot11Nope);
// Token: 0x04000094 RID: 148
public readonly VmInstrInfo Add_ = new VmInstrInfo(-1892228817, VmOperandType.Ot11Nope);
// Token: 0x04000095 RID: 149
public readonly VmInstrInfo Conv_ovf_u2_ = new VmInstrInfo(1775410326, VmOperandType.Ot11Nope);
// Token: 0x04000096 RID: 150
public readonly VmInstrInfo Xor_ = new VmInstrInfo(-273395395, VmOperandType.Ot11Nope);
// Token: 0x04000097 RID: 151
public readonly VmInstrInfo Stloc_1_ = new VmInstrInfo(-1446892238, VmOperandType.Ot11Nope);
// Token: 0x04000099 RID: 153
public readonly VmInstrInfo Conv_ovf_u2_un_ = new VmInstrInfo(-1274139658, VmOperandType.Ot11Nope);
// Token: 0x0400009B RID: 155
public readonly VmInstrInfo Ldc_i4_3_ = new VmInstrInfo(-722334296, VmOperandType.Ot11Nope);
// Token: 0x0400009E RID: 158
public readonly VmInstrInfo Ldelem_u1_ = new VmInstrInfo(580121148, VmOperandType.Ot11Nope);
// Token: 0x0400009F RID: 159
public readonly VmInstrInfo Ldelem_i4_ = new VmInstrInfo(778369289, VmOperandType.Ot11Nope);
// Token: 0x040000A0 RID: 160
public readonly VmInstrInfo Stfld_ = new VmInstrInfo(1721102239, VmOperandType.Ot5Int);
// Token: 0x040000A1 RID: 161
public readonly VmInstrInfo Ldc_i4_m1_ = new VmInstrInfo(-1374936951, VmOperandType.Ot11Nope);
// Token: 0x040000A2 RID: 162
public readonly VmInstrInfo Brfalse_ = new VmInstrInfo(476056811, VmOperandType.Ot0UInt);
// Token: 0x040000A3 RID: 163
public readonly VmInstrInfo Rem_ = new VmInstrInfo(1127773841, VmOperandType.Ot11Nope);
// Token: 0x040000A4 RID: 164
public readonly VmInstrInfo Neg_ = new VmInstrInfo(1824866698, VmOperandType.Ot11Nope);
// Token: 0x040000A5 RID: 165
public readonly VmInstrInfo Initblk_ = new VmInstrInfo(1848160160, VmOperandType.Ot11Nope);
// Token: 0x040000A6 RID: 166
public readonly VmInstrInfo Ldelem_r8_ = new VmInstrInfo(-522987252, VmOperandType.Ot11Nope);
// Token: 0x040000A9 RID: 169
public readonly VmInstrInfo Cpobj_ = new VmInstrInfo(1238115537, VmOperandType.Ot5Int);
// Token: 0x040000AA RID: 170
public readonly VmInstrInfo Ldarga_s_ = new VmInstrInfo(-1193068213, VmOperandType.Ot8Byte);
// Token: 0x040000AB RID: 171
public readonly VmInstrInfo Br_ = new VmInstrInfo(658728581, VmOperandType.Ot0UInt);
// Token: 0x040000AC RID: 172
public readonly VmInstrInfo Conv_u2_ = new VmInstrInfo(-2099750455, VmOperandType.Ot11Nope);
// Token: 0x040000AE RID: 174
public readonly VmInstrInfo Stelem_i_ = new VmInstrInfo(-358560507, VmOperandType.Ot11Nope);
// Token: 0x040000AF RID: 175
public readonly VmInstrInfo Stloc_s_ = new VmInstrInfo(1804315644, VmOperandType.Ot8Byte);
// Token: 0x040000B1 RID: 177
public readonly VmInstrInfo Ble_un_ = new VmInstrInfo(1001656673, VmOperandType.Ot0UInt);
// Token: 0x040000B4 RID: 180
public readonly VmInstrInfo Ldc_i4_2_ = new VmInstrInfo(-2082446517, VmOperandType.Ot11Nope);
// Token: 0x040000B5 RID: 181
public readonly VmInstrInfo Blt_un_ = new VmInstrInfo(-1002275164, VmOperandType.Ot0UInt);
// Token: 0x040000B7 RID: 183
public readonly VmInstrInfo Ldind_ref_ = new VmInstrInfo(-101579585, VmOperandType.Ot11Nope);
// Token: 0x040000BB RID: 187
public readonly VmInstrInfo Ldind_i2_ = new VmInstrInfo(1338544134, VmOperandType.Ot11Nope);
// Token: 0x040000BF RID: 191
public readonly VmInstrInfo Shr_ = new VmInstrInfo(2061114403, VmOperandType.Ot11Nope);
// Token: 0x040000C0 RID: 192
public readonly VmInstrInfo Sub_ovf_ = new VmInstrInfo(-1326124455, VmOperandType.Ot11Nope);
// Token: 0x040000C1 RID: 193
public readonly VmInstrInfo Mul_ = new VmInstrInfo(-368354161, VmOperandType.Ot11Nope);
// Token: 0x040000C2 RID: 194
public readonly VmInstrInfo Conv_r4_ = new VmInstrInfo(461467744, VmOperandType.Ot11Nope);
// Token: 0x040000C3 RID: 195
public readonly VmInstrInfo Ldarg_s_ = new VmInstrInfo(916919316, VmOperandType.Ot8Byte);
// Token: 0x040000C7 RID: 199
public readonly VmInstrInfo Conv_ovf_u8_ = new VmInstrInfo(-1916788012, VmOperandType.Ot11Nope);
// Token: 0x040000C8 RID: 200
public readonly VmInstrInfo Ldind_u2_ = new VmInstrInfo(-1831891367, VmOperandType.Ot11Nope);
// Token: 0x040000C9 RID: 201
public readonly VmInstrInfo Ldind_u4_ = new VmInstrInfo(-1620795876, VmOperandType.Ot11Nope);
// Token: 0x040000CA RID: 202
public readonly VmInstrInfo Conv_ovf_i4_ = new VmInstrInfo(488024265, VmOperandType.Ot11Nope);
// Token: 0x040000CD RID: 205
public readonly VmInstrInfo Ldarg_1_ = new VmInstrInfo(326597331, VmOperandType.Ot11Nope);
// Token: 0x040000CE RID: 206
public readonly VmInstrInfo Conv_ovf_u_ = new VmInstrInfo(115989675, VmOperandType.Ot11Nope);
// Token: 0x040000CF RID: 207
public readonly VmInstrInfo Ldloc_s_ = new VmInstrInfo(1019004451, VmOperandType.Ot8Byte);
// Token: 0x040000D0 RID: 208
public readonly VmInstrInfo Conv_i2_ = new VmInstrInfo(-108178384, VmOperandType.Ot11Nope);
// Token: 0x040000D1 RID: 209
public readonly VmInstrInfo Conv_ovf_i_ = new VmInstrInfo(-2109763431, VmOperandType.Ot11Nope);
// Token: 0x040000D2 RID: 210
public readonly VmInstrInfo Ble_ = new VmInstrInfo(1321262543, VmOperandType.Ot0UInt);
// Token: 0x040000D3 RID: 211
public readonly VmInstrInfo Unbox_ = new VmInstrInfo(-1668682548, VmOperandType.Ot5Int);
// Token: 0x040000D4 RID: 212
public readonly VmInstrInfo Stelem_r4_ = new VmInstrInfo(-1251429380, VmOperandType.Ot11Nope);
// Token: 0x040000D5 RID: 213
public readonly VmInstrInfo Stloc_3_ = new VmInstrInfo(1073782561, VmOperandType.Ot11Nope);
// Token: 0x040000D7 RID: 215
public readonly VmInstrInfo Brtrue_ = new VmInstrInfo(1985375111, VmOperandType.Ot0UInt);
// Token: 0x040000D8 RID: 216
public readonly VmInstrInfo Stelem_ = new VmInstrInfo(-633052479, VmOperandType.Ot5Int);
// Token: 0x040000D9 RID: 217
public readonly VmInstrInfo Stelem_i4_ = new VmInstrInfo(-638226942, VmOperandType.Ot11Nope);
// Token: 0x040000DA RID: 218
public readonly VmInstrInfo Conv_ovf_u1_un_ = new VmInstrInfo(-854623375, VmOperandType.Ot11Nope);
// Token: 0x040000DB RID: 219
public readonly VmInstrInfo Add_ovf_un_ = new VmInstrInfo(-2145629048, VmOperandType.Ot11Nope);
// Token: 0x040000DC RID: 220
public readonly VmInstrInfo Conv_u8_ = new VmInstrInfo(1396092080, VmOperandType.Ot11Nope);
// Token: 0x040000DE RID: 222
public readonly VmInstrInfo Bgt_ = new VmInstrInfo(-939929863, VmOperandType.Ot0UInt);
// Token: 0x040000E2 RID: 226
public readonly VmInstrInfo Bgt_un_ = new VmInstrInfo(-73779400, VmOperandType.Ot0UInt);
// Token: 0x040000E3 RID: 227
public readonly VmInstrInfo Stelem_r8_ = new VmInstrInfo(849078739, VmOperandType.Ot11Nope);
// Token: 0x040000E5 RID: 229
public readonly VmInstrInfo Mkrefany_ = new VmInstrInfo(1810420701, VmOperandType.Ot5Int);
// Token: 0x040000E6 RID: 230
public readonly VmInstrInfo Conv_ovf_u_un_ = new VmInstrInfo(-1209242284, VmOperandType.Ot11Nope);
// Token: 0x040000E7 RID: 231
public readonly VmInstrInfo Conv_ovf_i1_ = new VmInstrInfo(-1678823314, VmOperandType.Ot11Nope);
// Token: 0x040000E8 RID: 232
public readonly VmInstrInfo Conv_ovf_i1_un_ = new VmInstrInfo(-1171707127, VmOperandType.Ot11Nope);
// Token: 0x040000EA RID: 234
public readonly VmInstrInfo Stsfld_ = new VmInstrInfo(-1272257470, VmOperandType.Ot5Int);
// Token: 0x040000EB RID: 235
public readonly VmInstrInfo Starg_ = new VmInstrInfo(-1559324355, VmOperandType.Ot1UShort);
// Token: 0x040000EC RID: 236
public readonly VmInstrInfo Ldflda_ = new VmInstrInfo(685223722, VmOperandType.Ot5Int);
// Token: 0x040000EE RID: 238
public readonly VmInstrInfo Sub_ = new VmInstrInfo(1925911547, VmOperandType.Ot11Nope);
// Token: 0x040000F0 RID: 240
public readonly VmInstrInfo Conv_ovf_i2_ = new VmInstrInfo(2079826493, VmOperandType.Ot11Nope);
// Token: 0x040000F1 RID: 241
public readonly VmInstrInfo Ldarg_0_ = new VmInstrInfo(-1817778622, VmOperandType.Ot11Nope);
// Token: 0x040000F2 RID: 242
public readonly VmInstrInfo Ldelem_i2_ = new VmInstrInfo(-1703864226, VmOperandType.Ot11Nope);
// Token: 0x040000F3 RID: 243
public readonly VmInstrInfo Ceq_ = new VmInstrInfo(-490385948, VmOperandType.Ot11Nope);
// Token: 0x040000F4 RID: 244
public readonly VmInstrInfo Ldelema_ = new VmInstrInfo(-659575843, VmOperandType.Ot5Int);
// Token: 0x040000F5 RID: 245
public readonly VmInstrInfo Localloc_ = new VmInstrInfo(487454996, VmOperandType.Ot11Nope);
// Token: 0x040000F6 RID: 246
public readonly VmInstrInfo Conv_ovf_i4_un_ = new VmInstrInfo(-900057353, VmOperandType.Ot11Nope);
// Token: 0x040000F7 RID: 247
public readonly VmInstrInfo Bge_un_ = new VmInstrInfo(784647969, VmOperandType.Ot0UInt);
// Token: 0x040000F8 RID: 248
public readonly VmInstrInfo Ldelem_ref_ = new VmInstrInfo(880972378, VmOperandType.Ot11Nope);
// Token: 0x040000FA RID: 250
public readonly VmInstrInfo Conv_ovf_i8_un_ = new VmInstrInfo(20637445, VmOperandType.Ot11Nope);
// Token: 0x040000FB RID: 251
public readonly VmInstrInfo Ldind_i8_ = new VmInstrInfo(-607543449, VmOperandType.Ot11Nope);
// Token: 0x040000FC RID: 252
public readonly VmInstrInfo Refanyval_ = new VmInstrInfo(1010177566, VmOperandType.Ot5Int);
// Token: 0x040000FE RID: 254
public readonly VmInstrInfo Dup_ = new VmInstrInfo(85722172, VmOperandType.Ot11Nope);
// Token: 0x040000FF RID: 255
public readonly VmInstrInfo Stloc_0_ = new VmInstrInfo(-1071153572, VmOperandType.Ot11Nope);
// Token: 0x04000100 RID: 256
public readonly VmInstrInfo Ldc_i4_4_ = new VmInstrInfo(-72363801, VmOperandType.Ot11Nope);
// Token: 0x04000101 RID: 257
public readonly VmInstrInfo Ldind_r8_ = new VmInstrInfo(813030660, VmOperandType.Ot11Nope);
// Token: 0x04000102 RID: 258
public readonly VmInstrInfo Ldc_i4_7_ = new VmInstrInfo(-1136876649, VmOperandType.Ot11Nope);
// Token: 0x04000103 RID: 259
public readonly VmInstrInfo Stelem_i8_ = new VmInstrInfo(588832478, VmOperandType.Ot11Nope);
// Token: 0x04000105 RID: 261
public readonly VmInstrInfo Mul_ovf_un_ = new VmInstrInfo(-356198078, VmOperandType.Ot11Nope);
// Token: 0x04000106 RID: 262
public readonly VmInstrInfo Conv_u_ = new VmInstrInfo(1795519976, VmOperandType.Ot11Nope);
// Token: 0x04000108 RID: 264
public readonly VmInstrInfo Ldelem_i_ = new VmInstrInfo(1499071663, VmOperandType.Ot11Nope);
// Token: 0x04000109 RID: 265
public readonly VmInstrInfo Ldarg_ = new VmInstrInfo(-1071239412, VmOperandType.Ot1UShort);
// Token: 0x0400010A RID: 266
public readonly VmInstrInfo Conv_r_un_ = new VmInstrInfo(-23925463, VmOperandType.Ot11Nope);
// Token: 0x0400010B RID: 267
public readonly VmInstrInfo Ldc_i4_8_ = new VmInstrInfo(1119515810, VmOperandType.Ot11Nope);
// Token: 0x0400010C RID: 268
public readonly VmInstrInfo Conv_i8_ = new VmInstrInfo(1980167243, VmOperandType.Ot11Nope);
// Token: 0x0400010D RID: 269
public readonly VmInstrInfo Ldloc_1_ = new VmInstrInfo(704985473, VmOperandType.Ot11Nope);
// Token: 0x0400010E RID: 270
public readonly VmInstrInfo Ldelem_u2_ = new VmInstrInfo(-1142530894, VmOperandType.Ot11Nope);
// Token: 0x0400010F RID: 271
public readonly VmInstrInfo Throw_ = new VmInstrInfo(-958454075, VmOperandType.Ot11Nope);
// Token: 0x04000110 RID: 272
public readonly VmInstrInfo Cpblk_ = new VmInstrInfo(-123910492, VmOperandType.Ot11Nope);
// Token: 0x04000111 RID: 273
public readonly VmInstrInfo Ldind_u1_ = new VmInstrInfo(1476085916, VmOperandType.Ot11Nope);
// Token: 0x04000113 RID: 275
public readonly VmInstrInfo Stloc_2_ = new VmInstrInfo(392938325, VmOperandType.Ot11Nope);
// Token: 0x04000114 RID: 276
public readonly VmInstrInfo Ldarg_3_ = new VmInstrInfo(-1756998893, VmOperandType.Ot11Nope);
// Token: 0x04000115 RID: 277
public readonly VmInstrInfo Stloc_ = new VmInstrInfo(1447397361, VmOperandType.Ot1UShort);
// Token: 0x04000117 RID: 279
public readonly VmInstrInfo Ldc_i4_5_ = new VmInstrInfo(-656328799, VmOperandType.Ot11Nope);
// Token: 0x04000118 RID: 280
public readonly VmInstrInfo Conv_ovf_u1_ = new VmInstrInfo(344575979, VmOperandType.Ot11Nope);
// Token: 0x0400011A RID: 282
public readonly VmInstrInfo Ldind_i4_ = new VmInstrInfo(234126039, VmOperandType.Ot11Nope);
// Token: 0x0400011B RID: 283
public readonly VmInstrInfo Switch_ = new VmInstrInfo(8625656, VmOperandType.Ot9IntArr);
// Token: 0x0400011C RID: 284
public readonly VmInstrInfo Arglist_ = new VmInstrInfo(1783361912, VmOperandType.Ot11Nope);
// Token: 0x0400011F RID: 287
public readonly VmInstrInfo Shr_un_ = new VmInstrInfo(897680915, VmOperandType.Ot11Nope);
// Token: 0x04000120 RID: 288
public readonly VmInstrInfo Ldloc_2_ = new VmInstrInfo(-17993965, VmOperandType.Ot11Nope);
// Token: 0x04000121 RID: 289
public readonly VmInstrInfo Conv_ovf_u4_ = new VmInstrInfo(1596489702, VmOperandType.Ot11Nope);
// Token: 0x04000122 RID: 290
public readonly VmInstrInfo Bge_ = new VmInstrInfo(-1225693454, VmOperandType.Ot0UInt);
// Token: 0x04000123 RID: 291
public readonly VmInstrInfo Ldloc_0_ = new VmInstrInfo(1021709264, VmOperandType.Ot11Nope);
// Token: 0x04000124 RID: 292
public readonly VmInstrInfo Bne_un_ = new VmInstrInfo(68951288, VmOperandType.Ot0UInt);
// Token: 0x04000126 RID: 294
public readonly VmInstrInfo Stelem_i2_ = new VmInstrInfo(1223054294, VmOperandType.Ot11Nope);
// Token: 0x04000127 RID: 295
public readonly VmInstrInfo Sub_ovf_un_ = new VmInstrInfo(-851734976, VmOperandType.Ot11Nope);
// Token: 0x04000128 RID: 296
public readonly VmInstrInfo Ret_ = new VmInstrInfo(1882847521, VmOperandType.Ot11Nope);
#endregion
}
public enum VmOperandType
{
Ot0UInt, Ot1UShort, Ot2Byte, Ot3UShort, Ot4Double, Ot5Int, Ot6SByte, Ot7Long, Ot8Byte, Ot9IntArr, Ot10Float, Ot11Nope, Ot12Int
}
// Token: 0x0200005F RID: 95
public class VmInstrInfo // \u000F\u2005
{
// Token: 0x06000377 RID: 887 RVA: 0x00015B74 File Offset: 0x00013D74
public VmInstrInfo(int id, VmOperandType operandType)
{
Id = id;
OperandType = operandType;
}
// Token: 0x06000378 RID: 888 RVA: 0x00015B8C File Offset: 0x00013D8C
// Token: 0x06000379 RID: 889 RVA: 0x00015B94 File Offset: 0x00013D94
// Token: 0x0400018F RID: 399
public int Id { get; }
// Token: 0x0600037A RID: 890 RVA: 0x00015BA0 File Offset: 0x00013DA0
// Token: 0x04000190 RID: 400
public VmOperandType OperandType { get; }
// Token: 0x0600037B RID: 891 RVA: 0x00015BA8 File Offset: 0x00013DA8
public override bool Equals(object o)
{
var p = o as VmInstrInfo;
return (p != null) && EqualTo(p);
}
// Token: 0x0600037C RID: 892 RVA: 0x00015BD0 File Offset: 0x00013DD0
private bool EqualTo(VmInstrInfo p)
{
return p.Id== Id;
}
// Token: 0x0600037D RID: 893 RVA: 0x00015BE0 File Offset: 0x00013DE0
public static bool operator ==(VmInstrInfo o1, VmInstrInfo o2)
{
// ReSharper disable once PossibleNullReferenceException
return o1.EqualTo(o2);
}
// Token: 0x0600037E RID: 894 RVA: 0x00015BEC File Offset: 0x00013DEC
public static bool operator !=(VmInstrInfo o1, VmInstrInfo o2)
{
return !(o1 == o2);
}
// Token: 0x0600037F RID: 895 RVA: 0x00015BF8 File Offset: 0x00013DF8
public override int GetHashCode()
{
return Id.GetHashCode();
}
// Token: 0x06000380 RID: 896 RVA: 0x00015C14 File Offset: 0x00013E14
public override string ToString()
{
return Id.ToString();
}
}
}

View File

@ -0,0 +1,42 @@
namespace UnitTestProject.RefVm
{
// Token: 0x02000028 RID: 40
public sealed class VmMethodHeader // \u0006
{
// Token: 0x06000120 RID: 288 RVA: 0x00005F08 File Offset: 0x00004108
// Token: 0x06000121 RID: 289 RVA: 0x00005F10 File Offset: 0x00004110
// Token: 0x04000047 RID: 71
public LocalVarType[] LocalVarTypes /* \u0003 */ { get; set; }
// Token: 0x06000122 RID: 290 RVA: 0x00005F1C File Offset: 0x0000411C
// Token: 0x06000123 RID: 291 RVA: 0x00005F24 File Offset: 0x00004124
// Token: 0x0400004B RID: 75
public ArgTypeToOutput[] ArgsTypeToOutput /* \u000E */ { get; set; }
// Token: 0x06000124 RID: 292 RVA: 0x00005F30 File Offset: 0x00004130
// Token: 0x06000125 RID: 293 RVA: 0x00005F38 File Offset: 0x00004138
// Token: 0x04000048 RID: 72
public string Name /* \u0002 */ { get; set; }
// Token: 0x06000126 RID: 294 RVA: 0x00005F44 File Offset: 0x00004144
// Token: 0x06000127 RID: 295 RVA: 0x00005F4C File Offset: 0x0000414C
// Token: 0x04000046 RID: 70
public int ClassId /* \u0002 */ { get; set; }
// Token: 0x06000128 RID: 296 RVA: 0x00005F58 File Offset: 0x00004158
// Token: 0x06000129 RID: 297 RVA: 0x00005F60 File Offset: 0x00004160
// Token: 0x04000049 RID: 73
public int ReturnTypeId /* \u0008 */ { get; set; }
// Token: 0x0600012A RID: 298 RVA: 0x00005F6C File Offset: 0x0000416C
// Token: 0x0600012B RID: 299 RVA: 0x00005F74 File Offset: 0x00004174
// Token: 0x0400004A RID: 74
public byte Flags /* \u0006 */ { private get; set; }
// Token: 0x0600012C RID: 300 RVA: 0x00005F80 File Offset: 0x00004180
public bool IsStatic() // \u0002
{
return (Flags & 2) > 0;
}
}
}

View File

@ -0,0 +1,96 @@
using System;
using System.IO;
namespace UnitTestProject.RefVm
{
internal static class VmPosParser // \u0006\u2006
{
// Token: 0x0600016A RID: 362 RVA: 0x00007810 File Offset: 0x00005A10
public static byte[] Parse(string pos) // dest
{
if (pos == null)
{
throw new Exception();
}
var memoryStream = new MemoryStream(pos.Length * 4 / 5);
byte[] result;
using(memoryStream)
{
var cnt = 0;
var val = 0u;
foreach (var c in pos)
{
if (c == 'z' && cnt == 0)
{
WriteDwPart(memoryStream, val, 0);
}
else
{
if (c< '!' || c> 'u')
{
throw new Exception();
}
checked
{
val += (uint)(Arr[cnt] * (ulong)checked(c - '!'));
}
cnt++;
if (cnt == 5)
{
WriteDwPart(memoryStream, val, 0);
cnt = 0;
val = 0u;
}
}
}
if (cnt == 1)
{
throw new Exception();
}
if (cnt > 1)
{
for (var j = cnt; j < 5; j++)
{
checked
{
val += 84u * Arr[j];
}
}
WriteDwPart(memoryStream, val, 5 - cnt);
}
result = memoryStream.ToArray();
}
return result;
}
// Token: 0x0600016B RID: 363 RVA: 0x00007900 File Offset: 0x00005B00
private static void WriteDwPart(Stream dest, uint val, int ignoreLow) // dest
{
dest.WriteByte((byte)(val >> 24));
if (ignoreLow == 3)
{
return;
}
dest.WriteByte((byte)(val >> 16 & 255u));
if (ignoreLow == 2)
{
return;
}
dest.WriteByte((byte)(val >> 8 & 255u));
if (ignoreLow == 1)
{
return;
}
dest.WriteByte((byte)(val & 255u));
}
// Token: 0x04000131 RID: 305
private static readonly uint[] Arr = {
52200625u,
614125u,
7225u,
85u,
1u
};
}
}

View File

@ -0,0 +1,116 @@
using System;
using System.IO;
namespace UnitTestProject.RefVm
{
// Token: 0x02000021 RID: 33
public sealed class VmStreamWrapper : Stream // \u0005\u2005
{
// Token: 0x060000CB RID: 203 RVA: 0x00004A20 File Offset: 0x00002C20
public VmStreamWrapper(Stream src, int xorKey)
{
SetStream(src);
_xorKey = xorKey;
}
// Token: 0x060000CC RID: 204 RVA: 0x00004A38 File Offset: 0x00002C38
public Stream GetStream() // \u0008\u2003\u2003\u2001\u2001\u2000\u2000\u2008\u2000\u2001\u2000\u2008\u200A\u2008\u200B\u2003\u200B
{
return _srcStream;
}
// Token: 0x060000CD RID: 205 RVA: 0x00004A40 File Offset: 0x00002C40
private void SetStream(Stream src) // \u0002
{
_srcStream = src;
}
// Token: 0x17000001 RID: 1
// (get) Token: 0x060000CE RID: 206 RVA: 0x00004A4C File Offset: 0x00002C4C
public override bool CanRead => GetStream().CanRead;
// Token: 0x17000002 RID: 2
// (get) Token: 0x060000CF RID: 207 RVA: 0x00004A5C File Offset: 0x00002C5C
public override bool CanSeek => GetStream().CanSeek;
// Token: 0x17000003 RID: 3
// (get) Token: 0x060000D0 RID: 208 RVA: 0x00004A6C File Offset: 0x00002C6C
public override bool CanWrite => GetStream().CanWrite;
// Token: 0x060000D1 RID: 209 RVA: 0x00004A7C File Offset: 0x00002C7C
public override void Flush()
{
GetStream().Flush();
}
// Token: 0x17000004 RID: 4
// (get) Token: 0x060000D2 RID: 210 RVA: 0x00004A8C File Offset: 0x00002C8C
public override long Length => GetStream().Length;
// Token: 0x17000005 RID: 5
// (get) Token: 0x060000D3 RID: 211 RVA: 0x00004A9C File Offset: 0x00002C9C
// (set) Token: 0x060000D4 RID: 212 RVA: 0x00004AAC File Offset: 0x00002CAC
public override long Position
{
get
{
return GetStream().Position;
}
set
{
GetStream().Position = value;
}
}
// Token: 0x060000D5 RID: 213 RVA: 0x00004ABC File Offset: 0x00002CBC
private byte Xor(byte data, long key2) // \u0002
{
var b = (byte)(_xorKey ^ -559030707 ^ (int)((uint)key2));
return (byte)(data ^ b);
}
// Token: 0x060000D6 RID: 214 RVA: 0x00004AE0 File Offset: 0x00002CE0
public override void Write(byte[] data, int offset, int size)
{
var array = new byte[size];
Buffer.BlockCopy(data, offset, array, 0, size);
var position = Position;
for (var i = 0; i < size; i++)
{
array[i] = Xor(array[i], position + i);
}
GetStream().Write(array, 0, size);
}
// Token: 0x060000D7 RID: 215 RVA: 0x00004B30 File Offset: 0x00002D30
public override int Read(byte[] data, int offset, int size)
{
var position = Position;
var array = new byte[size];
var num = GetStream().Read(array, 0, size);
for (var i = 0; i < num; i++)
{
data[i + offset] = Xor(array[i], position + i);
}
return num;
}
// Token: 0x060000D8 RID: 216 RVA: 0x00004B7C File Offset: 0x00002D7C
public override long Seek(long pos, SeekOrigin from)
{
return GetStream().Seek(pos, from);
}
// Token: 0x060000D9 RID: 217 RVA: 0x00004B8C File Offset: 0x00002D8C
public override void SetLength(long val)
{
GetStream().SetLength(val);
}
// Token: 0x0400002A RID: 42
private readonly int _xorKey; // \u0002
// Token: 0x0400002B RID: 43
private Stream _srcStream; // \u0003
}
}

View File

@ -0,0 +1,110 @@
using System;
using System.Net;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using VMProtect;
namespace UnitTestProject
{
[TestClass]
public class UnitTest1
{
[TestMethod]
// ReSharper disable once InconsistentNaming
public void TestRC5()
{
var key = CipherRC5.CreateRandomKey();
var rc5 = new CipherRC5(key);
var dataStr = "Тестовые данные для TestRC5";
var dataBytes = Encoding.UTF8.GetBytes(dataStr);
Array.Resize(ref dataBytes, (dataBytes.Length + 7)/8*8);
var encodedBytes = rc5.Encrypt(dataBytes);
var dataBytes2 = rc5.Decrypt(encodedBytes);
CollectionAssert.AreNotEqual(dataBytes, encodedBytes);
CollectionAssert.AreEqual(dataBytes, dataBytes2);
}
[TestMethod]
public void TestHwid()
{
var hwid = new HardwareID();
Assert.AreNotSame(0, hwid.ToString().Length);
var machine = Dns.GetHostName().ToUpperInvariant();
var txtHwid = hwid.ToString();
if (machine == "ACER-V3")
Assert.AreEqual("2D3kAD28P7M7soVoCjyOUA==", txtHwid);
else if (machine == "WORK")
Assert.AreEqual("AIUkDL3k4HTLFrVrPmOIpw==", txtHwid);
else if (machine == "BUILD7N1")
Assert.AreEqual("HBG8w5UkOMh714KeZow8vg==", txtHwid);
else
Assert.Fail("Append branch for machine '{0}' with result '{1}'", machine, txtHwid);
}
[TestMethod]
public void TestHwidCompare()
{
var hwid = new HardwareID();
var cur = hwid.GetBytes();
var test = new byte[cur.Length];
Array.Copy(cur, test, cur.Length);
// change one id
for (var i = 0; i < cur.Length; i += 4)
{
test[i] = cur[i];
switch (test[i] & 3) {
case 3:
test[i] ^= 4;
break;
}
}
Assert.IsTrue(hwid.IsCorrect(test));
// change two ids
Array.Copy(cur, test, cur.Length);
for (var i = 0; i < cur.Length; i += 4)
{
switch (test[i] & 3)
{
case 2:
case 3:
test[i] ^= 4;
break;
}
}
Assert.IsFalse(hwid.IsCorrect(test));
// change three ids
Array.Copy(cur, test, cur.Length);
for (var i = 0; i < cur.Length; i += 4)
{
switch (test[i] & 3)
{
case 2:
case 3:
test[i] ^= 4;
break;
}
}
Assert.IsFalse(hwid.IsCorrect(test));
// change cpu`s id
Array.Copy(cur, test, cur.Length);
for (var i = 0; i < cur.Length; i += 4)
{
switch (test[i] & 3)
{
case 0:
test[i] ^= 4;
break;
}
}
Assert.IsFalse(hwid.IsCorrect(test));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{85318BED-28D8-4B31-A7BA-9ED7882D11FC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>UnitTestProject</RootNamespace>
<AssemblyName>UnitTestProject</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<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>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="..\..\Crypto.cs">
<Link>CipherRC5.cs</Link>
</Compile>
<Compile Include="..\..\Core.cs">
<Link>Core.cs</Link>
</Compile>
<Compile Include="..\..\CpuId.cs">
<Link>CpuId.cs</Link>
</Compile>
<Compile Include="..\..\Faces.cs">
<Link>Faces.cs</Link>
</Compile>
<Compile Include="..\..\HardwareID.cs">
<Link>HardwareID.cs</Link>
</Compile>
<Compile Include="..\..\LicensingManager.cs">
<Link>LicensingManager.cs</Link>
</Compile>
<Compile Include="..\..\Loader.cs">
<Link>Loader.cs</Link>
</Compile>
<Compile Include="..\..\LzmaDecoder.cs">
<Link>LzmaDecoder.cs</Link>
</Compile>
<Compile Include="..\..\Numerics\BigInteger.cs">
<Link>Numerics\BigInteger.cs</Link>
</Compile>
<Compile Include="..\..\Numerics\BigIntegerBuilder.cs">
<Link>Numerics\BigIntegerBuilder.cs</Link>
</Compile>
<Compile Include="..\..\Numerics\NumericHelpers.cs">
<Link>Numerics\NumericHelpers.cs</Link>
</Compile>
<Compile Include="..\..\StringManager.cs">
<Link>StringManager.cs</Link>
</Compile>
<Compile Include="..\..\VirtualMachine.cs">
<Link>VirtualMachine.cs</Link>
</Compile>
<Compile Include="..\..\Win32.cs">
<Link>Win32.cs</Link>
</Compile>
<Compile Include="LicensingManagerTests.cs" />
<Compile Include="LoaderTests.cs" />
<Compile Include="MsilToVmTestCompiler.cs" />
<Compile Include="RefVm\ElementedTypeHelper.cs" />
<Compile Include="RefVm\MyBuffer.cs" />
<Compile Include="RefVm\MyBufferReader.cs" />
<Compile Include="RefVm\MyCollection.cs" />
<Compile Include="RefVm\SdMetadataTokens.cs" />
<Compile Include="RefVm\SdTemplateStuff.cs" />
<Compile Include="RefVm\SimpleTypeHelper.cs" />
<Compile Include="RefVm\StringDecryptor.cs" />
<Compile Include="RefVm\TypeCompatibility.cs" />
<Compile Include="RefVm\VariantBase.cs" />
<Compile Include="RefVm\VariantFactory.cs" />
<Compile Include="RefVm\VmExecutor.cs" />
<Compile Include="RefVm\VmInstrCodesDb.cs" />
<Compile Include="RefVm\VmMethodHeader.cs" />
<Compile Include="RefVm\VmPosParser.cs" />
<Compile Include="RefVm\VmStreamWrapper.cs" />
<Compile Include="UnitTest1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UnitTestCombine.cs" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Service References\" />
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
</When>
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{85318BED-28D8-4B31-A7BA-9ED7882D11FC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>UnitTestProject</RootNamespace>
<AssemblyName>UnitTestProject</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<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>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="..\..\CipherRC5.cs">
<Link>CipherRC5.cs</Link>
</Compile>
<Compile Include="..\..\Core.cs">
<Link>Core.cs</Link>
</Compile>
<Compile Include="..\..\CpuId.cs">
<Link>CpuId.cs</Link>
</Compile>
<Compile Include="..\..\CRC32.cs">
<Link>CRC32.cs</Link>
</Compile>
<Compile Include="..\..\Faces.cs">
<Link>Faces.cs</Link>
</Compile>
<Compile Include="..\..\HardwareID.cs">
<Link>HardwareID.cs</Link>
</Compile>
<Compile Include="..\..\LicensingManager.cs">
<Link>LicensingManager.cs</Link>
</Compile>
<Compile Include="..\..\Numerics\BigInteger.cs">
<Link>Numerics\BigInteger.cs</Link>
</Compile>
<Compile Include="..\..\Numerics\BigIntegerBuilder.cs">
<Link>Numerics\BigIntegerBuilder.cs</Link>
</Compile>
<Compile Include="..\..\Numerics\NumericHelpers.cs">
<Link>Numerics\NumericHelpers.cs</Link>
</Compile>
<Compile Include="..\..\StringManager.cs">
<Link>StringManager.cs</Link>
</Compile>
<Compile Include="..\..\Win32.cs">
<Link>Win32.cs</Link>
</Compile>
<Compile Include="LicensingManagerTests.cs" />
<Compile Include="UnitTest1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Service References\" />
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
</When>
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,65 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworks>netstandard2.1;netcoreapp3.0;net20;net40</TargetFrameworks>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net20' Or '$(TargetFramework)' == 'net40'">
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Security" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<Optimize>true</Optimize>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);TRACE;RUNTIME</DefineConstants>
<OutputPath>..\..\bin\32\Release\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Optimize>true</Optimize>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);TRACE;RUNTIME</DefineConstants>
<OutputPath>..\..\bin\64\Release\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<Optimize>true</Optimize>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);TRACE;DEBUG;RUNTIME</DefineConstants>
<OutputPath>..\..\bin\32\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Optimize>true</Optimize>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);TRACE;DEBUG;RUNTIME</DefineConstants>
<OutputPath>..\..\bin\64\Debug\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Tests\**" />
<Compile Remove="VMProtect.Netcore\**" />
<Compile Remove="VMProtect.Runtime.Netstandard\**" />
<EmbeddedResource Remove="Tests\**" />
<EmbeddedResource Remove="VMProtect.Netcore\**" />
<EmbeddedResource Remove="VMProtect.Runtime.Netstandard\**" />
<None Remove="Tests\**" />
<None Remove="VMProtect.Netcore\**" />
<None Remove="VMProtect.Runtime.Netstandard\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{946D07D4-1AE4-4FC3-9A8C-563B5F64B0B6}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>VMProtect.Runtime</RootNamespace>
<AssemblyName>VMProtect.Runtime</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\bin\32\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;RUNTIME;NETFRAMEWORK</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\bin\32\Release\</OutputPath>
<DefineConstants>TRACE;RUNTIME;NETFRAMEWORK</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\bin\64\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;RUNTIME;NETFRAMEWORK</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>..\..\bin\64\Release\</OutputPath>
<DefineConstants>TRACE;RUNTIME;NETFRAMEWORK</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Security" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="LzmaDecoder.cs" />
<Compile Include="Numerics\BigInteger.cs" />
<Compile Include="Numerics\BigIntegerBuilder.cs" />
<Compile Include="Crypto.cs" />
<Compile Include="Core.cs" />
<Compile Include="CpuId.cs" />
<Compile Include="Faces.cs" />
<Compile Include="HardwareID.cs" />
<Compile Include="LicensingManager.cs" />
<Compile Include="Loader.cs" />
<Compile Include="Numerics\NumericHelpers.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StringManager.cs" />
<Compile Include="VirtualMachine.cs" />
<Compile Include="Win32.cs" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,825 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
// ReSharper disable once CheckNamespace
namespace VMProtect
{
public enum MessageBoxButtons : uint
{
OK,
OKCancel,
AbortRetryIgnore,
YesNoCancel,
YesNo,
RetryCancel,
CancelTryAgainContinue
}
public enum MessageBoxIcon : uint
{
Asterisk = 0x40,
Error = 0x10,
Exclamation = 0x30,
Hand = 0x10,
Information = 0x40,
None = 0,
Question = 0x20,
Stop = 0x10,
Warning = 0x30,
UserIcon = 0x80
}
internal static class Win32
{
[Flags()]
public enum AllocationType : uint
{
Commit = 0x1000,
Reserve = 0x2000,
}
[Flags()]
public enum FreeType : uint
{
Release = 0x8000,
}
[Flags()]
public enum MemoryProtection : uint
{
NoAccess = 0x01,
ReadOnly = 0x02,
ReadWrite = 0x04,
WriteCopy = 0x08,
Execute = 0x10,
ExecuteRead = 0x20,
ExecuteReadWrite = 0x40,
Guard = 0x100
}
[Flags()]
public enum MapAccess : uint
{
Copy = 0x0001,
Write = 0x0002,
Read = 0x0004,
AllAccess = 0x001f
}
[Flags()]
public enum SectionType : uint
{
Execute = 0x20000000,
Read = 0x40000000,
Write = 0x80000000
}
[StructLayout(LayoutKind.Sequential)]
public struct UNICODE_STRING
{
public readonly ushort Length;
public readonly ushort MaximumLength;
private readonly IntPtr Buffer;
public UNICODE_STRING(string str)
{
if (str == null)
{
Length = 0;
MaximumLength = 0;
Buffer = IntPtr.Zero;
}
else
{
Length = (ushort)(str.Length * UnicodeEncoding.CharSize);
MaximumLength = (ushort)(Length + UnicodeEncoding.CharSize);
Buffer = Marshal.StringToHGlobalUni(str);
}
}
public void Dispose()
{
if (Buffer != IntPtr.Zero)
Marshal.FreeHGlobal(Buffer);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct OBJECT_ATTRIBUTES
{
public readonly uint Length;
public readonly IntPtr RootDirectory;
public readonly IntPtr ObjectName;
public readonly uint Attributes;
public readonly IntPtr SecurityDescriptor;
public readonly IntPtr SecurityQualityOfService;
public OBJECT_ATTRIBUTES(UNICODE_STRING name, uint attrs)
{
Length = (uint)Marshal.SizeOf(typeof(OBJECT_ATTRIBUTES));
RootDirectory = IntPtr.Zero;
ObjectName = IntPtr.Zero;
Attributes = attrs;
SecurityDescriptor = IntPtr.Zero;
SecurityQualityOfService = IntPtr.Zero;
ObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(name));
Marshal.StructureToPtr(name, ObjectName, false);
}
public void Dispose()
{
Marshal.FreeHGlobal(ObjectName);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct IO_STATUS_BLOCK
{
public uint Status;
public IntPtr Information;
}
[StructLayout(LayoutKind.Sequential)]
public struct LARGE_INTEGER
{
public uint LowPart;
public uint HighPart;
}
public enum HardErrorResponse
{
ReturnToCaller,
NotHandled,
Abort, Cancel,
Ignore,
No,
Ok,
Retry,
Yes
}
public enum Values : uint
{
GENERIC_READ = 0x80000000,
FILE_SHARE_READ = 0x00000001,
FILE_SHARE_WRITE = 0x00000002,
FILE_READ_ATTRIBUTES = 0x00000080,
SYNCHRONIZE = 0x00100000,
SECTION_QUERY = 0x0001,
SECTION_MAP_WRITE = 0x0002,
SECTION_MAP_READ = 0x0004,
SECTION_MAP_EXECUTE = 0x0008,
SEC_COMMIT = 0x8000000,
FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020,
FILE_NON_DIRECTORY_FILE = 0x00000040,
}
public static readonly IntPtr InvalidHandleValue = new IntPtr(-1);
public static readonly IntPtr NullHandle = IntPtr.Zero;
public static readonly IntPtr CurrentProcess = new IntPtr(-1);
public static readonly IntPtr CurrentThread = new IntPtr(-2);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtQueryInformationProcess(IntPtr ProcessHandle, PROCESSINFOCLASS ProcessInformationClass,
IntPtr ProcessInformation, int ProcessInformationLength, out uint ReturnLength);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtSetInformationThread(IntPtr ThreadHandle, THREADINFOCLASS ThreadInformationClass, IntPtr ThreadInformation,
uint ThreadInformationLength);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tEnumSystemFirmwareTables(uint firmwareTableProviderSignature, IntPtr firmwareTableBuffer, uint bufferSize);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tGetSystemFirmwareTable(uint firmwareTableProviderSignature, uint firmwareTableID, IntPtr firmwareTableBuffer, uint bufferSize);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtClose(IntPtr Handle);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtProtectVirtualMemory(IntPtr ProcesssHandle, ref IntPtr BaseAddress, ref UIntPtr RegionSize, MemoryProtection Protect, out MemoryProtection OldProtect);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtAllocateVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, ref UIntPtr RegionSize, AllocationType AllocationType, MemoryProtection Protect);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtFreeVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref UIntPtr RegionSize, FreeType FreeType);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtUnmapViewOfSection(IntPtr ProcessHandle, IntPtr BaseAddress);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate IntPtr tMapViewOfFile(IntPtr hFileMappingObject, MapAccess dwDesiredAccess, int dwFileOffsetHigh, int dwFileOffsetLow, IntPtr dwNumBytesToMap);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtRaiseHardError(uint ErrorStatus, uint NumberOfParameters, uint UnicodeStringParameterMask, IntPtr[] Parameters, uint ValidResponseOptions, out HardErrorResponse Response);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtOpenFile(out IntPtr FileHandle, uint DesiredAccess, ref OBJECT_ATTRIBUTES ObjectAttributes, out IO_STATUS_BLOCK IoStatusBlock, uint ShareAccess, uint OpenOptions);
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate uint tNtCreateSection(out IntPtr SectionHandle, uint DesiredAccess, ref OBJECT_ATTRIBUTES ObjectAttributes, ref LARGE_INTEGER MaximumSize, MemoryProtection SectionPageProtection, uint AllocationAttributes, IntPtr FileHandle);
private static IntPtr _ntdll;
private static tNtQueryInformationProcess _nt_query_information_process;
private static tNtSetInformationThread _nt_set_information_thread;
private static tNtClose _nt_close;
private static tNtProtectVirtualMemory _nt_protect_virtual_memory;
private static tNtAllocateVirtualMemory _nt_allocate_virtual_memory;
private static tNtFreeVirtualMemory _nt_free_virtual_memory;
private static tNtUnmapViewOfSection _nt_unmap_view_of_section;
private static tNtRaiseHardError _nt_raise_hard_error;
private static tNtOpenFile _nt_open_file;
private static tNtCreateSection _nt_create_section;
private static IntPtr _kernel32;
private static tEnumSystemFirmwareTables _enum_system_firmware_tables;
private static tGetSystemFirmwareTable _get_system_firmware_table;
private static tMapViewOfFile _map_view_of_file;
static Win32()
{
_ntdll = GetModuleHandleEnc((uint)Faces.NTDLL_NAME);
_nt_query_information_process = (tNtQueryInformationProcess)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_QUERY_INFORMATION_PROCESS_NAME), typeof(tNtQueryInformationProcess));
_nt_set_information_thread = (tNtSetInformationThread)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_SET_INFORMATION_THREAD_NAME), typeof(tNtSetInformationThread));
_nt_close = (tNtClose)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_CLOSE), typeof(tNtClose));
_nt_protect_virtual_memory = (tNtProtectVirtualMemory)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_VIRTUAL_PROTECT_NAME), typeof(tNtProtectVirtualMemory));
_nt_allocate_virtual_memory = (tNtAllocateVirtualMemory)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_ALLOCATE_VIRTUAL_MEMORY_NAME), typeof(tNtAllocateVirtualMemory));
_nt_free_virtual_memory = (tNtFreeVirtualMemory)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_FREE_VIRTUAL_MEMORY_NAME), typeof(tNtFreeVirtualMemory));
_nt_unmap_view_of_section = (tNtUnmapViewOfSection)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_UNMAP_VIEW_OF_SECTION), typeof(tNtUnmapViewOfSection));
_nt_raise_hard_error = (tNtRaiseHardError)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_RAISE_HARD_ERROR_NAME), typeof(tNtRaiseHardError));
_nt_open_file = (tNtOpenFile)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_OPEN_FILE_NAME), typeof(tNtOpenFile));
_nt_create_section = (tNtCreateSection)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_ntdll, (uint)Faces.NT_CREATE_SECTION_NAME), typeof(tNtCreateSection));
_kernel32 = GetModuleHandleEnc((uint)Faces.KERNEL32_NAME);
IntPtr proc = GetProcAddressEnc(_kernel32, (uint)Faces.ENUM_SYSTEM_FIRMWARE_NAME);
if (proc != IntPtr.Zero)
_enum_system_firmware_tables = (tEnumSystemFirmwareTables)Marshal.GetDelegateForFunctionPointer(proc, typeof(tEnumSystemFirmwareTables));
proc = GetProcAddressEnc(_kernel32, (uint)Faces.GET_SYSTEM_FIRMWARE_NAME);
if (proc != IntPtr.Zero)
_get_system_firmware_table = (tGetSystemFirmwareTable)Marshal.GetDelegateForFunctionPointer(proc, typeof(tGetSystemFirmwareTable));
_map_view_of_file = (tMapViewOfFile)Marshal.GetDelegateForFunctionPointer(GetProcAddressEnc(_kernel32, (uint)Faces.NT_MAP_VIEW_OF_SECTION), typeof(tMapViewOfFile));
}
internal static IntPtr GetModuleHandleEnc(uint position)
{
long instance = Marshal.GetHINSTANCE(typeof(Loader).Module).ToInt64();
var buffer = new byte[100];
for (var pos = 0; pos < buffer.Length; pos++)
{
var c = (byte)(Marshal.ReadByte(new IntPtr(instance + position + pos)) ^ (BitRotate.Left((uint)Faces.STRING_DECRYPT_KEY, pos) + pos));
if (c == 0)
{
if (pos > 0)
return Win32.GetModuleHandle(Encoding.ASCII.GetString(buffer, 0, pos));
break;
}
buffer[pos] = c;
}
return IntPtr.Zero;
}
[DllImport("kernel32", SetLastError = true)]
public static extern uint GetFileSize(IntPtr handle, IntPtr lpFileSizeHigh);
[DllImport("kernel32", SetLastError = true)]
public static extern bool GetVolumeInformation(
string pathName,
StringBuilder volumeNameBuffer,
uint volumeNameSize,
ref uint volumeSerialNumber,
ref uint maximumComponentLength,
ref uint fileSystemFlags,
StringBuilder fileSystemNameBuffer,
uint fileSystemNameSize);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(String lpModuleName);
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_BASIC_INFORMATION
{
public IntPtr Reserved1;
public IntPtr PebBaseAddress;
public IntPtr Reserved2_0;
public IntPtr Reserved2_1;
public IntPtr UniqueProcessId;
public IntPtr InheritedFromUniqueProcessId;
}
public enum PROCESSINFOCLASS
{
ProcessBasicInformation = 0x00,
ProcessDebugPort = 0x07,
ProcessDebugObjectHandle = 0x1e
}
public enum THREADINFOCLASS
{
ThreadHideFromDebugger = 0x11
}
internal static IntPtr GetProcAddress(IntPtr module, object proc_name)
{
if (module == IntPtr.Zero || proc_name == null)
return IntPtr.Zero;
unsafe
{
byte* ptr = (byte*)module.ToPointer();
PE.IMAGE_DOS_HEADER* dos_header = (PE.IMAGE_DOS_HEADER*)ptr;
if (dos_header->e_magic != PE.IMAGE_DOS_SIGNATURE)
return IntPtr.Zero;
PE.IMAGE_NT_HEADERS* pe_header = (PE.IMAGE_NT_HEADERS*)(ptr + dos_header->e_lfanew);
if (pe_header->Signature != PE.IMAGE_NT_SIGNATURE)
return IntPtr.Zero;
if (pe_header->FileHeader.SizeOfOptionalHeader == 0)
return IntPtr.Zero;
PE.IMAGE_DATA_DIRECTORY* export_table;
byte* optional_header = (byte*)pe_header + Marshal.SizeOf(typeof(PE.IMAGE_NT_HEADERS));
switch (*(UInt16*)(optional_header))
{
case PE.IMAGE_NT_OPTIONAL_HDR32_MAGIC:
export_table = &((PE.IMAGE_OPTIONAL_HEADER32*)(optional_header))->ExportTable;
break;
case PE.IMAGE_NT_OPTIONAL_HDR64_MAGIC:
export_table = &((PE.IMAGE_OPTIONAL_HEADER64*)(optional_header))->ExportTable;
break;
default:
return IntPtr.Zero;
}
if (export_table->VirtualAddress == 0)
return IntPtr.Zero;
uint address = 0;
PE.IMAGE_EXPORT_DIRECTORY* export_directory = (PE.IMAGE_EXPORT_DIRECTORY*)(ptr + export_table->VirtualAddress);
if (proc_name is string)
{
string name = (string)proc_name;
if (export_directory->NumberOfNames > 0)
{
int left_index = 0;
int right_index = (int)export_directory->NumberOfNames - 1;
uint* names = (UInt32*)(ptr + export_directory->AddressOfNames);
while (left_index <= right_index)
{
int cur_index = (left_index + right_index) >> 1;
int cmp = String.CompareOrdinal(name, Marshal.PtrToStringAnsi(new IntPtr(module.ToInt64() + names[cur_index])));
if (cmp < 0)
right_index = cur_index - 1;
else if (cmp > 0)
left_index = cur_index + 1;
else
{
uint ordinal_index = ((UInt16*)(ptr + export_directory->AddressOfNameOrdinals))[cur_index];
if (ordinal_index < export_directory->NumberOfFunctions)
address = ((UInt32*)(ptr + export_directory->AddressOfFunctions))[ordinal_index];
break;
}
}
}
}
else
{
uint ordinal_index = System.Convert.ToUInt32(proc_name) - export_directory->Base;
if (ordinal_index < export_directory->NumberOfFunctions)
address = ((UInt32*)(ptr + export_directory->AddressOfFunctions))[ordinal_index];
}
if (address == 0)
return IntPtr.Zero;
if (address < export_table->VirtualAddress || address >= export_table->VirtualAddress + export_table->Size)
return new IntPtr(module.ToInt64() + address);
string forwarded_name = Marshal.PtrToStringAnsi(new IntPtr(module.ToInt64() + address));
int dot_pos = forwarded_name.IndexOf('.');
if (dot_pos > 0)
{
IntPtr forwarded_module = Win32.GetModuleHandle(forwarded_name.Substring(0, dot_pos));
if (forwarded_name[dot_pos + 1] == '#')
{
uint ordinal;
if (UInt32.TryParse(forwarded_name.Substring(dot_pos + 2), out ordinal))
return GetProcAddress(forwarded_module, ordinal);
}
else
return GetProcAddress(forwarded_module, forwarded_name.Substring(dot_pos + 1));
}
}
return IntPtr.Zero;
}
internal static IntPtr GetProcAddressEnc(IntPtr module, uint position)
{
long instance = Marshal.GetHINSTANCE(typeof(Loader).Module).ToInt64();
var buffer = new byte[100];
for (var pos = 0; pos < buffer.Length; pos++)
{
var c = (byte)(Marshal.ReadByte(new IntPtr(instance + position + pos)) ^ (BitRotate.Left((uint)Faces.STRING_DECRYPT_KEY, pos) + pos));
if (c == 0)
{
if (pos > 0)
return GetProcAddress(module, Encoding.ASCII.GetString(buffer, 0, pos));
break;
}
buffer[pos] = c;
}
return IntPtr.Zero;
}
public static uint NtQueryInformationProcess(IntPtr processHandle, Win32.PROCESSINFOCLASS processInformationClass,
out object processInformation, int processInformationLength, out uint returnLength)
{
IntPtr mem = Marshal.AllocHGlobal(processInformationLength);
uint res = _nt_query_information_process(processHandle, processInformationClass, mem, processInformationLength, out returnLength);
if (res == 0)
{
Type type;
switch (processInformationClass)
{
case Win32.PROCESSINFOCLASS.ProcessBasicInformation:
type = typeof(Win32.PROCESS_BASIC_INFORMATION);
break;
case Win32.PROCESSINFOCLASS.ProcessDebugPort:
case Win32.PROCESSINFOCLASS.ProcessDebugObjectHandle:
type = typeof(IntPtr);
break;
default:
type = null;
break;
}
processInformation = Marshal.PtrToStructure(mem, type);
}
else
processInformation = null;
Marshal.FreeHGlobal(mem);
return res;
}
public static uint NtSetInformationThread(IntPtr ThreadHandle, Win32.THREADINFOCLASS ThreadInformationClass, IntPtr ThreadInformation, uint ThreadInformationLength)
{
return _nt_set_information_thread(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength);
}
public static uint EnumSystemFirmwareTables(uint firmwareTableProviderSignature, IntPtr firmwareTableBuffer, uint bufferSize)
{
return _enum_system_firmware_tables(firmwareTableProviderSignature, firmwareTableBuffer, bufferSize);
}
public static uint GetSystemFirmwareTable(uint firmwareTableProviderSignature, uint firmwareTableID, IntPtr firmwareTableBuffer, uint bufferSize)
{
return _get_system_firmware_table(firmwareTableProviderSignature, firmwareTableID, firmwareTableBuffer, bufferSize);
}
public static bool CloseHandle(IntPtr handle)
{
return (_nt_close(handle) == 0);
}
public static IntPtr OpenFile(String FileName, uint DesiredAccess, uint ShareMode)
{
char[] preffix;
if (FileName[0] == '\\' && FileName[1] == '\\')
{
preffix = new char[7];
preffix[0] = '\\';
preffix[1] = '?';
preffix[2] = '?';
preffix[3] = '\\';
preffix[4] = 'U';
preffix[5] = 'N';
preffix[6] = 'C';
}
else
{
preffix = new char[4];
preffix[0] = '\\';
preffix[1] = '?';
preffix[2] = '?';
preffix[3] = '\\';
}
var str = new UNICODE_STRING(new string(preffix) + FileName);
var objectAttributes = new OBJECT_ATTRIBUTES(str, 0);
try
{
IntPtr res;
IO_STATUS_BLOCK io_status_block;
if (_nt_open_file(out res, DesiredAccess | (uint)Values.SYNCHRONIZE | (uint)Values.FILE_READ_ATTRIBUTES, ref objectAttributes, out io_status_block, ShareMode, (uint)Values.FILE_SYNCHRONOUS_IO_NONALERT | (uint)Values.FILE_NON_DIRECTORY_FILE) == 0)
return res;
}
finally
{
str.Dispose();
objectAttributes.Dispose();
}
return InvalidHandleValue;
}
public static bool VirtualProtect(IntPtr BaseAddress, UIntPtr RegionSize, MemoryProtection Protect, out MemoryProtection OldProtect)
{
return (_nt_protect_virtual_memory(CurrentProcess, ref BaseAddress, ref RegionSize, Protect, out OldProtect) == 0);
}
public static IntPtr VirtualAlloc(IntPtr BaseAddress, UIntPtr RegionSize, AllocationType AllocationType, MemoryProtection Protect)
{
if (_nt_allocate_virtual_memory(CurrentProcess, ref BaseAddress, IntPtr.Zero, ref RegionSize, AllocationType, Protect) == 0)
return BaseAddress;
return IntPtr.Zero;
}
public static bool VirtualFree(IntPtr BaseAddress, UIntPtr RegionSize, FreeType FreeType)
{
return (_nt_free_virtual_memory(CurrentProcess, ref BaseAddress, ref RegionSize, FreeType) == 0);
}
public static IntPtr CreateFileMapping(IntPtr FileHandle, IntPtr Attributes, MemoryProtection Protect, uint MaximumSizeLow, uint MaximumSizeHigh, String Name)
{
uint desiredAccess = (uint)Values.SECTION_MAP_READ;
if (Protect == MemoryProtection.ReadWrite)
desiredAccess |= (uint)Values.SECTION_MAP_WRITE;
else if (Protect == MemoryProtection.ExecuteReadWrite)
desiredAccess |= (uint)Values.SECTION_MAP_WRITE | (uint)Values.SECTION_MAP_EXECUTE;
else if (Protect == MemoryProtection.ExecuteRead)
desiredAccess |= (uint)Values.SECTION_MAP_EXECUTE;
IntPtr res;
var str = new UNICODE_STRING(null);
var objectAttributes = new OBJECT_ATTRIBUTES(str, 0);
try
{
var size = new LARGE_INTEGER();
size.LowPart = MaximumSizeLow;
size.HighPart = MaximumSizeHigh;
if (_nt_create_section(out res, desiredAccess, ref objectAttributes, ref size, Protect, (uint)Values.SEC_COMMIT, FileHandle) == 0)
return res;
}
finally
{
str.Dispose();
objectAttributes.Dispose();
}
return NullHandle;
}
public static IntPtr MapViewOfFile(IntPtr hFileMappingObject, MapAccess dwDesiredAccess, int dwFileOffsetHigh, int dwFileOffsetLow, IntPtr dwNumBytesToMap)
{
return _map_view_of_file(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumBytesToMap);
}
public static bool UnmapViewOfFile(IntPtr BaseAddress)
{
return (_nt_unmap_view_of_section(CurrentProcess, BaseAddress) == 0);
}
public static bool IsDebuggerPresent()
{
object obj;
if (NtQueryInformationProcess(CurrentProcess, PROCESSINFOCLASS.ProcessBasicInformation, out obj, Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)), out _) == 0)
{
if (Marshal.ReadByte(new IntPtr(((PROCESS_BASIC_INFORMATION)obj).PebBaseAddress.ToInt64() + 2)) != 0) // PEB.BeingDebugged
return true;
}
return false;
}
public static bool CheckRemoteDebuggerPresent()
{
object obj;
if (NtQueryInformationProcess(CurrentProcess, PROCESSINFOCLASS.ProcessDebugPort, out obj, IntPtr.Size, out _) == 0)
{
if ((IntPtr)obj != IntPtr.Zero)
return true;
}
if (NtQueryInformationProcess(CurrentProcess, PROCESSINFOCLASS.ProcessDebugObjectHandle, out _, IntPtr.Size, out _) == 0)
return true;
return false;
}
public static void ShowMessage(string Text, string Caption, MessageBoxButtons Buttons, MessageBoxIcon Icon)
{
IntPtr[] p = new IntPtr[4];
var strText = new UNICODE_STRING(Text);
var strCaption = new UNICODE_STRING(Caption);
p[0] = Marshal.AllocHGlobal(Marshal.SizeOf(strText));
p[1] = Marshal.AllocHGlobal(Marshal.SizeOf(strCaption));
try
{
Marshal.StructureToPtr(strText, p[0], false);
Marshal.StructureToPtr(strCaption, p[1], false);
p[2] = new IntPtr((uint)Buttons | (uint)Icon);
p[3] = new IntPtr(-1);
_nt_raise_hard_error(0x40000018 | 0x10000000, 4, 3, p, 0, out _);
}
finally
{
strText.Dispose();
strCaption.Dispose();
Marshal.FreeHGlobal(p[0]);
Marshal.FreeHGlobal(p[1]);
}
}
}
internal class PE
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_DOS_HEADER
{
public UInt16 e_magic;
public UInt16 e_cblp;
public UInt16 e_cp;
public UInt16 e_crlc;
public UInt16 e_cparhdr;
public UInt16 e_minalloc;
public UInt16 e_maxalloc;
public UInt16 e_ss;
public UInt16 e_sp;
public UInt16 e_csum;
public UInt16 e_ip;
public UInt16 e_cs;
public UInt16 e_lfarlc;
public UInt16 e_ovno;
public UInt16 e_res_0;
public UInt16 e_res_1;
public UInt16 e_res_2;
public UInt16 e_res_3;
public UInt16 e_oemid;
public UInt16 e_oeminfo;
public UInt16 e_res2_0;
public UInt16 e_res2_1;
public UInt16 e_res2_2;
public UInt16 e_res2_3;
public UInt16 e_res2_4;
public UInt16 e_res2_5;
public UInt16 e_res2_6;
public UInt16 e_res2_7;
public UInt16 e_res2_8;
public UInt16 e_res2_9;
public UInt32 e_lfanew;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_FILE_HEADER
{
public UInt16 Machine;
public UInt16 NumberOfSections;
public UInt32 TimeDateStamp;
public UInt32 PointerToSymbolTable;
public UInt32 NumberOfSymbols;
public UInt16 SizeOfOptionalHeader;
public UInt16 Characteristics;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_NT_HEADERS
{
public UInt32 Signature;
public IMAGE_FILE_HEADER FileHeader;
//IMAGE_OPTIONAL_HEADER OptionalHeader;
}
public const UInt16 IMAGE_DOS_SIGNATURE = 0x5A4D;
public const UInt32 IMAGE_NT_SIGNATURE = 0x00004550;
public const UInt16 IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b;
public const UInt16 IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_DATA_DIRECTORY
{
public UInt32 VirtualAddress;
public UInt32 Size;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_OPTIONAL_HEADER32
{
public UInt16 Magic;
public Byte MajorLinkerVersion;
public Byte MinorLinkerVersion;
public UInt32 SizeOfCode;
public UInt32 SizeOfInitializedData;
public UInt32 SizeOfUninitializedData;
public UInt32 AddressOfEntryPoint;
public UInt32 BaseOfCode;
public UInt32 BaseOfData;
public UInt32 ImageBase;
public UInt32 SectionAlignment;
public UInt32 FileAlignment;
public UInt16 MajorOperatingSystemVersion;
public UInt16 MinorOperatingSystemVersion;
public UInt16 MajorImageVersion;
public UInt16 MinorImageVersion;
public UInt16 MajorSubsystemVersion;
public UInt16 MinorSubsystemVersion;
public UInt32 Win32VersionValue;
public UInt32 SizeOfImage;
public UInt32 SizeOfHeaders;
public UInt32 CheckSum;
public UInt16 Subsystem;
public UInt16 DllCharacteristics;
public UInt32 SizeOfStackReserve;
public UInt32 SizeOfStackCommit;
public UInt32 SizeOfHeapReserve;
public UInt32 SizeOfHeapCommit;
public UInt32 LoaderFlags;
public UInt32 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, Pack = 1)]
public struct IMAGE_OPTIONAL_HEADER64
{
public UInt16 Magic;
public Byte MajorLinkerVersion;
public Byte MinorLinkerVersion;
public UInt32 SizeOfCode;
public UInt32 SizeOfInitializedData;
public UInt32 SizeOfUninitializedData;
public UInt32 AddressOfEntryPoint;
public UInt32 BaseOfCode;
public UInt64 ImageBase;
public UInt32 SectionAlignment;
public UInt32 FileAlignment;
public UInt16 MajorOperatingSystemVersion;
public UInt16 MinorOperatingSystemVersion;
public UInt16 MajorImageVersion;
public UInt16 MinorImageVersion;
public UInt16 MajorSubsystemVersion;
public UInt16 MinorSubsystemVersion;
public UInt32 Win32VersionValue;
public UInt32 SizeOfImage;
public UInt32 SizeOfHeaders;
public UInt32 CheckSum;
public UInt16 Subsystem;
public UInt16 DllCharacteristics;
public UInt64 SizeOfStackReserve;
public UInt64 SizeOfStackCommit;
public UInt64 SizeOfHeapReserve;
public UInt64 SizeOfHeapCommit;
public UInt32 LoaderFlags;
public UInt32 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)]
public struct IMAGE_EXPORT_DIRECTORY
{
public UInt32 Characteristics;
public UInt32 TimeDateStamp;
public UInt16 MajorVersion;
public UInt16 MinorVersion;
public UInt32 Name;
public UInt32 Base;
public UInt32 NumberOfFunctions;
public UInt32 NumberOfNames;
public UInt32 AddressOfFunctions;
public UInt32 AddressOfNames;
public UInt32 AddressOfNameOrdinals;
}
}
}

291
runtime/common.h Normal file
View File

@ -0,0 +1,291 @@
#ifndef COMMON_H
#define COMMON_H
#ifdef VMP_GNU
#define VMP_IMPORT
#else
#define VMP_IMPORT __declspec(dllimport)
#ifdef WIN_DRIVER
#ifdef _WIN64
#pragma comment(lib, "../bin/64/Driver/VMProtectDDK64.lib")
#else
#pragma comment(lib, "../bin/32/Driver/VMProtectDDK32.lib")
#endif // _WIN64
#else
#ifdef _WIN64
#ifdef NDEBUG
#pragma comment(lib, "../bin/64/Release/VMProtectSDK64.lib")
#else
#pragma comment(lib, "../bin/64/Debug/VMProtectSDK64.lib")
#endif
#else
#ifdef NDEBUG
#pragma comment(lib, "../bin/32/Release/VMProtectSDK32.lib")
#else
#pragma comment(lib, "../bin/32/Debug/VMProtectSDK32.lib")
#endif
#endif // _WIN64
#endif // WIN_DRIVER
#endif // VMP_GNU
#include "../sdk/sdk.h"
const size_t NOT_ID = (size_t)-1;
enum {
MESSAGE_DEBUGGER_FOUND,
MESSAGE_VIRTUAL_MACHINE_FOUND,
MESSAGE_FILE_CORRUPTED,
MESSAGE_SERIAL_NUMBER_REQUIRED,
MESSAGE_HWID_MISMATCHED,
MESSAGE_COUNT
};
#ifdef VMP_GNU
#define VMP_STR(s) s
#else
#define VMP_STR(s) L##s
#endif
#define MESSAGE_DEBUGGER_FOUND_STR VMP_STR("A debugger has been found running in your system.\nPlease, unload it from memory and restart your program.")
#define MESSAGE_VIRTUAL_MACHINE_FOUND_STR VMP_STR("Sorry, this application cannot run under a Virtual Machine.")
#define MESSAGE_FILE_CORRUPTED_STR VMP_STR("File corrupted! This program has been manipulated and maybe\nit's infected by a Virus or cracked. This file won't work anymore.")
#define MESSAGE_SERIAL_NUMBER_REQUIRED_STR VMP_STR("This code requires valid serial number to run.\nProgram will be terminated.")
#define MESSAGE_HWID_MISMATCHED_STR VMP_STR("This application cannot be executed on this computer.")
#define MESSAGE_UNREGISTERED_VERSION_STR VMP_STR("This application is protected with unregistered version of VMProtect and cannot be executed on this computer.")
enum {
VAR_IS_PATCH_DETECTED,
VAR_IS_DEBUGGER_DETECTED,
VAR_LOADER_CRC_INFO,
VAR_LOADER_CRC_INFO_SIZE,
VAR_LOADER_CRC_INFO_HASH,
VAR_SESSION_KEY,
VAR_DRIVER_UNLOAD,
VAR_CRC_IMAGE_SIZE,
VAR_LOADER_STATUS,
VAR_SERVER_DATE,
VAR_OS_BUILD_NUMBER,
VAR_CPU_COUNT,
VAR_CPU_HASH,
VAR_COUNT = VAR_CPU_HASH + 32
};
enum {
FACE_MASK = 0xFACE0000U,
FACE_RC5_P,
FACE_RC5_Q,
FACE_STRING_INFO,
FACE_RESOURCE_INFO,
FACE_STORAGE_INFO,
FACE_REGISTRY_INFO,
FACE_LICENSE_INFO,
FACE_LICENSE_INFO_SIZE,
FACE_KEY_INFO,
FACE_RUNTIME_ENTRY,
FACE_CRC_INFO_SALT,
FACE_CRC_TABLE_ENTRY,
FACE_CRC_TABLE_SIZE,
FACE_CRC_TABLE_HASH,
FACE_TRIAL_HWID,
FACE_TRIAL_HWID_SIZE,
FACE_CORE_OPTIONS,
FACE_IMAGE_BASE,
FACE_FILE_BASE,
FACE_NTOSKRNL_NAME,
FACE_HAL_NAME,
FACE_USER32_NAME,
FACE_MESSAGE_BOX_NAME,
FACE_KERNEL32_NAME,
FACE_CREATE_FILE_NAME,
FACE_CLOSE_HANDLE_NAME,
FACE_INITIALIZATION_ERROR,
FACE_PROC_NOT_FOUND,
FACE_ORDINAL_NOT_FOUND,
FACE_STRING_DECRYPT_KEY,
FACE_DRIVER_FORMAT_VALUE,
FACE_FILE_CORRUPTED,
FACE_LOADER_OPTIONS,
FACE_LOADER_DATA,
FACE_DEBUGGER_FOUND,
FACE_NT_SET_INFORMATION_PROCESS_NAME,
FACE_NT_RAISE_HARD_ERROR_NAME,
FACE_IS_WOW64_PROCESS_NAME,
FACE_WINE_GET_VERSION_NAME,
FACE_MACOSX_FORMAT_VALUE,
FACE_GNU_PTRACE,
FACE_UNREGISTERED_VERSION,
FACE_WTSAPI32_NAME,
FACE_WTS_SEND_MESSAGE_NAME,
FACE_NTDLL_NAME,
FACE_NT_QUERY_INFORMATION_NAME,
FACE_NT_SET_INFORMATION_THREAD_NAME,
FACE_SICE_NAME,
FACE_SIWVID_NAME,
FACE_NTICE_NAME,
FACE_ICEEXT_NAME,
FACE_SYSER_NAME,
FACE_VIRTUAL_MACHINE_FOUND,
FACE_SBIEDLL_NAME,
FACE_QUERY_VIRTUAL_MEMORY_NAME,
FACE_ENUM_SYSTEM_FIRMWARE_NAME,
FACE_GET_SYSTEM_FIRMWARE_NAME,
FACE_NT_QUERY_INFORMATION_PROCESS_NAME,
FACE_NT_VIRTUAL_PROTECT_NAME,
FACE_NT_OPEN_FILE_NAME,
FACE_NT_CREATE_SECTION_NAME,
FACE_NT_OPEN_SECTION_NAME,
FACE_NT_MAP_VIEW_OF_SECTION,
FACE_NT_UNMAP_VIEW_OF_SECTION,
FACE_NT_CLOSE,
FACE_SYSCALL,
FACE_NT_ALLOCATE_VIRTUAL_MEMORY_NAME,
FACE_NT_FREE_VIRTUAL_MEMORY_NAME,
FACE_PACKER_INFO = 0xFACE0100U,
FACE_PACKER_INFO_SIZE,
FACE_FILE_CRC_INFO,
FACE_FILE_CRC_INFO_SIZE,
FACE_LOADER_CRC_INFO,
FACE_LOADER_CRC_INFO_SIZE,
FACE_SECTION_INFO,
FACE_SECTION_INFO_SIZE,
FACE_FIXUP_INFO,
FACE_FIXUP_INFO_SIZE,
FACE_RELOCATION_INFO,
FACE_RELOCATION_INFO_SIZE,
FACE_IAT_INFO,
FACE_IAT_INFO_SIZE,
FACE_IMPORT_INFO,
FACE_IMPORT_INFO_SIZE,
FACE_INTERNAL_IMPORT_INFO,
FACE_INTERNAL_IMPORT_INFO_SIZE,
FACE_MEMORY_CRC_INFO,
FACE_MEMORY_CRC_INFO_SIZE,
FACE_DELAY_IMPORT_INFO,
FACE_DELAY_IMPORT_INFO_SIZE,
FACE_LOADER_CRC_INFO_HASH,
FACE_MEMORY_CRC_INFO_HASH,
FACE_TLS_INDEX_INFO,
FACE_GNU_RELRO_INFO,
FACE_NON_PAGED_POOL_NX,
FACE_DEFAULT_MDL_PRIORITY,
FACE_VAR = 0xFACE0200U,
FACE_VAR_IS_PATCH_DETECTED = FACE_VAR | (VAR_IS_PATCH_DETECTED << 4),
FACE_VAR_IS_DEBUGGER_DETECTED = FACE_VAR | (VAR_IS_DEBUGGER_DETECTED << 4),
FACE_VAR_LOADER_CRC_INFO = FACE_VAR | (VAR_LOADER_CRC_INFO << 4),
FACE_VAR_LOADER_CRC_INFO_SIZE = FACE_VAR | (VAR_LOADER_CRC_INFO_SIZE << 4),
FACE_VAR_LOADER_CRC_INFO_HASH = FACE_VAR | (VAR_LOADER_CRC_INFO_HASH << 4),
FACE_VAR_SESSION_KEY = FACE_VAR | (VAR_SESSION_KEY << 4),
FACE_VAR_DRIVER_UNLOAD = FACE_VAR | (VAR_DRIVER_UNLOAD << 4),
FACE_VAR_CRC_IMAGE_SIZE = FACE_VAR | (VAR_CRC_IMAGE_SIZE << 4),
FACE_VAR_LOADER_STATUS = FACE_VAR | (VAR_LOADER_STATUS << 4),
FACE_VAR_SERVER_DATE = FACE_VAR | (VAR_SERVER_DATE << 4),
FACE_VAR_CPU_COUNT = FACE_VAR | (VAR_CPU_COUNT << 4),
FACE_VAR_CPU_HASH = FACE_VAR | (VAR_CPU_HASH << 4),
FACE_VAR_OS_BUILD_NUMBER = FACE_VAR | (VAR_OS_BUILD_NUMBER << 4),
FACE_VAR_SALT = 0xFACE0300U,
FACE_VAR_IS_PATCH_DETECTED_SALT = FACE_VAR_SALT | VAR_IS_PATCH_DETECTED,
FACE_VAR_IS_DEBUGGER_DETECTED_SALT = FACE_VAR_SALT | VAR_IS_DEBUGGER_DETECTED,
FACE_VAR_LOADER_CRC_INFO_SALT = FACE_VAR_SALT | VAR_LOADER_CRC_INFO,
FACE_VAR_LOADER_CRC_INFO_SIZE_SALT = FACE_VAR_SALT | VAR_LOADER_CRC_INFO_SIZE,
FACE_VAR_LOADER_CRC_INFO_HASH_SALT = FACE_VAR_SALT | VAR_LOADER_CRC_INFO_HASH,
FACE_VAR_DRIVER_UNLOAD_SALT = FACE_VAR_SALT | VAR_DRIVER_UNLOAD,
FACE_VAR_CRC_IMAGE_SIZE_SALT = FACE_VAR_SALT | VAR_CRC_IMAGE_SIZE,
FACE_VAR_SERVER_DATE_SALT = FACE_VAR_SALT | VAR_SERVER_DATE,
FACE_VAR_CPU_COUNT_SALT = FACE_VAR_SALT | VAR_CPU_COUNT,
FACE_VAR_CPU_HASH_SALT = FACE_VAR_SALT | VAR_CPU_HASH,
FACE_VAR_OS_BUILD_NUMBER_SALT = FACE_VAR_SALT | VAR_OS_BUILD_NUMBER,
};
enum {
LOADER_OPTION_CHECK_PATCH = 0x1,
LOADER_OPTION_CHECK_DEBUGGER = 0x2,
LOADER_OPTION_CHECK_KERNEL_DEBUGGER = 0x4,
LOADER_OPTION_EXIT_PROCESS = 0x8,
LOADER_OPTION_CHECK_VIRTUAL_MACHINE = 0x10
};
enum {
CORE_OPTION_MEMORY_PROTECTION = 0x1,
CORE_OPTION_CHECK_DEBUGGER = 0x2
};
enum {
FILE_LOAD = 0x1,
FILE_REGISTER = 0x2,
FILE_INSTALL = 0x4,
};
enum {
FIELD_BUILD_DATE,
FIELD_PUBLIC_EXP_OFFSET,
FIELD_PUBLIC_EXP_SIZE,
FIELD_MODULUS_OFFSET,
FIELD_MODULUS_SIZE,
FIELD_BLACKLIST_OFFSET,
FIELD_BLACKLIST_SIZE,
FIELD_ACTIVATION_URL_OFFSET,
FIELD_ACTIVATION_URL_SIZE,
FIELD_CRC_OFFSET,
FIELD_COUNT
};
enum {
WOW64_FLAG = 0x8000
};
#ifndef _CONSOLE // google test
#define FACE_TO_INDEX(i) ((uint32_t)(i)/sizeof(size_t))
#ifdef VMP_GNU
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warray-bounds"
#endif
#else
#define FACE_TO_INDEX(i) (((uint32_t)(i) & 0xff) >> 4)
#endif
struct GlobalData {
bool is_patch_detected() { return ((v_[FACE_TO_INDEX(FACE_VAR_IS_PATCH_DETECTED)] ^ FACE_VAR_IS_PATCH_DETECTED_SALT) != 0); } //-V557
bool is_debugger_detected() { return ((v_[FACE_TO_INDEX(FACE_VAR_IS_DEBUGGER_DETECTED)] ^ FACE_VAR_IS_DEBUGGER_DETECTED_SALT) != 0); } //-V557
size_t loader_crc_info() { return (v_[FACE_TO_INDEX(FACE_VAR_LOADER_CRC_INFO)] ^ FACE_VAR_LOADER_CRC_INFO_SALT); } //-V557
size_t loader_crc_size() { return (v_[FACE_TO_INDEX(FACE_VAR_LOADER_CRC_INFO_SIZE)] ^ FACE_VAR_LOADER_CRC_INFO_SIZE_SALT); } //-V557
size_t loader_crc_hash() { return (v_[FACE_TO_INDEX(FACE_VAR_LOADER_CRC_INFO_HASH)] ^ FACE_VAR_LOADER_CRC_INFO_HASH_SALT); } //-V557
size_t cpu_hash(size_t index) { return (v_[FACE_TO_INDEX(FACE_VAR_CPU_HASH) + index] ^ FACE_VAR_CPU_HASH_SALT); }
size_t cpu_count() { return (v_[FACE_TO_INDEX(FACE_VAR_CPU_COUNT)] ^ FACE_VAR_CPU_COUNT_SALT); } //-V557
size_t session_key() { return (v_[FACE_TO_INDEX(FACE_VAR_SESSION_KEY)]); } //-V557
size_t driver_unload() { return (v_[FACE_TO_INDEX(FACE_VAR_DRIVER_UNLOAD)] ^ FACE_VAR_DRIVER_UNLOAD_SALT); } //-V557
size_t crc_image_size() { return (v_[FACE_TO_INDEX(FACE_VAR_CRC_IMAGE_SIZE)] ^ FACE_VAR_CRC_IMAGE_SIZE_SALT); } //-V557
uint32_t loader_status() { return static_cast<uint32_t>(v_[FACE_TO_INDEX(FACE_VAR_LOADER_STATUS)]); } //-V557
uint32_t server_date() { return static_cast<uint32_t>(v_[FACE_TO_INDEX(FACE_VAR_SERVER_DATE)] ^ FACE_VAR_SERVER_DATE_SALT); } //-V557
uint32_t os_build_number() { return static_cast<uint32_t>(v_[FACE_TO_INDEX(FACE_VAR_OS_BUILD_NUMBER)] ^ FACE_VAR_OS_BUILD_NUMBER_SALT); } //-V557
void set_is_patch_detected(bool value) { v_[FACE_TO_INDEX(FACE_VAR_IS_PATCH_DETECTED)] = static_cast<size_t>(value) ^ FACE_VAR_IS_PATCH_DETECTED_SALT; } //-V557
void set_is_debugger_detected(bool value) { v_[FACE_TO_INDEX(FACE_VAR_IS_DEBUGGER_DETECTED)] = static_cast<size_t>(value) ^ FACE_VAR_IS_DEBUGGER_DETECTED_SALT; } //-V557
void set_loader_crc_info(size_t value) { v_[FACE_TO_INDEX(FACE_VAR_LOADER_CRC_INFO)] = value ^ FACE_VAR_LOADER_CRC_INFO_SALT; } //-V557
void set_loader_crc_size(size_t value) { v_[FACE_TO_INDEX(FACE_VAR_LOADER_CRC_INFO_SIZE)] = value ^ FACE_VAR_LOADER_CRC_INFO_SIZE_SALT; } //-V557
void set_loader_crc_hash(size_t value) { v_[FACE_TO_INDEX(FACE_VAR_LOADER_CRC_INFO_HASH)] = value ^ FACE_VAR_LOADER_CRC_INFO_HASH_SALT; } //-V557
void set_cpu_hash(size_t index, size_t value) { v_[FACE_TO_INDEX(FACE_VAR_CPU_HASH) + index] = value ^ FACE_VAR_CPU_HASH_SALT; }
void set_cpu_count(size_t value) { v_[FACE_TO_INDEX(FACE_VAR_CPU_COUNT)] = value ^ FACE_VAR_CPU_COUNT_SALT; } //-V557
void set_session_key(size_t value) { v_[FACE_TO_INDEX(FACE_VAR_SESSION_KEY)] = value; } //-V557
void set_driver_unload(size_t value) { v_[FACE_TO_INDEX(FACE_VAR_DRIVER_UNLOAD)] = value ^ FACE_VAR_DRIVER_UNLOAD_SALT; } //-V557
void set_crc_image_size(size_t value) { v_[FACE_TO_INDEX(FACE_VAR_CRC_IMAGE_SIZE)] = value ^ FACE_VAR_CRC_IMAGE_SIZE_SALT; } //-V557
void set_loader_status(uint32_t value) { v_[FACE_TO_INDEX(FACE_VAR_LOADER_STATUS)] = value; } //-V557
void set_server_date(uint32_t value) { v_[FACE_TO_INDEX(FACE_VAR_SERVER_DATE)] = value ^ FACE_VAR_SERVER_DATE_SALT; } //-V557
void set_os_build_number(uint32_t value) { v_[FACE_TO_INDEX(FACE_VAR_OS_BUILD_NUMBER)] = value ^ FACE_VAR_OS_BUILD_NUMBER_SALT; } //-V557
private:
size_t v_[VAR_COUNT];
};
#ifndef _CONSOLE
#ifdef VMP_GNU
#pragma clang diagnostic pop
#endif
#endif
#endif

1365
runtime/core.cc Normal file

File diff suppressed because it is too large Load Diff

149
runtime/core.h Normal file
View File

@ -0,0 +1,149 @@
#ifndef CORE_H
#define CORE_H
class StringManager;
class LicensingManager;
class HardwareID;
#ifdef VMP_GNU
#elif defined(WIN_DRIVER)
#else
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif
#ifndef NTDDI_WIN7 //SDK 6.0
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation = 0,
ObjectTypeInformation = 2
} OBJECT_INFORMATION_CLASS;
typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION {
ULONG Attributes;
ACCESS_MASK GrantedAccess;
ULONG HandleCount;
ULONG PointerCount;
ULONG Reserved[10]; // reserved for internal use
} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION;
#endif
class ResourceManager;
class FileManager;
class RegistryManager;
class HookManager;
enum VirtualObjectType {
OBJECT_FILE,
OBJECT_SECTION,
OBJECT_MAP,
OBJECT_KEY,
};
class VirtualObject
{
public:
VirtualObject(VirtualObjectType type, void *ref, HANDLE handle, uint32_t access);
~VirtualObject();
void *ref() const { return ref_; }
VirtualObjectType type() const { return type_; }
HANDLE handle() const { return handle_; }
uint64_t file_position() const { return file_position_; }
void set_file_position(uint64_t position) { file_position_ = position; }
uint32_t attributes() const { return attributes_; }
void set_attributes(uint32_t attributes) { attributes_ = attributes; }
uint32_t access() const { return access_; }
private:
void *ref_;
HANDLE handle_;
VirtualObjectType type_;
uint64_t file_position_;
uint32_t attributes_;
uint32_t access_;
};
class VirtualObjectList
{
public:
VirtualObjectList();
~VirtualObjectList();
VirtualObject *Add(VirtualObjectType type, void *ref, HANDLE handle, uint32_t access);
void DeleteObject(HANDLE handle);
void DeleteRef(void *ref, HANDLE handle = 0);
VirtualObject *GetObject(HANDLE handle) const;
VirtualObject *GetFile(HANDLE handle) const;
VirtualObject *GetSection(HANDLE handle) const;
VirtualObject *GetMap(HANDLE process, void *map) const;
VirtualObject *GetKey(HANDLE handle) const;
VirtualObject *operator [] (size_t index) const { return v_[index]; }
size_t size() const { return v_.size(); }
CRITICAL_SECTION &critical_section() { return critical_section_; };
uint32_t GetHandleCount(HANDLE handle) const;
uint32_t GetPointerCount(const void *ref) const;
private:
void Delete(size_t index);
CRITICAL_SECTION critical_section_;
vector<VirtualObject *> v_;
};
#endif
#ifdef VMP_GNU
EXPORT_API extern GlobalData *loader_data;
#else
extern GlobalData *loader_data;
#endif
class Core
{
public:
static Core *Instance();
static void Free();
bool Init(HMODULE instance);
~Core();
StringManager *string_manager() const { return string_manager_; }
LicensingManager *licensing_manager() const { return licensing_manager_; }
HardwareID *hardware_id();
#ifdef VMP_GNU
#elif defined(WIN_DRIVER)
#else
NTSTATUS NtProtectVirtualMemory(HANDLE ProcesssHandle, LPVOID *BaseAddress, SIZE_T *Size, DWORD NewProtect, PDWORD OldProtect);
NTSTATUS NtClose(HANDLE Handle);
NTSTATUS NtQueryObject(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
NTSTATUS TrueNtQueryObject(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
ResourceManager *resource_manager() const { return resource_manager_; }
FileManager *file_manager() const { return file_manager_; }
RegistryManager *registry_manager() const { return registry_manager_; }
#endif
protected:
Core();
private:
StringManager *string_manager_;
LicensingManager *licensing_manager_;
HardwareID *hardware_id_;
#ifdef VMP_GNU
#elif defined(WIN_DRIVER)
#else
NTSTATUS TrueNtProtectVirtualMemory(HANDLE ProcesssHandle, LPVOID *BaseAddress, SIZE_T *Size, DWORD NewProtect, PDWORD OldProtect);
NTSTATUS TrueNtClose(HANDLE Handle);
void HookAPIs(HookManager &hook_manager, uint32_t options);
void UnhookAPIs(HookManager &hook_manager);
VirtualObjectList objects_;
ResourceManager *resource_manager_;
FileManager *file_manager_;
RegistryManager *registry_manager_;
HookManager *hook_manager_;
void *nt_protect_virtual_memory_;
void *nt_close_;
void *nt_query_object_;
void *dbg_ui_remote_breakin_;
#endif
static Core *self_;
// no copy ctr or assignment op
Core(const Core &);
Core &operator=(const Core &);
};
#endif

1086
runtime/crypto.cc Normal file

File diff suppressed because it is too large Load Diff

388
runtime/crypto.h Normal file
View File

@ -0,0 +1,388 @@
#ifndef CRYPTO_H
#define CRYPTO_H
#include "common.h"
uint32_t rand32();
uint64_t rand64();
#ifdef VMP_GNU
inline uint8_t _rotl8(uint8_t value, int shift)
{
__asm__ __volatile__ ("rolb %%cl, %0"
: "=r"(value)
: "0"(value), "c"(shift)
);
return value;
}
inline uint16_t _rotl16(uint16_t value, int shift)
{
__asm__ __volatile__ ("rolw %%cl, %0"
: "=r"(value)
: "0"(value), "c"(shift)
);
return value;
}
inline uint32_t _rotl32(uint32_t value, int shift)
{
__asm__ __volatile__ ("roll %%cl, %0"
: "=r"(value)
: "0"(value), "c"(shift)
);
return value;
}
inline uint64_t _rotl64(uint64_t value, int shift)
{
return (value << shift) | (value >> (sizeof(value) * 8 - shift));
}
inline uint8_t _rotr8(uint8_t value, int shift)
{
__asm__ __volatile__ ("rorb %%cl, %0"
: "=r"(value)
: "0"(value), "c"(shift)
);
return value;
}
inline uint16_t _rotr16(uint16_t value, int shift)
{
__asm__ __volatile__ ("rorw %%cl, %0"
: "=r"(value)
: "0"(value), "c"(shift)
);
return value;
}
inline uint32_t _rotr32(uint32_t value, int shift)
{
__asm__ __volatile__ ("rorl %%cl, %0"
: "=r"(value)
: "0"(value), "c"(shift)
);
return value;
}
inline uint64_t _rotr64(uint64_t value, int shift)
{
return (value >> shift) | (value << (sizeof(value) * 8 - shift));
}
inline uint64_t __rdtsc()
{
uint32_t hi, lo;
__asm__ __volatile__ ("rdtsc"
: "=a"(lo), "=d"(hi)
);
return static_cast<uint64_t>(lo) | static_cast<uint64_t>(hi) << 32;
}
inline void __cpuid(int regs[4], uint32_t value)
{
__asm__ __volatile__ ("cpuid"
: "=a"(regs[0]), "=b"(regs[1]), "=c"(regs[2]), "=d"(regs[3])
: "a"(value)
);
}
inline void __movsb(void *d, const void *s, size_t n) {
asm volatile ("rep movsb"
: "=D" (d),
"=S" (s),
"=c" (n)
: "0" (d),
"1" (s),
"2" (n)
: "memory");
}
#ifdef __APPLE__
inline uint16_t __builtin_bswap16(uint16_t value)
{
__asm__ __volatile__ ("rorw $8, %0"
: "+r"(value)
);
return value;
}
#endif
#else
#define _rotl32 _lrotl
#define _rotr32 _lrotr
#define __builtin_bswap16 _byteswap_ushort
#define __builtin_bswap32 _byteswap_ulong
#define __builtin_bswap64 _byteswap_uint64
inline unsigned long __builtin_ctz(unsigned int x) { unsigned long r; _BitScanForward(&r, x); return r; }
#if defined(WIN_DRIVER) && (WDK_NTDDI_VERSION <= NTDDI_WIN7)
#ifndef WIN64
#ifdef __cplusplus
extern "C" {
#endif
VOID
__movsb(
__out_ecount_full(Count) PUCHAR Destination,
__in_ecount(Count) UCHAR const *Source,
__in SIZE_T Count
);
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif
inline uint64_t ByteToInt64(uint8_t value)
{
return static_cast<int64_t>(static_cast<int8_t>(value));
}
inline uint64_t WordToInt64(uint16_t value)
{
return static_cast<int64_t>(static_cast<int16_t>(value));
}
inline uint64_t DWordToInt64(uint32_t value)
{
return static_cast<int64_t>(static_cast<int32_t>(value));
}
struct RC5Key {
uint8_t Value[8];
#ifndef RUNTIME
uint32_t P;
uint32_t Q;
#endif
RC5Key() {} //-V730 <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#ifdef RUNTIME
RC5Key(const uint8_t *key)
{
memcpy(Value, key, sizeof(Value));
}
#endif
void Create();
};
class CipherRC5
{
public:
CipherRC5(const RC5Key &key);
void Encrypt(uint8_t *buff, size_t count) const;
void Decrypt(const uint8_t *in, uint8_t *out, size_t count) const;
void Encrypt(const uint32_t *in, uint32_t *out) const;
void Decrypt(const uint32_t *in, uint32_t *out) const;
private:
enum {
w = 32, // u32 size in bits
r = 15, // number of rounds
b = 8, // number of bytes in key
c = 8 * b / w, // 16 - number u32s in key = ceil(8*b/w)
t = 2 * (r + 1), // 34 - size of table S = 2*(r+1) u32s
};
uint32_t S[t]; // expanded key table
#ifdef RUNTIME
enum {
P = FACE_RC5_P,
Q = FACE_RC5_Q
};
#else
uint32_t P;
uint32_t Q;
#endif
};
class CryptoContainer;
typedef unsigned short BignumInt;
typedef unsigned long BignumDblInt;
typedef BignumInt *Bignum;
class BigNumber
{
public:
BigNumber();
BigNumber(const BigNumber &src);
BigNumber(const uint8_t *data, size_t size, bool inverse_order = false);
~BigNumber();
BigNumber modpow(const BigNumber &exp, const BigNumber &mod) const;
CryptoContainer *modpow(const CryptoContainer &source, size_t exp_offset, size_t exp_size, size_t mod_offset, size_t mod_size) const;
size_t size() const;
bool operator < (const BigNumber &b) const;
uint8_t operator [] (size_t index) const;
BignumInt data(size_t index) const { return bignum_get_word(data_ + index); }
private:
// no assignment op
BigNumber &operator =(const BigNumber &);
BigNumber(Bignum data, const BignumInt *salt);
BignumInt bignum_get_word(Bignum b) const;
void bignum_set_word(Bignum b, BignumInt value) const;
void init(size_t length);
void internal_mul(BignumInt *a, BignumInt *b, BignumInt *c, int len) const;
void internal_add_shifted(BignumInt *number, unsigned n, int shift) const;
void internal_mod(BignumInt *a, int alen, BignumInt *m, int mlen, BignumInt *quot, int qshift) const;
uint8_t bignum_byte(Bignum bn, size_t i) const;
int bignum_cmp(const BigNumber &b) const;
enum {
BIGNUM_INT_MASK = 0xFFFFU,
BIGNUM_TOP_BIT = 0x8000U,
BIGNUM_INT_BITS = 16,
BIGNUM_INT_BYTES = (BIGNUM_INT_BITS / 8)
};
Bignum data_;
#ifdef RUNTIME
BignumInt salt_[20 / BIGNUM_INT_BYTES];
#endif
};
enum {
ATL_BASE64_FLAG_NONE = 0,
ATL_BASE64_FLAG_NOPAD,
ATL_BASE64_FLAG_NOCRLF
};
bool Base64Encode(const uint8_t *src, size_t src_len, char *dst, size_t &dst_len);
bool Base64Decode(const char *src, size_t src_len, uint8_t *dst, size_t &dst_len);
size_t Base64EncodeGetRequiredLength(size_t src_len);
class CryptoContainer
{
public:
CryptoContainer(uint8_t *data, size_t size, const RC5Key &key);
CryptoContainer(size_t size, const RC5Key &key);
CryptoContainer(const BigNumber &bn);
~CryptoContainer();
const uint8_t *data() const { return reinterpret_cast<const uint8_t *>(data_); }
size_t size() const { return size_; }
uint32_t GetDWord(size_t pos) const;
uint16_t GetWord(size_t pos) const;
uint8_t GetByte(size_t pos) const;
uint64_t GetQWord(size_t pos) const;
bool SetDWord(size_t pos, uint32_t value) const;
bool SetWord(size_t pos, uint16_t value) const;
bool SetByte(size_t pos, uint8_t value) const;
void UTF8ToUnicode(size_t offset, size_t len, VMP_WCHAR *dest, size_t dest_size) const;
private:
#define RC5_BLOCK_SIZE 8
bool EncryptValue(size_t pos, uint8_t *value, size_t value_size) const;
bool DecryptValue(size_t pos, uint8_t *value, size_t value_size) const;
bool is_own_data_;
uint32_t *data_;
size_t size_;
CipherRC5 *cipher_;
// no copy ctr or assignment op
CryptoContainer(const CryptoContainer &);
CryptoContainer &operator =(const CryptoContainer &);
};
class SHA1
{
public:
SHA1();
void Reset();
void Input(const uint8_t *data, size_t size);
void Input(const CryptoContainer &data, size_t offset, size_t size);
const uint8_t *Result();
size_t ResultSize() const { return sizeof(digest_); }
bool operator ==(SHA1 &other) { return memcmp(Result(), other.Result(), ResultSize()) == 0; }
private:
void ProcessMessageBlock();
void PadMessage();
bool computed_;
size_t message_block_index_;
uint8_t message_block_[64];
uint32_t length_high_;
uint32_t length_low_;
uint32_t hash_[5];
uint32_t digest_[5];
};
static uint32_t crc32_table[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#ifdef RUNTIME
#ifdef VMP_GNU
EXPORT_API uint32_t WINAPI CalcCRC(const void * key, size_t len) __asm__ ("CalcCRC");
#else
EXPORT_API uint32_t WINAPI CalcCRC(const void * key, size_t len);
#endif
#else
uint32_t CalcCRC(const void * key, size_t len);
#endif
class CRCValueCryptor
{
public:
#ifdef RUNTIME
FORCE_INLINE CRCValueCryptor() : key_(FACE_CRC_INFO_SALT) {}
FORCE_INLINE uint32_t Decrypt(uint32_t value)
{
uint32_t res = value ^ key_;
key_ = _rotl32(key_, 7) ^ res;
return res;
}
#else
CRCValueCryptor(uint32_t key) : key_(key) {}
uint32_t Encrypt(uint32_t value)
{
uint32_t old_key = key_;
key_ = _rotl32(key_, 7) ^ value;
return value ^ old_key;
}
#endif
private:
uint32_t key_;
};
#endif

1189
runtime/file_manager.cc Normal file

File diff suppressed because it is too large Load Diff

348
runtime/file_manager.h Normal file
View File

@ -0,0 +1,348 @@
#ifndef FILE_MANAGER_H
#define FILE_MANAGER_H
#include "loader.h"
#include "registry_manager.h"
class CipherRC5;
typedef struct _FILE_BASIC_INFORMATION {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
ULONG FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
typedef enum _SECTION_INFORMATION_CLASS {
SectionBasicInformation,
SectionImageInformation,
SectionRelocationInformation
} SECTION_INFORMATION_CLASS, *PSECTION_INFORMATION_CLASS;
typedef struct _SECTION_BASIC_INFORMATION {
ULONG BaseAddress;
ULONG Attributes;
LARGE_INTEGER Size;
} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;
typedef struct _SECTION_IMAGE_INFORMATION {
PVOID EntryPoint;
ULONG StackZeroBits;
ULONG StackReserved;
ULONG StackCommit;
ULONG ImageSubsystem;
WORD SubSystemVersionLow;
WORD SubSystemVersionHigh;
ULONG Unknown1;
ULONG ImageCharacteristics;
ULONG ImageMachineType;
ULONG Unknown2[3];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
#define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xC000007BL)
#define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS)0xC0000045L)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
#define STATUS_NO_MORE_ENTRIES ((NTSTATUS)0x8000001AL)
#ifndef STATUS_INVALID_PARAMETER
#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL)
#endif
#define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS)0xC0000010L)
#define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS)0xC0000020L)
#define OBJ_HANDLE_TAGBITS 0x00000003L
#define EXHANDLE(x) ((HANDLE)((ULONG_PTR)(x) &~ OBJ_HANDLE_TAGBITS))
#define FILE_SUPERSEDE 0x00000000
#define FILE_OPEN 0x00000001
#define FILE_CREATE 0x00000002
#define FILE_OPEN_IF 0x00000003
#define FILE_OVERWRITE 0x00000004
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_MAXIMUM_DISPOSITION 0x00000005
#define FILE_SUPERSEDED 0x00000000
#define FILE_OPENED 0x00000001
#define FILE_CREATED 0x00000002
#define FILE_OVERWRITTEN 0x00000003
#define FILE_EXISTS 0x00000004
#define FILE_DOES_NOT_EXIST 0x00000005
#define FILE_USE_FILE_POINTER_POSITION 0xfffffffe
#define IMAGE_FILE_MACHINE_I486 0x14D
#define IMAGE_FILE_MACHINE_I586 0x14E
#define FileBothDirectoryInformation (FILE_INFORMATION_CLASS)0x03
#define FileBasicInformation (FILE_INFORMATION_CLASS)0x04
#define FileStandardInformation (FILE_INFORMATION_CLASS)0x05
#define FileNameInformation (FILE_INFORMATION_CLASS)0x09
#define FilePositionInformation (FILE_INFORMATION_CLASS)0x0e
#define FileIdBothDirectoryInformation (FILE_INFORMATION_CLASS)0x25
#define FileAllInformation (FILE_INFORMATION_CLASS)0x12
typedef struct _FILE_POSITION_INFORMATION {
LARGE_INTEGER CurrentByteOffset;
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
typedef struct _FILE_STANDARD_INFORMATION {
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG NumberOfLinks;
BOOLEAN DeletePending;
BOOLEAN Directory;
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
typedef struct _FILE_NAME_INFORMATION {
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
typedef struct _FILE_INTERNAL_INFORMATION {
LARGE_INTEGER IndexNumber;
} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
typedef struct _FILE_EA_INFORMATION {
ULONG EaSize;
} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;
typedef struct _FILE_ACCESS_INFORMATION {
ACCESS_MASK AccessFlags;
} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION;
typedef struct _FILE_MODE_INFORMATION {
ULONG Mode;
} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;
typedef struct _FILE_ALIGNMENT_INFORMATION {
ULONG AlignmentRequirement;
} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;
typedef struct _FILE_ALL_INFORMATION {
FILE_BASIC_INFORMATION BasicInformation;
FILE_STANDARD_INFORMATION StandardInformation;
FILE_INTERNAL_INFORMATION InternalInformation;
FILE_EA_INFORMATION EaInformation;
FILE_ACCESS_INFORMATION AccessInformation;
FILE_POSITION_INFORMATION PositionInformation;
FILE_MODE_INFORMATION ModeInformation;
FILE_ALIGNMENT_INFORMATION AlignmentInformation;
FILE_NAME_INFORMATION NameInformation;
} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;
typedef struct _OBJECT_NAME_INFORMATION {
UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
typedef enum _FSINFOCLASS {
FileFsVolumeInformation = 1,
FileFsLabelInformation, // 2
FileFsSizeInformation, // 3
FileFsDeviceInformation, // 4
FileFsAttributeInformation, // 5
FileFsControlInformation, // 6
FileFsFullSizeInformation, // 7
FileFsObjectIdInformation, // 8
FileFsDriverPathInformation, // 9
FileFsVolumeFlagsInformation,// 10
FileFsMaximumInformation
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
typedef struct _FILE_FS_DEVICE_INFORMATION {
DEVICE_TYPE DeviceType;
ULONG Characteristics;
} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
typedef struct _FILE_FS_ATTRIBUTE_INFORMATION {
ULONG FileSystemAttributes;
LONG MaximumComponentNameLength;
ULONG FileSystemNameLength;
WCHAR FileSystemName[1];
} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
typedef struct _FILE_FS_VOLUME_INFORMATION {
LARGE_INTEGER VolumeCreationTime;
ULONG VolumeSerialNumber;
ULONG VolumeLabelLength;
BOOLEAN SupportsObjects;
WCHAR VolumeLabel[1];
} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
typedef struct _FILE_BOTH_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[12];
WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
typedef struct _FILE_ID_BOTH_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[12];
LARGE_INTEGER FileId;
WCHAR FileName[1];
} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;
struct OBJECT_DIRECTORY {
uint32_t NumberOfEntries;
// OBJECT_ENTRY Entries[];
};
#define ObjectNameInformation (OBJECT_INFORMATION_CLASS)1
struct OBJECT_ENTRY {
uint32_t NameOffset;
uint32_t OffsetToData;
uint32_t Size;
uint32_t Options;
};
class Path
{
public:
Path(wchar_t *str)
{
const wchar_t *last = str;
const wchar_t *cur = str;
while (*cur) {
if (*cur == '\\') {
if (cur > last)
list_.push_back(UnicodeString(last, cur - last));
last = cur + 1;
}
cur++;
}
if (cur > last)
list_.push_back(UnicodeString(last, cur - last));
}
UnicodeString Combine(wchar_t *str)
{
vector<const UnicodeString *> folder_list;
for (size_t i = 0; i < list_.size(); i++) {
folder_list.push_back(&list_[i]);
}
Path p(str);
for (size_t i = 0; i < p.list_.size(); i++) {
const UnicodeString &folder = p.list_[i];
if (folder == L".")
continue;
if (folder == L"..")
folder_list.pop_back();
else
folder_list.push_back(&folder);
}
UnicodeString res;
for (size_t i = 0; i < folder_list.size(); i++) {
if (i > 0)
res.append(L"\\", 1);
res.append(folder_list[i]->c_str());
}
return res;
}
private:
vector<UnicodeString> list_;
};
class HookManager;
class FileManager
{
public:
FileManager(const uint8_t *data, HMODULE instance, const uint8_t *key, VirtualObjectList *objects);
void HookAPIs(HookManager &hook_manager);
void UnhookAPIs(HookManager &hook_manager);
bool OpenFiles(RegistryManager &registry_manager);
NTSTATUS NtQueryAttributesFile(POBJECT_ATTRIBUTES ObjectAttributes, PFILE_BASIC_INFORMATION FileInformation);
NTSTATUS NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength);
NTSTATUS NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions);
NTSTATUS NtQueryInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
NTSTATUS NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass);
NTSTATUS NtSetInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
NTSTATUS NtQueryDirectoryFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry, PUNICODE_STRING FileName, BOOLEAN RestartScan);
NTSTATUS NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);
NTSTATUS NtCreateSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle);
NTSTATUS NtQuerySection(HANDLE SectionHandle, SECTION_INFORMATION_CLASS InformationClass, PVOID InformationBuffer, ULONG InformationBufferSize, PULONG ResultLength);
NTSTATUS NtMapViewOfSection(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, SECTION_INHERIT InheritDisposition, ULONG AllocationType, ULONG Win32Protect);
NTSTATUS NtUnmapViewOfSection(HANDLE ProcessHandle, PVOID BaseAddress);
NTSTATUS NtQueryVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID Buffer, ULONG Length, PULONG ResultLength);
private:
NTSTATUS TrueNtQueryAttributesFile(POBJECT_ATTRIBUTES ObjectAttributes, PFILE_BASIC_INFORMATION FileInformation);
NTSTATUS TrueNtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength);
NTSTATUS TrueNtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions);
NTSTATUS TrueNtQueryInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
NTSTATUS TrueNtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass);
NTSTATUS TrueNtSetInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
NTSTATUS TrueNtQueryDirectoryFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry, PUNICODE_STRING FileName, BOOLEAN RestartScan);
NTSTATUS TrueNtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);
NTSTATUS TrueNtCreateSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle);
NTSTATUS TrueNtQuerySection(HANDLE SectionHandle, SECTION_INFORMATION_CLASS InformationClass, PVOID InformationBuffer, ULONG InformationBufferSize, PULONG ResultLength);
NTSTATUS TrueNtMapViewOfSection(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, SECTION_INHERIT InheritDisposition, ULONG AllocationType, ULONG Win32Protect);
NTSTATUS TrueNtUnmapViewOfSection(HANDLE ProcessHandle, PVOID BaseAddress);
NTSTATUS TrueNtQueryVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID Buffer, ULONG Length, PULONG ResultLength);
NTSTATUS TrueNtQueryObject(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
OBJECT_DIRECTORY DecryptDirectory(const OBJECT_DIRECTORY *directory_enc) const;
OBJECT_ENTRY DecryptEntry(const OBJECT_ENTRY *entry_enc) const;
bool DecryptString(LPCWSTR str_enc, LPWSTR str, size_t max_size) const;
const OBJECT_ENTRY *FindEntry(HANDLE directory, PUNICODE_STRING object_name);
bool ReadFile(const OBJECT_ENTRY *entry, uint64_t offset, void *dst, size_t size) const;
NTSTATUS ReadImageHeader(const OBJECT_ENTRY *entry, IMAGE_NT_HEADERS *header) const;
NTSTATUS ReadImage(const OBJECT_ENTRY *entry, void *image_base) const;
HMODULE instance_;
uint32_t key_;
VirtualObjectList *objects_;
const uint8_t *data_;
void *nt_query_attributes_file_;
void *nt_create_file_;
void *nt_open_file_;
void *nt_read_file_;
void *nt_query_information_file_;
void *nt_query_volume_information_file_;
void *nt_set_information_file_;
void *nt_query_directory_file_;
void *nt_close_;
void *nt_create_section_;
void *nt_query_section_;
void *nt_map_view_of_section_;
void *nt_unmap_view_of_section_;
void *nt_query_virtual_memory_;
vector<UnicodeString> file_name_list_;
UnicodeString dos_root_;
UnicodeString nt_root_;
// no copy ctr or assignment op
FileManager(const FileManager &);
FileManager &operator =(const FileManager &);
};
#endif

738
runtime/hook_manager.cc Normal file
View File

@ -0,0 +1,738 @@
#ifdef WIN_DRIVER
#else
#include "common.h"
#include "objects.h"
#include "utils.h"
#include "hook_manager.h"
/**
* HookManager
*/
HookManager::HookManager()
: update_count_(0)
{
}
void *HookManager::HookAPI(HMODULE dll, const char *api_name, void *handler, bool show_error, void **result)
{
void *res = NULL;
void *api_address = InternalGetProcAddress(dll, api_name);
if (api_address) {
Begin();
HookedAPI *hooked_api = new HookedAPI();
if (hooked_api->Hook(api_address, handler, result)) {
api_list_.push_back(hooked_api);
res = hooked_api->old_handler();
} else {
delete hooked_api;
}
End();
}
if (!res && show_error) {
wchar_t error[512] = {};
{
// string "Error at hooking API \"%S\"\n"
wchar_t str[] = { L'E', L'r', L'r', L'o', L'r', L' ', L'a', L't', L' ', L'h', L'o', L'o', L'k', L'i', L'n', L'g', L' ', L'A', L'P', L'I', L' ', L'\"', L'%', L'S', L'\"', L'\n', 0 };
swprintf_s(error, str, api_name);
}
if (api_address){
int n = 32;
wchar_t line[100] = {};
{
// string "Dumping first %d bytes:\n"
wchar_t str[] = { L'D', L'u', L'm', L'p', L'i', L'n', L'g', L' ', L'f', L'i', L'r', L's', L't', L' ', L'%', L'd', L' ', L'b', L'y', L't', L'e', L's', L':', L'\n', 0 };
swprintf_s(line, str, n);
}
wcscat_s(error, line);
for (int i = 0; i < n; i++) {
wchar_t str[] = { L'%', L'0', L'2', L'X', (i % 16 == 15) ? L'\n' : L' ', 0};
swprintf_s(line, str, reinterpret_cast<uint8_t *>(api_address)[i]);
wcscat_s(error, line);
}
}
ShowMessage(error);
::TerminateProcess(::GetCurrentProcess(), 0xDEADC0DE);
}
return res;
}
bool HookManager::UnhookAPI(void *handler)
{
if (!handler)
return false;
bool res = false;
Begin();
for (size_t i = 0; i < api_list_.size(); i++) {
HookedAPI *hooked_api = api_list_[i];
if (hooked_api->old_handler() == handler) {
api_list_.erase(i);
hooked_api->Unhook();
delete hooked_api;
res = true;
break;
}
}
End();
return res;
}
void HookManager::GetThreads()
{
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (h == INVALID_HANDLE_VALUE)
return;
THREADENTRY32 thread_entry;
thread_entry.dwSize = sizeof(thread_entry);
if (Thread32First(h, &thread_entry)) {
DWORD process_id = GetCurrentProcessId();
DWORD thread_id = GetCurrentThreadId();
do {
if (thread_entry.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(thread_entry.th32OwnerProcessID))
{
if (thread_entry.th32OwnerProcessID == process_id && thread_entry.th32ThreadID != thread_id) {
HANDLE thread = ::OpenThread(THREAD_SUSPEND_RESUME, FALSE, thread_entry.th32ThreadID);
if (thread)
thread_list_.push_back(thread);
}
}
thread_entry.dwSize = sizeof(thread_entry);
} while (Thread32Next(h, &thread_entry));
}
::CloseHandle(h);
}
void HookManager::SuspendThreads()
{
for (size_t i = 0; i < thread_list_.size(); i++) {
::SuspendThread(thread_list_[i]);
}
}
void HookManager::ResumeThreads()
{
for (size_t i = 0; i < thread_list_.size(); i++) {
::ResumeThread(thread_list_[i]);
}
}
void HookManager::FreeThreads()
{
for (size_t i = 0; i < thread_list_.size(); i++) {
::CloseHandle(thread_list_[i]);
}
thread_list_.clear();
}
void HookManager::Begin()
{
if (!update_count_) {
GetThreads();
SuspendThreads();
}
update_count_++;
}
void HookManager::End()
{
update_count_--;
if (!update_count_) {
ResumeThreads();
FreeThreads();
}
}
/**
* HookedAPI
*/
static bool PutJump(uint8_t *address, const uint8_t *jump_dest)
{
INT64 offset = reinterpret_cast<uint64_t>(jump_dest) - reinterpret_cast<uint64_t>(address) - 5;
if (offset < INT_MIN || offset > INT_MAX)
return false;
uint8_t buff[5];
buff[0] = 0xE9;
*(reinterpret_cast<uint32_t *>(buff + 1)) = static_cast<uint32_t>(offset);
return FALSE != WriteProcessMemory(GetCurrentProcess(), address, buff, sizeof(buff), NULL);
}
static bool PutJumpMem(uint8_t *address, const uint8_t *memory)
{
#ifdef _WIN64
// offset is relative
INT64 offset = reinterpret_cast<uint64_t>(memory) - reinterpret_cast<uint64_t>(address) - 6;
if (offset < INT_MIN || offset > INT_MAX)
return false;
#else
// offset is absolute
uint32_t offset = reinterpret_cast<uint32_t>(memory);
#endif
uint8_t buff[6];
buff[0] = 0xFF;
buff[1] = 0x25;
*(reinterpret_cast<uint32_t *>(buff + 2)) = static_cast<uint32_t>(offset);
return FALSE != WriteProcessMemory(GetCurrentProcess(), address, buff, sizeof(buff), NULL);
}
enum eCommandType
{
CT_UNKNOWN = 0,
CT_JMP,
CT_RET
};
struct sCommandInfo
{
DWORD dwSize;
DWORD dwRelOffset;
eCommandType cmdType;
};
#define C_66 0x00000001 // 66-prefix
#define C_67 0x00000002 // 67-prefix
#define C_LOCK 0x00000004 // lock
#define C_REP 0x00000008 // repz/repnz
#define C_SEG 0x00000010 // seg-prefix
#define C_OPCODE2 0x00000020 // 2nd opcode present (1st == 0F)
#define C_MODRM 0x00000040 // modrm present
#define C_SIB 0x00000080 // sib present
bool GetInstructionSize(const byte *pOpCode, sCommandInfo &info)
{
const byte *opcode = pOpCode;
// BYTE disasm_seg = 0; // CS DS ES SS FS GS
// BYTE disasm_rep = 0; // REPZ/REPNZ
BYTE disasm_opcode = 0; // opcode
BYTE disasm_opcode2 = 0; // used when opcode == 0F
BYTE disasm_modrm = 0; // modxxxrm
BYTE disasm_sib = 0; // scale-index-base
#ifdef _WIN64
BYTE disasm_preffix = {0};
#endif
// DWORD disasm_len = 0; // 0 if error
DWORD disasm_flag = 0; // C_xxx
DWORD disasm_memsize = 0; // value = disasm_mem
DWORD disasm_datasize = 0; // value = disasm_data
DWORD disasm_defdata = 4; // == C_66 ? 2 : 4
DWORD disasm_defmem = 4; // == C_67 ? 2 : 4
DWORD disasm_offset = 0;
BYTE mod = 0;
BYTE rm = 0;
if (! pOpCode) return false;
info.dwSize = 0;
info.dwRelOffset = 0;
info.cmdType = CT_UNKNOWN;
RETRY:
disasm_opcode = *opcode ++;
switch (disasm_opcode)
{
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x08: case 0x09: case 0x0A: case 0x0B:
case 0x10: case 0x11: case 0x12: case 0x13:
case 0x18: case 0x19: case 0x1A: case 0x1B:
case 0x20: case 0x21: case 0x22: case 0x23:
case 0x28: case 0x29: case 0x2A: case 0x2B:
case 0x30: case 0x31: case 0x32: case 0x33:
case 0x38: case 0x39: case 0x3A: case 0x3B:
case 0x84: case 0x85: case 0x86: case 0x87:
case 0x88: case 0x89: case 0x8A: case 0x8B:
case 0x8C: case 0x8D: case 0x8E:
case 0xD0: case 0xD1: case 0xD2: case 0xD3:
case 0xD8: case 0xD9: case 0xDA: case 0xDB:
case 0xDC: case 0xDD: case 0xDE: case 0xDF:
disasm_flag |= C_MODRM;
break;
case 0x04: case 0x05: case 0x0C: case 0x0D:
case 0x14: case 0x15: case 0x1C: case 0x1D:
case 0x24: case 0x25: case 0x2C: case 0x2D:
case 0x34: case 0x35: case 0x3C: case 0x3D:
case 0xA8: case 0xA9:
if (disasm_opcode & 1)
{
disasm_datasize += disasm_defdata;
}
else
{
disasm_datasize ++;
}
break;
case 0xA0: case 0xA1: case 0xA2: case 0xA3:
if (disasm_opcode & 1)
{
#ifdef _WIN64
if (!(disasm_flag & C_66) && (disasm_preffix & 8))
{
disasm_datasize += 8;
}
else
#endif
{
disasm_datasize += disasm_defdata;
}
}
else
{
disasm_datasize ++;
}
break;
case 0x06: case 0x07: case 0x0E:
case 0x16: case 0x17: case 0x1E: case 0x1F:
case 0x27: case 0x2F:
case 0x37: case 0x3F:
case 0x60: case 0x61:
case 0xCE:
#ifdef _WIN64
return false;
#else
break;
#endif
case 0x26: case 0x2E:
case 0x36: case 0x3E:
case 0x64: case 0x65:
disasm_flag |= C_SEG;
goto RETRY;
case 0x40: case 0x41: case 0x42: case 0x43:
case 0x44: case 0x45: case 0x46: case 0x47:
case 0x48: case 0x49: case 0x4A: case 0x4B:
case 0x4C: case 0x4D: case 0x4E: case 0x4F:
#ifdef _WIN64
disasm_preffix = disasm_opcode;
goto RETRY;
#else
break;
#endif
case 0x50: case 0x51: case 0x52: case 0x53:
case 0x54: case 0x55: case 0x56: case 0x57:
case 0x58: case 0x59: case 0x5A: case 0x5B:
case 0x5C: case 0x5D: case 0x5E: case 0x5F:
case 0x6C: case 0x6D: case 0x6E: case 0x6F:
case 0x90: case 0x91: case 0x92: case 0x93:
case 0x94: case 0x95: case 0x96: case 0x97:
case 0x98: case 0x99: case 0x9B: case 0x9C:
case 0x9D: case 0x9E: case 0x9F:
case 0xA4: case 0xA5: case 0xA6: case 0xA7:
case 0xAA: case 0xAB: case 0xAC: case 0xAD:
case 0xAE: case 0xAF:
case 0xC3: case 0xC9: case 0xCB: case 0xCC:
case 0xCF:
case 0xD7:
case 0xEC: case 0xED: case 0xEE: case 0xEF:
case 0xF4: case 0xF5: case 0xF8: case 0xF9:
case 0xFA: case 0xFB: case 0xFC: case 0xFD:
break;
case 0x62:
case 0xC4: case 0xC5:
#ifdef _WIN64
return false;
#else
disasm_flag |= C_MODRM;
break;
#endif
case 0x66:
disasm_flag |= C_66;
disasm_defdata = 2;
goto RETRY;
case 0x67:
disasm_flag |= C_67;
disasm_defmem = 2;
goto RETRY;
case 0x69:
case 0x81:
case 0xC1:
disasm_flag |= C_MODRM;
disasm_datasize += disasm_defdata;
break;
case 0x6A:
case 0x70: case 0x71: case 0x72: case 0x73:
case 0x74: case 0x75: case 0x76: case 0x77:
case 0x78: case 0x79: case 0x7A: case 0x7B:
case 0x7C: case 0x7D: case 0x7E: case 0x7F:
case 0xB0: case 0xB1: case 0xB2: case 0xB3:
case 0xB4: case 0xB5: case 0xB6: case 0xB7:
case 0xCD:
case 0xE0: case 0xE1: case 0xE2: case 0xE3:
case 0xE4: case 0xE5: case 0xE6: case 0xE7:
disasm_datasize ++;
break;
case 0xEB:
info.cmdType = CT_JMP;
disasm_offset = (DWORD) (opcode - pOpCode);
disasm_datasize ++;
break;
case 0x8F:
if ((*opcode >> 3) & 7)
return false;
disasm_flag |= C_MODRM;
break;
case 0x9A: case 0xEA:
#ifdef _WIN64
return false;
#else
disasm_datasize += (disasm_defdata + 2);
break;
#endif
case 0x68:
disasm_datasize += disasm_defdata;
break;
case 0xB8: case 0xB9: case 0xBA: case 0xBB:
case 0xBC: case 0xBD: case 0xBE: case 0xBF:
#ifdef _WIN64
if (!(disasm_flag & C_66) && (disasm_preffix & 8))
disasm_datasize += 8;
else
#endif
disasm_datasize += disasm_defdata;
break;
//case 0x68:
//case 0xB8: case 0xB9: case 0xBA: case 0xBB:
//case 0xBC: case 0xBD: case 0xBE: case 0xBF:
// disasm_datasize += disasm_defdata;
// break;
case 0xE8: case 0xE9:
if (disasm_defdata == 2)
return false;
disasm_offset = (DWORD) (opcode - pOpCode);
disasm_datasize += disasm_defdata;
break;
case 0x6B:
case 0x80: case 0x82: case 0x83:
case 0xC0:
disasm_flag |= C_MODRM;
disasm_datasize ++;
break;
case 0xC2:
disasm_datasize += 2;
break;
case 0xC6: case 0xC7:
if ((*opcode >> 3) & 7)
return false;
disasm_flag |= C_MODRM;
if (disasm_opcode & 1)
{
disasm_datasize += disasm_defdata;
}
else
{
disasm_datasize ++;
}
break;
case 0xC8:
disasm_datasize += 3;
break;
case 0xCA:
disasm_datasize += 2;
break;
case 0xD4: case 0xD5:
#ifdef _WIN64
return false;
#else
disasm_datasize ++;
break;
#endif
case 0xF0:
disasm_flag |= C_LOCK;
goto RETRY;
case 0xF2: case 0xF3:
disasm_flag |= C_REP;
goto RETRY;
case 0xF6: case 0xF7:
disasm_flag |= C_MODRM;
if (((*opcode >> 3) & 7) < 2)
{
if (disasm_opcode & 1)
{
disasm_datasize += disasm_defdata;
}
else
{
disasm_datasize ++;
}
}
break;
case 0xFE:
if (((*opcode >> 3) & 7) > 1)
return false;
disasm_flag |= C_MODRM;
break;
case 0xFF:
if (((*opcode >> 3) & 7) == 7)
return false;
disasm_flag |= C_MODRM;
break;
case 0x0F:
disasm_flag |= C_OPCODE2;
disasm_opcode2 = *opcode ++;
switch (disasm_opcode2)
{
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x90: case 0x91: case 0x92: case 0x93:
case 0x94: case 0x95: case 0x96: case 0x97:
case 0x98: case 0x99: case 0x9A: case 0x9B:
case 0x9C: case 0x9D: case 0x9E: case 0x9F:
case 0xA3: case 0xA5: case 0xAB: case 0xAD:
case 0xAF:
case 0xB0: case 0xB1: case 0xB2: case 0xB3:
case 0xB4: case 0xB5: case 0xB6: case 0xB7:
case 0xBB:
case 0xBC: case 0xBD: case 0xBE: case 0xBF:
case 0xC0: case 0xC1:
disasm_flag |= C_MODRM;
break;
case 0x06:
case 0x08: case 0x09: case 0x0A: case 0x0B:
case 0xA0: case 0xA1: case 0xA2: case 0xA8:
case 0xA9: case 0xAA:
case 0xC8: case 0xC9: case 0xCA: case 0xCB:
case 0xCC: case 0xCD: case 0xCE: case 0xCF:
break;
case 0x80: case 0x81: case 0x82: case 0x83:
case 0x84: case 0x85: case 0x86: case 0x87:
case 0x88: case 0x89: case 0x8A: case 0x8B:
case 0x8C: case 0x8D: case 0x8E: case 0x8F:
if (disasm_defdata == 2)
return false;
disasm_offset = (DWORD) (opcode - pOpCode);
disasm_datasize += disasm_defdata;
break;
case 0xA4: case 0xAC:
case 0xBA:
disasm_datasize ++;
disasm_flag |= C_MODRM;
break;
default:
return false;
}
default:
return false;
}
if (disasm_flag & C_MODRM)
{
disasm_modrm = *opcode ++;
mod = disasm_modrm & 0xC0;
rm = disasm_modrm & 0x07;
if (mod != 0xC0)
{
if (mod == 0x40) disasm_memsize ++;
if (mod == 0x80) disasm_memsize += disasm_defmem;
if (disasm_defmem == 2) // modrm16
{
if ((mod == 0x00) && (rm == 0x06))
{
disasm_memsize += 2;
}
}
else // modrm32
{
if (rm == 0x04)
{
disasm_flag |= C_SIB;
disasm_sib = *opcode ++;
rm = disasm_sib & 0x07;
}
if ((mod == 0x00) && (rm == 0x05))
{
#ifdef _WIN64
if (!(disasm_flag & C_SIB))
disasm_offset = (DWORD) (opcode - pOpCode);
#endif
disasm_memsize += 4;
}
}
}
}
info.dwSize =(DWORD) (opcode - pOpCode) + disasm_memsize + disasm_datasize;
info.dwRelOffset = disasm_offset;
return true;
}
size_t MoveCode(byte *&pSrcOriginal, byte *pDst, size_t nNeedBytes)
{
size_t nBytes = 0;
byte *pSrc = pSrcOriginal;
sCommandInfo ii;
while (nBytes < nNeedBytes)
{
if (!GetInstructionSize(pSrc, ii))
return 0; // error
if (nBytes == 0 && ii.cmdType == CT_JMP && ii.dwSize - ii.dwRelOffset == 1)
{ // this is a short jump and we need to follow it
ptrdiff_t offset = static_cast<char>(pSrc[ii.dwSize - 1]);
pSrcOriginal += offset + ii.dwSize; // skip JMP XX
pSrc = pSrcOriginal;
continue;
}
memcpy(pDst, pSrc, ii.dwSize); // copy original bytes
if (ii.dwRelOffset)
*reinterpret_cast<int32_t*>(pDst + ii.dwRelOffset) = static_cast<int32_t>(pSrc + *reinterpret_cast<int32_t*>(pSrc + ii.dwRelOffset) - pDst);
pSrc += ii.dwSize;
pDst += ii.dwSize;
nBytes += ii.dwSize;
}
return nBytes; // return number of bytes copied
}
size_t HookedAPI::page_size_ = 0;
HookedAPI::HookedAPI()
: size_(0), api_(NULL), old_handler_(NULL), crc_(0)
{
}
bool HookedAPI::Hook(void *api, void *handler, void **result)
{
if (!page_size_) {
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
page_size_ = (system_info.dwPageSize > 2048) ? system_info.dwPageSize : 2048;
}
uint8_t *p = static_cast<uint8_t *>(api);
// alloc virtual memory
#ifdef _WIN64
for (size_t i = 0; i < 0x70000000; i += page_size_) {
old_handler_ = ::VirtualAlloc(p + i, page_size_, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (old_handler_)
break;
}
#else
old_handler_ = ::VirtualAlloc(NULL, page_size_, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#endif
if (!old_handler_)
return false;
uint8_t *memory = static_cast<uint8_t *>(old_handler_);
if (result)
*result = memory;
// structure of the block:
// some api commands
// jmp api + 5
// original commands
// jmp [handler]
// handler
// copy api code to the new place
size_ = MoveCode(p, memory, 5);
if (!size_)
return false;
// add JMP command
if (!PutJump(memory + size_, p + size_))
return false;
// copy original commands
memcpy(memory + size_ + 5, p, size_);
// jmp [handler]
uint8_t *jump = memory + size_ * 2 + 5;
if (!PutJumpMem(jump, jump + 6))
return false;
// put handler to [handler]
*(reinterpret_cast<void **>(jump + 6)) = handler;
// put JMP at the beginning of the API
if (!PutJump(p, jump))
return false;
api_ = p; // this line should be below MoveCode, because pAPI can be corrected by it
crc_ = *reinterpret_cast<uint32_t *>(p + 1);
DWORD old_protect;
VirtualProtect(old_handler_, page_size_, PAGE_EXECUTE_READ, &old_protect);
return true;
}
void HookedAPI::Unhook()
{
if (!api_)
return;
// check CRC
uint8_t *p = static_cast<uint8_t *>(api_);
if (*p == 0xE9 && *reinterpret_cast<uint32_t *>(p + 1) == crc_) {
// put original bytes back
WriteProcessMemory(GetCurrentProcess(), api_, reinterpret_cast<uint8_t *>(old_handler_) + size_ + 5, size_, NULL);
VirtualFree(old_handler_, 0, MEM_RELEASE);
} else {
// API hooked by another code
WriteProcessMemory(GetCurrentProcess(), static_cast<uint8_t *>(old_handler_) + size_ * 2 + 5 + 6, &old_handler_, sizeof(old_handler_), NULL);
}
// cleanup
size_ = 0;
api_ = old_handler_ = NULL;
}
#endif

40
runtime/hook_manager.h Normal file
View File

@ -0,0 +1,40 @@
#ifndef HOOK_MANAGER_H
#define HOOK_MANAGER_H
class HookedAPI
{
public:
HookedAPI();
bool Hook(void *api, void *handler, void **result);
void Unhook();
void *old_handler() const { return old_handler_; }
private:
static size_t page_size_;
size_t size_;
void *api_;
void *old_handler_;
uint32_t crc_;
};
class HookManager
{
public:
HookManager();
void Begin();
void End();
void *HookAPI(HMODULE dll, const char *api_name, void *handler, bool show_error = true, void **result = NULL);
bool UnhookAPI(void * handler);
private:
HookManager(const HookManager &src);
HookManager & operator = (const HookManager &);// block the assignment operator
void GetThreads();
void SuspendThreads();
void ResumeThreads();
void FreeThreads();
vector<HookedAPI *> api_list_;
vector<HANDLE> thread_list_;
size_t update_count_;
};
#endif

688
runtime/hwid.cc Normal file
View File

@ -0,0 +1,688 @@
#include "common.h"
#include "objects.h"
#include "utils.h"
#include "hwid.h"
#include "core.h"
#include "crypto.h"
#ifdef __unix__
#include <mntent.h>
#include <dirent.h>
#include <net/if.h>
#include <pthread.h>
#endif
#ifdef VMP_GNU
EXPORT_API int WINAPI ExportedGetCurrentHWID(char *buffer, int size) __asm__ ("ExportedGetCurrentHWID");
#endif
#ifdef WIN_DRIVER
#include <ntddndis.h>
extern "C" {
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateEvent (
PHANDLE EventHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
EVENT_TYPE EventType,
BOOLEAN InitialState
);
NTSYSAPI
NTSTATUS
NTAPI
ZwWaitForSingleObject(
HANDLE Handle,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout
);
}
#endif
int WINAPI ExportedGetCurrentHWID(char *buffer, int size)
{
HardwareID *hardware_id = Core::Instance()->hardware_id();
return hardware_id ? hardware_id->GetCurrent(buffer, size) : 0;
}
/**
* HardwareID
*/
#ifdef WIN_DRIVER
bool GetRegValue(LPCWSTR reg_path, LPCWSTR value_name, LPWSTR buffer, size_t *size)
{
UNICODE_STRING unicode_reg_path, unicode_value_name;
OBJECT_ATTRIBUTES object_attributes;
NTSTATUS status;
HANDLE key_handle;
ULONG information_size;
KEY_VALUE_PARTIAL_INFORMATION *information;
bool res = false;
RtlInitUnicodeString(&unicode_reg_path, reg_path);
RtlInitUnicodeString(&unicode_value_name, value_name);
InitializeObjectAttributes(&object_attributes, &unicode_reg_path, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenKey(&key_handle, KEY_QUERY_VALUE, &object_attributes);
if (NT_SUCCESS(status)) {
information_size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + MAX_PATH * sizeof(WCHAR);
information = reinterpret_cast<KEY_VALUE_PARTIAL_INFORMATION*>(new uint8_t[information_size]);
status = ZwQueryValueKey(key_handle, &unicode_value_name, KeyValuePartialInformation, information, information_size, &information_size);
if (NT_SUCCESS(status)) {
size_t len = information->DataLength / sizeof(wchar_t);
if (*size < len + 1) {
*size = len + 1;
} else {
RtlCopyMemory(buffer, information->Data, information->DataLength);
buffer[len] = 0;
*size = wcslen(buffer);
res = true;
}
}
delete [] information;
ZwClose(key_handle);
}
return res;
}
#endif
HardwareID::HardwareID()
: block_count_(0), start_block_(0)
{
uint64_t timestamp = __rdtsc(); // exactly 8 bytes
timestamp ^= ~timestamp << 32; // remove zeroes at the beginning
blocks_ = new CryptoContainer(sizeof(uint32_t) * MAX_BLOCKS, reinterpret_cast<uint8_t *>(&timestamp));
// old methods
GetCPU(0);
GetCPU(1);
start_block_ = block_count_;
// new methods, we'll return HWID starting from this DWORD
GetCPU(2);
GetMachineName();
GetHDD();
GetMacAddresses();
}
HardwareID::~HardwareID()
{
delete blocks_;
}
void HardwareID::AddBlock(const void *p, size_t size, BlockType type)
{
if (block_count_ == MAX_BLOCKS) return; // no free space
SHA1 hash;
hash.Input(reinterpret_cast<const uint8_t *>(p), size);
uint32_t block = __builtin_bswap32(*reinterpret_cast<const uint32_t *>(hash.Result()));
block &= ~TYPE_MASK; // zero two lower bits
block |= type & TYPE_MASK; // set type bits
// check existing blocks
for (size_t i = block_count_; i > start_block_; i--) {
uint32_t prev_block = blocks_->GetDWord((i - 1) * sizeof(uint32_t));
if (prev_block == block)
return;
if ((prev_block & TYPE_MASK) != (block & TYPE_MASK))
break;
}
blocks_->SetDWord(block_count_ * sizeof(uint32_t), block);
block_count_++;
}
void HardwareID::GetCPU(uint8_t method)
{
uint32_t old_block_count = block_count_;
#ifdef WIN_DRIVER
KAFFINITY system_mask = KeQueryActiveProcessors();
KAFFINITY mask = 1;
#endif
#ifdef VMP_GNU
// set process affinity mask to system affinity mask
#ifdef __APPLE__
//FIXME
if (0) {
#else
cpu_set_t process_mask, system_mask;
memset(&system_mask, 0xFF, sizeof(system_mask));
if (0 == sched_getaffinity(0, sizeof(process_mask), &process_mask)) {
sched_setaffinity(0, sizeof(system_mask), &system_mask); //try all CPUs, will set MAX CPUs
sched_getaffinity(0, sizeof(system_mask), &system_mask); //get MAX CPUs
#endif
#else
#ifndef WIN_DRIVER
DWORD_PTR process_mask, system_mask;
HANDLE process = GetCurrentProcess();
if (GetProcessAffinityMask(process, &process_mask, &system_mask)) {
if (process_mask != system_mask)
SetProcessAffinityMask(process, system_mask);
DWORD_PTR mask = 1;
HANDLE thread = GetCurrentThread();
#endif
#endif
#ifdef VMP_GNU
// set thread affinity mask to mask
#ifdef __APPLE__
//FIXME
while (false) {
if (false) {
#else
for (size_t i = 0; i < sizeof(system_mask) * 8; i++) {
if (__CPU_ISSET_S(i, sizeof(system_mask), &system_mask)) {
cpu_set_t mask;
__CPU_ZERO_S(sizeof(mask), &mask);
__CPU_SET_S(i, sizeof(mask), &mask);
sched_setaffinity(0, sizeof(mask), &mask);
#endif
#else
for (size_t i = 0; i < sizeof(mask) * 8; i++) {
if (system_mask & mask) {
#ifdef WIN_DRIVER
KeSetSystemAffinityThread(mask);
#else
DWORD_PTR old_mask = SetThreadAffinityMask(thread, mask);
Sleep(0);
#endif
#endif
ProcessCPU(method);
#ifdef VMP_GNU
// set thread affinity mask back to old_mask
#ifdef __APPLE__
//FIXME
#else
//do nothing
#endif
#else
#ifdef WIN_DRIVER
KeRevertToUserAffinityThread();
#else
SetThreadAffinityMask(thread, old_mask);
#endif
#endif
}
#ifndef VMP_GNU
mask <<= 1;
#endif
}
#ifndef WIN_DRIVER
#ifdef VMP_GNU
// set process affinity mask back to process_mask
#ifdef __APPLE__
//FIXME
#else
sched_setaffinity(0, sizeof(process_mask), &process_mask);
#endif
#else
if (process_mask != system_mask)
SetProcessAffinityMask(process, process_mask);
#endif
}
#endif
if (old_block_count == block_count_)
ProcessCPU(method);
}
void HardwareID::ProcessCPU(uint8_t method)
{
int info[4];
__cpuid(info, 1);
if ((info[0] & 0xFF0) == 0xFE0)
info[0] ^= 0x20; // fix Athlon bug
info[1] &= 0x00FFFFFF; // mask out APIC Physical ID
if (method == 2) {
info[2] = 0;
} else if (method == 1) {
info[2] &= ~(1 << 27);
}
AddBlock(info, sizeof(info), BLOCK_CPU);
}
void HardwareID::GetMachineName()
{
#ifdef __APPLE__
CFStringRef computer_name = SCDynamicStoreCopyComputerName(NULL, NULL);
if (!computer_name)
return;
CFIndex len = CFStringGetLength(computer_name);
CFIndex size = CFStringGetMaximumSizeForEncoding(len, kCFStringEncodingUTF8);
char *buf = new char[size];
if (CFStringGetCString(computer_name, buf, size, kCFStringEncodingUTF8))
AddBlock(buf, strlen(buf), BLOCK_HOST);
delete [] buf;
CFRelease(computer_name);
#elif defined(__unix__)
char buf[HOST_NAME_MAX+1] = {0};
if (0 == gethostname(buf, HOST_NAME_MAX))
AddBlock(buf, strlen(buf), BLOCK_HOST);
#elif defined(WIN_DRIVER)
#define MAX_COMPUTERNAME_LENGTH 31
wchar_t buf[MAX_COMPUTERNAME_LENGTH + 1];
size_t size = _countof(buf);
if (GetRegValue(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ComputerName", L"ComputerName", buf, &size) ||
GetRegValue(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName", L"ComputerName", buf, &size)) {
AddBlock(buf, size * sizeof(wchar_t), BLOCK_HOST);
}
#else
HMODULE dll = LoadLibraryA(VMProtectDecryptStringA("kernel32.dll"));
if (!dll)
return;
typedef ULONG (WINAPI *GET_COMPUTER_NAME) (wchar_t *, uint32_t *);
GET_COMPUTER_NAME get_computer_name = reinterpret_cast<GET_COMPUTER_NAME>(InternalGetProcAddress(dll, VMProtectDecryptStringA("GetComputerNameW")));
if (get_computer_name) {
wchar_t buf[MAX_COMPUTERNAME_LENGTH + 1];
uint32_t size = _countof(buf);
if (get_computer_name(buf, &size))
AddBlock(buf, size * sizeof(wchar_t), BLOCK_HOST);
}
FreeLibrary(dll);
#endif
}
void HardwareID::ProcessMAC(const uint8_t *p, size_t size)
{
// this big IF construction allows to put constants to the code, not to the data segment
// it is harder to find them in the code after virtualisation
uint32_t dw = (p[0] << 16) + (p[1] << 8) + p[2];
if (dw == 0x000569 || dw == 0x000C29 || dw == 0x001C14 || dw == 0x005056 || // vmware
dw == 0x0003FF || dw == 0x000D3A || dw == 0x00125A || dw == 0x00155D || dw == 0x0017FA || dw == 0x001DD8 || dw == 0x002248 || dw == 0x0025AE || dw == 0x0050F2 || // microsoft
dw == 0x001C42 || // parallels
dw == 0x0021F6) // virtual iron
return;
AddBlock(p, size, BLOCK_MAC);
}
void HardwareID::GetMacAddresses()
{
#ifdef __APPLE__
ifaddrs *addrs;
if (getifaddrs(&addrs) == 0) {
uint32_t block_count_no_mac = block_count_;
const uint8_t *mac = NULL;
size_t size = 0;
for (ifaddrs *cur_addr = addrs; cur_addr != 0; cur_addr = cur_addr->ifa_next) {
if (cur_addr->ifa_addr->sa_family != AF_LINK)
continue;
const sockaddr_dl *dl_addr = reinterpret_cast<const sockaddr_dl *>(cur_addr->ifa_addr);
if (dl_addr->sdl_type == IFT_ETHER) {
mac = reinterpret_cast<const uint8_t *>(&dl_addr->sdl_data[dl_addr->sdl_nlen]);
size = dl_addr->sdl_alen;
ProcessMAC(mac, size);
}
}
if (block_count_no_mac == block_count_ && mac && size)
AddBlock(mac, size, BLOCK_MAC);
freeifaddrs(addrs);
}
#elif defined(__unix__)
std::string dir_name("/sys/class/net/");
if (DIR *dir = opendir(dir_name.c_str())) {
uint32_t block_count_no_mac = block_count_;
uint8_t mac[6];
size_t size = 0;
while (struct dirent *entry = readdir(dir)) {
// skip "." and ".."
if (entry->d_name[0] == '.') {
if (entry->d_name[1] == 0 || (entry->d_name[1] == '.' && entry->d_name[2] == 0))
continue;
}
struct stat st;
if (fstatat(dirfd(dir), entry->d_name, &st, 0) >= 0 && S_ISDIR(st.st_mode)) {
std::string file_name = dir_name + entry->d_name + "/address";
if (FILE *faddr = fopen(file_name.c_str(), "r")) {
char addr[18] = {0};
if (fgets(addr, sizeof(addr) - 1, faddr)) {
uint8_t m[6];
size_t c = sscanf_s(addr, "%02hx:%02hx:%02hx:%02hx:%02hx:%02hx",
m+0, m+1, m+2, m+3, m+4, m+5);
if (c == 6 && m[0]+m[1]+m[2]+m[3]+m[4]+m[5] != 0) {
memcpy(mac, m, sizeof(mac));
size = c;
ProcessMAC(mac, size);
}
}
fclose(faddr);
}
}
}
closedir(dir);
if (block_count_no_mac == block_count_ && size)
AddBlock(mac, size, BLOCK_MAC);
}
#elif defined(WIN_DRIVER)
UNICODE_STRING unicode_string;
OBJECT_ATTRIBUTES object_attributes;
NTSTATUS status;
HANDLE key_handle, file_handle, event_handle;
IO_STATUS_BLOCK status_block;
ULONG code = OID_802_3_CURRENT_ADDRESS;
uint8_t mac[6];
size_t size = 0;
InitializeObjectAttributes(&object_attributes, NULL, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwCreateEvent(&event_handle, EVENT_ALL_ACCESS, &object_attributes, NotificationEvent, FALSE);
if (!NT_SUCCESS(status))
return;
RtlInitUnicodeString(&unicode_string, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters");
InitializeObjectAttributes(&object_attributes, &unicode_string, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenKey(&key_handle, GENERIC_READ, &object_attributes);
if (NT_SUCCESS(status)) {
uint32_t block_count_no_mac = block_count_;
ULONG sub_key_size = sizeof(KEY_BASIC_INFORMATION) + sizeof(wchar_t) * MAX_PATH;
KEY_BASIC_INFORMATION *sub_key_value = static_cast<KEY_BASIC_INFORMATION *>(ExAllocatePool(PagedPool, sub_key_size));
wchar_t *service_name = static_cast<wchar_t *>(ExAllocatePool(PagedPool, sizeof(wchar_t) * MAX_PATH));
ULONG ret_size;
for (ULONG i = 0; NT_SUCCESS(ZwEnumerateKey(key_handle, i, KeyBasicInformation, sub_key_value, sub_key_size, &ret_size)); i++) {
if (sub_key_value->NameLength > (MAX_PATH - 10) * sizeof(wchar_t))
continue;
if (sub_key_value->NameLength == 18 && _wcsnicmp(sub_key_value->Name, L"NdisWanIp", 9) == 0)
continue;
RtlZeroMemory(service_name, sizeof(wchar_t) * MAX_PATH);
#if WDK_NTDDI_VERSION > NTDDI_WIN7
wcscat_s(service_name, MAX_PATH, L"\\??\\");
#else
wcscat(service_name, L"\\??\\");
#endif
RtlCopyMemory(service_name + wcslen(service_name), sub_key_value->Name, sub_key_value->NameLength);
RtlInitUnicodeString(&unicode_string, service_name);
InitializeObjectAttributes(&object_attributes, &unicode_string, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenFile(&file_handle, 0, &object_attributes, &status_block, FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
if (NT_SUCCESS(status)) {
status = ZwDeviceIoControlFile(file_handle, event_handle, 0, 0, &status_block, IOCTL_NDIS_QUERY_GLOBAL_STATS, &code, sizeof(code), mac, sizeof(mac));
if (status == STATUS_PENDING)
status = ZwWaitForSingleObject(event_handle, FALSE, NULL);
if (NT_SUCCESS(status)) {
size = sizeof(mac);
ProcessMAC(mac, size);
}
ZwClose(file_handle);
}
}
ExFreePool(service_name);
ExFreePool(sub_key_value);
ZwClose(key_handle);
if (block_count_no_mac == block_count_ && size)
AddBlock(mac, size, BLOCK_MAC);
}
ZwClose(event_handle);
#else
HMODULE dll = LoadLibraryA(VMProtectDecryptStringA("iphlpapi.dll"));
if (!dll)
return;
typedef ULONG (WINAPI *GET_ADAPTERS_INFO) (PIP_ADAPTER_INFO AdapterInfo, PULONG SizePointer);
GET_ADAPTERS_INFO get_adapters_info = reinterpret_cast<GET_ADAPTERS_INFO>(InternalGetProcAddress(dll, VMProtectDecryptStringA("GetAdaptersInfo")));
if (get_adapters_info) {
ULONG buf_len = 0;
if (ERROR_BUFFER_OVERFLOW == get_adapters_info(NULL, &buf_len)) {
uint32_t block_count_no_mac = block_count_;
const uint8_t *mac = NULL;
size_t size = 0;
uint8_t *info = new uint8_t[buf_len];
if (ERROR_SUCCESS == get_adapters_info(reinterpret_cast<IP_ADAPTER_INFO *>(info), &buf_len)) {
for (IP_ADAPTER_INFO *adapter_info = reinterpret_cast<IP_ADAPTER_INFO *>(info); adapter_info != 0; adapter_info = adapter_info->Next) {
mac = adapter_info->Address;
size = adapter_info->AddressLength;
ProcessMAC(mac, size);
}
}
if (block_count_no_mac == block_count_ && mac && size)
AddBlock(mac, size, BLOCK_MAC);
delete [] info;
}
}
FreeLibrary(dll);
#endif
}
void HardwareID::GetHDD()
{
#ifdef __APPLE__
DASessionRef session = DASessionCreate(NULL);
if (session) {
struct statfs statFS;
statfs ("/", &statFS);
DADiskRef disk = DADiskCreateFromBSDName(NULL, session, statFS.f_mntfromname);
if (disk) {
CFDictionaryRef descDict = DADiskCopyDescription(disk);
if (descDict) {
CFUUIDRef value = (CFUUIDRef)CFDictionaryGetValue(descDict, CFSTR("DAVolumeUUID"));
CFUUIDBytes bytes = CFUUIDGetUUIDBytes(value);
AddBlock(&bytes, sizeof(bytes), BLOCK_HDD);
CFRelease(descDict);
}
CFRelease(disk);
}
CFRelease(session);
}
#elif defined(__unix__)
std::string root_uuid;
if (FILE *mtab = setmntent("/etc/mtab", "r")) {
std::string root_fs_path;
while (struct mntent *entry = getmntent(mtab)) {
if (entry->mnt_dir[0] == '/' && entry->mnt_dir[1] == 0) {
root_fs_path = entry->mnt_fsname;
break;
}
}
endmntent(mtab);
if (!root_fs_path.empty()) {
std::string dir_name("/dev/disk/by-uuid/");
if (DIR *dir = opendir(dir_name.c_str())) {
while (struct dirent *entry = readdir(dir)) {
// skip "." and ".."
if (entry->d_name[0] == '.') {
if (entry->d_name[1] == 0 || (entry->d_name[1] == '.' && entry->d_name[2] == 0))
continue;
}
char resolved_link_path[PATH_MAX];
std::string path = dir_name + entry->d_name;
if (realpath(path.c_str(), resolved_link_path)) {
if (strcmp(resolved_link_path, root_fs_path.c_str()) == 0) {
root_uuid = entry->d_name;
break;
}
}
}
closedir(dir);
}
}
}
if (!root_uuid.empty())
AddBlock(root_uuid.c_str(), root_uuid.size(), BLOCK_HDD);
#elif defined(WIN_DRIVER)
wchar_t buf[MAX_PATH];
size_t size = _countof(buf);
UNICODE_STRING unicode_string;
OBJECT_ATTRIBUTES object_attributes;
NTSTATUS status;
HANDLE handle;
IO_STATUS_BLOCK status_block;
if (!GetRegValue(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion", L"SystemRoot", buf, &size))
return;
if (buf[1] == ':' && buf[2] == '\\') {
wchar_t system_drive[] = {'\\', 'D', 'o', 's', 'D', 'e', 'v', 'i', 'c', 'e', 's', '\\', buf[0], ':', '\\', 0};
RtlInitUnicodeString(&unicode_string, system_drive);
InitializeObjectAttributes(&object_attributes, &unicode_string, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwCreateFile(&handle, SYNCHRONIZE | FILE_READ_ACCESS,
&object_attributes,
&status_block,
NULL,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (NT_SUCCESS(status)) {
RtlInitUnicodeString(&unicode_string, L"ZwQueryVolumeInformationFile");
typedef NTSTATUS (NTAPI *QUERY_VOLUME_INFORMATION_FILE) (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FS_INFORMATION_CLASS);
QUERY_VOLUME_INFORMATION_FILE query_volume_information_file = reinterpret_cast<QUERY_VOLUME_INFORMATION_FILE>(MmGetSystemRoutineAddress(&unicode_string));
if (query_volume_information_file) {
ULONG size = sizeof(FILE_FS_VOLUME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
FILE_FS_VOLUME_INFORMATION *information = reinterpret_cast<FILE_FS_VOLUME_INFORMATION*>(new uint8_t[size]);
status = query_volume_information_file(handle, &status_block, information, size, FileFsVolumeInformation);
if (NT_SUCCESS(status))
AddBlock(&information->VolumeSerialNumber, sizeof(information->VolumeSerialNumber), BLOCK_HDD);
delete [] information;
}
ZwClose(handle);
}
}
#else
HMODULE dll = LoadLibraryA(VMProtectDecryptStringA("kernel32.dll"));
if (!dll)
return;
typedef ULONG (WINAPI *GET_WINDOWS_DIRECTORY) (wchar_t *, DWORD);
GET_WINDOWS_DIRECTORY get_windows_directory = reinterpret_cast<GET_WINDOWS_DIRECTORY>(InternalGetProcAddress(dll, VMProtectDecryptStringA("GetWindowsDirectoryW")));
typedef BOOL (WINAPI *GET_VOLUME_INFORMATION) (const wchar_t *, wchar_t *, DWORD, DWORD *, DWORD *, DWORD *, wchar_t *, DWORD);
GET_VOLUME_INFORMATION get_volume_information = reinterpret_cast<GET_VOLUME_INFORMATION>(InternalGetProcAddress(dll, VMProtectDecryptStringA("GetVolumeInformationW")));
if (get_windows_directory && get_volume_information) {
wchar_t buf[MAX_PATH] = {0};
UINT ures = get_windows_directory(buf, _countof(buf));
if (ures > 0 && buf[1] == ':' && buf[2] == '\\') {
buf[3] = 0;
DWORD volumeSerialNumber = 0;
if (get_volume_information(buf, NULL, 0, &volumeSerialNumber, NULL, NULL, NULL, 0)) {
AddBlock(&volumeSerialNumber, sizeof(volumeSerialNumber), BLOCK_HDD);
}
}
}
FreeLibrary(dll);
#endif
}
size_t HardwareID::Copy(void *dest, size_t size) const
{
uint32_t *p = reinterpret_cast<uint32_t *>(dest);
// need skip old methods
size_t res = std::min(static_cast<size_t>(block_count_ - start_block_), size / sizeof(uint32_t));
for (size_t i = 0; i < res; i++) {
p[i] = blocks_->GetDWord((start_block_ + i) * sizeof(uint32_t));
}
return res * sizeof(uint32_t);
}
/*
Rules:
1. if pointer to buffer is NULL, second parameter is ignored and returned size of buffer that will fit HWID (with trailing 0)
2. if buffer is ok and the second parameters is zero, we should return zero and doesn't change the buffer
3. if buffer is OK and the second parameter is less than we need, we should return as much bytes as we can and return the second parameter itself
and we should put 0 to the last available position at buffer
4. if buffer is bigger that we need, we should put HWID, trailing 0 and return strlen(hwid) + 1
*/
int HardwareID::GetCurrent(char *buffer, int size)
{
if (buffer && size == 0)
return 0; // see rule #2
uint8_t b[MAX_BLOCKS *sizeof(uint32_t)];
size_t hwid_size = Copy(b, sizeof(b));
size_t need_size = Base64EncodeGetRequiredLength(hwid_size);
char *p = new char[need_size + 1];
Base64Encode(b, hwid_size, p, need_size); // it never should return false
size_t copy = 0;
if (buffer) {
// if nSize is less, we have to leave space for trailing zero (see rule #3)
// if nNeedSize is less, we already have this space, as we allocated nNeedSize + 1 bytes
copy = std::min(static_cast<size_t>(size - 1), need_size);
for (size_t i = 0; i < copy; i++) {
buffer[i] = p[i];
}
buffer[copy++] = 0;
}
else {
// see rule #1
copy = need_size + 1;
}
delete [] p;
return static_cast<int>(copy);
}
bool HardwareID::IsCorrect(uint8_t *p, size_t size) const
{
if (p == 0 || size == 0 || (size & 3))
return false;
bool equals[4];
bool found[4];
for (size_t i = 0; i < 4; i++) {
equals[i] = false;
found[i] = false;
}
size_t blocks = size / sizeof(uint32_t);
uint32_t *d = reinterpret_cast<uint32_t *>(p);
for (size_t j = 0; j < block_count_; j++) {
uint32_t id1 = blocks_->GetDWord(j * sizeof(uint32_t));
found[id1 & 3] = true;
for (size_t i = 0; i < blocks; i++) {
uint32_t id2 = d[i];
if (id1 == id2) {
equals[id1 & 3] = true;
break;
}
}
}
// check CPU
if (!equals[0])
return false;
// check if at least 3 items are OK
size_t n = 0;
size_t c = 0;
for (size_t i = 0; i < 4; i++) {
if (found[i])
c++;
if (equals[i])
n++;
}
return (n == c || n >= 3);
}
bool HardwareID::IsCorrect(CryptoContainer &cont, size_t offset, size_t size) const
{
if (size == 0 || (size & 3) || size > MAX_BLOCKS * sizeof(uint32_t))
return false;
uint32_t buff[MAX_BLOCKS];
for (size_t i = 0; i < size / sizeof(uint32_t); i++) {
buff[i] = cont.GetDWord(offset + i * sizeof(uint32_t));
}
return IsCorrect(reinterpret_cast<uint8_t *>(buff), size);
}

45
runtime/hwid.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef HWID_H
#define HWID_H
class CryptoContainer;
class HardwareID
{
public:
HardwareID();
~HardwareID();
size_t Copy(void *dest, size_t size) const;
int GetCurrent(char *buffer, int size);
bool IsCorrect(uint8_t *p, size_t s) const;
bool IsCorrect(CryptoContainer &cont, size_t offset, size_t size) const;
private:
enum {
MAX_BLOCKS = 16,
TYPE_MASK = 3
};
enum BlockType {
BLOCK_CPU,
BLOCK_HOST,
BLOCK_MAC,
BLOCK_HDD,
};
uint32_t block_count_;
uint32_t start_block_;
CryptoContainer *blocks_;
void AddBlock(const void *p, size_t size, BlockType type);
void ProcessMAC(const uint8_t *p, size_t size);
void ProcessCPU(uint8_t method);
void GetCPU(uint8_t method);
void GetMacAddresses();
void GetMachineName();
void GetHDD();
// no copy ctr or assignment op
HardwareID(const HardwareID &);
HardwareID &operator =(const HardwareID &);
};
#endif

1135
runtime/licensing_manager.cc Normal file

File diff suppressed because it is too large Load Diff

100
runtime/licensing_manager.h Normal file
View File

@ -0,0 +1,100 @@
#ifndef LICENSING_MANAGER_H
#define LICENSING_MANAGER_H
class CryptoContainer;
class LicensingManager
{
public:
LicensingManager(uint8_t *data, uint32_t size, uint8_t *key);
~LicensingManager();
int SetSerialNumber(const char *serial);
int GetSerialNumberState();
bool GetSerialNumberData(VMProtectSerialNumberData *data, int size);
int ActivateLicense(const char *code, char *serial, int size) const;
int DeactivateLicense(const char *serial) const;
int GetOfflineActivationString(const char *code, char *buf, int size) const;
int GetOfflineDeactivationString(const char *serial, char *buf, int size) const;
void DecryptBuffer(uint8_t *buffer);
static uint32_t GetCurrentDate();
private:
enum ChunkType
{
SERIAL_CHUNK_VERSION = 0x01, // 1 byte of data - version
SERIAL_CHUNK_USER_NAME = 0x02, // 1 + N bytes - length + N bytes of customer's name (without enging \0).
SERIAL_CHUNK_EMAIL = 0x03, // 1 + N bytes - length + N bytes of customer's email (without ending \0).
SERIAL_CHUNK_HWID = 0x04, // 1 + N bytes - length + N bytes of hardware id (N % 4 == 0)
SERIAL_CHUNK_EXP_DATE = 0x05, // 4 bytes - (year << 16) + (month << 8) + (day)
SERIAL_CHUNK_RUNNING_TIME_LIMIT = 0x06, // 1 byte - number of minutes
SERIAL_CHUNK_PRODUCT_CODE = 0x07, // 8 bytes - used for decrypting some parts of exe-file
SERIAL_CHUNK_USER_DATA = 0x08, // 1 + N bytes - length + N bytes of user data
SERIAL_CHUNK_MAX_BUILD = 0x09, // 4 bytes - (year << 16) + (month << 8) + (day)
SERIAL_CHUNK_END = 0xFF // 4 bytes - checksum: the first four bytes of sha-1 hash from the data before that chunk
};
int save_state(int state);
int ParseSerial(VMProtectSerialNumberData *data);
bool CheckLicenseDataCRC() const;
bool SendRequest(char *url, char *response, size_t size) const;
CryptoContainer *license_data_;
int state_;
uint32_t start_tick_count_;
size_t start_;
CryptoContainer *serial_;
uint64_t product_code_;
uint32_t session_key_;
CRITICAL_SECTION critical_section_;
// no copy ctr or assignment op
LicensingManager(const LicensingManager &);
LicensingManager &operator =(const LicensingManager &);
};
#ifndef WIN_DRIVER
class BaseRequest
{
public:
BaseRequest();
virtual ~BaseRequest();
bool Send();
const char *response() const { return response_; }
const char *url() const { return url_; }
protected:
bool BuildUrl(const CryptoContainer &license_data);
void EncodeUrl();
void AppendUrlParam(const char *param, const char *value);
private:
void AppendUrl(const char *str, bool escape);
char url_[2048];
char *response_;
// no copy ctr or assignment op
BaseRequest(const BaseRequest &);
BaseRequest &operator =(const BaseRequest &);
};
class ActivationRequest : public BaseRequest
{
public:
ActivationRequest();
int Process(const CryptoContainer &license_data, const char *code, bool offline);
const char *serial() const { return serial_; }
private:
bool VerifyCode(const char *code) const;
bool BuildUrl(const CryptoContainer &license_data, const char *code, bool offline);
const char *serial_;
};
class DeactivationRequest : public BaseRequest
{
public:
int Process(const CryptoContainer &license_data, const char *serial, bool offline);
private:
bool VerifySerial(const char *serial) const;
bool BuildUrl(const CryptoContainer &license_data, const char *serial, bool offline);
};
#endif
#endif

32
runtime/lin_runtime.mak Normal file
View File

@ -0,0 +1,32 @@
SOURCES := core.cc crypto.cc loader.cc licensing_manager.cc string_manager.cc hwid.cc objects.cc utils.cc ../third-party/lzma/LzmaDecode.cc
PROJECT := lin_runtime
TARGET := $(PROJECT).so
BIN_DIR := ../bin/$(ARCH_DIR)/Release
LIB_TARGET := $(BIN_DIR)/$(PROJECT).a
TMP_DIR := ../tmp/lin/runtime/$(ARCH_DIR)/runtime
PCH_DIR := $(TMP_DIR)/runtime.gch
DEFINES :=
LFLAGS := $(LFLAGS) -Wl,--no-undefined -shared -Wl,--wrap=memcpy -Wl,--wrap=__poll_chk -Wl,--wrap=__fdelt_chk
LIBS = ~/curl-7.35.0-$(ARCH_DIR)/lib/libcurl.so -ldl -lrt -L../bin/ -lVMProtectSDK$(ARCH_DIR)
DYLIBS := ../bin/libVMProtectSDK$(ARCH_DIR).so
OBJCOMP :=
OBJECTS := $(addprefix $(TMP_DIR)/, $(SOURCES:.cc=.o))
INCFLAGS := -I ~/curl-7.35.0-$(ARCH_DIR)/include
include ../lin_common.mak
clean:
-$(DEL_FILE) $(LIB_TARGET)
-$(DEL_FILE) $(OBJECTS)
-$(DEL_FILE) $(PCH_CPP)
-$(DEL_FILE) $(BIN_TARGET)
$(LIB_TARGET): $(OBJECTS) $(BIN_DIR)/.sentinel
ar $(SLIBFLAGS) $(LIB_TARGET) $(abspath $(OBJECTS)) $(OBJCOMP)
$(BIN_TARGET): $(LIB_TARGET) $(OBJCOMP) $(DYLIBS)
$(LINK) $(LFLAGS) -o $(BIN_TARGET) $(OBJECTS) $(LIBS) $(OBJCOMP)
$(TMP_DIR)/%.o: %.cc $(PCH_CPP) $(TMP_DIR)/%/../.sentinel
$(CXX) -c -include-pch $(PCH_CPP) $(CXXFLAGS) $(INCFLAGS) -o $(abspath $@) $(abspath $<)

View File

@ -0,0 +1,3 @@
ARCH := i386-linux-gnu
ARCH_DIR := 32
include lin_runtime.mak

View File

@ -0,0 +1,4 @@
ARCH := x86_64-linux-gnu
ARCH_DIR := 64
LFLAGS := $(LFLAGS) -Wl,-z,max-page-size=4096
include lin_runtime.mak

2946
runtime/loader.cc Normal file

File diff suppressed because it is too large Load Diff

570
runtime/loader.h Normal file
View File

@ -0,0 +1,570 @@
#ifndef LOADER_H
#define LOADER_H
#pragma pack(push, 1)
struct CRC_INFO {
uint32_t Address;
uint32_t Size;
uint32_t Hash;
};
struct FILE_CRC_INFO {
uint32_t FileSize;
// CRCInfo crc_info[1]
};
struct SECTION_INFO {
uint32_t Address;
uint32_t Size;
uint32_t Type;
};
struct PACKER_INFO {
uint32_t Src;
uint32_t Dst;
};
struct IAT_INFO {
uint32_t Src;
uint32_t Dst;
uint32_t Size;
};
struct DLL_INFO {
uint32_t Name;
// IMPORT_INFO import_info[1];
};
struct IMPORT_INFO {
uint32_t Name;
uint32_t Address;
int32_t Key;
};
struct FIXUP_INFO {
uint32_t Address;
uint32_t BlockSize;
// uint32_t type_offset[1];
};
struct RELOCATION_INFO {
uint32_t Address;
uint32_t Source;
uint32_t Type;
};
struct SETUP_IMAGE_DATA {
NOINLINE SETUP_IMAGE_DATA() { empty_ = 0; }
NOINLINE uint8_t *file_base() { return reinterpret_cast<uint8_t *>(FACE_FILE_BASE) - empty_; }
NOINLINE uint8_t *image_base() { return reinterpret_cast<uint8_t *>(FACE_IMAGE_BASE) - empty_; }
NOINLINE uint32_t options() { return FACE_LOADER_OPTIONS - empty_; }
NOINLINE uint32_t storage() { return FACE_LOADER_DATA - empty_; }
NOINLINE uint32_t runtime_entry() { return FACE_RUNTIME_ENTRY - empty_; }
#ifdef __unix__
NOINLINE uint32_t relro_info() { return FACE_GNU_RELRO_INFO - empty_; }
#elif defined(__APPLE__)
#elif defined(WIN_DRIVER)
#else
NOINLINE uint32_t tls_index_info() { return FACE_TLS_INDEX_INFO - empty_; }
#endif
// file CRC information
NOINLINE uint32_t file_crc_info() { return FACE_FILE_CRC_INFO - empty_; }
NOINLINE uint32_t file_crc_info_size() { return FACE_FILE_CRC_INFO_SIZE - empty_; }
// header and loader CRC information
NOINLINE uint32_t loader_crc_info() { return FACE_LOADER_CRC_INFO - empty_; }
NOINLINE uint32_t loader_crc_info_size() { return FACE_LOADER_CRC_INFO_SIZE - empty_; }
NOINLINE uint32_t loader_crc_info_hash() { return FACE_LOADER_CRC_INFO_HASH - empty_; }
// section information
NOINLINE uint32_t section_info() { return FACE_SECTION_INFO - empty_; }
NOINLINE uint32_t section_info_size() { return FACE_SECTION_INFO_SIZE - empty_; }
// packer information
NOINLINE uint32_t packer_info() { return FACE_PACKER_INFO - empty_; }
NOINLINE uint32_t packer_info_size() { return FACE_PACKER_INFO_SIZE - empty_; }
// fixups information
NOINLINE uint32_t fixup_info() { return FACE_FIXUP_INFO - empty_; }
NOINLINE uint32_t fixup_info_size() { return FACE_FIXUP_INFO_SIZE - empty_; }
// relocations information
NOINLINE uint32_t relocation_info() { return FACE_RELOCATION_INFO - empty_; }
NOINLINE uint32_t relocation_info_size() { return FACE_RELOCATION_INFO_SIZE - empty_; }
// IAT information
NOINLINE uint32_t iat_info() { return FACE_IAT_INFO - empty_; }
NOINLINE uint32_t iat_info_size() { return FACE_IAT_INFO_SIZE - empty_; }
// import information
NOINLINE uint32_t import_info() { return FACE_IMPORT_INFO - empty_; }
NOINLINE uint32_t import_info_size() { return FACE_IMPORT_INFO_SIZE - empty_; }
// internal import information
NOINLINE uint32_t internal_import_info() { return FACE_INTERNAL_IMPORT_INFO - empty_; }
NOINLINE uint32_t internal_import_info_size() { return FACE_INTERNAL_IMPORT_INFO_SIZE - empty_; }
// memory CRC information
NOINLINE uint32_t memory_crc_info() { return FACE_MEMORY_CRC_INFO - empty_; }
NOINLINE uint32_t memory_crc_info_size() { return FACE_MEMORY_CRC_INFO_SIZE - empty_; }
NOINLINE uint32_t memory_crc_info_hash() { return FACE_MEMORY_CRC_INFO_HASH - empty_; }
// delay import information
NOINLINE uint32_t delay_import_info() { return FACE_DELAY_IMPORT_INFO - empty_; }
NOINLINE uint32_t delay_import_info_size() { return FACE_DELAY_IMPORT_INFO_SIZE - empty_; }
private:
uint32_t empty_;
};
#pragma pack(pop)
#ifndef VMP_GNU
#define MAXIMUM_FILENAME_LENGTH 256
typedef struct _SYSTEM_MODULE_ENTRY
{
#ifdef _WIN64
ULONGLONG Unknown1;
ULONGLONG Unknown2;
#else
ULONG Unknown1;
ULONG Unknown2;
#endif
PVOID BaseAddress;
ULONG Size;
ULONG Flags;
ULONG EntryIndex;
USHORT NameLength; // Length of module name not including the path, this field contains valid value only for NTOSKRNL module
USHORT PathLength; // Length of 'directory path' part of modulename
CHAR Name[MAXIMUM_FILENAME_LENGTH];
} SYSTEM_MODULE_ENTRY;
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Count;
#ifdef _WIN64
ULONG Unknown1;
#endif
SYSTEM_MODULE_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION;
typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION
{
BOOLEAN DebuggerEnabled;
BOOLEAN DebuggerNotPresent;
} SYSTEM_KERNEL_DEBUGGER_INFORMATION;
typedef enum _MEMORY_INFORMATION_CLASS {
MemoryBasicInformation
} MEMORY_INFORMATION_CLASS, *PMEMORY_INFORMATION_CLASS;
#ifdef WIN_DRIVER
#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
#define IMAGE_OS2_SIGNATURE 0x454E // NE
#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
#define IMAGE_VXD_SIGNATURE 0x454C // LE
#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
#pragma pack(push, 2)
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
#pragma pack(pop)
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
//
// NT additional fields.
//
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_ROM_OPTIONAL_HEADER {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD BaseOfBss;
DWORD GprMask;
DWORD CprMask[4];
DWORD GpValue;
} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER;
typedef struct _IMAGE_OPTIONAL_HEADER64 {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
ULONGLONG ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
ULONGLONG SizeOfStackReserve;
ULONGLONG SizeOfStackCommit;
ULONGLONG SizeOfHeapReserve;
ULONGLONG SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
typedef struct _IMAGE_NT_HEADERS64 {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
typedef struct _IMAGE_ROM_HEADERS {
IMAGE_FILE_HEADER FileHeader;
IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS;
#ifdef _WIN64
typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS;
typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS;
#else
typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS;
typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS;
#endif
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[8];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
// IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage)
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
#define IMAGE_REL_BASED_ABSOLUTE 0
#define IMAGE_REL_BASED_HIGH 1
#define IMAGE_REL_BASED_LOW 2
#define IMAGE_REL_BASED_HIGHLOW 3
#define IMAGE_REL_BASED_HIGHADJ 4
#define IMAGE_REL_BASED_MIPS_JMPADDR 5
#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
#define IMAGE_REL_BASED_IA64_IMM64 9
#define IMAGE_REL_BASED_DIR64 10
#define IMAGE_ORDINAL_FLAG64 0x8000000000000000
#define IMAGE_ORDINAL_FLAG32 0x80000000
#define IMAGE_ORDINAL64(Ordinal) (Ordinal & 0xffff)
#define IMAGE_ORDINAL32(Ordinal) (Ordinal & 0xffff)
#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64) != 0)
#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG32) != 0)
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions; // RVA from base of image
DWORD AddressOfNames; // RVA from base of image
DWORD AddressOfNameOrdinals; // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
#define MAX_PATH 260
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemModuleInformation = 0xb,
SystemKernelDebuggerInformation = 0x23,
SystemFirmwareTableInformation = 0x4c
} SYSTEM_INFORMATION_CLASS;
extern "C" {
NTKERNELAPI NTSTATUS NTAPI NtQuerySystemInformation(
SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength);
}
#else
#define FILE_OPEN 0x00000001
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040
typedef enum _SECTION_INHERIT {
ViewShare=1,
ViewUnmap=2
} SECTION_INHERIT, *PSECTION_INHERIT;
#define SystemModuleInformation (SYSTEM_INFORMATION_CLASS)11
#define SystemKernelDebuggerInformation (SYSTEM_INFORMATION_CLASS)35
#define ThreadHideFromDebugger (THREADINFOCLASS)17
#define ProcessDebugPort (PROCESSINFOCLASS)0x7
#define ProcessDebugObjectHandle (PROCESSINFOCLASS)0x1e
#define ProcessDefaultHardErrorMode (PROCESSINFOCLASS)0x0c
#define ProcessInstrumentationCallback (PROCESSINFOCLASS)40
#define MemoryMappedFilenameInformation (MEMORY_INFORMATION_CLASS)2
#define STATUS_PORT_NOT_SET ((NTSTATUS)0xC0000353L)
#define STATUS_SERVICE_NOTIFICATION ((NTSTATUS)0x40000018L)
#define HARDERROR_OVERRIDE_ERRORMODE 0x10000000
#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 )
#define NtCurrentThread() ( (HANDLE)(LONG_PTR) -2 )
typedef struct _PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION
{
ULONG Version;
ULONG Reserved;
PVOID Callback;
} PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION, *PPROCESS_INSTRUMENTATION_CALLBACK_INFORMATION;
typedef enum HardErrorResponse {
ResponseReturnToCaller,
ResponseNotHandled,
ResponseAbort, ResponseCancel,
ResponseIgnore,
ResponseNo,
ResponseOk,
ResponseRetry,
ResponseYes
} HardErrorResponse;
typedef enum HardErrorResponseButton {
ResponseButtonOK,
ResponseButtonOKCancel,
ResponseButtonAbortRetryIgnore,
ResponseButtonYesNoCancel,
ResponseButtonYesNo,
ResponseButtonRetryCancel,
ResponseButtonCancelTryAgainContinue
} HardErrorResponseButton;
typedef enum HardErrorResponseIcon {
IconAsterisk = 0x40,
IconError = 0x10,
IconExclamation = 0x30,
IconHand = 0x10,
IconInformation = 0x40,
IconNone = 0,
IconQuestion = 0x20,
IconStop = 0x10,
IconWarning = 0x30,
IconUserIcon = 0x80
} HardErrorResponseIcon;
#define SEC_IMAGE_NO_EXECUTE (SEC_IMAGE | SEC_NOCACHE)
enum {
WINDOWS_XP = 2600,
WINDOWS_2003 = 3790,
WINDOWS_VISTA = 6000,
WINDOWS_VISTA_SP1 = 6001,
WINDOWS_VISTA_SP2 = 6002,
WINDOWS_7 = 7600,
WINDOWS_7_SP1 = 7601,
WINDOWS_8 = 9200,
WINDOWS_8_1 = 9600,
WINDOWS_10_TH1 = 10240,
WINDOWS_10_TH2 = 10586,
WINDOWS_10_RS1 = 14393,
WINDOWS_10_RS2 = 15063,
WINDOWS_10_RS3 = 16299,
WINDOWS_10_RS4 = 17134,
WINDOWS_10_RS5 = 17763,
WINDOWS_10_19H1 = 18362,
WINDOWS_10_19H2 = 18363,
WINDOWS_10_20H1 = 19041,
WINDOWS_10_20H2 = 19042,
WINDOWS_10_21H1 = 19043,
WINDOWS_10_21H2 = 19044,
WINDOWS_10_22H2 = 19045,
WINDOWS_11_21H2 = 22000,
WINDOWS_11_22H2 = 22621,
};
#define IS_KNOWN_WINDOWS_BUILD(b) ( \
(b) == WINDOWS_XP || \
(b) == WINDOWS_2003 || \
(b) == WINDOWS_VISTA || \
(b) == WINDOWS_VISTA_SP1 || \
(b) == WINDOWS_VISTA_SP2 || \
(b) == WINDOWS_7 || \
(b) == WINDOWS_7_SP1 || \
(b) == WINDOWS_8 || \
(b) == WINDOWS_8_1 || \
(b) == WINDOWS_10_TH1 || \
(b) == WINDOWS_10_TH2 || \
(b) == WINDOWS_10_RS1 || \
(b) == WINDOWS_10_RS2 || \
(b) == WINDOWS_10_RS3 || \
(b) == WINDOWS_10_RS4 || \
(b) == WINDOWS_10_RS5 || \
(b) == WINDOWS_10_19H1 || \
(b) == WINDOWS_10_19H2 || \
(b) == WINDOWS_10_20H1 || \
(b) == WINDOWS_10_20H2 || \
(b) == WINDOWS_10_21H1 || \
(b) == WINDOWS_10_21H2 || \
(b) == WINDOWS_10_22H2 \
)
#endif // WIN_DRIVER
#endif // VMP_GNU
typedef struct _PEB32 {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[0xa1];
ULONG OSMajorVersion;
ULONG OSMinorVersion;
USHORT OSBuildNumber;
} PEB32;
typedef struct _PEB64 {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[0x115];
ULONG OSMajorVersion;
ULONG OSMinorVersion;
USHORT OSBuildNumber;
} PEB64;
#endif

31
runtime/mac_runtime.mak Normal file
View File

@ -0,0 +1,31 @@
SOURCES := core.cc crypto.cc loader.cc licensing_manager.cc string_manager.cc hwid.cc objects.cc utils.cc ../third-party/lzma/LzmaDecode.cc
PROJECT := mac_runtime
TARGET := $(PROJECT).dylib
BIN_DIR := ../bin/$(ARCH_DIR)/Release
LIB_TARGET := $(BIN_DIR)/$(PROJECT).a
TMP_DIR := ../tmp/mac/runtime/$(ARCH_DIR)/runtime
PCH_DIR := $(TMP_DIR)/runtime.gch
DEFINES :=
LFLAGS := -dynamiclib
LIBS = $(SDK_LIBS) -framework DiskArbitration
DYLIBS := ../bin/libVMProtectSDK.dylib
OBJCOMP :=
OBJECTS := $(addprefix $(TMP_DIR)/, $(SOURCES:.cc=.o))
include ../mac_common.mak
clean:
-$(DEL_FILE) $(LIB_TARGET)
-$(DEL_FILE) $(OBJECTS)
-$(DEL_FILE) $(PCH_CPP)
-$(DEL_FILE) $(BIN_TARGET)
$(LIB_TARGET): $(OBJECTS) $(BIN_DIR)/.sentinel
libtool $(SLIBFLAGS) -o $(LIB_TARGET) $(abspath $(OBJECTS)) $(OBJCOMP)
$(BIN_TARGET): $(LIB_TARGET) $(OBJCOMP) $(DYLIBS)
$(LINK) $(LFLAGS) -o $(BIN_TARGET) $(OBJECTS) $(LIBS) $(OBJCOMP) $(DYLIBS)
$(TMP_DIR)/%.o: %.cc $(PCH_CPP) $(TMP_DIR)/%/../.sentinel
$(CXX) -c -include-pch $(PCH_CPP) $(CXXFLAGS) $(INCFLAGS) -o $(abspath $@) $(abspath $<)

View File

@ -0,0 +1,3 @@
ARCH := i386
ARCH_DIR := 32
include mac_runtime.mak

View File

@ -0,0 +1,3 @@
ARCH := x86_64
ARCH_DIR := 64
include mac_runtime.mak

59
runtime/objects.cc Normal file
View File

@ -0,0 +1,59 @@
#include "objects.h"
#ifdef WIN_DRIVER
extern "C" EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler3(int a, int b, int c, int d)
{
return ExceptionContinueSearch;
}
#endif
/**
* CriticalSection
*/
CriticalSection::CriticalSection(CRITICAL_SECTION &critical_section)
: critical_section_(critical_section)
{
#ifdef VMP_GNU
pthread_mutex_lock(&critical_section_);
#elif defined(WIN_DRIVER)
KeWaitForMutexObject(&critical_section_, Executive, KernelMode, FALSE, NULL);
#else
EnterCriticalSection(&critical_section_);
#endif
}
CriticalSection::~CriticalSection()
{
#ifdef VMP_GNU
pthread_mutex_unlock(&critical_section_);
#elif defined(WIN_DRIVER)
KeReleaseMutex(&critical_section_, FALSE);
#else
LeaveCriticalSection(&critical_section_);
#endif
}
void CriticalSection::Init(CRITICAL_SECTION &critical_section)
{
#ifdef VMP_GNU
pthread_mutex_init(&critical_section, NULL);
#elif defined(WIN_DRIVER)
KeInitializeMutex(&critical_section, 0);
#else
InitializeCriticalSection(&critical_section);
#endif
}
void CriticalSection::Free(CRITICAL_SECTION &critical_section)
{
#ifdef VMP_GNU
pthread_mutex_destroy(&critical_section);
#elif defined(WIN_DRIVER)
// do nothing
#else
DeleteCriticalSection(&critical_section);
#endif
}

78
runtime/objects.h Normal file
View File

@ -0,0 +1,78 @@
#ifndef OBJECTS_H
#define OBJECTS_H
template<class T>
class vector
{
public:
vector() : data_(NULL), total_(0), size_(0) {}
~vector() { delete [] data_; }
size_t size() const { return size_; }
bool empty() const { return size_ == 0; }
const T &operator[] (size_t index) const { return data_[index]; }
T &operator[] (size_t index) {return data_[index]; }
void push_back(const T &t)
{
if (size_ == total_) {
// no free space
size_t new_total = (total_ == 0) ? 1 : total_ * 2;
T *new_data = new T[new_total];
for (size_t i = 0; i < size_; i++) {
new_data[i] = data_[i];
}
delete [] data_;
data_ = new_data;
total_ = new_total;
}
data_[size_++] = t;
}
void pop_back()
{
if (size_)
size_--;
}
void erase(size_t pos)
{
if (pos >= size_)
return; // error
for (size_t i = pos; i < size_ - 1; i++) {
data_[i] = data_[i + 1];
}
size_--;
}
template <typename X>
size_t find(const X &v) const
{
for (size_t i = 0; i < size_; i++) {
if (data_[i] == v)
return i;
}
return -1;
}
void clear()
{
size_ = total_ = 0;
delete [] data_;
data_ = NULL;
}
private:
T *data_;
size_t total_;
size_t size_;
};
class CriticalSection
{
public:
CriticalSection(CRITICAL_SECTION &critical_section);
~CriticalSection();
static void Init(CRITICAL_SECTION &critical_section);
static void Free(CRITICAL_SECTION &critical_section);
private:
CRITICAL_SECTION &critical_section_;
};
#endif

146
runtime/precommon.h Normal file
View File

@ -0,0 +1,146 @@
#pragma once
#ifndef PRECOMMON_PCH
#define PRECOMMON_PCH
#define NOMINMAX
#ifdef WIN_DRIVER
#define _STL70_
#include <ntddk.h>
#endif
#ifdef __cplusplus
#include <string> // because of non-usual new operator
#endif
#ifdef _DEBUG
#if defined(_MSC_VER)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif
#endif
#endif
#include <sys/stat.h>
#if defined(__unix__)
#include <linux/limits.h>
enum { FALSE, TRUE };
typedef void VOID;
#endif
#if defined(_MSC_VER)
#define NOINLINE __declspec(noinline)
#define FORCE_INLINE __forceinline
#elif defined(__GNUC__)
#define NOINLINE __attribute__((noinline))
#define FORCE_INLINE inline __attribute__((always_inline))
#else
#define NOINLINE
#endif
#include <stdio.h>
#include <string.h>
#if defined(__APPLE__) || defined(__unix__)
#define VMP_GNU
#include <stdint.h>
#include <pthread.h>
typedef int HANDLE;
typedef void *LPVOID;
typedef void *HMODULE;
#if defined(__APPLE__)
typedef mach_port_t HPROCESS;
#endif
#if defined(__unix__)
typedef int HPROCESS;
inline size_t strlcpy(char *dst, const char *src, size_t size)
{
dst[size - 1] = '\0';
strncpy(dst, src, size - 1);
return strlen(dst);
}
#endif
#define INVALID_HANDLE_VALUE ((HANDLE)-1)
#define _countof(x) (sizeof(x) / sizeof(x[0]))
#define _strtoui64 strtoull
#define _strtoi64 strtoll
#define VMP_API
typedef char VMP_CHAR;
typedef unsigned short VMP_WCHAR;
inline void strncpy_s(char *strDestination, size_t sz, const char *strSource, size_t src_sz) { strncpy(strDestination, strSource, sz + 0 * src_sz); }
#ifdef __cplusplus
namespace os {
typedef unsigned short unicode_char;
typedef std::basic_string<unicode_char, std::char_traits<unicode_char>, std::allocator<unicode_char> > unicode_string;
};
template <size_t sz> void strcpy_s(char (&strDestination)[sz], const char *strSource) { strlcpy(strDestination, strSource, sz); }
template <size_t sz> void strncpy_s(char (&strDestination)[sz], const char *strSource, size_t src_sz) { strncpy_s(&strDestination[0], sz, strSource, src_sz); }
#endif
#define _TRUNCATE ((size_t)-1)
#define _vsnprintf_s(dest, dest_sz, cnt, fmt, args) _vsnprintf((dest), (dest_sz), (fmt), (args))
#define _vsnprintf vsnprintf
#define vsprintf_s vsprintf
#define sprintf_s sprintf
#define _strcmpi strcasecmp
#define _strdup strdup
#define sscanf_s sscanf
#define strcat_s strcat
#define LOWORD(l) ((uint16_t)(((uint32_t)(l)) & 0xffff))
#define HIWORD(l) ((uint16_t)((((uint32_t)(l)) >> 16) & 0xffff))
typedef int BOOL;
typedef unsigned int UINT;
typedef char CHAR;
typedef uint8_t BYTE, *PBYTE;
typedef short SHORT;
typedef uint16_t WORD, USHORT, *PWORD, *PUSHORT;
typedef uint32_t DWORD, ULONG, ULONG32, *PDWORD, *PULONG, *PULONG32;
typedef int32_t LONG, LONG32, *PLONG, *PLONG32;
typedef uint64_t DWORD64, ULONGLONG, ULONG64, *PDWORD64, *PULONGLONG, *PULONG64;
typedef struct _GUID {
uint32_t Data1;
uint16_t Data2;
uint16_t Data3;
uint8_t Data4[8];
} GUID;
#define CRITICAL_SECTION pthread_mutex_t
#else
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef __int64 int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
#define VMP_API __stdcall
typedef wchar_t VMP_CHAR;
typedef wchar_t VMP_WCHAR;
#ifdef __cplusplus
namespace os {
typedef std::wstring unicode_string;
typedef wchar_t unicode_char;
};
#endif
typedef void *HPROCESS;
#endif
#ifdef __cplusplus
#include <algorithm>
#endif
#endif //PRECOMMON_PCH

1
runtime/precompiled.cc Normal file
View File

@ -0,0 +1 @@
#include "precompiled.h"

133
runtime/precompiled.h Normal file
View File

@ -0,0 +1,133 @@
#pragma once
#ifndef WR_PCH
#define WR_PCH
#ifndef VMP_GNU
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
#endif
#include "precommon.h"
#ifdef WIN_DRIVER
void * __cdecl operator new(size_t size);
void __cdecl operator delete(void* p);
void __cdecl operator delete(void* p, size_t);
void * __cdecl operator new[](size_t size);
void __cdecl operator delete[](void *p);
#endif
#define RUNTIME
#ifdef VMP_GNU
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <ifaddrs.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/sysctl.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/ptrace.h>
#ifdef __APPLE__
#include <net/if_dl.h>
#include <net/if_types.h>
#include <sys/syslimits.h>
#include <mach/mach_init.h>
#include <mach/mach_time.h>
#include <mach/vm_map.h>
#include <mach-o/dyld.h>
#include <mach-o/fat.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <SystemConfiguration/SystemConfiguration.h>
#endif
#define WINAPI
#ifdef __APPLE__
#define EXPORT_API __attribute__ ((visibility ("default")))
#else
#define EXPORT_API __attribute__ ((visibility ("protected")))
#endif
#else
#define EXPORT_API __declspec(dllexport)
#ifdef WIN_DRIVER
#include <windef.h>
#include <stdlib.h>
#if defined(__cplusplus)
extern "C" {
#endif
void __cpuid(int a[4], int b);
void __nop();
#ifdef _WIN64
unsigned __int64 __readeflags(void);
void __writeeflags(unsigned __int64);
#else
unsigned __readeflags(void);
void __writeeflags(unsigned);
#endif
#if defined(__cplusplus)
}
#endif // WIN_DRIVER
typedef unsigned long DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef HANDLE HGLOBAL;
typedef unsigned int UINT;
#define WINAPI __stdcall
#define CRITICAL_SECTION KMUTEX
#ifdef _WIN64
typedef INT_PTR (FAR WINAPI *FARPROC)();
#else
typedef int (FAR WINAPI *FARPROC)();
#endif // _WIN64
#else
#include <windows.h>
#include <iphlpapi.h>
#include <intrin.h>
#include <wtsapi32.h>
#include <winternl.h>
#include <tlhelp32.h>
#endif
#endif // VMP_GNU
#include <cassert>
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif
#ifndef InitializeObjectAttributes
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#endif
#ifndef OBJ_CASE_INSENSITIVE
#define OBJ_CASE_INSENSITIVE 0x00000040L
#endif
#endif //WR_PCH

1390
runtime/registry_manager.cc Normal file

File diff suppressed because it is too large Load Diff

299
runtime/registry_manager.h Normal file
View File

@ -0,0 +1,299 @@
#ifndef REGISTRY_MANAGER_H
#define REGISTRY_MANAGER_H
struct REGISTRY_DIRECTORY {
uint32_t Reserved1;
uint32_t Reserved2;
};
typedef struct _KEY_VALUE_BASIC_INFORMATION {
ULONG TitleIndex;
ULONG Type;
ULONG NameLength;
WCHAR Name[1]; // Variable size
} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;
typedef struct _KEY_VALUE_FULL_INFORMATION {
ULONG TitleIndex;
ULONG Type;
ULONG DataOffset;
ULONG DataLength;
ULONG NameLength;
WCHAR Name[1]; // Variable size
// Data[1]; // Variable size data not declared
} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
ULONG TitleIndex;
ULONG Type;
ULONG DataLength;
UCHAR Data[1]; // Variable size
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
typedef struct _KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 {
ULONG Type;
ULONG DataLength;
UCHAR Data[1]; // Variable size
} KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, *PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64;
typedef enum _KEY_VALUE_INFORMATION_CLASS {
KeyValueBasicInformation,
KeyValueFullInformation,
KeyValuePartialInformation,
KeyValueFullInformationAlign64,
KeyValuePartialInformationAlign64,
MaxKeyValueInfoClass // MaxKeyValueInfoClass should always be the last enum
} KEY_VALUE_INFORMATION_CLASS;
typedef struct _KEY_BASIC_INFORMATION {
LARGE_INTEGER LastWriteTime;
ULONG TitleIndex;
ULONG NameLength;
WCHAR Name[1]; // Variable length string
} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
typedef struct _KEY_NODE_INFORMATION {
LARGE_INTEGER LastWriteTime;
ULONG TitleIndex;
ULONG ClassOffset;
ULONG ClassLength;
ULONG NameLength;
WCHAR Name[1]; // Variable length string
// Class[1]; // Variable length string not declared
} KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION;
typedef struct _KEY_FULL_INFORMATION {
LARGE_INTEGER LastWriteTime;
ULONG TitleIndex;
ULONG ClassOffset;
ULONG ClassLength;
ULONG SubKeys;
ULONG MaxNameLen;
ULONG MaxClassLen;
ULONG Values;
ULONG MaxValueNameLen;
ULONG MaxValueDataLen;
WCHAR Class[1]; // Variable length
} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION;
typedef struct _KEY_NAME_INFORMATION {
ULONG NameLength;
WCHAR Name[1]; // Variable length
} KEY_NAME_INFORMATION, *PKEY_NAME_INFORMATION;
typedef struct _KEY_CACHED_INFORMATION {
LARGE_INTEGER LastWriteTime;
ULONG TitleIndex;
ULONG SubKeys;
ULONG MaxNameLen;
ULONG Values;
ULONG MaxValueNameLen;
ULONG MaxValueDataLen;
ULONG NameLength;
} KEY_CACHED_INFORMATION, *PKEY_CACHED_INFORMATION;
typedef struct _KEY_HANDLE_TAGS_INFORMATION {
ULONG HandleTags;
} KEY_HANDLE_TAGS_INFORMATION, *PKEY_HANDLE_TAGS_INFORMATION;
typedef enum _KEY_INFORMATION_CLASS {
KeyBasicInformation,
KeyNodeInformation,
KeyFullInformation,
KeyNameInformation,
KeyCachedInformation,
KeyFlagsInformation,
KeyVirtualizationInformation,
KeyHandleTagsInformation,
MaxKeyInfoClass // MaxKeyInfoClass should always be the last enum
} KEY_INFORMATION_CLASS;
class RegistryValue
{
public:
RegistryValue(const wchar_t *name);
~RegistryValue();
const wchar_t *name() const { return name_; }
uint32_t type() const { return type_; }
uint32_t size() const { return size_; }
void *data() const { return data_; }
void SetValue(uint32_t type, void *data, uint32_t size);
private:
wchar_t *name_;
uint32_t type_;
uint8_t *data_;
uint32_t size_;
// no copy ctr or assignment op
RegistryValue(const RegistryValue &);
RegistryValue &operator =(const RegistryValue &);
};
class UnicodeString
{
public:
UnicodeString()
: data_(NULL), size_(0)
{
data_ = new wchar_t[size_ + 1];
data_[size_] = 0;
}
UnicodeString(const wchar_t *str)
: data_(NULL), size_(wcslen(str))
{
data_ = new wchar_t[size_ + 1];
memcpy(data_, str, size_ * sizeof(wchar_t));
data_[size_] = 0;
}
UnicodeString(const wchar_t *str, size_t size)
: data_(NULL), size_(size)
{
data_ = new wchar_t[size_ + 1];
memcpy(data_, str, size_ * sizeof(wchar_t));
data_[size_] = 0;
}
UnicodeString(const UnicodeString &str)
: data_(NULL), size_(str.size_)
{
data_ = new wchar_t[size_ + 1];
memcpy(data_, str.data_, size_ * sizeof(wchar_t));
data_[size_] = 0;
}
UnicodeString &operator=(const UnicodeString &src)
{
if (&src != this)
{
delete [] data_;
size_ = src.size();
data_ = new wchar_t[size_ + 1];
memcpy(data_, src.c_str(), size_ * sizeof(wchar_t));
data_[size_] = 0;
}
return *this;
}
~UnicodeString()
{
delete [] data_;
}
size_t size() const { return size_; }
const wchar_t *c_str() const { return data_; }
UnicodeString &append(const wchar_t *str) { return append (str, wcslen(str)); }
UnicodeString &append(const wchar_t *str, size_t str_size)
{
size_t new_size = size_ + str_size;
wchar_t *new_data = new wchar_t[new_size + 1];
memcpy(new_data, data_, size_ * sizeof(wchar_t));
memcpy(new_data + size_, str, str_size * sizeof(wchar_t));
new_data[new_size] = 0;
delete [] data_;
data_ = new_data;
size_ = new_size;
return *this;
}
UnicodeString &operator + (wchar_t c) { return append(&c, 1); }
UnicodeString &operator + (const wchar_t *str) { return append(str, wcslen(str)); }
bool operator == (const wchar_t *str) const { return wcscmp(c_str(), str) == 0; }
private:
wchar_t *data_;
size_t size_;
};
class RegistryKey
{
public:
RegistryKey();
RegistryKey(RegistryKey *owner, const wchar_t *name, bool is_real);
~RegistryKey();
RegistryKey *GetKey(const wchar_t *name) const;
RegistryKey *AddKey(const wchar_t *name, bool is_real, bool *is_exists);
bool DeleteKey(RegistryKey *key);
const wchar_t *name() const { return name_; }
UnicodeString full_name() const;
void SetValue(wchar_t *name, uint32_t type, void *data, uint32_t size);
bool DeleteValue(wchar_t *name);
RegistryValue *GetValue(const wchar_t *name) const;
bool is_real() const { return is_real_; }
void set_is_wow(bool value) { is_wow_ = value; }
RegistryKey *owner() const { return owner_; }
RegistryKey *key(size_t index) const { return keys_[index]; }
size_t keys_size() const { return keys_.size(); }
RegistryValue *value(size_t index) const { return values_[index]; }
size_t values_size() const { return values_.size(); }
uint64_t last_write_time() const { return last_write_time_; }
private:
RegistryKey *GetChild(const wchar_t *name) const;
RegistryKey *AddChild(const wchar_t *name, bool is_real, bool *is_exists);
RegistryValue *AddValue(wchar_t *value_name);
bool is_wow_node(const wchar_t *name) const;
wchar_t *name_;
RegistryKey *owner_;
bool is_real_;
bool is_wow_;
vector<RegistryKey *> keys_;
vector<RegistryValue *> values_;
uint64_t last_write_time_;
// no copy ctr or assignment op
RegistryKey(const RegistryKey &);
RegistryKey &operator =(const RegistryKey &);
};
class VirtualObjectList;
class RegistryManager
{
public:
RegistryManager(const uint8_t *data, HMODULE instance, const uint8_t *key, VirtualObjectList *objects);
void HookAPIs(HookManager &hook_manager);
void UnhookAPIs(HookManager &hook_manager);
void BeginRegisterServer();
void EndRegisterServer();
NTSTATUS NtSetValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName, ULONG TitleIndex, ULONG Type, PVOID Data, ULONG DataSize);
NTSTATUS NtDeleteValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName);
NTSTATUS NtCreateKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG TitleIndex, PUNICODE_STRING Class, ULONG CreateOptions, PULONG Disposition);
NTSTATUS NtQueryValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength);
NTSTATUS NtOpenKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
NTSTATUS NtOpenKeyEx(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG OpenOptions);
NTSTATUS NtDeleteKey(HANDLE KeyHandle);
NTSTATUS NtQueryKey(HANDLE KeyHandle, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength);
NTSTATUS NtEnumerateValueKey(HANDLE KeyHandle, ULONG Index, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength);
NTSTATUS NtEnumerateKey(HANDLE KeyHandle, ULONG Index, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength);
private:
NTSTATUS TrueNtSetValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName, ULONG TitleIndex, ULONG Type, PVOID Data, ULONG DataSize);
NTSTATUS TrueNtDeleteValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName);
NTSTATUS TrueNtCreateKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG TitleIndex, PUNICODE_STRING Class, ULONG CreateOptions, PULONG Disposition);
NTSTATUS TrueNtQueryValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength);
NTSTATUS TrueNtOpenKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
NTSTATUS TrueNtOpenKeyEx(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG OpenOptions);
NTSTATUS TrueNtDeleteKey(HANDLE KeyHandle);
NTSTATUS TrueNtQueryKey(HANDLE KeyHandle, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength);
NTSTATUS TrueNtEnumerateValueKey(HANDLE KeyHandle, ULONG Index, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength);
NTSTATUS TrueNtEnumerateKey(HANDLE KeyHandle, ULONG Index, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength);
NTSTATUS TrueNtQueryObject(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
REGISTRY_DIRECTORY DecryptDirectory(const REGISTRY_DIRECTORY *directory_enc) const;
RegistryKey *GetRootKey(HANDLE root, uint32_t *access, bool can_create);
NTSTATUS QueryValueKey(RegistryValue *value, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength);
NTSTATUS QueryKey(RegistryKey *key, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength);
HMODULE instance_;
const uint8_t *data_;
uint32_t key_;
void *nt_set_value_key_;
void *nt_delete_value_key_;
void *nt_create_key_;
void *nt_open_key_;
void *nt_open_key_ex_;
void *nt_query_value_key_;
void *nt_delete_key_;
void *nt_query_key_;
void *nt_enumerate_value_key_;
void *nt_enumerate_key_;
RegistryKey cache_;
VirtualObjectList *objects_;
bool append_mode_;
// no copy ctr or assignment op
RegistryManager(const RegistryManager &);
RegistryManager &operator =(const RegistryManager &);
};
#endif

1022
runtime/resource_manager.cc Normal file

File diff suppressed because it is too large Load Diff

148
runtime/resource_manager.h Normal file
View File

@ -0,0 +1,148 @@
#ifndef RESOURCE_MANAGER_H
#define RESOURCE_MANAGER_H
#pragma pack(push, 1)
class CipherRC5;
struct RESOURCE_DIRECTORY {
uint32_t NumberOfNamedEntries;
uint32_t NumberOfIdEntries;
// RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
};
//#pragma warning(push)
//#pragma warning(disable:4201) // named type definition in parentheses
struct RESOURCE_DIRECTORY_ENTRY {
union {
struct {
uint32_t NameOffset:31;
uint32_t NameIsString:1;
} /*DUMMYSTRUCTNAME*/;
uint32_t Name;
uint16_t Id;
} /*DUMMYUNIONNAME*/;
union {
uint32_t OffsetToData;
struct {
uint32_t OffsetToDirectory:31;
uint32_t DataIsDirectory:1;
} /*DUMMYSTRUCTNAME2*/;
} /*DUMMYUNIONNAME2*/;
};
//#pragma warning(pop)
struct RESOURCE_DATA_ENTRY {
uint32_t OffsetToData;
uint32_t Size;
uint32_t CodePage;
uint32_t Reserved;
};
#pragma pack(pop)
struct LDR_RESOURCE_INFO {
LPWSTR Type;
LPWSTR Name;
WORD Language;
};
class VirtualResource
{
public:
VirtualResource(const RESOURCE_DATA_ENTRY *entry, uint32_t key);
~VirtualResource();
HGLOBAL Decrypt(HMODULE instance, uint32_t key);
const RESOURCE_DATA_ENTRY *entry() const { return entry_; }
HRSRC handle() const { return reinterpret_cast<HRSRC>(const_cast<IMAGE_RESOURCE_DATA_ENTRY *>(&handle_)); }
private:
const RESOURCE_DATA_ENTRY *entry_;
IMAGE_RESOURCE_DATA_ENTRY handle_;
uint8_t *address_;
// no copy ctr or assignment op
VirtualResource(const VirtualResource &);
VirtualResource &operator =(const VirtualResource &);
};
class VirtualResourceList
{
public:
~VirtualResourceList();
VirtualResource *Add(const RESOURCE_DATA_ENTRY *entry, uint32_t key);
void Delete(size_t index);
size_t IndexByEntry(const RESOURCE_DATA_ENTRY *entry) const;
size_t IndexByHandle(HRSRC handle) const;
VirtualResource *operator [] (size_t index) const { return v_[index]; }
size_t size() const { return v_.size(); }
private:
vector<VirtualResource *> v_;
};
class ResourceManager
{
public:
ResourceManager(const uint8_t *data, HMODULE instance, const uint8_t *key);
~ResourceManager();
void HookAPIs(HookManager &hook_manager);
void UnhookAPIs(HookManager &hook_manager);
HGLOBAL LoadResource(HMODULE module, HRSRC res_info);
HRSRC FindResourceA(HMODULE module, LPCSTR name, LPCSTR type);
HRSRC FindResourceExA(HMODULE module, LPCSTR type, LPCSTR name, WORD language);
HRSRC FindResourceW(HMODULE module, LPCWSTR name, LPCWSTR type);
HRSRC FindResourceExW(HMODULE module, LPCWSTR type, LPCWSTR name, WORD language);
int LoadStringA(HMODULE module, UINT id, LPSTR buffer, int buffer_max);
int LoadStringW(HMODULE module, UINT id, LPWSTR buffer, int buffer_max);
NTSTATUS LdrFindResource_U(HMODULE module, const LDR_RESOURCE_INFO *res_info, ULONG level, const IMAGE_RESOURCE_DATA_ENTRY **entry);
NTSTATUS LdrAccessResource(HMODULE module, const IMAGE_RESOURCE_DATA_ENTRY *entry, void **res, ULONG *size);
BOOL EnumResourceNamesA(HMODULE module, LPCSTR type, ENUMRESNAMEPROCA enum_func, LONG_PTR param);
BOOL EnumResourceNamesW(HMODULE module, LPCWSTR type, ENUMRESNAMEPROCW enum_func, LONG_PTR param);
BOOL EnumResourceLanguagesA(HMODULE module, LPCSTR type, LPCSTR name, ENUMRESLANGPROCA enum_func, LONG_PTR param);
BOOL EnumResourceLanguagesW(HMODULE module, LPCWSTR type, LPCWSTR name, ENUMRESLANGPROCW enum_func, LONG_PTR param);
BOOL EnumResourceTypesA(HMODULE module, ENUMRESTYPEPROCA enum_func, LONG_PTR param);
BOOL EnumResourceTypesW(HMODULE module, ENUMRESTYPEPROCW enum_func, LONG_PTR param);
private:
RESOURCE_DIRECTORY DecryptDirectory(const RESOURCE_DIRECTORY *directory_enc) const;
RESOURCE_DIRECTORY_ENTRY DecryptDirectoryEntry(const RESOURCE_DIRECTORY_ENTRY *entry_enc) const;
int CompareStringEnc(LPCWSTR name, LPCWSTR str_enc) const;
LPWSTR DecryptStringW(LPCWSTR src_enc) const;
LPSTR DecryptStringA(LPCWSTR src_enc) const;
const RESOURCE_DIRECTORY *FindEntryById(const RESOURCE_DIRECTORY *directory, WORD id, DWORD dir_type);
const RESOURCE_DIRECTORY *FindEntryByName(const RESOURCE_DIRECTORY *directory, LPCWSTR name, DWORD dir_type);
const RESOURCE_DIRECTORY *FindEntry(const RESOURCE_DIRECTORY *directory, LPCWSTR name, DWORD dir_type);
const RESOURCE_DIRECTORY *FindFirstEntry(const RESOURCE_DIRECTORY *directory, DWORD dir_type);
const RESOURCE_DIRECTORY *FindResourceEntry(LPCWSTR type, LPCWSTR name, WORD language);
HRSRC InternalFindResourceExW(HMODULE module, LPCWSTR type, LPCWSTR name, WORD language);
HGLOBAL InternalLoadResource(HMODULE module, HRSRC res_info);
LPWSTR InternalFindStringResource(HMODULE module, UINT id);
int InternalLoadStringW(LPCWSTR res, LPWSTR buffer, int buffer_max);
int InternalLoadStringA(LPCWSTR res, LPSTR buffer, int buffer_max);
uint16_t DecryptWord(uint16_t value) const;
int TrueLoadStringA(HMODULE module, UINT id, LPSTR buffer, int buffer_max);
int TrueLoadStringW(HMODULE module, UINT id, LPWSTR buffer, int buffer_max);
NTSTATUS TrueLdrFindResource_U(HMODULE module, const LDR_RESOURCE_INFO *res_info, ULONG level, const IMAGE_RESOURCE_DATA_ENTRY **entry);
NTSTATUS TrueLdrAccessResource(HMODULE module, const IMAGE_RESOURCE_DATA_ENTRY *entry, void **res, ULONG *size);
HMODULE instance_;
uint32_t key_;
CRITICAL_SECTION critical_section_;
VirtualResourceList resources_;
const uint8_t *data_;
void *load_resource_;
void *load_string_a_;
void *load_string_w_;
void *load_string_a_kernel_;
void *load_string_w_kernel_;
void *ldr_find_resource_u_;
void *ldr_access_resource_;
void *get_thread_ui_language_;
// no copy ctr or assignment op
ResourceManager(const ResourceManager &);
ResourceManager &operator =(const ResourceManager &);
};
#endif

33
runtime/runtime.def Normal file
View File

@ -0,0 +1,33 @@
EXPORTS
SetupImage
FreeImage
ExportedDecryptString
ExportedFreeString
ExportedLoadResource
ExportedFindResourceA
ExportedFindResourceExA
ExportedFindResourceW
ExportedFindResourceExW
ExportedLoadStringA
ExportedLoadStringW
ExportedEnumResourceNamesA
ExportedEnumResourceNamesW
ExportedEnumResourceLanguagesA
ExportedEnumResourceLanguagesW
ExportedEnumResourceTypesA
ExportedEnumResourceTypesW
ExportedSetSerialNumber
ExportedGetSerialNumberState
ExportedGetSerialNumberData
ExportedGetCurrentHWID
ExportedActivateLicense
ExportedDeactivateLicense
ExportedGetOfflineActivationString
ExportedGetOfflineDeactivationString
ExportedIsValidImageCRC
ExportedIsDebuggerPresent
ExportedIsVirtualMachinePresent
ExportedDecryptBuffer
ExportedIsProtected
CalcCRC
LoaderData = loader_data

184
runtime/string_manager.cc Normal file
View File

@ -0,0 +1,184 @@
#include "objects.h"
#include "common.h"
#include "core.h"
#include "crypto.h"
#include "string_manager.h"
/**
* exported functions
*/
#ifdef VMP_GNU
EXPORT_API const void * WINAPI ExportedDecryptString(const void *str) __asm__ ("ExportedDecryptString");
EXPORT_API bool WINAPI ExportedFreeString(const void *str) __asm__ ("ExportedFreeString");
#endif
const void * WINAPI ExportedDecryptString(const void *str)
{
StringManager *string_manager = Core::Instance()->string_manager();
return string_manager ? string_manager->DecryptString(str) : str;
}
bool WINAPI ExportedFreeString(const void *str)
{
StringManager *string_manager = Core::Instance()->string_manager();
return string_manager ? string_manager->FreeString(str) : false;
}
/**
* StringManager
*/
StringManager::StringManager(const uint8_t *data, HMODULE instance, const uint8_t *key)
: data_(data), instance_(instance)
{
CriticalSection::Init(critical_section_);
key_ = *(reinterpret_cast<const uint32_t *>(key));
const STRING_DIRECTORY *directory_enc = reinterpret_cast<const STRING_DIRECTORY *>(data_);
STRING_DIRECTORY directory = DecryptDirectory(directory_enc);
size_ = directory.NumberOfEntries;
strings_ = new VirtualString*[size_];
memset(strings_, 0, sizeof(VirtualString *) * size_);
}
StringManager::~StringManager()
{
for (size_t i = 0; i < size_; i++) {
delete strings_[i];
}
delete [] strings_;
CriticalSection::Free(critical_section_);
}
STRING_DIRECTORY StringManager::DecryptDirectory(const STRING_DIRECTORY *directory_enc) const
{
STRING_DIRECTORY res;
res.NumberOfEntries = directory_enc->NumberOfEntries ^ key_;
return res;
}
STRING_ENTRY StringManager::DecryptEntry(const STRING_ENTRY *entry_enc) const
{
STRING_ENTRY res;
res.Id = entry_enc->Id ^ key_;
res.OffsetToData = entry_enc->OffsetToData ^ key_;
res.Size = entry_enc->Size ^ key_;
return res;
}
size_t StringManager::IndexById(uint32_t id) const
{
const STRING_ENTRY *entry_enc = reinterpret_cast<const STRING_ENTRY *>(data_ + sizeof(STRING_DIRECTORY));
int min = 0;
int max = (int)size_ - 1;
while (min <= max) {
int i = (min + max) / 2;
STRING_ENTRY entry = DecryptEntry(entry_enc + i);
if (entry.Id == id) {
return i;
}
if (entry.Id > id) {
max = i - 1;
} else {
min = i + 1;
}
}
return NOT_ID;
}
const void *StringManager::DecryptString(const void *str)
{
size_t id = reinterpret_cast<size_t>(str) - reinterpret_cast<size_t>(instance_);
if ((id >> 31) == 0) {
size_t i = IndexById(static_cast<uint32_t>(id));
if (i != NOT_ID) {
CriticalSection cs(critical_section_);
VirtualString *string = strings_[i];
if (!string) {
const STRING_ENTRY *entry_enc = reinterpret_cast<const STRING_ENTRY *>(data_ + sizeof(STRING_DIRECTORY));
string = new VirtualString(entry_enc + i, instance_, key_);
strings_[i] = string;
}
return string->AcquirePointer();
}
}
return str;
}
size_t StringManager::IndexByAddress(const void *address) const
{
for (size_t i = 0; i < size_; i++) {
VirtualString *string = strings_[i];
if (string && string->address() == address)
return i;
}
return NOT_ID;
}
bool StringManager::FreeString(const void *str)
{
CriticalSection cs(critical_section_);
size_t i = IndexByAddress(str);
if (i == NOT_ID)
return false;
VirtualString *string = strings_[i];
if (string->Release()) {
delete string;
strings_[i] = NULL;
}
return true;
}
/**
* VirtualString
*/
VirtualString::VirtualString(const STRING_ENTRY *entry_enc, HMODULE instance, uint32_t key)
: use_count_(0)
{
STRING_ENTRY entry;
entry.Id = entry_enc->Id ^ key;
entry.OffsetToData = entry_enc->OffsetToData ^ key;
entry.Size = entry_enc->Size ^ key;
size_ = entry.Size;
address_ = new uint8_t[size_];
uint8_t *source = reinterpret_cast<uint8_t *>(instance) + entry.OffsetToData;
for (size_t i = 0; i < size_; i++) {
address_[i] = static_cast<uint8_t>(source[i] ^ (_rotl32(key, static_cast<int>(i)) + i));
}
}
VirtualString::~VirtualString()
{
Clear();
}
void VirtualString::Clear()
{
if (address_) {
volatile uint8_t *ptrSecureZeroing = address_;
while (size_--) *ptrSecureZeroing++ = 0;
delete [] address_;
address_ = NULL;
}
}
uint8_t *VirtualString::AcquirePointer()
{
use_count_++;
return address_;
}
bool VirtualString::Release()
{
use_count_--;
if (use_count_)
return false;
Clear();
return true;
}

60
runtime/string_manager.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef STRING_MANAGER_H
#define STRING_MANAGER_H
class CipherRC5;
struct STRING_DIRECTORY {
uint32_t NumberOfEntries;
// STRING_ENTRY Entries[];
};
struct STRING_ENTRY {
uint32_t Id;
uint32_t OffsetToData;
uint32_t Size;
};
class VirtualString
{
public:
VirtualString(const STRING_ENTRY *entry, HMODULE instance, uint32_t key);
~VirtualString();
uint8_t *AcquirePointer();
bool Release();
uint8_t *address() const { return address_; }
private:
void Clear();
size_t use_count_;
uint8_t *address_;
size_t size_;
// no copy ctr or assignment op
VirtualString(const VirtualString &);
VirtualString &operator =(const VirtualString &);
};
class StringManager
{
public:
StringManager(const uint8_t *data, HMODULE instance, const uint8_t *key);
~StringManager();
const void *DecryptString(const void *str);
bool FreeString(const void *str);
private:
STRING_DIRECTORY DecryptDirectory(const STRING_DIRECTORY *directory_enc) const;
STRING_ENTRY DecryptEntry(const STRING_ENTRY *entry_enc) const;
size_t IndexById(uint32_t id) const;
size_t IndexByAddress(const void *address) const;
const uint8_t *data_;
HMODULE instance_;
CRITICAL_SECTION critical_section_;
VirtualString **strings_;
uint32_t key_;
size_t size_;
// no copy ctr or assignment op
StringManager(const StringManager &);
StringManager &operator =(const StringManager &);
};
#endif

290
runtime/utils.cc Normal file
View File

@ -0,0 +1,290 @@
#include "common.h"
#include "utils.h"
#include "loader.h"
#ifdef __unix__
#ifdef __i386__
__asm__(".symver memcpy,memcpy@GLIBC_2.0");
__asm__(".symver clock_gettime,clock_gettime@LIBRT_2.12");
#else
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
__asm__(".symver clock_gettime,clock_gettime@LIBRT_2.12");
#endif
extern "C"
{
void *__wrap_memcpy(void *dest, const void *src, size_t n)
{
return memcpy(dest, src, n);
}
#include <sys/poll.h>
int __wrap___poll_chk (struct pollfd *fds, nfds_t nfds, int timeout, __SIZE_TYPE__ fdslen)
{
if (fdslen / sizeof (*fds) < nfds)
abort();
return poll (fds, nfds, timeout);
}
#include <sys/select.h>
long int __wrap___fdelt_chk (long int d)
{
if (d < 0 || d >= FD_SETSIZE)
abort();
return d / __NFDBITS;
}
}
extern "C" size_t __fread_chk (void *destv, size_t dest_size, size_t size, size_t nmemb, FILE *f)
{
if (size > dest_size) {
//_chk_fail(__FUNCTION__);
size = dest_size;
}
return fread(destv, size, nmemb, f);
}
extern "C" int __isoc99_sscanf(const char *a, const char *b, va_list args)
{
int i;
va_list ap;
va_copy(ap, args);
i = sscanf(a, b, ap);
va_end(ap);
return i;
}
#include <setjmp.h>
extern "C" void __longjmp_chk (jmp_buf env, int val)
{
// TODO: Glibc's __longjmp_chk additionally does some sanity checks about
// whether we're jumping a sane stack frame.
longjmp(env, val);
}
#endif
void ShowMessage(const VMP_CHAR *message)
{
#ifdef __APPLE__
char file_name[PATH_MAX];
uint32_t name_size = sizeof(file_name);
const char *title;
if (_NSGetExecutablePath(file_name, &name_size) == 0) {
char *p = strrchr(file_name, '/');
title = p ? p + 1 : file_name;
} else {
title = "Fatal Error";
}
CFStringRef title_ref = CFStringCreateWithCString(NULL, title, kCFStringEncodingMacRoman);
CFStringRef message_ref = CFStringCreateWithCString(NULL, message, kCFStringEncodingUTF8);
CFOptionFlags result;
CFUserNotificationDisplayAlert(
0, // no timeout
kCFUserNotificationStopAlertLevel, //change it depending message_type flags ( MB_ICONASTERISK.... etc.)
NULL, //icon url, use default, you can change it depending message_type flags
NULL, //not used
NULL, //localization of strings
title_ref, //title text
message_ref, //message text
NULL, //default "ok" text in button
NULL, //alternate button title
NULL, //other button title, null--> no other button
&result //response flags
);
CFRelease(title_ref);
CFRelease(message_ref);
#elif defined(__unix__)
char file_name[PATH_MAX] = {0};
const char *title = file_name;
ssize_t len = ::readlink("/proc/self/exe", file_name, sizeof(file_name)-1);
if (len != -1) {
for (ssize_t i = 0; i < len; i++) {
if (file_name[i] == '/')
title = file_name + i + 1;
if (file_name[i] == '\'' || file_name[i] == '\\')
file_name[i] = '"';
}
file_name[len] = '\0';
} else {
title = "Fatal Error";
}
std::string cmd_line = "zenity";
cmd_line += " --error --no-markup --text='";
cmd_line += title;
cmd_line += ": ";
char *message_buffer = strdup(message);
char *msg_ptr = message_buffer;
while (*msg_ptr)
{
if (*msg_ptr == '\'' || *msg_ptr == '\\')
*msg_ptr = '"';
msg_ptr++;
}
cmd_line += message_buffer;
free(message_buffer);
cmd_line += "'";
int status = system(cmd_line.c_str());
if (status == -1 || WEXITSTATUS(status) == 127)
puts(message);
#elif defined(WIN_DRIVER)
DbgPrint("%ws\n", message);
#else
VMP_CHAR file_name[MAX_PATH + 1] = {0};
const VMP_CHAR *title;
if (GetModuleFileNameW(reinterpret_cast<HMODULE>(FACE_IMAGE_BASE), file_name, _countof(file_name) - 1)) {
wchar_t *p = wcsrchr(file_name, L'\\');
title = p ? p + 1 : file_name;
} else {
title = L"Fatal Error";
}
HMODULE ntdll = GetModuleHandleA(VMProtectDecryptStringA("ntdll.dll"));
typedef NTSTATUS(NTAPI tNtRaiseHardError)(NTSTATUS ErrorStatus, ULONG NumberOfParameters,
ULONG UnicodeStringParameterMask, PULONG_PTR Parameters,
ULONG ValidResponseOptions,
HardErrorResponse *Response);
if (tNtRaiseHardError *raise_hard_error = reinterpret_cast<tNtRaiseHardError *>(InternalGetProcAddress(ntdll, VMProtectDecryptStringA("NtRaiseHardError")))) {
UNICODE_STRING message_str;
UNICODE_STRING title_str;
InitUnicodeString(&message_str, (PWSTR)message);
InitUnicodeString(&title_str, (PWSTR)title);
ULONG_PTR params[4] = {
(ULONG_PTR)&message_str,
(ULONG_PTR)&title_str,
(
(ULONG)ResponseButtonOK | IconError
),
INFINITE
};
HardErrorResponse response;
raise_hard_error(STATUS_SERVICE_NOTIFICATION | HARDERROR_OVERRIDE_ERRORMODE, 4, 3, params, 0, &response);
}
#endif
}
#ifdef VMP_GNU
#elif defined(WIN_DRIVER)
#else
void *InternalGetProcAddress(HMODULE module, const char *proc_name)
{
// check input
if (!module || !proc_name)
return NULL;
// check module's header
PIMAGE_DOS_HEADER dos_header = reinterpret_cast<PIMAGE_DOS_HEADER>(module);
if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
// check NT header
PIMAGE_NT_HEADERS pe_header = reinterpret_cast<PIMAGE_NT_HEADERS>(reinterpret_cast<uint8_t *>(module) + dos_header->e_lfanew);
if (pe_header->Signature != IMAGE_NT_SIGNATURE)
return NULL;
// get the export directory
uint32_t export_adress = pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
if (!export_adress)
return NULL;
uint32_t export_size = pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
uint32_t address;
uint32_t ordinal_index = -1;
PIMAGE_EXPORT_DIRECTORY export_directory = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(reinterpret_cast<uint8_t *>(module) + export_adress);
if (proc_name <= reinterpret_cast<const char *>(0xFFFF)) {
// ordinal
ordinal_index = static_cast<uint32_t>(INT_PTR(proc_name)) - export_directory->Base; //-V221
// index is either less than base or bigger than number of functions
if (ordinal_index >= export_directory->NumberOfFunctions)
return NULL;
// get the function offset by the ordinal
address = (reinterpret_cast<uint32_t *>(reinterpret_cast<uint8_t *>(module) + export_directory->AddressOfFunctions))[ordinal_index];
// check for empty offset
if (!address)
return NULL;
} else {
// name of function
if (export_directory->NumberOfNames) {
// start binary search
int left_index = 0;
int right_index = export_directory->NumberOfNames - 1;
uint32_t *names = reinterpret_cast<uint32_t *>(reinterpret_cast<uint8_t *>(module) + export_directory->AddressOfNames);
while (left_index <= right_index) {
uint32_t cur_index = (left_index + right_index) >> 1;
switch (strcmp((const char *)(reinterpret_cast<uint8_t *>(module) + names[cur_index]), proc_name)) {
case 0:
ordinal_index = (reinterpret_cast<WORD *>(reinterpret_cast<uint8_t *>(module) + export_directory->AddressOfNameOrdinals))[cur_index];
left_index = right_index + 1;
break;
case 1:
right_index = cur_index - 1;
break;
case -1:
left_index = cur_index + 1;
break;
}
}
}
// if nothing has been found
if (ordinal_index >= export_directory->NumberOfFunctions)
return NULL;
// get the function offset by the ordinal
address = (reinterpret_cast<uint32_t *>(reinterpret_cast<uint8_t *>(module) + export_directory->AddressOfFunctions))[ordinal_index];
if (!address)
return NULL;
}
// if it is just a pointer - return it
if (address < export_adress || address >= export_adress + export_size)
return reinterpret_cast<FARPROC>(reinterpret_cast<uint8_t *>(module) + address);
// it is a forward
const char *name = reinterpret_cast<const char *>(reinterpret_cast<uint8_t *>(module) + address); // get a pointer to the module's name
const char *tmp = name;
const char *name_dot = NULL;
// get a pointer to the function's name
while (*tmp) {
if (*tmp == '.') {
name_dot = tmp;
break;
}
tmp++;
}
if (!name_dot)
return NULL;
size_t name_len = name_dot - name;
if (name_len >= MAX_PATH)
return NULL;
// copy module name
char file_name[MAX_PATH];
size_t i;
for (i = 0; i < name_len && name[i] != 0; i++) {
file_name[i] = name[i];
}
file_name[i] = 0;
module = GetModuleHandleA(file_name);
if (!module)
return NULL;
// now the function's name
// if it is not an ordinal, just forward it
if (name_dot[1] != '#')
return InternalGetProcAddress(module, name_dot + 1);
// is is an ordinal
int ordinal = atoi(name_dot + 2);
return InternalGetProcAddress(module, LPCSTR(INT_PTR(ordinal)));
}
#endif

23
runtime/utils.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef UTILS_H
#define UTILS_H
void ShowMessage(const VMP_CHAR *message);
#ifdef VMP_GNU
#elif defined(WIN_DRIVER)
HMODULE GetModuleHandleA(const char *name);
#else
void *InternalGetProcAddress(HMODULE module, const char *proc_name);
__forceinline void InitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
{
if (SourceString)
DestinationString->MaximumLength = (DestinationString->Length = (USHORT)(wcslen(SourceString) * sizeof(WCHAR))) + sizeof(UNICODE_NULL);
else
DestinationString->MaximumLength = DestinationString->Length = 0;
DestinationString->Buffer = (PWCH)SourceString;
}
#endif
#endif