424 lines
11 KiB
C
424 lines
11 KiB
C
|
/*++
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Copyright (c) 1990 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
dbgsec.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Argus debugging extensions. The routines here dump out Security Descriptors
|
|||
|
and allow you to examine them.
|
|||
|
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Krishna Ganugapati (KrishnaG) 1-July-1993
|
|||
|
|
|||
|
Revision History:
|
|||
|
KrishnaG: Created: 1-July-1993 (imported most of IanJa's stuff)
|
|||
|
KrishnaG: Added: 7-July-1993 (added AndrewBe's UnicodeAnsi conversion
|
|||
|
KrishnaG Added: 3-Aug-1993 (added DevMode/SecurityDescriptor dumps)
|
|||
|
t-blakej Added: 1-July-1997 (added single-address dump, PID)
|
|||
|
|
|||
|
|
|||
|
To do:
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#define NOMINMAX
|
|||
|
#define SECURITY_WIN32
|
|||
|
#include <nt.h>
|
|||
|
#include <ntrtl.h>
|
|||
|
#include <nturtl.h>
|
|||
|
#include <windows.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <math.h>
|
|||
|
#include <ntsdexts.h>
|
|||
|
|
|||
|
#include <windows.h>
|
|||
|
#include <winspool.h>
|
|||
|
#include <security.h>
|
|||
|
#include <wchar.h>
|
|||
|
#include <winldap.h>
|
|||
|
|
|||
|
#include "dbglocal.h"
|
|||
|
|
|||
|
#define NULL_TERMINATED 0
|
|||
|
|
|||
|
|
|||
|
#define MAXDEPTH 10
|
|||
|
|
|||
|
typedef struct _ADSMEMTAG {
|
|||
|
DWORD Tag ;
|
|||
|
DWORD Size ;
|
|||
|
PVOID pvBackTrace[MAXDEPTH+1];
|
|||
|
LPSTR pszSymbol[MAXDEPTH+1];
|
|||
|
DWORD uDepth;
|
|||
|
LIST_ENTRY List ;
|
|||
|
} ADSMEMTAG, *PADSMEMTAG ;
|
|||
|
|
|||
|
typedef struct _ADS_LDP {
|
|||
|
LIST_ENTRY List ;
|
|||
|
LPWSTR Server ;
|
|||
|
ULONG RefCount ;
|
|||
|
LUID Luid ;
|
|||
|
DWORD Flags ;
|
|||
|
LDAP *LdapHandle ;
|
|||
|
PVOID *pCredentials;
|
|||
|
DWORD PortNumber;
|
|||
|
DWORD TickCount ;
|
|||
|
PVOID **ReferralEntries;
|
|||
|
DWORD nReferralEntries;
|
|||
|
} ADS_LDP, *PADS_LDP ;
|
|||
|
|
|||
|
ULONG
|
|||
|
TranslateAddress (
|
|||
|
IN DWORD dwProcessId,
|
|||
|
IN ULONG Address,
|
|||
|
OUT LPSTR Name,
|
|||
|
IN ULONG MaxNameLength
|
|||
|
);
|
|||
|
|
|||
|
void print_struct_ldap(
|
|||
|
HANDLE hCurrentProcess,
|
|||
|
HANDLE hCurrentThread,
|
|||
|
DWORD dwCurrentPc,
|
|||
|
PNTSD_EXTENSION_APIS lpExtensionApis,
|
|||
|
LDAP ldap_struct);
|
|||
|
|
|||
|
DWORD
|
|||
|
SimpleAToI(LPSTR *lppStr)
|
|||
|
{
|
|||
|
DWORD dwResult = 0;
|
|||
|
while (isspace(**lppStr)) (*lppStr)++;
|
|||
|
while (isdigit(**lppStr))
|
|||
|
{
|
|||
|
dwResult = dwResult * 10 + (**lppStr - '0');
|
|||
|
(*lppStr)++;
|
|||
|
}
|
|||
|
return dwResult;
|
|||
|
}
|
|||
|
|
|||
|
BOOL
|
|||
|
dmem(
|
|||
|
HANDLE hCurrentProcess,
|
|||
|
HANDLE hCurrentThread,
|
|||
|
DWORD dwCurrentPc,
|
|||
|
PNTSD_EXTENSION_APIS lpExtensionApis,
|
|||
|
LPSTR lpArgumentString)
|
|||
|
{
|
|||
|
PNTSD_OUTPUT_ROUTINE Print;
|
|||
|
PNTSD_GET_EXPRESSION EvalExpression;
|
|||
|
PNTSD_GET_SYMBOL GetSymbol;
|
|||
|
DWORD Address = (DWORD)NULL;
|
|||
|
DWORD dwProcessId = 0;
|
|||
|
|
|||
|
BOOL bThereAreOptions = TRUE;
|
|||
|
BOOL bDoOneAddress = FALSE;
|
|||
|
|
|||
|
LIST_ENTRY ListEntry;
|
|||
|
LIST_ENTRY AdsMemHeader;
|
|||
|
ADSMEMTAG AdsMemTag;
|
|||
|
|
|||
|
DWORD pEntry = 0;
|
|||
|
DWORD pTemp = 0;
|
|||
|
DWORD pMem = 0;
|
|||
|
CHAR szSymbolName[MAX_PATH];
|
|||
|
|
|||
|
DWORD i = 0;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER(hCurrentProcess);
|
|||
|
UNREFERENCED_PARAMETER(hCurrentThread);
|
|||
|
UNREFERENCED_PARAMETER(dwCurrentPc);
|
|||
|
|
|||
|
Print = lpExtensionApis->lpOutputRoutine;
|
|||
|
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
|
|||
|
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
|
|||
|
|
|||
|
dwProcessId = GetCurrentProcessId();
|
|||
|
while (bThereAreOptions) {
|
|||
|
while (isspace(*lpArgumentString)) {
|
|||
|
lpArgumentString++;
|
|||
|
}
|
|||
|
|
|||
|
switch (*lpArgumentString) {
|
|||
|
//
|
|||
|
// Read symbols from the process whose PID is an arg to "p".
|
|||
|
//
|
|||
|
case 'p':
|
|||
|
lpArgumentString++;
|
|||
|
|
|||
|
// EvalValue uses hex, and I don't want to bother fiddling with
|
|||
|
// it enough to make it do decimal.
|
|||
|
dwProcessId = SimpleAToI(&lpArgumentString);
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// Dump the single address given as an arg to "a".
|
|||
|
//
|
|||
|
case 'a':
|
|||
|
lpArgumentString++;
|
|||
|
|
|||
|
Address = EvalValue(&lpArgumentString, EvalExpression, Print);
|
|||
|
bDoOneAddress = TRUE;
|
|||
|
break;
|
|||
|
|
|||
|
default: // go get the address because there's nothing else
|
|||
|
bThereAreOptions = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!bDoOneAddress) {
|
|||
|
if (*lpArgumentString != 0) {
|
|||
|
Address = EvalValue(&lpArgumentString, EvalExpression, Print);
|
|||
|
}
|
|||
|
|
|||
|
// if we've got no address, then quit now - nothing we can do
|
|||
|
|
|||
|
if (Address == (DWORD)NULL) {
|
|||
|
Print("We have a Null address\n");
|
|||
|
return(0);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
movestruct(Address, &AdsMemHeader, LIST_ENTRY);
|
|||
|
pEntry = AdsMemHeader.Flink;
|
|||
|
|
|||
|
|
|||
|
while(pEntry != Address) {
|
|||
|
movestruct(pEntry, &ListEntry, LIST_ENTRY);
|
|||
|
|
|||
|
pTemp = (BYTE*)pEntry;
|
|||
|
pTemp = pTemp - sizeof(DWORD) - sizeof(DWORD)
|
|||
|
- sizeof(DWORD) -
|
|||
|
(sizeof(CHAR*) + sizeof(LPVOID))*( MAXDEPTH +1);
|
|||
|
|
|||
|
pMem = (ADSMEMTAG*)pTemp;
|
|||
|
|
|||
|
movestruct(pMem, &AdsMemTag, ADSMEMTAG);
|
|||
|
|
|||
|
Print("[oleds] Memory leak!!! size = %ld\n", AdsMemTag.Size);
|
|||
|
|
|||
|
for (i = 0; i < AdsMemTag.uDepth; i++) {
|
|||
|
TranslateAddress(dwProcessId, AdsMemTag.pvBackTrace[i],
|
|||
|
szSymbolName, 256);
|
|||
|
|
|||
|
Print("%.8x %s\n", AdsMemTag.pvBackTrace[i], szSymbolName);
|
|||
|
}
|
|||
|
Print("\n");
|
|||
|
|
|||
|
pEntry = ListEntry.Flink;
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
TranslateAddress(dwProcessId, Address, szSymbolName, 256);
|
|||
|
Print("%.8x %s\n", Address, szSymbolName);
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
|
|||
|
DBG_UNREFERENCED_PARAMETER(hCurrentProcess);
|
|||
|
DBG_UNREFERENCED_PARAMETER(hCurrentThread);
|
|||
|
DBG_UNREFERENCED_PARAMETER(dwCurrentPc);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Give it the adsldpc!BindCache address and it will give
|
|||
|
// the BindCache info.
|
|||
|
//
|
|||
|
|
|||
|
BOOL
|
|||
|
dcache(
|
|||
|
HANDLE hCurrentProcess,
|
|||
|
HANDLE hCurrentThread,
|
|||
|
DWORD dwCurrentPc,
|
|||
|
PNTSD_EXTENSION_APIS lpExtensionApis,
|
|||
|
LPSTR lpArgumentString)
|
|||
|
{
|
|||
|
PNTSD_OUTPUT_ROUTINE Print;
|
|||
|
PNTSD_GET_EXPRESSION EvalExpression;
|
|||
|
PNTSD_GET_SYMBOL GetSymbol;
|
|||
|
DWORD Address = (DWORD)NULL;
|
|||
|
DWORD dwProcessId = 0;
|
|||
|
|
|||
|
BOOL bThereAreOptions = TRUE;
|
|||
|
BOOL bDoOneAddress = FALSE;
|
|||
|
|
|||
|
|
|||
|
ADS_LDP BindCacheEntry;
|
|||
|
|
|||
|
ADS_LDP ads_ldp_struct;
|
|||
|
|
|||
|
DWORD pEntry = 0;
|
|||
|
DWORD pTemp = 0;
|
|||
|
ADS_LDP *pMem = NULL;
|
|||
|
CHAR szSymbolName[MAX_PATH];
|
|||
|
LDAP LDAPStruct;
|
|||
|
|
|||
|
DWORD i = 0;
|
|||
|
WCHAR serverName[250];
|
|||
|
|
|||
|
|
|||
|
//DebugBreak();
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER(hCurrentProcess);
|
|||
|
UNREFERENCED_PARAMETER(hCurrentThread);
|
|||
|
UNREFERENCED_PARAMETER(dwCurrentPc);
|
|||
|
|
|||
|
Print = lpExtensionApis->lpOutputRoutine;
|
|||
|
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
|
|||
|
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
|
|||
|
|
|||
|
dwProcessId = GetCurrentProcessId();
|
|||
|
while (bThereAreOptions) {
|
|||
|
while (isspace(*lpArgumentString)) {
|
|||
|
lpArgumentString++;
|
|||
|
}
|
|||
|
|
|||
|
switch (*lpArgumentString) {
|
|||
|
//
|
|||
|
// Read symbols from the process whose PID is an arg to "p".
|
|||
|
//
|
|||
|
case 'p':
|
|||
|
lpArgumentString++;
|
|||
|
|
|||
|
// EvalValue uses hex, and I don't want to bother fiddling with
|
|||
|
// it enough to make it do decimal.
|
|||
|
dwProcessId = SimpleAToI(&lpArgumentString);
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// Dump the single address given as an arg to "a".
|
|||
|
//
|
|||
|
case 'a':
|
|||
|
lpArgumentString++;
|
|||
|
|
|||
|
Address = EvalValue(&lpArgumentString, EvalExpression, Print);
|
|||
|
bDoOneAddress = TRUE;
|
|||
|
break;
|
|||
|
|
|||
|
default: // go get the address because there's nothing else
|
|||
|
bThereAreOptions = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!bDoOneAddress) {
|
|||
|
if (*lpArgumentString != 0) {
|
|||
|
Address = EvalValue(&lpArgumentString, EvalExpression, Print);
|
|||
|
}
|
|||
|
|
|||
|
// if we've got no address, then quit now - nothing we can do
|
|||
|
|
|||
|
if (Address == (DWORD)NULL) {
|
|||
|
Print("We have a Null address\n");
|
|||
|
return(0);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
movestruct(Address, &BindCacheEntry, LIST_ENTRY);
|
|||
|
pEntry = BindCacheEntry.List.Flink;
|
|||
|
|
|||
|
Print("Bind Cache Address passed is 0x%x\n", pEntry);
|
|||
|
|
|||
|
while(pEntry != Address) {
|
|||
|
|
|||
|
movestruct(pEntry, &BindCacheEntry, ADS_LDP);
|
|||
|
movemem(BindCacheEntry.Server, serverName, 250);
|
|||
|
// get the LDAP struct also now
|
|||
|
movestruct(BindCacheEntry.LdapHandle, &LDAPStruct, LDAP);
|
|||
|
|
|||
|
Print("BindCache Information :\n");
|
|||
|
Print(" Server : %S\n", serverName);
|
|||
|
Print(" RefCount : %lu\n", BindCacheEntry.RefCount);
|
|||
|
Print(" LUID.High : %ld\n", BindCacheEntry.Luid.HighPart);
|
|||
|
Print(" LUID.Low : %ld\n", BindCacheEntry.Luid.LowPart);
|
|||
|
Print(" FLAGS : %ld\n", BindCacheEntry.Flags);
|
|||
|
Print(" LDAPHandle :0x%X\n", BindCacheEntry.LdapHandle);
|
|||
|
print_struct_ldap(
|
|||
|
hCurrentProcess,
|
|||
|
hCurrentThread,
|
|||
|
dwCurrentPc,
|
|||
|
lpExtensionApis,
|
|||
|
LDAPStruct);
|
|||
|
|
|||
|
Print(" pCredenti : 0x%X\n", BindCacheEntry.pCredentials);
|
|||
|
Print(" PortNo : %ld\n", BindCacheEntry.PortNumber);
|
|||
|
Print(" Referrals : %ld\n", BindCacheEntry.nReferralEntries);
|
|||
|
|
|||
|
|
|||
|
pEntry = BindCacheEntry.List.Flink;
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
TranslateAddress(dwProcessId, Address, szSymbolName, 256);
|
|||
|
Print("%.8x %s\n", Address, szSymbolName);
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
|
|||
|
DBG_UNREFERENCED_PARAMETER(hCurrentProcess);
|
|||
|
DBG_UNREFERENCED_PARAMETER(hCurrentThread);
|
|||
|
DBG_UNREFERENCED_PARAMETER(dwCurrentPc);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void print_struct_ldap(
|
|||
|
HANDLE hCurrentProcess,
|
|||
|
HANDLE hCurrentThread,
|
|||
|
DWORD dwCurrentPc,
|
|||
|
PNTSD_EXTENSION_APIS lpExtensionApis,
|
|||
|
LDAP ldap_struct)
|
|||
|
{
|
|||
|
PNTSD_OUTPUT_ROUTINE Print;
|
|||
|
UCHAR u_char_string[250];
|
|||
|
|
|||
|
Print = lpExtensionApis->lpOutputRoutine;
|
|||
|
|
|||
|
if (ldap_struct.ld_host) {
|
|||
|
movemem(ldap_struct.ld_host, u_char_string, 250);
|
|||
|
Print(" ld_host, address : 0x%X, string value: %s\n",
|
|||
|
ldap_struct.ld_host, u_char_string);
|
|||
|
}
|
|||
|
|
|||
|
Print(" ld_version : %lu\n", ldap_struct.ld_version);
|
|||
|
|
|||
|
Print(" ld_lberoptions (UCHAR) : %c\n",
|
|||
|
ldap_struct.ld_lberoptions);
|
|||
|
Print(" ld_deref : %lu\n", ldap_struct.ld_deref);
|
|||
|
Print(" ld_timelimit : %lu\n", ldap_struct.ld_timelimit);
|
|||
|
Print(" ld_sizelimit : %lu\n", ldap_struct.ld_sizelimit);
|
|||
|
Print(" ld_errno : %lu\n", ldap_struct.ld_errno);
|
|||
|
|
|||
|
if (ldap_struct.ld_matched) {
|
|||
|
movemem(ldap_struct.ld_matched, u_char_string, 250);
|
|||
|
Print(" ld_matched address : 0x%X, string value: %s\n",
|
|||
|
ldap_struct.ld_matched, u_char_string);
|
|||
|
}
|
|||
|
|
|||
|
if (ldap_struct.ld_error) {
|
|||
|
movemem(ldap_struct.ld_error, u_char_string, 250);
|
|||
|
Print(" ld_error address : 0x%X, string value: %s\n",
|
|||
|
ldap_struct.ld_error, u_char_string);
|
|||
|
}
|
|||
|
|
|||
|
Print(" ld_msgid : %lu\n", ldap_struct.ld_msgid);
|
|||
|
Print(" ld_cldaptries : %lu\n", ldap_struct.ld_cldaptries);
|
|||
|
Print(" ld_cldaptimeout : %lu\n", ldap_struct.ld_cldaptimeout);
|
|||
|
Print(" ld_refhoplimit : %lu\n", ldap_struct.ld_refhoplimit);
|
|||
|
Print(" ld_options : %lu\n", ldap_struct.ld_options);
|
|||
|
|
|||
|
}
|
|||
|
|