Created
June 3, 2017 04:19
-
-
Save xpcmdshell/0a7906cd6bab09e7870ae6bafca9725f to your computer and use it in GitHub Desktop.
Application Verifier Basics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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