374 lines
7.3 KiB
C
374 lines
7.3 KiB
C
/*++
|
|
|
|
Copyright (c) 1996-2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
miscellaneous.c
|
|
|
|
Abstract:
|
|
|
|
Quick and not-so-dirty user-mode dh for heap.
|
|
|
|
Author(s):
|
|
|
|
Silviu Calinoiu (SilviuC) 06-Feb-00
|
|
|
|
Revision History:
|
|
|
|
SilviuC 06-Feb-00 Initial version
|
|
|
|
--*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <windows.h>
|
|
|
|
#include "miscellaneous.h"
|
|
|
|
GLOBALS Globals;
|
|
|
|
PVOID
|
|
Xalloc (
|
|
PCHAR File,
|
|
ULONG Line,
|
|
SIZE_T Size
|
|
)
|
|
{
|
|
PSIZE_T Result;
|
|
|
|
Result = (PSIZE_T) malloc (Size + sizeof (SIZE_T));
|
|
|
|
if (Result == NULL) {
|
|
|
|
//
|
|
// We will never return from this call.
|
|
//
|
|
|
|
Comment( "malloc(%p) failed %s:%d",Size-sizeof(SIZE_T),File,Line);
|
|
return NULL;
|
|
}
|
|
|
|
Globals.CurrentHeapUsage += Size;
|
|
|
|
if (Globals.CurrentHeapUsage > Globals.MaximumHeapUsage) {
|
|
Globals.MaximumHeapUsage = Globals.CurrentHeapUsage;
|
|
}
|
|
|
|
ZeroMemory (Result, Size + sizeof(SIZE_T));
|
|
*Result = Size;
|
|
|
|
return (PVOID)(Result + 1);
|
|
}
|
|
|
|
VOID
|
|
Xfree (
|
|
PVOID Object
|
|
)
|
|
{
|
|
PSIZE_T Block;
|
|
|
|
if (Object) {
|
|
|
|
Block = (PSIZE_T)Object;
|
|
Block -= 1;
|
|
|
|
Globals.CurrentHeapUsage -= *Block;
|
|
|
|
free (Block);
|
|
}
|
|
}
|
|
|
|
PVOID
|
|
Xrealloc (
|
|
PCHAR File,
|
|
ULONG Line,
|
|
PVOID Object,
|
|
SIZE_T Size
|
|
)
|
|
{
|
|
PVOID Block;
|
|
SIZE_T OldSize;
|
|
|
|
Block = Xalloc (File, Line, Size);
|
|
|
|
if (Block == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
OldSize = *((PSIZE_T)Object - 1);
|
|
CopyMemory (Block, Object, (Size > OldSize) ? OldSize : Size);
|
|
Xfree (Object);
|
|
|
|
return Block;;
|
|
}
|
|
|
|
VOID
|
|
ReportStatistics (
|
|
)
|
|
{
|
|
Comment ("UMDH version: %s", Globals.Version);
|
|
Comment ("Peak heap usage: %p bytes", Globals.MaximumHeapUsage);
|
|
}
|
|
|
|
VOID
|
|
Info (
|
|
PCHAR Format,
|
|
...
|
|
)
|
|
{
|
|
va_list Params;
|
|
|
|
va_start (Params, Format);
|
|
|
|
vfprintf (Globals.OutFile, Format, Params);
|
|
fprintf (Globals.OutFile, "\n");
|
|
fflush( Globals.OutFile );
|
|
}
|
|
|
|
VOID
|
|
Comment (
|
|
PCHAR Format,
|
|
...
|
|
)
|
|
{
|
|
va_list Params;
|
|
|
|
va_start (Params, Format);
|
|
|
|
fprintf (Globals.OutFile, "// ");
|
|
vfprintf (Globals.OutFile, Format, Params);
|
|
fprintf (Globals.OutFile, "\n");
|
|
fflush( Globals.OutFile );
|
|
}
|
|
|
|
VOID
|
|
Warning (
|
|
PCHAR File,
|
|
ULONG Line,
|
|
PCHAR Format,
|
|
...
|
|
)
|
|
{
|
|
va_list Params;
|
|
|
|
va_start (Params, Format);
|
|
|
|
if (File) {
|
|
fprintf (Globals.ErrorFile, "Warning: %s: %u: ", File, Line);
|
|
}
|
|
else {
|
|
fprintf (Globals.ErrorFile, "Warning: ");
|
|
}
|
|
|
|
vfprintf (Globals.ErrorFile, Format, Params);
|
|
fprintf (Globals.ErrorFile, "\n");
|
|
fflush( Globals.ErrorFile );
|
|
}
|
|
|
|
VOID
|
|
Error (
|
|
PCHAR File,
|
|
ULONG Line,
|
|
PCHAR Format,
|
|
...
|
|
)
|
|
{
|
|
va_list Params;
|
|
|
|
va_start (Params, Format);
|
|
|
|
if (File) {
|
|
fprintf (Globals.ErrorFile, "Error: %s: %u: ", File, Line);
|
|
}
|
|
else {
|
|
fprintf (Globals.ErrorFile, "Error: ");
|
|
}
|
|
|
|
vfprintf (Globals.ErrorFile, Format, Params);
|
|
fprintf (Globals.ErrorFile, "\n");
|
|
fflush( Globals.ErrorFile );
|
|
}
|
|
|
|
VOID
|
|
Debug (
|
|
PCHAR File,
|
|
ULONG Line,
|
|
PCHAR Format,
|
|
...
|
|
)
|
|
{
|
|
va_list Params;
|
|
|
|
va_start (Params, Format);
|
|
|
|
if (Globals.Verbose) {
|
|
|
|
if (File) {
|
|
fprintf (Globals.ErrorFile, "Debug: %s: %u: ", File, Line);
|
|
}
|
|
else {
|
|
fprintf (Globals.ErrorFile, "Debug: ");
|
|
}
|
|
|
|
vfprintf (Globals.ErrorFile, Format, Params);
|
|
fprintf (Globals.ErrorFile, "\n");
|
|
fflush( Globals.ErrorFile );
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
UmdhReadAtVa(
|
|
IN PCHAR File,
|
|
IN ULONG Line,
|
|
IN HANDLE Process,
|
|
IN PVOID Address,
|
|
IN PVOID Data,
|
|
IN SIZE_T Size
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
UmdhReadAtVa
|
|
|
|
Arguments:
|
|
|
|
Address - address in the target process at which we begin reading;
|
|
Data - pointer to the buffer (in our process) to be written to the
|
|
with data read from the target process;
|
|
Size - number of bytes to be read.
|
|
|
|
Return Value:
|
|
|
|
Returns TRUE if the write was successful, FALSE otherwise.
|
|
|
|
--*/
|
|
{
|
|
BOOL Result;
|
|
SIZE_T BytesRead = 0;
|
|
|
|
Result = ReadProcessMemory(Process,
|
|
Address,
|
|
Data,
|
|
Size,
|
|
&BytesRead);
|
|
|
|
if (Result == FALSE) {
|
|
|
|
Error (File, Line,
|
|
"ReadProcessMemory (%p for %d) failed with winerror %u (bytes read: %d)",
|
|
Address,
|
|
Size,
|
|
GetLastError(),
|
|
BytesRead);
|
|
|
|
//
|
|
// Try to give more information about why we failed.
|
|
//
|
|
|
|
{
|
|
MEMORY_BASIC_INFORMATION MemoryInfo;
|
|
SIZE_T Bytes;
|
|
|
|
Bytes = VirtualQueryEx (Process,
|
|
Address,
|
|
&MemoryInfo,
|
|
sizeof MemoryInfo);
|
|
|
|
if (Bytes != sizeof MemoryInfo) {
|
|
Error (NULL, 0, "VirtualQueryEx (%p) failed with error %u",
|
|
Address, GetLastError());
|
|
}
|
|
|
|
Error (NULL, 0, " BaseAddress %p", MemoryInfo.BaseAddress);
|
|
Error (NULL, 0, " AllocationBase %p", MemoryInfo.AllocationBase);
|
|
Error (NULL, 0, " RegionSize %p", MemoryInfo.RegionSize);
|
|
Error (NULL, 0, " State %08X", MemoryInfo.State);
|
|
Error (NULL, 0, " Protect %08X", MemoryInfo.Protect);
|
|
Error (NULL, 0, " Type %08X", MemoryInfo.Type);
|
|
|
|
if (MemoryInfo.State == MEM_RESERVE) {
|
|
Error (NULL, 0, " Uncommitted memory area");
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
else {
|
|
if( Globals.InfoLevel > 0 ) {
|
|
Comment( "ReadProcessMemory( %p for % d)",Address,BytesRead);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
SetSymbolsPath (
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
SetSymbolsPath tries to set automatically the symbol path if
|
|
_NT_SYMBOL_PATH environment variable is not already defined.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Returns TRUE if the symbols path seems to be ok, that is
|
|
_NT_SYMBOL_PATH was defined or we managed to define it to
|
|
a meaningful value.
|
|
|
|
--*/
|
|
{
|
|
TCHAR Buffer [MAX_PATH];
|
|
DWORD Length;
|
|
BOOL Result;
|
|
|
|
Length = GetEnvironmentVariable (TEXT("_NT_SYMBOL_PATH"),
|
|
Buffer,
|
|
MAX_PATH);
|
|
|
|
if (Length == 0) {
|
|
|
|
Warning (NULL, 0,
|
|
"_NT_SYMBOL_PATH variable is not defined. Will be set to %%windir%%\\symbols.");
|
|
|
|
Length = GetEnvironmentVariable (TEXT("windir"),
|
|
Buffer,
|
|
MAX_PATH);
|
|
|
|
if (Length == 0) {
|
|
Error (NULL, 0,
|
|
"Cannot get value of WINDIR environment variable.");
|
|
return FALSE;
|
|
}
|
|
|
|
strcat (Buffer, TEXT("\\symbols"));
|
|
|
|
Result = SetEnvironmentVariable (TEXT("_NT_SYMBOL_PATH"),
|
|
Buffer);
|
|
|
|
if (Result == FALSE) {
|
|
|
|
Error (NULL, 0,
|
|
"Failed to set _NT_SYMBOL_PATH to `%s'", Buffer);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
Comment ("_NT_SYMBOL_PATH set by default to %s", Buffer);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|