-
Автор темы
- #1
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
и так мои дорогие пастерочки, решил вам слить очень жeсткий драйвер для уд +- 4 часика
Driver:
#pragma once
#include <windows.h>
#include <string>
#include <vector>
#include <thread>
#include <iostream>
#include <functional>
#include <chrono>
#include <string>
#include "driverdefs.h"
#include <mutex>
std::mutex isuse;
class Driver
{
public:
UINT ProcessId;
const bool Init(const BOOL PhysicalMode) {
this->bPhysicalMode = PhysicalMode;
this->hDriver = CreateFileA((("\\\\.\\\SPACEPORT")), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (this->hDriver != INVALID_HANDLE_VALUE) {
if (this->SharedBuffer = VirtualAlloc(0, sizeof(REQUEST_DATA), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)) {
UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\ALG");
if (!RegistryUtils::WriteRegistry(RegPath, RTL_CONSTANT_STRING(L"cac"), &this->SharedBuffer, REG_QWORD, 8)) {
return false;
}
PVOID pid = (PVOID)GetCurrentProcessId();
if (!RegistryUtils::WriteRegistry(RegPath, RTL_CONSTANT_STRING(L"pi"), &pid, REG_QWORD, 8)) {
return false;
}
auto OLD_MAGGICCODE = this->MAGGICCODE;
SendRequest(99, 0);
if (this->MAGGICCODE == OLD_MAGGICCODE)
this->MAGGICCODE = (ULONG64)RegistryUtils::ReadRegistry<LONG64>(RegPath, RTL_CONSTANT_STRING(L"awer"));
return true;
}
}
return false;
}
const NTSTATUS SendRequest(const UINT type, const PVOID args) {
std::scoped_lock lock(isuse);
REQUEST_DATA req;
NTSTATUS status;
req.MaggicCode = &this->MAGGICCODE;
req.Type = type;
req.Arguments = args;
req.Status = &status;
memcpy(this->SharedBuffer, &req, sizeof(REQUEST_DATA));
FlushFileBuffers(this->hDriver);
return status;
}
NTSTATUS ReadProcessMemory(uint64_t src, void* dest, uint32_t size) {
REQUEST_READ req;
req.ProcessId = ProcessId;
req.Src = src;
req.Dest = dest;
req.Size = size;
req.bPhysicalMem = bPhysicalMode;
return SendRequest(REQUEST_TYPE::READ, &req);
}
NTSTATUS WriteProcessMemory(PVOID src, PVOID dest, DWORD size) {
REQUEST_WRITE req;
req.ProcessId = ProcessId;
req.Src = src;
req.Dest = dest;
req.Size = size;
req.bPhysicalMem = bPhysicalMode;
return SendRequest(REQUEST_TYPE::WRITE, &req);
}
const UINT GetProcessThreadNumByID(DWORD dwPID)
{
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
return 0;
PROCESSENTRY32 pe32 = { 0 };
pe32.dwSize = sizeof(pe32);
BOOL bRet = ::Process32First(hProcessSnap, &pe32);;
while (bRet)
{
if (pe32.th32ProcessID == dwPID)
{
::CloseHandle(hProcessSnap);
return pe32.cntThreads;
}
bRet = ::Process32Next(hProcessSnap, &pe32);
}
return 0;
}
NTSTATUS ZwQueryVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, DWORD Type, PVOID Buffer, SIZE_T Size)
{
REQUEST_ZWQUERY req;
req.ProcessHandle = ProcessHandle;
req.BaseAddress = BaseAddress;
req.Type = Type;
req.Buffer = Buffer;
req.Size = Size;
return SendRequest(REQUEST_TYPE::ZWQUERY, &req);
}
NTSTATUS PsLookupProcessByProcessIdEx(HANDLE ProcessId, PVOID OutProcess)
{
REQUEST_PSLOOKUP req;
req.ProcessId = ProcessId;
req.OutProcess = OutProcess;
return SendRequest(REQUEST_TYPE::PSLOOKUP, &req);
}
const bool Attach(DWORD ProcessID) {
this->ProcessId = ProcessID;
return true;
}
const uint64_t GetModuleBase(const wchar_t* ModuleName = 0) {
if (bPhysicalMode) {
REQUEST_MAINBASE req;
uint64_t base = NULL;
req.ProcessId = ProcessId;
req.OutAddress = (PBYTE*)&base;
SendRequest(REQUEST_TYPE::MAINBASE, &req);
return { base };
}
else {
if (!ModuleName)
return { 0 };
REQUEST_MODULE req;
uint64_t base = NULL;
DWORD size = NULL;
req.ProcessId = ProcessId;
req.OutAddress = (PBYTE*)&base;
req.OutSize = &size;
wcscpy_s(req.Module, sizeof(req.Module) / sizeof(req.Module[0]), ModuleName);
SendRequest(REQUEST_TYPE::MODULE, &req);
return { base };
}
}
private:
PVOID SharedBuffer;
HANDLE hDriver;
ULONG64 MAGGICCODE = 0x25001730218c1e2dul;
BOOL bPhysicalMode = FALSE;
typedef enum _REQUEST_TYPE : UINT {
WRITE,
READ,
PROTECT,
ALLOC,
FREE,
MODULE,
MAINBASE,
THREADCALL,
ZWQUERY,
PSLOOKUP
} REQUEST_TYPE;
typedef struct _REQUEST_DATA {
ULONG64* MaggicCode;
UINT Type;
PVOID Arguments;
NTSTATUS* Status;
} REQUEST_DATA, * PREQUEST_DATA;
typedef struct _REQUEST_WRITE {
DWORD ProcessId;
PVOID Dest;
PVOID Src;
DWORD Size;
BOOL bPhysicalMem;
} REQUEST_WRITE, * PREQUEST_WRITE;
typedef struct _REQUEST_READ {
DWORD ProcessId;
void* Dest;
uint64_t Src;
uint32_t Size;
BOOL bPhysicalMem;
} REQUEST_READ, * PREQUEST_READ;
typedef struct _REQUEST_PROTECT {
DWORD ProcessId;
PVOID Address;
DWORD Size;
PDWORD InOutProtect;
} REQUEST_PROTECT, * PREQUEST_PROTECT;
typedef struct _REQUEST_ALLOC {
DWORD ProcessId;
PVOID OutAddress;
DWORD Size;
DWORD Protect;
} REQUEST_ALLOC, * PREQUEST_ALLOC;
typedef struct _REQUEST_FREE {
DWORD ProcessId;
PVOID Address;
} REQUEST_FREE, * PREQUEST_FREE;
typedef struct _REQUEST_MODULE {
DWORD ProcessId;
WCHAR Module[0xFF];
PBYTE* OutAddress;
DWORD* OutSize;
} REQUEST_MODULE, * PREQUEST_MODULE;
typedef struct _REQUEST_MAINBASE {
DWORD ProcessId;
PBYTE* OutAddress;
} REQUEST_MAINBASE, * PREQUEST_MAINBASE;
typedef struct _REQUEST_ZWQUERY {
HANDLE ProcessHandle;
PVOID BaseAddress;
DWORD Type;
PVOID Buffer;
SIZE_T Size;
} REQUEST_ZWQUERY, * PREQUEST_ZWQUERY;
typedef struct _REQUEST_PSLOOKUP {
HANDLE ProcessId;
PVOID OutProcess;
} REQUEST_PSLOOKUP, * PREQUEST_PSLOOKUP;
};
Driver* driver = new Driver;
template <typename T>
T read(const uintptr_t address)
{
T buffer;
driver->ReadProcessMemory(address, &buffer, sizeof(T));
return buffer;
}
template <typename T>
T write(const uintptr_t address, T buffer)
{
driver->WriteProcessMemory((PVOID)&buffer, (PVOID)address, sizeof(T));
return buffer;
}
DriverDefs:
#pragma once
#include <Windows.h>
#include <iostream>
#include <winternl.h>
#include <ntstatus.h>
#include <atomic>
#include <mutex>
#include <TlHelp32.h>
#include <d3d9.h>
#include <dwmapi.h>
#include <xmmintrin.h>
#pragma comment(lib, "ntdll.lib")
#pragma comment(lib, "dwmapi.lib")
typedef enum _KEY_VALUE_INFORMATION_CLASS {
KeyValueBasicInformation,
KeyValueFullInformation,
KeyValuePartialInformation,
KeyValueFullInformationAlign64,
KeyValuePartialInformationAlign64,
KeyValueLayerInformation,
MaxKeyValueInfoClass // MaxKeyValueInfoClass should always be the last enum
} KEY_VALUE_INFORMATION_CLASS;
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;
#ifdef __cplusplus
extern "C++"
{
char _RTL_CONSTANT_STRING_type_check(const char* s);
char _RTL_CONSTANT_STRING_type_check(const WCHAR* s);
// __typeof would be desirable here instead of sizeof.
template <size_t N> class _RTL_CONSTANT_STRING_remove_const_template_class;
template <> class _RTL_CONSTANT_STRING_remove_const_template_class<sizeof(char)> { public: typedef char T; };
template <> class _RTL_CONSTANT_STRING_remove_const_template_class<sizeof(WCHAR)> { public: typedef WCHAR T; };
#define _RTL_CONSTANT_STRING_remove_const_macro(s) \
(const_cast<_RTL_CONSTANT_STRING_remove_const_template_class<sizeof((s)[0])>::T*>(s))
}
#else
char _RTL_CONSTANT_STRING_type_check(const void* s);
#define _RTL_CONSTANT_STRING_remove_const_macro(s) (s)
#endif
#define RTL_CONSTANT_STRING(s) \
{ \
sizeof( s ) - sizeof( (s)[0] ), \
sizeof( s ) / sizeof(_RTL_CONSTANT_STRING_type_check(s)), \
_RTL_CONSTANT_STRING_remove_const_macro(s) \
}
extern "C" {
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryValueKey(
[I]In[/I] HANDLE KeyHandle,
[I]In[/I] PUNICODE_STRING ValueName,
[I]In[/I] KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
[I]Out_writes_bytes_to_opt[/I](Length, *ResultLength) PVOID KeyValueInformation,
[I]In[/I] ULONG Length,
[I]Out[/I] PULONG ResultLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZwClose(
[I]In[/I] HANDLE Handle
);
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenKey(
[I]Out[/I] PHANDLE KeyHandle,
[I]In[/I] ACCESS_MASK DesiredAccess,
[I]In[/I] POBJECT_ATTRIBUTES ObjectAttributes
);
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryValueKey(
[I]In[/I] HANDLE KeyHandle,
[I]In[/I] PUNICODE_STRING ValueName,
[I]In[/I] KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
[I]Out_writes_bytes_to_opt[/I](Length, *ResultLength) PVOID KeyValueInformation,
[I]In[/I] ULONG Length,
[I]Out[/I] PULONG ResultLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZwSetValueKey(
[I]In[/I] HANDLE KeyHandle,
[I]In[/I] PUNICODE_STRING ValueName,
[I]In_opt[/I] ULONG TitleIndex,
[I]In[/I] ULONG Type,
[I]In_reads_bytes_opt[/I](DataSize) PVOID Data,
[I]In[/I] ULONG DataSize
);
NTSYSAPI NTSTATUS ZwCreateKey(
PHANDLE KeyHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
ULONG TitleIndex,
PUNICODE_STRING Class,
ULONG CreateOptions,
PULONG Disposition
);
}
namespace RegistryUtils
{
__forceinline ULONG GetKeyInfoSize(HANDLE hKey, PUNICODE_STRING Key)
{
NTSTATUS Status;
ULONG KeySize;
Status = ZwQueryValueKey(hKey, Key, KeyValueFullInformation, 0, 0, &KeySize);
if (Status == STATUS_BUFFER_TOO_SMALL || Status == STATUS_BUFFER_OVERFLOW)
return KeySize;
return 0;
}
template <typename type>
__forceinline type ReadRegistry(UNICODE_STRING RegPath, UNICODE_STRING Key)
{
HANDLE hKey;
OBJECT_ATTRIBUTES ObjAttr;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
InitializeObjectAttributes(&ObjAttr, &RegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
Status = ZwOpenKey(&hKey, KEY_ALL_ACCESS, &ObjAttr);
if (NT_SUCCESS(Status))
{
ULONG KeyInfoSize = GetKeyInfoSize(hKey, &Key);
ULONG KeyInfoSizeNeeded;
if (KeyInfoSize == NULL)
{
ZwClose(hKey);
return 0;
}
PKEY_VALUE_FULL_INFORMATION pKeyInfo = (PKEY_VALUE_FULL_INFORMATION)malloc(KeyInfoSize);
RtlZeroMemory(pKeyInfo, KeyInfoSize);
Status = ZwQueryValueKey(hKey, &Key, KeyValueFullInformation, pKeyInfo, KeyInfoSize, &KeyInfoSizeNeeded);
if (!NT_SUCCESS(Status) || (KeyInfoSize != KeyInfoSizeNeeded))
{
ZwClose(hKey);
free(pKeyInfo);
return 0;
}
ZwClose(hKey);
free(pKeyInfo);
return [I](type[/I])((LONG64)pKeyInfo + pKeyInfo->DataOffset);
}
return 0;
}
__forceinline bool WriteRegistry(UNICODE_STRING RegPath, UNICODE_STRING Key, PVOID Address, ULONG Type, ULONG Size)
{
bool Success = false;
HANDLE hKey;
OBJECT_ATTRIBUTES ObjAttr;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
InitializeObjectAttributes(&ObjAttr, &RegPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
Status = ZwOpenKey(&hKey, KEY_ALL_ACCESS, &ObjAttr);
if (NT_SUCCESS(Status))
{
Status = ZwSetValueKey(hKey, &Key, NULL, Type, Address, Size);
if (NT_SUCCESS(Status))
Success = true;
ZwClose(hKey);
}
else {
Status = ZwCreateKey(&hKey, KEY_ALL_ACCESS, &ObjAttr, 0, &RegPath, 0, 0);
if (NT_SUCCESS(Status))
{
Status = ZwSetValueKey(hKey, &Key, NULL, Type, Address, Size);
if (NT_SUCCESS(Status))
Success = true;
}
ZwClose(hKey);
}
return Success;
}
}
offsets:
#pragma once
#include <Windows.h>
#define GWorld 0xe762638
#define VIEW_POINT 0xE2CED18
namespace OFFSETS
{
uintptr_t UWORLD = 0xe762638;
uintptr_t Viewpoint = 0xE2CED18;
uintptr_t Gameinstance = 0x1b8;
uintptr_t LocalPlayers = 0x38;
uintptr_t PlayerController = 0x30;
uintptr_t LocalPawn = 0x338;
uintptr_t PlayerState = 0x2b0;
uintptr_t RootComponet = 0x198;
uintptr_t GameState = 0x158;
uintptr_t PersistentLevel = 0x30;
uintptr_t LastSubmitTime = 0x360;
uintptr_t LastRenderTimeOnScreen = 0x368;
uintptr_t ActorCount = 0xA0;
uintptr_t Cameramanager = 0x348;
uintptr_t AActor = 0x98;
uintptr_t CurrentActor = 0x8;
uintptr_t Mesh = 0x318;
uintptr_t Revivefromdbnotime = 0x4af8;
uintptr_t TeamId = 0x10D8;
uintptr_t ActorTeamId = 0x10C8;
uintptr_t IsDBNO = 0x872;
uintptr_t LocalActorPos = 0x128;
uintptr_t ComponetToWorld = 0x240;
uintptr_t BoneArray = 0x600;
uintptr_t Bonecache = 0x648;
uintptr_t Velocity = 0xb8;
uintptr_t Private = 0x308; //PawnPrivate
uintptr_t PlayerArray = 0x2A8;
uintptr_t relativelocation = 0x128;
uintptr_t UCharacterMovementComponent = 0x318;
uintptr_t entity_actor = 0x310;
uintptr_t bIsReloadingWeapon = 0x358;
uintptr_t GlobalAnimRateScale = 0xA80;
uintptr_t CurrentWeapon = 0x948;
uintptr_t Wireframe = 0x194;
uintptr_t SkeletalMeshes = 0x56e;
uintptr_t PawnMaterials_ALL = 0x5A60;
}
Defs:
#pragma warning(push, 0)
#ifndef HEXRAYS_DEFS_H
#define HEXRAYS_DEFS_H
#if defined([B]GNUC[/B])
typedef long long ll;
typedef unsigned long long ull;
#define __int64 long long
#define __int32 int
#define __int16 short
#define __int8 char
#define MAKELL(num) num ## LL
#define FMT_64 "ll"
#elif defined(_MSC_VER)
typedef __int64 ll;
typedef unsigned __int64 ull;
#define MAKELL(num) num ## i64
#define FMT_64 "I64"
#elif defined ([B]BORLANDC[/B])
typedef __int64 ll;
typedef unsigned __int64 ull;
#define MAKELL(num) num ## i64
#define FMT_64 "L"
#else
#error "unknown compiler"
#endif
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef char int8;
typedef signed char sint8;
typedef unsigned char uint8;
typedef short int16;
typedef signed short sint16;
typedef unsigned short uint16;
typedef int int32;
typedef signed int sint32;
typedef unsigned int uint32;
typedef ll int64;
typedef ll sint64;
typedef ull uint64;
// Partially defined types. They are used when the decompiler does not know
// anything about the type except its size.
#define _BYTE uint8
#define _WORD uint16
#define _DWORD uint32
#define _QWORD uint64
#if !defined(_MSC_VER)
#define _LONGLONG __int128
#endif
// Non-standard boolean types. They are used when the decompiler can not use
// the standard "bool" type because of the size mistmatch but the possible
// values are only 0 and 1. See also 'BOOL' type below.
typedef int8 _BOOL1;
typedef int16 _BOOL2;
typedef int32 _BOOL4;
//#ifndef [I]WINDOWS[/I]
//typedef int8 BYTE;
//typedef int16 WORD;
//typedef int32 DWORD;
//typedef int32 LONG;
//typedef int BOOL; // uppercase BOOL is usually 4 bytes
//#endif
//typedef int64 QWORD;
#ifndef __cplusplus
typedef int bool; // we want to use bool in our C programs
#endif
#define __pure // pure function: always returns the same value, has no
// side effects
// Non-returning function
#if defined([B]GNUC[/B])
#define [B]noreturn __attribute[/B]((noreturn))
#else
#define __noreturn __declspec(noreturn)
#endif
#ifndef NULL
#define NULL 0
#endif
// Some convenience macros to make partial accesses nicer
#define LAST_IND(x,part_type) (sizeof(x)/sizeof(part_type) - 1)
#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN
# define LOW_IND(x,part_type) LAST_IND(x,part_type)
# define HIGH_IND(x,part_type) 0
#else
# define HIGH_IND(x,part_type) LAST_IND(x,part_type)
# define LOW_IND(x,part_type) 0
#endif
// first unsigned macros:
//#define LODWORD(x) ([I]((DWORD[/I])&(x))) // low dword
//#define HIDWORD(x) ([I]((DWORD[/I])&(x)+1))
#define BYTEn(x, n) ([I]((_BYTE[/I])&(x)+n))
#define WORDn(x, n) ([I]((_WORD[/I])&(x)+n))
#define DWORDn(x, n) ([I]((_DWORD[/I])&(x)+n))
#define LOBYTE(x) BYTEn(x,LOW_IND(x,_BYTE))
#define LOWORD(x) WORDn(x,LOW_IND(x,_WORD))
#define LODWORD(x) DWORDn(x,LOW_IND(x,_DWORD))
#define HIBYTE(x) BYTEn(x,HIGH_IND(x,_BYTE))
#define HIWORD(x) WORDn(x,HIGH_IND(x,_WORD))
#define HIDWORD(x) DWORDn(x,HIGH_IND(x,_DWORD))
#define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0)
#define BYTE2(x) BYTEn(x, 2)
#define BYTE3(x) BYTEn(x, 3)
#define BYTE4(x) BYTEn(x, 4)
#define BYTE5(x) BYTEn(x, 5)
#define BYTE6(x) BYTEn(x, 6)
#define BYTE7(x) BYTEn(x, 7)
#define BYTE8(x) BYTEn(x, 8)
#define BYTE9(x) BYTEn(x, 9)
#define BYTE10(x) BYTEn(x, 10)
#define BYTE11(x) BYTEn(x, 11)
#define BYTE12(x) BYTEn(x, 12)
#define BYTE13(x) BYTEn(x, 13)
#define BYTE14(x) BYTEn(x, 14)
#define BYTE15(x) BYTEn(x, 15)
#define WORD1(x) WORDn(x, 1)
#define WORD2(x) WORDn(x, 2) // third word of the object, unsigned
#define WORD3(x) WORDn(x, 3)
#define WORD4(x) WORDn(x, 4)
#define WORD5(x) WORDn(x, 5)
#define WORD6(x) WORDn(x, 6)
#define WORD7(x) WORDn(x, 7)
// now signed macros (the same but with sign extension)
#define SBYTEn(x, n) ([I]((int8[/I])&(x)+n))
#define SWORDn(x, n) ([I]((int16[/I])&(x)+n))
#define SDWORDn(x, n) ([I]((int32[/I])&(x)+n))
#define SLOBYTE(x) SBYTEn(x,LOW_IND(x,int8))
#define SLOWORD(x) SWORDn(x,LOW_IND(x,int16))
#define SLODWORD(x) SDWORDn(x,LOW_IND(x,int32))
#define SHIBYTE(x) SBYTEn(x,HIGH_IND(x,int8))
#define SHIWORD(x) SWORDn(x,HIGH_IND(x,int16))
#define SHIDWORD(x) SDWORDn(x,HIGH_IND(x,int32))
#define SBYTE1(x) SBYTEn(x, 1)
#define SBYTE2(x) SBYTEn(x, 2)
#define SBYTE3(x) SBYTEn(x, 3)
#define SBYTE4(x) SBYTEn(x, 4)
#define SBYTE5(x) SBYTEn(x, 5)
#define SBYTE6(x) SBYTEn(x, 6)
#define SBYTE7(x) SBYTEn(x, 7)
#define SBYTE8(x) SBYTEn(x, 8)
#define SBYTE9(x) SBYTEn(x, 9)
#define SBYTE10(x) SBYTEn(x, 10)
#define SBYTE11(x) SBYTEn(x, 11)
#define SBYTE12(x) SBYTEn(x, 12)
#define SBYTE13(x) SBYTEn(x, 13)
#define SBYTE14(x) SBYTEn(x, 14)
#define SBYTE15(x) SBYTEn(x, 15)
#define SWORD1(x) SWORDn(x, 1)
#define SWORD2(x) SWORDn(x, 2)
#define SWORD3(x) SWORDn(x, 3)
#define SWORD4(x) SWORDn(x, 4)
#define SWORD5(x) SWORDn(x, 5)
#define SWORD6(x) SWORDn(x, 6)
#define SWORD7(x) SWORDn(x, 7)
// Helper functions to represent some assembly instructions.
#ifdef __cplusplus
// compile time assertion
#define [B]CASSERT_N0[/B](l) COMPILE_TIME_ASSERT_ ## l
#define [B]CASSERT_N1[/B](l) [B]CASSERT_N0[/B](l)
#define CASSERT(cnd) typedef char [B]CASSERT_N1[/B]([B]LINE[/B]) [(cnd) ? 1 : -1]
// check that unsigned multiplication does not overflow
template<class T> bool is_mul_ok(T count, T elsize)
{
CASSERT((T)(-1) > 0); // make sure T is unsigned
if (elsize == 0 || count == 0)
return true;
return count <= ((T)(-1)) / elsize;
}
// multiplication that saturates (yields the biggest value) instead of overflowing
// such a construct is useful in "operator new[]"
template<class T> bool saturated_mul(T count, T elsize)
{
return is_mul_ok(count, elsize) ? count * elsize : T(-1);
}
#include <stddef.h> // for size_t
// memcpy() with determined behavoir: it always copies
// from the start to the end of the buffer
// note: it copies byte by byte, so it is not equivalent to, for example, rep movsd
inline void* qmemcpy(void* dst, const void* src, size_t cnt)
{
char* out = (char*)dst;
const char* in = (const char*)src;
while (cnt > 0)
{
*out++ = *in++;
--cnt;
}
return dst;
}
// Generate a reference to pair of operands
template<class T> int16 [B]PAIR[/B](int8 high, T low) { return (((int16)high) << sizeof(high) * 8) | uint8(low); }
template<class T> int32 [B]PAIR[/B](int16 high, T low) { return (((int32)high) << sizeof(high) * 8) | uint16(low); }
template<class T> int64 [B]PAIR[/B](int32 high, T low) { return (((int64)high) << sizeof(high) * 8) | uint32(low); }
template<class T> uint16 [B]PAIR[/B](uint8 high, T low) { return (((uint16)high) << sizeof(high) * 8) | uint8(low); }
template<class T> uint32 [B]PAIR[/B](uint16 high, T low) { return (((uint32)high) << sizeof(high) * 8) | uint16(low); }
template<class T> uint64 [B]PAIR[/B](uint32 high, T low) { return (((uint64)high) << sizeof(high) * 8) | uint32(low); }
// rotate left
template<class T> T [B]ROL[/B](T value, int count)
{
const uint nbits = sizeof(T) * 8;
if (count > 0)
{
count %= nbits;
T high = value >> (nbits - count);
if (T(-1) < 0)
high &= ~((T(-1) << count));
value <<= count;
value |= high;
}
else
{
count = -count % nbits;
T low = value << (nbits - count);
value >>= count;
value |= low;
}
return value;
}
inline uint8 [B]ROL1[/B](uint8 value, int count) { return [B]ROL[/B]((uint8)value, count); }
inline uint16 [B]ROL2[/B](uint16 value, int count) { return [B]ROL[/B]((uint16)value, count); }
inline uint32 [B]ROL4[/B](uint32 value, int count) { return [B]ROL[/B]((uint32)value, count); }
inline uint64 [B]ROL8[/B](uint64 value, int count) { return [B]ROL[/B]((uint64)value, count); }
inline uint8 [B]ROR1[/B](uint8 value, int count) { return [B]ROL[/B]((uint8)value, -count); }
inline uint16 [B]ROR2[/B](uint16 value, int count) { return [B]ROL[/B]((uint16)value, -count); }
inline uint32 [B]ROR4[/B](uint32 value, int count) { return [B]ROL[/B]((uint32)value, -count); }
inline uint64 [B]ROR8[/B](uint64 value, int count) { return [B]ROL[/B]((uint64)value, -count); }
// carry flag of left shift
template<class T> int8 [B]MKCSHL[/B](T value, uint count)
{
const uint nbits = sizeof(T) * 8;
count %= nbits;
return (value >> (nbits - count)) & 1;
}
// carry flag of right shift
template<class T> int8 [B]MKCSHR[/B](T value, uint count)
{
return (value >> (count - 1)) & 1;
}
// sign flag
template<class T> int8 [B]SETS[/B](T x)
{
if (sizeof(T) == 1)
return int8(x) < 0;
if (sizeof(T) == 2)
return int16(x) < 0;
if (sizeof(T) == 4)
return int32(x) < 0;
return int64(x) < 0;
}
// overflow flag of subtraction (x-y)
template<class T, class U> int8 [B]OFSUB[/B](T x, U y)
{
if (sizeof(T) < sizeof(U))
{
U x2 = x;
int8 sx = [B]SETS[/B](x2);
return (sx ^ [B]SETS[/B](y)) & (sx ^ [B]SETS[/B](x2 - y));
}
else
{
T y2 = y;
int8 sx = [B]SETS[/B](x);
return (sx ^ [B]SETS[/B](y2)) & (sx ^ [B]SETS[/B](x - y2));
}
}
// overflow flag of addition (x+y)
template<class T, class U> int8 [B]OFADD[/B](T x, U y)
{
if (sizeof(T) < sizeof(U))
{
U x2 = x;
int8 sx = [B]SETS[/B](x2);
return ((1 ^ sx) ^ [B]SETS[/B](y)) & (sx ^ [B]SETS[/B](x2 + y));
}
else
{
T y2 = y;
int8 sx = [B]SETS[/B](x);
return ((1 ^ sx) ^ [B]SETS[/B](y2)) & (sx ^ [B]SETS[/B](x + y2));
}
}
// carry flag of subtraction (x-y)
template<class T, class U> int8 [B]CFSUB[/B](T x, U y)
{
int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U);
if (size == 1)
return uint8(x) < uint8(y);
if (size == 2)
return uint16(x) < uint16(y);
if (size == 4)
return uint32(x) < uint32(y);
return uint64(x) < uint64(y);
}
// carry flag of addition (x+y)
template<class T, class U> int8 [B]CFADD[/B](T x, U y)
{
int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U);
if (size == 1)
return uint8(x) > uint8(x + y);
if (size == 2)
return uint16(x) > uint16(x + y);
if (size == 4)
return uint32(x) > uint32(x + y);
return uint64(x) > uint64(x + y);
}
#else
// The following definition is not quite correct because it always returns
// uint64. The above C++ functions are good, though.
#define [B]PAIR[/B](high, low) (((uint64)(high)<<sizeof(high)*8) | low)
// For C, we just provide macros, they are not quite correct.
#define [B]ROL[/B](x, y) [B]rotl[/B](x, y) // Rotate left
#define [B]ROR[/B](x, y) [B]rotr[/B](x, y) // Rotate right
#define [B]CFSHL[/B](x, y) invalid_operation // Generate carry flag for (x<<y)
#define [B]CFSHR[/B](x, y) invalid_operation // Generate carry flag for (x>>y)
#define [B]CFADD[/B](x, y) invalid_operation // Generate carry flag for (x+y)
#define [B]CFSUB[/B](x, y) invalid_operation // Generate carry flag for (x-y)
#define [B]OFADD[/B](x, y) invalid_operation // Generate overflow flag for (x+y)
#define [B]OFSUB[/B](x, y) invalid_operation // Generate overflow flag for (x-y)
#endif
// No definition for rcl/rcr because the carry flag is unknown
#define [B]RCL[/B](x, y) invalid_operation // Rotate left thru carry
#define [B]RCR[/B](x, y) invalid_operation // Rotate right thru carry
#define [B]MKCRCL[/B](x, y) invalid_operation // Generate carry flag for a RCL
#define [B]MKCRCR[/B](x, y) invalid_operation // Generate carry flag for a RCR
#define [B]SETP[/B](x, y) invalid_operation // Generate parity flag for (x-y)
// In the decompilation listing there are some objects declarared as _UNKNOWN
// because we could not determine their types. Since the C compiler does not
// accept void item declarations, we replace them by anything of our choice,
// for example a char:
#define _UNKNOWN char
//#ifdef _MSC_VER
//#define snprintf _snprintf
//#define vsnprintf _vsnprintf
//#endif
#endif // HEXRAYS_DEFS_H
#pragma warning(pop)