A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #26968  by Vrtule
 Thu Oct 15, 2015 4:40 pm
Thanks. But I use this API (and try to lock process address space) on WIN10, it cause BSOD.
Use WinDbg to get the lock type (e.g. fast mutex, guarded mutex, ERESOURCE, pushlock...). The type tells you what API you need to use to work with it (ExAcquireFastMutex, ExAcquireGuardedMutex, ExAcquireResourceExclusiveLite...). The type of the lock may change accross various versions of Windows, so take that into account (that should not be a problem since you need to know offset of the lock within the EPROCESS structure for every relevat version of Windows).

I can actually give you my code related to VADs but as I said in my previous post(s):
1) it does no locking so it is always dangerous to run it,
2) it does not work on W8 and newer Windows versions,
3) it contains some comments but they are in Czech :-(.

If you still wish to get the code, visit the following link:
http://www.jadro-windows.cz/download/vad3.zip
 #26970  by myid
 Thu Oct 15, 2015 5:16 pm
Brock wrote:Post relevant code please
Code: Select all
SIZE_T ReadSizeT(SIZE_T address)
{
	return *(PSIZE_T)address;
}

NTKERNELAPI VOID KeAcquireGuardedMutex(PKGUARDED_MUTEX Mutex);
NTKERNELAPI VOID KeReleaseGuardedMutex(PKGUARDED_MUTEX Mutex);

void LOCK_UNLOCK_PROCESS_SPACE(SIZE_T process, BOOLEAN IsLock) //LEAD TO BSOD
{
	SIZE_T lock = ReadSizeT(process + OFFSET_EPROCESS_AddressCreationLock);
	PKGUARDED_MUTEX mutex = (PKGUARDED_MUTEX)(&lock);
	if(IsLock)
		KeAcquireGuardedMutex(mutex);
	else
		KeReleaseGuardedMutex(mutex);
}
Last edited by myid on Thu Oct 15, 2015 5:33 pm, edited 1 time in total.
 #26971  by myid
 Thu Oct 15, 2015 5:31 pm
Vrtule wrote:
Thanks. But I use this API (and try to lock process address space) on WIN10, it cause BSOD.
Use WinDbg to get the lock type (e.g. fast mutex, guarded mutex, ERESOURCE, pushlock...). The type tells you what API you need to use to work with it (ExAcquireFastMutex, ExAcquireGuardedMutex, ExAcquireResourceExclusiveLite...). The type of the lock may change accross various versions of Windows, so take that into account (that should not be a problem since you need to know offset of the lock within the EPROCESS structure for every relevat version of Windows).

I can actually give you my code related to VADs but as I said in my previous post(s):
1) it does no locking so it is always dangerous to run it,
2) it does not work on W8 and newer Windows versions,
3) it contains some comments but they are in Czech :-(.

If you still wish to get the code, visit the following link:
http://www.jadro-windows.cz/download/vad3.zip
Thanks a lot! I have visit your website for serval times.
All of your demo code are very wonderful.
 #26972  by Brock
 Thu Oct 15, 2015 7:06 pm
Windows 10 uses _EX_PUSH_LOCK, I just checked. Like Vrtule mentioned use WinDbg to locate what type of lock for each OS version etc. you plan to support. It's not hard. Make sure you have symbol path properly configured beforehand
 #26974  by myid
 Fri Oct 16, 2015 12:03 am
Brock wrote:Windows 10 uses _EX_PUSH_LOCK, I just checked. Like Vrtule mentioned use WinDbg to locate what type of lock for each OS version etc. you plan to support. It's not hard. Make sure you have symbol path properly configured beforehand
I know WIN10 uses _EX_PUSH_LOCK, could you tell me the related API name of _EX_PUSH_LOCK?
 #26979  by Vrtule
 Fri Oct 16, 2015 10:03 am
myid wrote:
Brock wrote:Windows 10 uses _EX_PUSH_LOCK, I just checked. Like Vrtule mentioned use WinDbg to locate what type of lock for each OS version etc. you plan to support. It's not hard. Make sure you have symbol path properly configured beforehand
I know WIN10 uses _EX_PUSH_LOCK, could you tell me the related API name of _EX_PUSH_LOCK?
AFAIK, pushlock API is not documented as a general kernel API, however, it is available to FS minifilters. The minifilter API should be only stubs around the real one, see:
https://msdn.microsoft.com/en-us/librar ... s.85).aspx

If you wish to use the kernel API (and not to go through fltmgr), here is my source for that. You need to provide a routine that provides you with the operating system version which should not be a problem.
Code: Select all

/**
 * @file: pushlock.c
 *
 * Pushlocky jsou nedokumentovana synchronizacni primitiva, ktera pouziva jadro Windows
 * od verze XP stale vice a vice. Jedna se o zamky reader-writer ne nepodobne zamkum
 * SRWL (Slim Reader Writer Locks) z uzivatelskeho rezimu Vista/7. Velikost je rovna
 * delce adresy. 
 *
 * Tento soubor dovoluje i vyvojarum ovladacu tato primitiva vyuzivat. Zaroven je
 * kompatibilni i s Windows 2000, protoze adresy jednotlivych rutin pro praci s pushlocky
 * nacita dynamicky pres MmGetSystemRoutineAddress.
 */
#include <ntifs.h>
#include "utils-pushlock.h"

// Definice jednotlivych rutin pro praci s pushlocky tak, jak jsou zapsany v ntoskrnl.exe

// Inicializace zamku
typedef VOID (*EXINITIALIZEPUSHLOCK)(PVOID *Lock);
// Zamknout pro exklizivni pristup
typedef VOID (FASTCALL *EXFACQUIREPUSHLOCKEXCLUSIVE)(PVOID *Lock);
// Zamknout pro sdileny pristup
typedef VOID (FASTCALL *EXFACQUIREPUSHLOCKSHARED)(PVOID *Lock);
// Odemknout sdileny pristup
typedef VOID (FASTCALL *EXFRELEASEPUSHLOCKSHARED)(PVOID *Lock);
// Odemknout exkluzivni pristup
typedef VOID (FASTCALL *EXFRELEASEPUSHLOCKEXCLUSIVE)(PVOID *Lock);
// Odemknuti zamku zamceneho pro libovolny pristup.
typedef VOID (FASTCALL *EXFRELEASEPUSHLOCK)(PVOID *Lock);

// Promenne pro uchovani adres rutin pro praci s pushlocky v ntoskrnl.exe
static EXINITIALIZEPUSHLOCK _ExInitializePushLock = NULL;
static EXFACQUIREPUSHLOCKSHARED _ExfAcquirePushLockShared = NULL;
static EXFACQUIREPUSHLOCKEXCLUSIVE _ExfAcquirePushLockExclusive = NULL;
static EXFRELEASEPUSHLOCKSHARED _ExfReleasePushLockShared = NULL;
static EXFRELEASEPUSHLOCKEXCLUSIVE _ExfReleasePushLockExclusive = NULL;
static EXFRELEASEPUSHLOCK _ExfReleasePushLock = NULL;


/** Vrati adresu zadane rutiny.
 *
 * Prohledavaji se pouze moduly ntoskrnl.exe a hal.dll.
 *
 * @param RoutineName Retezec obsahujici nazev hledane rutiny.
 * 
 * @return Funkce vraci adresu hledane rutiny. Pokud rutina daneho jmena neexistuje ani
 * v ntoskrnl.exe ani v hal.dll, funkce vraci NULL.
 */
static PVOID _GetRoutineAddress(PWCHAR RoutineName)
{
  PVOID Ret = NULL;
  UNICODE_STRING uName;

  RtlInitUnicodeString(&uName, RoutineName);
  Ret = MmGetSystemRoutineAddress(&uName);

  return Ret;
}


/* 
 * Nasleduji "proxy" funkce, ktere obaluji jednotliva volani rutin pro praci
 * s pushlocky v ntoskrnl.exe. Ne vsechny rutiny pro praci s pushlocky jsou definovany
 * na vsech verzich Windows (XP, 2003, Vista, 7), a tak se nektere proxy funkce pouzivaji
 * jen na nekterych verzich OS.
 */

 
/** Inicializuje pushlock.
 *
 * @param Lock adresa promenne, ktera ma byt inicializovana jako pushlock.
 */
VOID PushLockInitialize(PVOID *Lock)
{
  _ExInitializePushLock(Lock);

  return;
}


/** Zamkne pushlock pro sdileny pristup.
 *
 * Rutina taky zakaze normalni APC jadra vstoupenim do kritickeho regionu.
 *
 * @param Lock Adresa pushlocku, ktery si volajici preje zamknout pro sdileny pristup.
 */
VOID PushLockAcquireShared(PVOID *Lock)
{
  KeEnterCriticalRegion();
  _ExfAcquirePushLockShared(Lock);

  return;
}


/** Zamkne pushlock pro exkluzivni pristup.
 *
 * Rutina taky zakaze normalni APC jadra vstoupenim do kritickeho regionu.
 *
 * @param Lock Adresa pushlocku, ktery si volajici preje zamknout pro exkluzivni pristup.
 */
VOID PushLockAcquireExclusive(PVOID *Lock)
{
  KeEnterCriticalRegion();
  _ExfAcquirePushLockExclusive(Lock);

  return;
}

/** Odemkne pushlock zamceny pro sdileny pristup.
 *
 * Rutina zaroven povoli normalni APC jadra vystoupenim z kritickeho regionu.
 *
 * @param Lock Adresa pushlocku, ktery chce volajici odemknout.
 */
VOID PushLockReleaseShared(PVOID *Lock)
{
  _ExfReleasePushLockShared(Lock);
  KeLeaveCriticalRegion();

  return;
}


/** Odemkne pushlock zamceny pro exkluzivni pristup.
 *
 * Rutina zaroven povoli normalni APC jadra vystoupenim z kritickeho regionu.
 *
 * @param Lock Adresa pushlocku, ktery chce volajici odemknout.
 */
 VOID PushLockReleaseExclusive(PVOID *Lock)
{
  _ExfReleasePushLockExclusive(Lock);
  KeLeaveCriticalRegion();

  return;
}


/** Odemkne pushlock. Pushlock muze byt zamcen pro libovolny pristup.
 *
 * Rutina zaroven povoli normalni APC jadra vystoupenim z kritickeho regionu.
 *
 * #param Lock Adresa pushlocku, ktery si volajici preje odemknout.
 */
VOID PushLockRelease(PVOID *Lock)
{
  _ExfReleasePushLock(Lock);
  KeLeaveCriticalRegion();

  return;
}

/*
 * Nasledujici funkce jsou nahrazky za rutiny, ktere na starsich Windows (XP, 2K3)
 * jeste neexistuji. Jejich vyznam je stejny jako v rutinach popsanych vyse.
 */

static VOID WXPW2K3ExInitializePushLock(PVOID *Lock)
{
  *Lock = NULL;

  return;
}

static VOID FASTCALL WXPExfReleasePushLockShared(PVOID *Lock)
{
  _ExfReleasePushLock(Lock);

  return;
}

static VOID FASTCALL WXPExfReleasePushLockExclusive(PVOID *Lock)
{
  _ExfReleasePushLock(Lock);

  return;
}


/** Provadi inicializaci modulu pro praci s pushlocky.
 *
 * Rutina nejprve zjisti aktualni verzi operacniho systemu. Pokud se nejedna o 
 * Windows 2000, rutina namapuje jednotlive funkce na adresy v ntoskrnl.exe. Mapovani
 * se napric verzemi Windows muze lisit, protoze kazda nova verze podporuje vetsi
 * mnozstvi funkci pro praci s pushlocky.
 *
 * @return Funkce vraci hodnotu NTSTATUS indikujici uspech ci neuspech operace.
 */
NTSTATUS PushLockModuleInit(VOID)
{
  LONG VersionCode = 0;
  NTSTATUS Status = STATUS_UNSUCCESSFUL;
  KdPrint(("pushlock.c: PushLockModuleInit()\n"));

  VersionCode = GetVersionCode();
  if (VersionCode != VERSION_UNKNOWN)
    Status = STATUS_SUCCESS;

  if (NT_SUCCESS(Status) && VersionCode != VERSION_W2K) {
	_ExfAcquirePushLockShared = (EXFACQUIREPUSHLOCKSHARED)_GetRoutineAddress(L"ExfAcquirePushLockShared");
    _ExfAcquirePushLockExclusive = (EXFACQUIREPUSHLOCKEXCLUSIVE)_GetRoutineAddress(L"ExfAcquirePushLockExclusive");
	_ExfReleasePushLock = (EXFRELEASEPUSHLOCK)_GetRoutineAddress(L"ExfReleasePushLock");

	if (VersionCode != VERSION_WXP && VersionCode != VERSION_W2K3)
	  _ExInitializePushLock = (EXINITIALIZEPUSHLOCK)_GetRoutineAddress(L"ExInitializePushLock");
	else _ExInitializePushLock = WXPW2K3ExInitializePushLock;
	
	if (VersionCode != VERSION_WXP) {
	  _ExfReleasePushLockShared = (EXFRELEASEPUSHLOCKSHARED)_GetRoutineAddress(L"ExfReleasePushLockShared");
     _ExfReleasePushLockExclusive = (EXFRELEASEPUSHLOCKEXCLUSIVE)_GetRoutineAddress(L"ExfReleasePushLockExclusive");
	} else {
	  _ExfReleasePushLockShared = WXPExfReleasePushLockShared;
	  _ExfReleasePushLockExclusive = WXPExfReleasePushLockExclusive;
	}

    if (_ExInitializePushLock == NULL || _ExfAcquirePushLockShared == NULL ||
	    _ExfAcquirePushLockExclusive == NULL || _ExfReleasePushLockShared == NULL ||
	    _ExfReleasePushLockExclusive == NULL || _ExfReleasePushLock == NULL) {
      Status = STATUS_NOT_FOUND;
      if (_ExInitializePushLock == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExInitializePushLock\n"));

      if (_ExfAcquirePushLockShared == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExfAcquirePushLockShared\n"));

      if (_ExfAcquirePushLockExclusive == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExfAcquirePushLockExclusive\n"));

      if (_ExfReleasePushLockShared == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExfReleasePushLockShared\n"));

      if (_ExfReleasePushLockExclusive == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExfReleasePushLockExclusive\n"));

      if (_ExfReleasePushLock == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExfReleasePushLock\n"));
    }
  }
  KdPrint(("pushlock.c: PushLockModuleInit(-):0x%x\n", Status));
  return Status;
}


/** Provadi uklid po modulu pracujiciho s pushlocky.
 *
 * Jelikoz tento modul nezasahuje nijak do internich struktur jadra, neni co uklizet. 
 * Funkce tedy nedela nic.
 */
VOID PushLockModuleFinit(VOID)
{
  KdPrint(("pushlock.c: PushLockModuleFinit()\n"));

  KdPrint(("pushlock.c: PushLockModuleFinit(-)\n"));
  return;
}

 #26987  by myid
 Sat Oct 17, 2015 1:47 am
Vrtule wrote:
myid wrote:
Brock wrote:Windows 10 uses _EX_PUSH_LOCK, I just checked. Like Vrtule mentioned use WinDbg to locate what type of lock for each OS version etc. you plan to support. It's not hard. Make sure you have symbol path properly configured beforehand
I know WIN10 uses _EX_PUSH_LOCK, could you tell me the related API name of _EX_PUSH_LOCK?
AFAIK, pushlock API is not documented as a general kernel API, however, it is available to FS minifilters. The minifilter API should be only stubs around the real one, see:
https://msdn.microsoft.com/en-us/librar ... s.85).aspx

If you wish to use the kernel API (and not to go through fltmgr), here is my source for that. You need to provide a routine that provides you with the operating system version which should not be a problem.
Code: Select all

/**
 * @file: pushlock.c
 *
 * Pushlocky jsou nedokumentovana synchronizacni primitiva, ktera pouziva jadro Windows
 * od verze XP stale vice a vice. Jedna se o zamky reader-writer ne nepodobne zamkum
 * SRWL (Slim Reader Writer Locks) z uzivatelskeho rezimu Vista/7. Velikost je rovna
 * delce adresy. 
 *
 * Tento soubor dovoluje i vyvojarum ovladacu tato primitiva vyuzivat. Zaroven je
 * kompatibilni i s Windows 2000, protoze adresy jednotlivych rutin pro praci s pushlocky
 * nacita dynamicky pres MmGetSystemRoutineAddress.
 */
#include <ntifs.h>
#include "utils-pushlock.h"

// Definice jednotlivych rutin pro praci s pushlocky tak, jak jsou zapsany v ntoskrnl.exe

// Inicializace zamku
typedef VOID (*EXINITIALIZEPUSHLOCK)(PVOID *Lock);
// Zamknout pro exklizivni pristup
typedef VOID (FASTCALL *EXFACQUIREPUSHLOCKEXCLUSIVE)(PVOID *Lock);
// Zamknout pro sdileny pristup
typedef VOID (FASTCALL *EXFACQUIREPUSHLOCKSHARED)(PVOID *Lock);
// Odemknout sdileny pristup
typedef VOID (FASTCALL *EXFRELEASEPUSHLOCKSHARED)(PVOID *Lock);
// Odemknout exkluzivni pristup
typedef VOID (FASTCALL *EXFRELEASEPUSHLOCKEXCLUSIVE)(PVOID *Lock);
// Odemknuti zamku zamceneho pro libovolny pristup.
typedef VOID (FASTCALL *EXFRELEASEPUSHLOCK)(PVOID *Lock);

// Promenne pro uchovani adres rutin pro praci s pushlocky v ntoskrnl.exe
static EXINITIALIZEPUSHLOCK _ExInitializePushLock = NULL;
static EXFACQUIREPUSHLOCKSHARED _ExfAcquirePushLockShared = NULL;
static EXFACQUIREPUSHLOCKEXCLUSIVE _ExfAcquirePushLockExclusive = NULL;
static EXFRELEASEPUSHLOCKSHARED _ExfReleasePushLockShared = NULL;
static EXFRELEASEPUSHLOCKEXCLUSIVE _ExfReleasePushLockExclusive = NULL;
static EXFRELEASEPUSHLOCK _ExfReleasePushLock = NULL;


/** Vrati adresu zadane rutiny.
 *
 * Prohledavaji se pouze moduly ntoskrnl.exe a hal.dll.
 *
 * @param RoutineName Retezec obsahujici nazev hledane rutiny.
 * 
 * @return Funkce vraci adresu hledane rutiny. Pokud rutina daneho jmena neexistuje ani
 * v ntoskrnl.exe ani v hal.dll, funkce vraci NULL.
 */
static PVOID _GetRoutineAddress(PWCHAR RoutineName)
{
  PVOID Ret = NULL;
  UNICODE_STRING uName;

  RtlInitUnicodeString(&uName, RoutineName);
  Ret = MmGetSystemRoutineAddress(&uName);

  return Ret;
}


/* 
 * Nasleduji "proxy" funkce, ktere obaluji jednotliva volani rutin pro praci
 * s pushlocky v ntoskrnl.exe. Ne vsechny rutiny pro praci s pushlocky jsou definovany
 * na vsech verzich Windows (XP, 2003, Vista, 7), a tak se nektere proxy funkce pouzivaji
 * jen na nekterych verzich OS.
 */

 
/** Inicializuje pushlock.
 *
 * @param Lock adresa promenne, ktera ma byt inicializovana jako pushlock.
 */
VOID PushLockInitialize(PVOID *Lock)
{
  _ExInitializePushLock(Lock);

  return;
}


/** Zamkne pushlock pro sdileny pristup.
 *
 * Rutina taky zakaze normalni APC jadra vstoupenim do kritickeho regionu.
 *
 * @param Lock Adresa pushlocku, ktery si volajici preje zamknout pro sdileny pristup.
 */
VOID PushLockAcquireShared(PVOID *Lock)
{
  KeEnterCriticalRegion();
  _ExfAcquirePushLockShared(Lock);

  return;
}


/** Zamkne pushlock pro exkluzivni pristup.
 *
 * Rutina taky zakaze normalni APC jadra vstoupenim do kritickeho regionu.
 *
 * @param Lock Adresa pushlocku, ktery si volajici preje zamknout pro exkluzivni pristup.
 */
VOID PushLockAcquireExclusive(PVOID *Lock)
{
  KeEnterCriticalRegion();
  _ExfAcquirePushLockExclusive(Lock);

  return;
}

/** Odemkne pushlock zamceny pro sdileny pristup.
 *
 * Rutina zaroven povoli normalni APC jadra vystoupenim z kritickeho regionu.
 *
 * @param Lock Adresa pushlocku, ktery chce volajici odemknout.
 */
VOID PushLockReleaseShared(PVOID *Lock)
{
  _ExfReleasePushLockShared(Lock);
  KeLeaveCriticalRegion();

  return;
}


/** Odemkne pushlock zamceny pro exkluzivni pristup.
 *
 * Rutina zaroven povoli normalni APC jadra vystoupenim z kritickeho regionu.
 *
 * @param Lock Adresa pushlocku, ktery chce volajici odemknout.
 */
 VOID PushLockReleaseExclusive(PVOID *Lock)
{
  _ExfReleasePushLockExclusive(Lock);
  KeLeaveCriticalRegion();

  return;
}


/** Odemkne pushlock. Pushlock muze byt zamcen pro libovolny pristup.
 *
 * Rutina zaroven povoli normalni APC jadra vystoupenim z kritickeho regionu.
 *
 * #param Lock Adresa pushlocku, ktery si volajici preje odemknout.
 */
VOID PushLockRelease(PVOID *Lock)
{
  _ExfReleasePushLock(Lock);
  KeLeaveCriticalRegion();

  return;
}

/*
 * Nasledujici funkce jsou nahrazky za rutiny, ktere na starsich Windows (XP, 2K3)
 * jeste neexistuji. Jejich vyznam je stejny jako v rutinach popsanych vyse.
 */

static VOID WXPW2K3ExInitializePushLock(PVOID *Lock)
{
  *Lock = NULL;

  return;
}

static VOID FASTCALL WXPExfReleasePushLockShared(PVOID *Lock)
{
  _ExfReleasePushLock(Lock);

  return;
}

static VOID FASTCALL WXPExfReleasePushLockExclusive(PVOID *Lock)
{
  _ExfReleasePushLock(Lock);

  return;
}


/** Provadi inicializaci modulu pro praci s pushlocky.
 *
 * Rutina nejprve zjisti aktualni verzi operacniho systemu. Pokud se nejedna o 
 * Windows 2000, rutina namapuje jednotlive funkce na adresy v ntoskrnl.exe. Mapovani
 * se napric verzemi Windows muze lisit, protoze kazda nova verze podporuje vetsi
 * mnozstvi funkci pro praci s pushlocky.
 *
 * @return Funkce vraci hodnotu NTSTATUS indikujici uspech ci neuspech operace.
 */
NTSTATUS PushLockModuleInit(VOID)
{
  LONG VersionCode = 0;
  NTSTATUS Status = STATUS_UNSUCCESSFUL;
  KdPrint(("pushlock.c: PushLockModuleInit()\n"));

  VersionCode = GetVersionCode();
  if (VersionCode != VERSION_UNKNOWN)
    Status = STATUS_SUCCESS;

  if (NT_SUCCESS(Status) && VersionCode != VERSION_W2K) {
	_ExfAcquirePushLockShared = (EXFACQUIREPUSHLOCKSHARED)_GetRoutineAddress(L"ExfAcquirePushLockShared");
    _ExfAcquirePushLockExclusive = (EXFACQUIREPUSHLOCKEXCLUSIVE)_GetRoutineAddress(L"ExfAcquirePushLockExclusive");
	_ExfReleasePushLock = (EXFRELEASEPUSHLOCK)_GetRoutineAddress(L"ExfReleasePushLock");

	if (VersionCode != VERSION_WXP && VersionCode != VERSION_W2K3)
	  _ExInitializePushLock = (EXINITIALIZEPUSHLOCK)_GetRoutineAddress(L"ExInitializePushLock");
	else _ExInitializePushLock = WXPW2K3ExInitializePushLock;
	
	if (VersionCode != VERSION_WXP) {
	  _ExfReleasePushLockShared = (EXFRELEASEPUSHLOCKSHARED)_GetRoutineAddress(L"ExfReleasePushLockShared");
     _ExfReleasePushLockExclusive = (EXFRELEASEPUSHLOCKEXCLUSIVE)_GetRoutineAddress(L"ExfReleasePushLockExclusive");
	} else {
	  _ExfReleasePushLockShared = WXPExfReleasePushLockShared;
	  _ExfReleasePushLockExclusive = WXPExfReleasePushLockExclusive;
	}

    if (_ExInitializePushLock == NULL || _ExfAcquirePushLockShared == NULL ||
	    _ExfAcquirePushLockExclusive == NULL || _ExfReleasePushLockShared == NULL ||
	    _ExfReleasePushLockExclusive == NULL || _ExfReleasePushLock == NULL) {
      Status = STATUS_NOT_FOUND;
      if (_ExInitializePushLock == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExInitializePushLock\n"));

      if (_ExfAcquirePushLockShared == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExfAcquirePushLockShared\n"));

      if (_ExfAcquirePushLockExclusive == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExfAcquirePushLockExclusive\n"));

      if (_ExfReleasePushLockShared == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExfReleasePushLockShared\n"));

      if (_ExfReleasePushLockExclusive == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExfReleasePushLockExclusive\n"));

      if (_ExfReleasePushLock == NULL)
        KdPrint(("pushlock.c: PushLockModuleInit(): Failed to find nt!ExfReleasePushLock\n"));
    }
  }
  KdPrint(("pushlock.c: PushLockModuleInit(-):0x%x\n", Status));
  return Status;
}


/** Provadi uklid po modulu pracujiciho s pushlocky.
 *
 * Jelikoz tento modul nezasahuje nijak do internich struktur jadra, neni co uklizet. 
 * Funkce tedy nedela nic.
 */
VOID PushLockModuleFinit(VOID)
{
  KdPrint(("pushlock.c: PushLockModuleFinit()\n"));

  KdPrint(("pushlock.c: PushLockModuleFinit(-)\n"));
  return;
}

Thanks. I have saved your code.
 #27033  by tigerite
 Thu Oct 22, 2015 8:12 am
Have you looked into Blackbone? https://github.com/DarthTon/Blackbone I used some of this code (along with cross-checking the structures in the volatility and rekall libraries, these are written in python though) to update VMXArk (https://code.google.com/p/vmxark) to work on Win 8.1 x64 with the VAD traversal, and although I do not inspect the Subsection element. I do read the relevant Tag value (VadS or VadL) which you would need to tell whether Subsection is valid or not. I can post some code if that would help, it was also in a driver however.
 #27216  by myid
 Fri Nov 13, 2015 7:23 am
tigerite wrote:Have you looked into Blackbone? https://github.com/DarthTon/Blackbone I used some of this code (along with cross-checking the structures in the volatility and rekall libraries, these are written in python though) to update VMXArk (https://code.google.com/p/vmxark) to work on Win 8.1 x64 with the VAD traversal, and although I do not inspect the Subsection element. I do read the relevant Tag value (VadS or VadL) which you would need to tell whether Subsection is valid or not. I can post some code if that would help, it was also in a driver however.
Thanks.
 #27230  by kerpow1
 Sun Nov 15, 2015 1:42 pm
Code: Select all
typedef enum _WinVer
{
	WINVER_7     = 0x0610,
	WINVER_7_SP1 = 0x0611,
	WINVER_8     = 0x0620,
	WINVER_81    = 0x0630,
	WINVER_10    = 0x0A00,
} WinVer;
Code: Select all
PVOID GetVAD(HANDLE processID)
{
       PVOID pVadRoot = NULL;
       PEPROCESS pEprocess = NULL;
       
	   __try
	   {
		   if (!NT_SUCCESS(PsLookupProcessByProcessId(processID, &pEprocess)))
			   return NULL;
	   }
	   __except(EXCEPTION_EXECUTE_HANDLER)
	   {
		   return NULL;
	   }
       
       //DbgPrint("\n\nEPROCESS : 0x%p \n\n", pEprocess);
       
       if(pEprocess == 0x0)
       {
                    //DbgPrint("\nProcess not found\n");
                    return 0x0;
       }

	   if (g_dynData.VadRootOffset)
	   {
		   switch (g_dynData.ver)
		   {
		   case WINVER_7:
		   case WINVER_7_SP1:
		   case WINVER_8:
			   pVadRoot = (PVOID)((PUCHAR)pEprocess + g_dynData.VadRootOffset);
			   break;
		   case WINVER_81:
		   case WINVER_10:
			   pVadRoot = (PVOID)*(PHANDLE)((PUCHAR)pEprocess + g_dynData.VadRootOffset);
			   break;
		   default:
			   break;
		   }		   
		   //DbgPrint("\n\nVADRoot : 0x%p\n\n", pVadRoot);
	   }
       ObDereferenceObject(pEprocess);
       
       return pVadRoot;
}