Skip to content

Instantly share code, notes, and snippets.

@xpcmdshell
Created June 3, 2017 04:19
Show Gist options
  • Save xpcmdshell/0a7906cd6bab09e7870ae6bafca9725f to your computer and use it in GitHub Desktop.
Save xpcmdshell/0a7906cd6bab09e7870ae6bafca9725f to your computer and use it in GitHub Desktop.
Application Verifier Basics
#include "stdafx.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include "prio.h"
//Convenient define for the fdwReason
#define VERIFIER_LOAD 4
/*
Prototypes for additional event callbacks (dll load, unload, and heap free). If you wanted to, you could respond to these events. We will
leave their function bodies undefined.
*/
typedef VOID(NTAPI* RTL_VERIFIER_DLL_LOAD_CALLBACK) (PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved);
typedef VOID(NTAPI* RTL_VERIFIER_DLL_UNLOAD_CALLBACK) (PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved);
typedef VOID(NTAPI* RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK) (PVOID AllocationBase, SIZE_T AllocationSize);
//Necessary structures
typedef struct _RTL_VERIFIER_THUNK_DESCRIPTOR {
PCHAR ThunkName;
PVOID ThunkOldAddress;
PVOID ThunkNewAddress;
} RTL_VERIFIER_THUNK_DESCRIPTOR, *PRTL_VERIFIER_THUNK_DESCRIPTOR;
typedef struct _RTL_VERIFIER_DLL_DESCRIPTOR {
PWCHAR DllName;
DWORD DllFlags;
PVOID DllAddress;
PRTL_VERIFIER_THUNK_DESCRIPTOR DllThunks;
} RTL_VERIFIER_DLL_DESCRIPTOR, *PRTL_VERIFIER_DLL_DESCRIPTOR;
typedef struct _RTL_VERIFIER_PROVIDER_DESCRIPTOR {
DWORD Length;
PRTL_VERIFIER_DLL_DESCRIPTOR ProviderDlls;
RTL_VERIFIER_DLL_LOAD_CALLBACK ProviderDllLoadCallback;
RTL_VERIFIER_DLL_UNLOAD_CALLBACK ProviderDllUnloadCallback;
PWSTR VerifierImage;
DWORD VerifierFlags;
DWORD VerifierDebug;
PVOID RtlpGetStackTraceAddress;
PVOID RtlpDebugPageHeapCreate;
PVOID RtlpDebugPageHeapDestroy;
RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK ProviderNtdllHeapFreeCallback;
} RTL_VERIFIER_PROVIDER_DESCRIPTOR, *PRTL_VERIFIER_PROVIDER_DESCRIPTOR;
//DbgPrint
typedef ULONG(__cdecl* PFN_DbgPrint)(PCH, ...);
PFN_DbgPrint DbgPrint;
//PR_WRITE prototype
typedef PRInt32(WINAPI* PFN_PRWRITE)(PRFileDesc *fd, const void *buf, PRInt32 amount);
PRInt32 PR_WRITE_HOOK(PRFileDesc *fd, const void *buf, PRInt32 amount);
/*
Arrays containing information about the functions we are hooking, and where they are located.
In this case, PR_WRITE is located in nss3.dll
*/
static RTL_VERIFIER_THUNK_DESCRIPTOR aThunks[] = { { "PR_Write", NULL, PR_WRITE_HOOK },{} };
static RTL_VERIFIER_DLL_DESCRIPTOR aDlls[] = { { L"nss3.dll", 0, NULL, &aThunks[0] },{} };
static RTL_VERIFIER_PROVIDER_DESCRIPTOR vpd = { sizeof(RTL_VERIFIER_PROVIDER_DESCRIPTOR), aDlls };
/*
This is the routine that will be called when PR_WRITE is executed; We
process/inspect the data and save it, then forward the parameters to the
real function.
*/
PRInt32 PR_WRITE_HOOK(PRFileDesc *fd, const void *buf, PRInt32 amount) {
DbgPrint("PR_WRITE(%d) = %s\n", amount, buf);
HANDLE hFile = CreateFileA("C:\\Users\\testuser\\Desktop\\traffic.txt", FILE_APPEND_DATA, FILE_SHARE_WRITE, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
WriteFile(hFile, buf, amount, NULL, NULL);
CloseHandle(hFile);
PRInt32 ret = ((PFN_PRWRITE)(aThunks[0].ThunkOldAddress))(fd, buf, amount);
return ret;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, PRTL_VERIFIER_PROVIDER_DESCRIPTOR* pVPD)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case VERIFIER_LOAD:
//Resolve the location of DbgPrint() at runtime
DbgPrint = (PFN_DbgPrint)::GetProcAddress(::GetModuleHandle(TEXT("NTDLL")), "DbgPrint");
*pVPD = &vpd;
break;
}
return TRUE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment