800 lines
20 KiB
C
800 lines
20 KiB
C
|
#include "sfcp.h"
|
||
|
#include "sfcfiles.h"
|
||
|
#include <wchar.h>
|
||
|
|
||
|
#define NOEXTAPI
|
||
|
#include <wdbgexts.h>
|
||
|
#undef DECLARE_API
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
#define CPPMOD extern "C"
|
||
|
#else
|
||
|
#define CPPMOD
|
||
|
#endif
|
||
|
|
||
|
#define DECLARE_API(s) \
|
||
|
CPPMOD VOID \
|
||
|
s( \
|
||
|
HANDLE hCurrentProcess, \
|
||
|
HANDLE hCurrentThread, \
|
||
|
DWORD_PTR dwCurrentPc, \
|
||
|
PWINDBG_EXTENSION_APIS lpExtensionApis, \
|
||
|
LPSTR lpArgumentString \
|
||
|
)
|
||
|
|
||
|
#define INIT_API() { \
|
||
|
ExtensionApis = *lpExtensionApis; \
|
||
|
ExtensionCurrentProcess = hCurrentProcess; \
|
||
|
}
|
||
|
|
||
|
#define dprintf (ExtensionApis.lpOutputRoutine)
|
||
|
#define GetExpression (ExtensionApis.lpGetExpressionRoutine)
|
||
|
#define GetSymbol (ExtensionApis.lpGetSymbolRoutine)
|
||
|
#define Disasm (ExtensionApis.lpDisasmRoutine)
|
||
|
#define CheckControlC (ExtensionApis.lpCheckControlCRoutine)
|
||
|
#define ReadMemory(a,b,c,d) \
|
||
|
((ExtensionApis.nSize == sizeof(WINDBG_OLD_EXTENSION_APIS)) ? \
|
||
|
ReadProcessMemory( ExtensionCurrentProcess, (LPCVOID)(a), (b), (c), (d) ) \
|
||
|
: ExtensionApis.lpReadProcessMemoryRoutine( (ULONG_PTR)(a), (b), (c), ((DWORD *)d) ))
|
||
|
|
||
|
#define WriteMemory(a,b,c,d) \
|
||
|
((ExtensionApis.nSize == sizeof(WINDBG_OLD_EXTENSION_APIS)) ? \
|
||
|
WriteProcessMemory( ExtensionCurrentProcess, (LPVOID)(a), (LPVOID)(b), (c), (d) ) \
|
||
|
: ExtensionApis.lpWriteProcessMemoryRoutine( (ULONG_PTR)(a), (LPVOID)(b), (c), ((DWORD *)d) ))
|
||
|
|
||
|
#define Ioctl (ExtensionApis.lpIoctlRoutine)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
WINDBG_EXTENSION_APIS ExtensionApis;
|
||
|
HANDLE ExtensionCurrentProcess;
|
||
|
|
||
|
|
||
|
|
||
|
PWSTR
|
||
|
MultiByteToUnicode(
|
||
|
IN PCSTR String,
|
||
|
IN UINT Codepage
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Convert a string to unicode.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
String - supplies string to be converted.
|
||
|
|
||
|
Codepage - supplies codepage to be used for the conversion.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
NULL if string could not be converted (out of memory or invalid cp)
|
||
|
Caller can free buffer with MyFree().
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
UINT BytesIn8BitString;
|
||
|
UINT CharsInUnicodeString;
|
||
|
PWSTR UnicodeString;
|
||
|
|
||
|
BytesIn8BitString = lstrlenA(String) + 1;
|
||
|
|
||
|
//
|
||
|
// Allocate maximally sized buffer.
|
||
|
// If every character is a single-byte character,
|
||
|
// then the buffer needs to be twice the size
|
||
|
// as the 8bit string. Otherwise it might be smaller,
|
||
|
// as some characters are 2 bytes in their unicode and
|
||
|
// 8bit representations.
|
||
|
//
|
||
|
UnicodeString = malloc(BytesIn8BitString * sizeof(WCHAR));
|
||
|
if(UnicodeString == NULL) {
|
||
|
return(NULL);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Perform the conversion.
|
||
|
//
|
||
|
CharsInUnicodeString = MultiByteToWideChar(
|
||
|
Codepage,
|
||
|
MB_PRECOMPOSED,
|
||
|
String,
|
||
|
BytesIn8BitString,
|
||
|
UnicodeString,
|
||
|
BytesIn8BitString
|
||
|
);
|
||
|
|
||
|
if(CharsInUnicodeString == 0) {
|
||
|
free(UnicodeString);
|
||
|
return(NULL);
|
||
|
}
|
||
|
|
||
|
return(UnicodeString);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void
|
||
|
dump_SFC_REGISTRY_VALUE(
|
||
|
PSFC_REGISTRY_VALUE srv,
|
||
|
DWORD_PTR Addr
|
||
|
)
|
||
|
{
|
||
|
SIZE_T cb;
|
||
|
WCHAR buf[512];
|
||
|
|
||
|
dprintf( "SFC_REGISTRY_VALUE at %p\n", Addr );
|
||
|
dprintf( "\tEntry.Flink = 0x%08x\n", srv->Entry.Flink );
|
||
|
dprintf( "\tEntry.Blink = 0x%08x\n", srv->Entry.Blink );
|
||
|
ReadMemory( srv->FileName.Buffer, buf, srv->FileName.Length+sizeof(WCHAR), &cb);
|
||
|
dprintf( "\tFileName = %ws\n", buf );
|
||
|
ReadMemory( srv->DirName.Buffer, buf, srv->DirName.Length+sizeof(WCHAR), &cb);
|
||
|
dprintf( "\tDirName = %ws\n", buf );
|
||
|
ReadMemory( srv->FullPathName.Buffer, buf, srv->FullPathName.Length+sizeof(WCHAR), &cb);
|
||
|
dprintf( "\tFullPathName = %ws\n", buf );
|
||
|
ReadMemory( srv->InfName.Buffer, buf, srv->FileName.Length+sizeof(WCHAR), &cb);
|
||
|
dprintf( "\tInfName = %ws\n", srv->InfName );
|
||
|
ReadMemory( srv->SourceFileName.Buffer, buf, srv->SourceFileName.Length+sizeof(WCHAR), &cb);
|
||
|
dprintf( "\tSourceFileName = %ws\n", srv->SourceFileName );
|
||
|
dprintf( "\tDirHandle = 0x%08x\n", srv->DirHandle );
|
||
|
//dprintf( "\tFlags = 0x%08x\n", srv->IgnoreNextChange );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
dump_IMAGE_VALIDATION_DATA(
|
||
|
PIMAGE_VALIDATION_DATA ivd
|
||
|
)
|
||
|
{
|
||
|
dprintf( "DllVersion = 0x%I64x\n", ivd->DllVersion );
|
||
|
dprintf( "DllCheckSum = 0x%08x\n", ivd->DllCheckSum );
|
||
|
dprintf( "SignatureValid = %s\n", ivd->SignatureValid ? "true" : "false" );
|
||
|
dprintf( "FilePresent = %s\n", ivd->FilePresent ? "true" : "false" );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
dump_COMPLETE_VALIDATION_DATA(
|
||
|
PCOMPLETE_VALIDATION_DATA cvd
|
||
|
)
|
||
|
{
|
||
|
dprintf( "*Original* = 0x%08x\n", &cvd->Original );
|
||
|
dump_IMAGE_VALIDATION_DATA( &cvd->Original );
|
||
|
dprintf( "*Cache* = 0x%08x\n", &cvd->Cache );
|
||
|
dump_IMAGE_VALIDATION_DATA( &cvd->Cache );
|
||
|
dprintf( "*New* = 0x%08x\n", &cvd->New );
|
||
|
dump_IMAGE_VALIDATION_DATA( &cvd->New );
|
||
|
dprintf( "RestoreFromReal = %s\n", cvd->RestoreFromReal ? "true" : "false" );
|
||
|
dprintf( "RestoreFromCache = %s\n", cvd->RestoreFromCache ? "true" : "false" );
|
||
|
dprintf( "RestoreFromMedia = %s\n", cvd->RestoreFromMedia ? "true" : "false" );
|
||
|
dprintf( "NotifyUser = %s\n", cvd->NotifyUser ? "true" : "false" );
|
||
|
dprintf( "BadCacheEntry = %s\n", cvd->BadCacheEntry ? "true" : "false" );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
dump_RESTORE_QUEUE(
|
||
|
PRESTORE_QUEUE rq,
|
||
|
DWORD_PTR Addr
|
||
|
)
|
||
|
{
|
||
|
dprintf( "RESTORE_QUEUE at %p\n", Addr );
|
||
|
dprintf( "FileQueue = %p\n", rq->FileQueue );
|
||
|
dprintf( "QueueCount = %d\n", rq->QueueCount );
|
||
|
dprintf( "RestoreInProgress = %s\n", rq->RestoreInProgress ? "true" : "false" );
|
||
|
dprintf( "RestoreComplete = %s\n", rq->RestoreComplete ? "true" : "false" );
|
||
|
dprintf( "RestoreStatus = %s\n", rq->RestoreStatus ? "true" : "false" );
|
||
|
dprintf( "LastErrorCode = %d (0x%08x)\n", rq->LastErrorCode, rq->LastErrorCode );
|
||
|
dprintf( "WorkerThreadHandle = %d\n", rq->WorkerThreadHandle );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
dump_VALIDATION_REQUEST_DATA(
|
||
|
PVALIDATION_REQUEST_DATA vrd,
|
||
|
DWORD_PTR Addr
|
||
|
)
|
||
|
{
|
||
|
SIZE_T cb;
|
||
|
SFC_REGISTRY_VALUE RegVal;
|
||
|
|
||
|
|
||
|
dprintf( "**VALIDATION_REQUEST_DATA at address = 0x%p**\n", Addr );
|
||
|
|
||
|
#if DBG
|
||
|
if (vrd->Signature != 0x69696969) {
|
||
|
dprintf( "**** invalid queue entry, signature does not match\n" );
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
dprintf( "\tEntry.Flink = 0x%08x\n", vrd->Entry.Flink );
|
||
|
dprintf( "\tEntry.Blink = 0x%08x\n", vrd->Entry.Blink );
|
||
|
dprintf( "\tImageValData = 0x%08x\n", &vrd->ImageValData );
|
||
|
dump_COMPLETE_VALIDATION_DATA( &vrd->ImageValData );
|
||
|
dprintf( "\tRegVal = 0x%08x\n", vrd->RegVal );
|
||
|
ReadMemory( vrd->RegVal, &RegVal, sizeof(SFC_REGISTRY_VALUE), &cb);
|
||
|
dump_SFC_REGISTRY_VALUE( &RegVal, (DWORD_PTR)vrd->RegVal );
|
||
|
dprintf( "\tChangeType = %d\n", vrd->ChangeType );
|
||
|
dprintf( "\tCopyCompleted = %s\n", vrd->CopyCompleted ? "true" : "false" );
|
||
|
dprintf( "\tWin32Error = %d (0x%08x)\n", vrd->Win32Error, vrd->Win32Error );
|
||
|
dprintf( "\tFlags = 0x%08x\n", vrd->Flags );
|
||
|
dprintf( "\tRetryCount = 0x%08x\n", vrd->RetryCount );
|
||
|
dprintf( "\tSyncOnly = %s\n", vrd->SyncOnly ? "true" : "false" );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
dump_PROTECT_FILE_ENTRY(
|
||
|
PPROTECT_FILE_ENTRY Entry,
|
||
|
DWORD_PTR Addr
|
||
|
)
|
||
|
{
|
||
|
WCHAR SourceFileBuffer[MAX_PATH];
|
||
|
WCHAR DestFileBuffer[MAX_PATH];
|
||
|
WCHAR InfNameBuffer[MAX_PATH];
|
||
|
SIZE_T cb;
|
||
|
|
||
|
if (Entry->SourceFileName) {
|
||
|
ReadMemory( Entry->SourceFileName, SourceFileBuffer, sizeof(SourceFileBuffer), &cb);
|
||
|
}else {
|
||
|
SourceFileBuffer[0] = L'\0';
|
||
|
}
|
||
|
|
||
|
if (Entry->FileName) {
|
||
|
ReadMemory( Entry->FileName, DestFileBuffer, sizeof(DestFileBuffer), &cb);
|
||
|
}else {
|
||
|
DestFileBuffer[0] = L'\0';
|
||
|
}
|
||
|
|
||
|
if (Entry->InfName) {
|
||
|
ReadMemory( Entry->InfName, InfNameBuffer, sizeof(InfNameBuffer), &cb);
|
||
|
}else {
|
||
|
InfNameBuffer[0] = L'\0';
|
||
|
}
|
||
|
|
||
|
dprintf( " PROTECT_FILE_ENTRY at %p\n", Addr );
|
||
|
dprintf( " \tSourceFileName = %S\n" , SourceFileBuffer[0] ? SourceFileBuffer : L"[Same as target name]" );
|
||
|
dprintf( " \tFileName = %S\n" , DestFileBuffer );
|
||
|
dprintf( " \tInfName = %S\n" , InfNameBuffer[0] ? InfNameBuffer : L"[None, default to layout.inf]" );
|
||
|
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
DoesProtFileEntryMatch(
|
||
|
PPROTECT_FILE_ENTRY Entry,
|
||
|
DWORD_PTR Addr,
|
||
|
PCWSTR FileName
|
||
|
)
|
||
|
{
|
||
|
WCHAR SourceFileBuffer[MAX_PATH];
|
||
|
WCHAR DestFileBuffer[MAX_PATH];
|
||
|
WCHAR InfNameBuffer[MAX_PATH];
|
||
|
DWORD count;
|
||
|
PCWSTR p;
|
||
|
SIZE_T cb;
|
||
|
PCWSTR a[3] = { SourceFileBuffer, DestFileBuffer, InfNameBuffer } ;
|
||
|
|
||
|
if (Entry->SourceFileName) {
|
||
|
ReadMemory( Entry->SourceFileName, SourceFileBuffer, sizeof(SourceFileBuffer), &cb);
|
||
|
}else {
|
||
|
SourceFileBuffer[0] = L'\0';
|
||
|
}
|
||
|
|
||
|
if (Entry->FileName) {
|
||
|
ReadMemory( Entry->FileName, DestFileBuffer, sizeof(DestFileBuffer), &cb);
|
||
|
}else {
|
||
|
DestFileBuffer[0] = L'\0';
|
||
|
}
|
||
|
|
||
|
if (Entry->InfName) {
|
||
|
ReadMemory( Entry->InfName, InfNameBuffer, sizeof(InfNameBuffer), &cb);
|
||
|
}else {
|
||
|
InfNameBuffer[0] = L'\0';
|
||
|
}
|
||
|
|
||
|
for (count = 0; count < 3; count++) {
|
||
|
|
||
|
p = wcsrchr( a[count], L'\\' );
|
||
|
if (p) {
|
||
|
p += 1;
|
||
|
if (_wcsicmp(p, FileName)== 0) {
|
||
|
return(TRUE);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
DoesRegEntryMatch(
|
||
|
PSFC_REGISTRY_VALUE Entry,
|
||
|
DWORD_PTR Addr,
|
||
|
PCWSTR FileName
|
||
|
)
|
||
|
{
|
||
|
WCHAR Buffer[MAX_PATH];
|
||
|
DWORD count;
|
||
|
PCWSTR p;
|
||
|
SIZE_T cb;
|
||
|
PUNICODE_STRING a[5];
|
||
|
|
||
|
a[0] = &Entry->FileName;
|
||
|
a[1] = &Entry->DirName;
|
||
|
a[2] = &Entry->FullPathName;
|
||
|
a[3] = &Entry->InfName;
|
||
|
a[4] = &Entry->SourceFileName;
|
||
|
|
||
|
for (count = 0; count < 5; count++) {
|
||
|
if (a[count]->Buffer) {
|
||
|
ReadMemory( a[count]->Buffer, Buffer, sizeof(Buffer), &cb);
|
||
|
}
|
||
|
p = wcsrchr( Buffer, L'\\' );
|
||
|
if (p) {
|
||
|
p += 1;
|
||
|
} else {
|
||
|
p = Buffer;
|
||
|
}
|
||
|
if (_wcsicmp(p, FileName)== 0) {
|
||
|
return(TRUE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
DECLARE_API( help )
|
||
|
{
|
||
|
INIT_API();
|
||
|
|
||
|
dprintf( "WFP debugger extension commands:\n" );
|
||
|
dprintf( "dumpq - dump validation queue\n" );
|
||
|
dprintf( "dumpsettings - dump global WFP settings\n" );
|
||
|
dprintf( "isprotfile [filename] - search for a particular protected file in the list\n" );
|
||
|
dprintf( "isprotfile [list address] [list count address] [filename] - search for a particular protected file in the list\n" );
|
||
|
dprintf( "protfile - list all protected files in list\n" );
|
||
|
dprintf( "protfile - [list address] [list count address] list all protected files in list\n" );
|
||
|
}
|
||
|
|
||
|
|
||
|
DECLARE_API( dumpq )
|
||
|
{
|
||
|
DWORD_PTR addr;
|
||
|
SIZE_T cb;
|
||
|
LIST_ENTRY Next;
|
||
|
VALIDATION_REQUEST_DATA vrd;
|
||
|
|
||
|
|
||
|
|
||
|
INIT_API();
|
||
|
|
||
|
addr = GetExpression( "SfcErrorQueue" );
|
||
|
if (!addr) {
|
||
|
dprintf("couldn't get address");
|
||
|
return;
|
||
|
}
|
||
|
dprintf( "SfcErrorQueue address=0x%p\n", addr );
|
||
|
|
||
|
ReadMemory( addr, &Next, sizeof(Next), &cb);
|
||
|
|
||
|
if (Next.Flink == (PVOID)addr) {
|
||
|
dprintf( "queue is empty\n" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
do {
|
||
|
ReadMemory( Next.Flink, &vrd, sizeof(VALIDATION_REQUEST_DATA), &cb);
|
||
|
dump_VALIDATION_REQUEST_DATA( &vrd, (DWORD_PTR)Next.Flink );
|
||
|
Next.Flink = vrd.Entry.Flink;
|
||
|
if (Next.Flink != (PVOID)addr) {
|
||
|
dprintf( "\n******************************************\n\n" );
|
||
|
}
|
||
|
|
||
|
if (CheckControlC() ) {
|
||
|
dprintf( "\nInterrupted\n\n" );
|
||
|
break;
|
||
|
}
|
||
|
} while (Next.Flink != (PVOID)addr);
|
||
|
}
|
||
|
|
||
|
DECLARE_API( dumpsettings )
|
||
|
{
|
||
|
DWORD_PTR addr;
|
||
|
SIZE_T cb;
|
||
|
DWORD val;
|
||
|
|
||
|
|
||
|
INIT_API();
|
||
|
|
||
|
|
||
|
addr = GetExpression( "SFCDisable" );
|
||
|
|
||
|
if (!addr) {
|
||
|
dprintf("couldn't get address");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ReadMemory( addr, &val, sizeof(DWORD), &cb);
|
||
|
dprintf( "SFCDisable = %d\n", val );
|
||
|
}
|
||
|
|
||
|
DECLARE_API( dumpregval )
|
||
|
{
|
||
|
DWORD_PTR addr;
|
||
|
SIZE_T cb;
|
||
|
SFC_REGISTRY_VALUE regval;
|
||
|
|
||
|
INIT_API();
|
||
|
|
||
|
while (*lpArgumentString == ' ') {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
|
||
|
if (*lpArgumentString) {
|
||
|
addr = GetExpression( lpArgumentString );
|
||
|
} else {
|
||
|
dprintf("bogus usage\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!addr) {
|
||
|
dprintf("couldn't get address");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ReadMemory( addr, ®val, sizeof(SFC_REGISTRY_VALUE), &cb);
|
||
|
dump_SFC_REGISTRY_VALUE( ®val, (DWORD_PTR)addr );
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
DECLARE_API( dumprq )
|
||
|
{
|
||
|
DWORD_PTR addr;
|
||
|
SIZE_T cb;
|
||
|
RESTORE_QUEUE rq;
|
||
|
|
||
|
INIT_API();
|
||
|
|
||
|
while (*lpArgumentString == ' ') {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
|
||
|
if (*lpArgumentString) {
|
||
|
addr = GetExpression( lpArgumentString );
|
||
|
} else {
|
||
|
dprintf("bogus usage\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!addr) {
|
||
|
dprintf("couldn't get address");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ReadMemory( addr, &rq, sizeof(RESTORE_QUEUE), &cb);
|
||
|
dump_RESTORE_QUEUE( &rq, addr );
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
DECLARE_API( dumpvrd )
|
||
|
{
|
||
|
DWORD_PTR addr;
|
||
|
SIZE_T cb;
|
||
|
VALIDATION_REQUEST_DATA vrd;
|
||
|
|
||
|
INIT_API();
|
||
|
|
||
|
while (*lpArgumentString == ' ') {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
|
||
|
if (*lpArgumentString) {
|
||
|
addr = GetExpression( lpArgumentString );
|
||
|
} else {
|
||
|
dprintf("bogus usage\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!addr) {
|
||
|
dprintf("couldn't get address");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ReadMemory( addr, &vrd, sizeof(VALIDATION_REQUEST_DATA), &cb);
|
||
|
dump_VALIDATION_REQUEST_DATA( &vrd, addr );
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
DECLARE_API( protfile )
|
||
|
{
|
||
|
DWORD_PTR addrNext, addrTotal;
|
||
|
SIZE_T cb;
|
||
|
PROTECT_FILE_ENTRY Next;
|
||
|
ULONG Total;
|
||
|
ULONG Current;
|
||
|
|
||
|
INIT_API();
|
||
|
|
||
|
while (*lpArgumentString == ' ') {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
|
||
|
if (*lpArgumentString) {
|
||
|
addrNext = GetExpression( lpArgumentString );
|
||
|
|
||
|
while (*lpArgumentString && (*lpArgumentString != ' ') ) {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
while (*lpArgumentString == ' ') {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
|
||
|
if (*lpArgumentString) {
|
||
|
addrTotal = GetExpression( lpArgumentString );
|
||
|
} else {
|
||
|
dprintf("bogus usage\n");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else {
|
||
|
addrNext = GetExpression( "sfc!Tier2Files" );
|
||
|
addrTotal = GetExpression( "sfc!CountTier2Files" );
|
||
|
}
|
||
|
|
||
|
if (!addrTotal || !addrNext) {
|
||
|
dprintf("couldn't get address");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ReadMemory( addrNext, &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
|
||
|
ReadMemory( addrTotal, &Total, sizeof(ULONG), &cb);
|
||
|
|
||
|
dprintf( "Tier2Files: address=0x%p Total=%d\n", addrNext, Total );
|
||
|
|
||
|
Current = 0;
|
||
|
while (Current < Total) {
|
||
|
|
||
|
dump_PROTECT_FILE_ENTRY( &Next, addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)) );
|
||
|
|
||
|
ReadMemory( addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)), &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
|
||
|
|
||
|
Current += 1;
|
||
|
|
||
|
if ( CheckControlC() ) {
|
||
|
dprintf( "\nInterrupted\n\n" );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
DECLARE_API( isprotfile )
|
||
|
{
|
||
|
DWORD_PTR addrNext, addrTotal;
|
||
|
PCSTR FileName;
|
||
|
SIZE_T cb;
|
||
|
PROTECT_FILE_ENTRY Next;
|
||
|
ULONG Total;
|
||
|
ULONG Current;
|
||
|
BOOL FoundMatch = FALSE;
|
||
|
PCWSTR FileNameW;
|
||
|
|
||
|
|
||
|
INIT_API();
|
||
|
|
||
|
while (*lpArgumentString == ' ') {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
|
||
|
if (*lpArgumentString) {
|
||
|
FileName = lpArgumentString;
|
||
|
addrNext = GetExpression( lpArgumentString );
|
||
|
|
||
|
while (*lpArgumentString && (*lpArgumentString != ' ') ) {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
while (*lpArgumentString == ' ') {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
|
||
|
if (*lpArgumentString) {
|
||
|
addrTotal = GetExpression( lpArgumentString );
|
||
|
} else {
|
||
|
addrNext = GetExpression( "sfc!Tier2Files" );
|
||
|
addrTotal = GetExpression( "sfc!CountTier2Files" );
|
||
|
goto doit;
|
||
|
}
|
||
|
|
||
|
while (*lpArgumentString && (*lpArgumentString != ' ') ) {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
while (*lpArgumentString == ' ') {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
|
||
|
if (*lpArgumentString) {
|
||
|
FileName = lpArgumentString;
|
||
|
} else {
|
||
|
dprintf("bogus usage\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
dprintf("bogus usage\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
doit:
|
||
|
|
||
|
if (!addrTotal || !addrNext) {
|
||
|
dprintf("couldn't get address");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ReadMemory( addrNext, &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
|
||
|
ReadMemory( addrTotal, &Total, sizeof(ULONG), &cb);
|
||
|
|
||
|
|
||
|
FileNameW = MultiByteToUnicode( FileName, CP_ACP );
|
||
|
if (!FileNameW) {
|
||
|
dprintf("Error: couldn't convert filename to unicode string\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Current = 0;
|
||
|
while (Current < Total) {
|
||
|
|
||
|
if (DoesProtFileEntryMatch( &Next, addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)),FileNameW )) {
|
||
|
dump_PROTECT_FILE_ENTRY( &Next, addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)) );
|
||
|
FoundMatch = TRUE;
|
||
|
}
|
||
|
|
||
|
ReadMemory( addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)), &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
|
||
|
|
||
|
Current += 1;
|
||
|
|
||
|
if ( CheckControlC() ) {
|
||
|
dprintf( "\nInterrupted\n\n" );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!FoundMatch) {
|
||
|
dprintf( "Couldn't find %s in list\n", FileName );
|
||
|
}
|
||
|
|
||
|
free((PVOID)FileNameW);
|
||
|
|
||
|
}
|
||
|
|
||
|
DECLARE_API( regvals )
|
||
|
{
|
||
|
DWORD_PTR addrNext, addrTotal;
|
||
|
SIZE_T cb;
|
||
|
SFC_REGISTRY_VALUE Next;
|
||
|
ULONG Total;
|
||
|
ULONG Current;
|
||
|
|
||
|
|
||
|
|
||
|
INIT_API();
|
||
|
|
||
|
addrNext = GetExpression( "sfc!SfcProtectedDllsList" );
|
||
|
addrTotal = GetExpression( "sfc!SfcProtectedDllCount" );
|
||
|
|
||
|
if (!addrNext || ! addrTotal) {
|
||
|
dprintf("Error: couldn't resolve sfc!SfcProtectedDllsList and sfc!SfcProtectedDllCount\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ReadMemory( addrNext, &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
|
||
|
ReadMemory( addrTotal, &Total, sizeof(ULONG), &cb);
|
||
|
|
||
|
|
||
|
dprintf( "SfcProtectedDllsList: address=0x%p Total=%d\n", addrNext, Total );
|
||
|
|
||
|
Current = 0;
|
||
|
while (Current < Total) {
|
||
|
|
||
|
dump_SFC_REGISTRY_VALUE( &Next, addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)) );
|
||
|
|
||
|
ReadMemory( addrNext+(Current*sizeof(SFC_REGISTRY_VALUE)), &Next, sizeof(SFC_REGISTRY_VALUE), &cb);
|
||
|
|
||
|
Current += 1;
|
||
|
|
||
|
if ( CheckControlC() ) {
|
||
|
dprintf( "\nInterrupted\n\n" );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
DECLARE_API( getregval )
|
||
|
{
|
||
|
DWORD_PTR addrNext, addrTotal;
|
||
|
PCSTR FileName;
|
||
|
SIZE_T cb;
|
||
|
SFC_REGISTRY_VALUE Next;
|
||
|
ULONG Total;
|
||
|
ULONG Current;
|
||
|
BOOL FoundMatch = FALSE;
|
||
|
PCWSTR FileNameW;
|
||
|
|
||
|
INIT_API();
|
||
|
|
||
|
while (*lpArgumentString == ' ') {
|
||
|
lpArgumentString++;
|
||
|
}
|
||
|
|
||
|
if (*lpArgumentString) {
|
||
|
FileName = lpArgumentString;
|
||
|
} else {
|
||
|
dprintf("bogus usage\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
addrNext = GetExpression( "sfc!SfcProtectedDllsList" );
|
||
|
addrTotal = GetExpression( "sfc!SfcProtectedDllCount" );
|
||
|
|
||
|
if (!addrNext || ! addrTotal) {
|
||
|
dprintf("Error: couldn't resolve sfc!SfcProtectedDllsList and sfc!SfcProtectedDllCount\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ReadMemory( addrNext, &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
|
||
|
ReadMemory( addrTotal, &Total, sizeof(ULONG), &cb);
|
||
|
|
||
|
|
||
|
FileNameW = MultiByteToUnicode( FileName, CP_ACP );
|
||
|
if (!FileNameW) {
|
||
|
dprintf("Error: couldn't convert filename to unicode string\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Current = 0;
|
||
|
while (Current < Total) {
|
||
|
|
||
|
if (DoesRegEntryMatch( &Next, addrNext+(Current*sizeof(SFC_REGISTRY_VALUE)),FileNameW )) {
|
||
|
dump_SFC_REGISTRY_VALUE( &Next, addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)) );
|
||
|
FoundMatch = TRUE;
|
||
|
}
|
||
|
|
||
|
ReadMemory( addrNext+(Current*sizeof(SFC_REGISTRY_VALUE)), &Next, sizeof(SFC_REGISTRY_VALUE), &cb);
|
||
|
|
||
|
Current += 1;
|
||
|
|
||
|
if ( CheckControlC() ) {
|
||
|
dprintf( "\nInterrupted\n\n" );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!FoundMatch) {
|
||
|
dprintf( "Couldn't find %s in list\n", FileName );
|
||
|
}
|
||
|
|
||
|
free((PVOID)FileNameW);
|
||
|
}
|