Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

pctohdr.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1992 Microsoft Corporation 00004 00005 Module Name: 00006 00007 pctohdr.c 00008 00009 Abstract: 00010 00011 This module implements code to locate the file header for an image or 00012 dll given a PC value that lies within the image. 00013 00014 N.B. This routine is conditionalized for user mode and kernel mode. 00015 00016 Author: 00017 00018 Steve Wood (stevewo) 18-Aug-1989 00019 00020 Environment: 00021 00022 User Mode or Kernel Mode 00023 00024 Revision History: 00025 00026 --*/ 00027 00028 #if defined(NTOS_KERNEL_RUNTIME) 00029 #include "ntos.h" 00030 #else 00031 #include <nt.h> 00032 #include <ntrtl.h> 00033 #include <nturtl.h> 00034 #endif 00035 00036 #if !defined(NTOS_KERNEL_RUNTIME) 00037 extern PVOID NtDllBase; // defined in ntos\dll\ldrinit.c 00038 #endif 00039 00040 00041 PVOID 00042 RtlPcToFileHeader( 00043 IN PVOID PcValue, 00044 OUT PVOID *BaseOfImage 00045 ) 00046 00047 /*++ 00048 00049 Routine Description: 00050 00051 This function returns the base of an image that contains the 00052 specified PcValue. An image contains the PcValue if the PcValue 00053 is within the ImageBase, and the ImageBase plus the size of the 00054 virtual image. 00055 00056 Arguments: 00057 00058 PcValue - Supplies a PcValue. All of the modules mapped into the 00059 calling processes address space are scanned to compute which 00060 module contains the PcValue. 00061 00062 BaseOfImage - Returns the base address for the image containing the 00063 PcValue. This value must be added to any relative addresses in 00064 the headers to locate portions of the image. 00065 00066 Return Value: 00067 00068 NULL - No image was found that contains the PcValue. 00069 00070 NON-NULL - Returns the base address of the image that contain the 00071 PcValue. 00072 00073 --*/ 00074 00075 { 00076 00077 #if defined(NTOS_KERNEL_RUNTIME) 00078 00079 extern LIST_ENTRY PsLoadedModuleList; 00080 extern KSPIN_LOCK PsLoadedModuleSpinLock; 00081 00082 PVOID Base; 00083 ULONG_PTR Bounds; 00084 PLDR_DATA_TABLE_ENTRY Entry; 00085 PLIST_ENTRY Next; 00086 KIRQL OldIrql; 00087 00088 // 00089 // Acquire the loaded module list spinlock and scan the list for the 00090 // specified PC value if the list has been initialized. 00091 // 00092 00093 ExAcquireSpinLock(&PsLoadedModuleSpinLock, &OldIrql); 00094 Next = PsLoadedModuleList.Flink; 00095 if (Next != NULL) { 00096 while (Next != &PsLoadedModuleList) { 00097 Entry = CONTAINING_RECORD(Next, 00098 LDR_DATA_TABLE_ENTRY, 00099 InLoadOrderLinks); 00100 00101 Next = Next->Flink; 00102 Base = Entry->DllBase; 00103 Bounds = (ULONG_PTR)Base + Entry->SizeOfImage; 00104 if (((ULONG_PTR)PcValue >= (ULONG_PTR)Base) && ((ULONG_PTR)PcValue < Bounds)) { 00105 ExReleaseSpinLock(&PsLoadedModuleSpinLock, OldIrql); 00106 *BaseOfImage = Base; 00107 return Base; 00108 } 00109 } 00110 } 00111 00112 // 00113 // Release the loaded module list spin lock and return NULL. 00114 // 00115 00116 ExReleaseSpinLock(&PsLoadedModuleSpinLock, OldIrql); 00117 *BaseOfImage = NULL; 00118 return NULL; 00119 00120 #else 00121 00122 PVOID Base; 00123 ULONG_PTR Bounds; 00124 PLDR_DATA_TABLE_ENTRY Entry; 00125 PLIST_ENTRY ModuleListHead; 00126 PLIST_ENTRY Next; 00127 PIMAGE_NT_HEADERS NtHeaders; 00128 PPEB Peb; 00129 PTEB Teb; 00130 MEMORY_BASIC_INFORMATION MemInfo; 00131 NTSTATUS st; 00132 00133 // 00134 // Acquire the Loader lock for the current process and scan the loaded 00135 // module list for the specified PC value if all the data structures 00136 // have been initialized. 00137 // 00138 00139 if ( !RtlTryEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock) ) { 00140 00141 // 00142 // We could not get the loader lock, so call the system to find the image that 00143 // contains this pc 00144 // 00145 00146 st = NtQueryVirtualMemory( 00147 NtCurrentProcess(), 00148 PcValue, 00149 MemoryBasicInformation, 00150 (PVOID)&MemInfo, 00151 sizeof(MemInfo), 00152 NULL 00153 ); 00154 if ( !NT_SUCCESS(st) ) { 00155 MemInfo.AllocationBase = NULL;; 00156 } 00157 else { 00158 if ( MemInfo.Type == MEM_IMAGE ) { 00159 try { 00160 *BaseOfImage = MemInfo.AllocationBase; 00161 } 00162 except (EXCEPTION_EXECUTE_HANDLER) { 00163 MemInfo.AllocationBase = NULL; 00164 } 00165 } 00166 else { 00167 MemInfo.AllocationBase = NULL;; 00168 } 00169 } 00170 return MemInfo.AllocationBase; 00171 } 00172 00173 try { 00174 Teb = NtCurrentTeb(); 00175 if (Teb != NULL) { 00176 Peb = Teb->ProcessEnvironmentBlock; 00177 if (Peb->Ldr != NULL) { 00178 ModuleListHead = &Peb->Ldr->InLoadOrderModuleList; 00179 Next = ModuleListHead->Flink; 00180 if (Next != NULL) { 00181 while (Next != ModuleListHead) { 00182 Entry = CONTAINING_RECORD(Next, 00183 LDR_DATA_TABLE_ENTRY, 00184 InLoadOrderLinks); 00185 00186 Next = Next->Flink; 00187 Base = Entry->DllBase; 00188 NtHeaders = RtlImageNtHeader(Base); 00189 Bounds = (ULONG_PTR)Base + NtHeaders->OptionalHeader.SizeOfImage; 00190 if (((ULONG_PTR)PcValue >= (ULONG_PTR)Base) && ((ULONG_PTR)PcValue < Bounds)) { 00191 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00192 *BaseOfImage = Base; 00193 return Base; 00194 } 00195 } 00196 } 00197 00198 } else { 00199 00200 // 00201 // ( Peb->Ldr == NULL ) 00202 // 00203 // If called during process intialization before the Ldr 00204 // module list has been setup, code executing must be in 00205 // NTDLL module. If NtDllBase is non-NULL and the PcValue 00206 // falls into the NTDLL range, return a valid Base. This 00207 // allows DbgPrint's during LdrpInitializeProcess to work 00208 // on RISC machines. 00209 // 00210 00211 if ( NtDllBase != NULL ) { 00212 Base = NtDllBase; 00213 NtHeaders = RtlImageNtHeader( Base ); 00214 Bounds = (ULONG_PTR)Base + NtHeaders->OptionalHeader.SizeOfImage; 00215 if (((ULONG_PTR)PcValue >= (ULONG_PTR)Base) && ((ULONG_PTR)PcValue < Bounds)) { 00216 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00217 *BaseOfImage = Base; 00218 return Base; 00219 } 00220 } 00221 } 00222 } 00223 00224 } except(EXCEPTION_EXECUTE_HANDLER) { 00225 NOTHING; 00226 } 00227 00228 // 00229 // Release the Loader lock for the current process a return NULL. 00230 // 00231 00232 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00233 *BaseOfImage = NULL; 00234 return NULL; 00235 00236 #endif 00237 00238 }

Generated on Sat May 15 19:41:08 2004 for test by doxygen 1.3.7