📄 symbols.c
字号:
return bResult;
}
//*************************************************************************
// ReadHex()
//
//*************************************************************************
BOOLEAN ReadHex(LPSTR p,PULONG pValue)
{
ULONG result=0,i;
for(i=0;i<8 && p[i]!=0 && p[i]!=' ';i++)
{
if(p[i]>='0' && p[i]<='9')
{
result<<=4;
result|=(ULONG)(UCHAR)(p[i]-'0');
}
else if(p[i]>='A' && p[i]<='F')
{
result<<=4;
result|=(ULONG)(UCHAR)(p[i]-'A'+10);
}
else if(p[i]>='a' && p[i]<='f')
{
result<<=4;
result|=(ULONG)(UCHAR)(p[i]-'a'+10);
}
else
return FALSE;
}
*pValue = result;
return TRUE;
}
//*************************************************************************
// ScanExportLine()
//
//*************************************************************************
BOOLEAN ScanExportLine(LPSTR p,PULONG ulValue,LPSTR* ppPtrToSymbol)
{
BOOLEAN bResult = FALSE;
if(ReadHex(p,ulValue))
{
p += 11;
*ppPtrToSymbol += 11;
bResult = TRUE;
}
return bResult;
}
//*************************************************************************
// ValidityCheckSymbols()
//
//*************************************************************************
BOOLEAN ValidityCheckSymbols(PICE_SYMBOLFILE_HEADER* pSymbols)
{
BOOLEAN bRet;
DPRINT((0,"ValidityCheckSymbols()\n"));
bRet = (IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToHeaders,pSymbols->ulSizeOfHeader) &&
IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToGlobals,pSymbols->ulSizeOfGlobals) &&
IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToGlobalsStrings,pSymbols->ulSizeOfGlobalsStrings) &&
IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToStabs,pSymbols->ulSizeOfStabs) &&
IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings,pSymbols->ulSizeOfStabsStrings));
DPRINT((0,"ValidityCheckSymbols(): symbols are %s\n",bRet?"VALID":"NOT VALID"));
return bRet;
}
//*************************************************************************
// FindModuleSymbols()
//
//*************************************************************************
PICE_SYMBOLFILE_HEADER* FindModuleSymbols(ULONG addr)
{
ULONG start,end,i;
PDEBUG_MODULE pd = pdebug_module_head;
DPRINT((0,"FindModuleSymbols(%x)\n",addr));
if(BuildModuleList())
{
i=0;
pd = pdebug_module_head;
do
{
DPRINT((0,"pd: %x\n", pd));
if(pd->size)
{
start = (ULONG)pd->BaseAddress;
end = start + pd->size;
DPRINT((0,"FindModuleSymbols(): %S %x-%x\n",pd->name,start,end));
if(addr>=start && addr<end)
{
DPRINT((0,"FindModuleSymbols(): address matches %S %x-%x\n",pd->name,start,end));
for(i=0;i<ulNumSymbolsLoaded;i++)
{
DPRINT((0,"%S -", apSymbols[i]->name ));
if(PICE_wcsicmp(pd->name,apSymbols[i]->name) == 0)
{
if(ValidityCheckSymbols(apSymbols[i]))
return apSymbols[i];
else
return NULL;
}
}
}
}
}while((pd = pd->next) != pdebug_module_tail);
}
return NULL;
}
//*************************************************************************
// FindModuleFromAddress()
//
//*************************************************************************
PDEBUG_MODULE FindModuleFromAddress(ULONG addr)
{
PDEBUG_MODULE pd;
ULONG start,end;
DPRINT((0,"FindModuleFromAddress()\n"));
if(BuildModuleList())
{
pd = pdebug_module_head;
do
{
if(pd->size)
{
start = (ULONG)pd->BaseAddress;
end = start + pd->size;
DPRINT((0,"FindModuleFromAddress(): %S %x-%x\n",pd->name,start,end));
if(addr>=start && addr<end)
{
DPRINT((0,"FindModuleFromAddress(): found %S\n",pd->name));
return pd;
}
}
}while((pd = pd->next)!=pdebug_module_tail);
}
return NULL;
}
//*************************************************************************
// FindModuleByName()
//
//*************************************************************************
PDEBUG_MODULE FindModuleByName(LPSTR modname)
{
PDEBUG_MODULE pd;
WCHAR tempstr[DEBUG_MODULE_NAME_LEN];
DPRINT((0,"FindModuleFromAddress()\n"));
if( !PICE_MultiByteToWideChar(CP_ACP, NULL, modname, -1, tempstr, DEBUG_MODULE_NAME_LEN ) )
{
DPRINT((0,"Can't convert module name.\n"));
return NULL;
}
if(BuildModuleList())
{
pd = pdebug_module_head;
do
{
if(pd->size)
{
if(PICE_wcsicmp(tempstr,pd->name) == 0)
{
DPRINT((0,"FindModuleByName(): found %S\n",pd->name));
return pd;
}
}
}while((pd = pd->next) != pdebug_module_tail);
}
return NULL;
}
//*************************************************************************
// FindModuleSymbolsByModuleName()
//
//*************************************************************************
PICE_SYMBOLFILE_HEADER* FindModuleSymbolsByModuleName(LPSTR modname)
{
ULONG i;
WCHAR tempstr[DEBUG_MODULE_NAME_LEN];
DPRINT((0,"FindModuleSymbols()\n"));
if( !PICE_MultiByteToWideChar(CP_ACP, NULL, modname, -1, tempstr, DEBUG_MODULE_NAME_LEN ) )
{
DPRINT((0,"Can't convert module name in FindModuleSymbols.\n"));
return NULL;
}
for(i=0;i<ulNumSymbolsLoaded;i++)
{
if(PICE_wcsicmp(tempstr,apSymbols[i]->name) == 0)
return apSymbols[i];
}
return NULL;
}
//*************************************************************************
// ScanExportsByAddress()
//
//*************************************************************************
BOOLEAN ScanExportsByAddress(LPSTR *pFind,ULONG ulValue)
{
char temp[256];
static char temp3[256];
LPSTR p,pStartOfLine,pSymbolName=NULL;
ULONG ulCurrentValue=0;
BOOLEAN bResult = FALSE;
PDEBUG_MODULE pd;
ULONG ulMinValue = -1;
PIMAGE_SYMBOL pSym,pSymEnd; //running pointer to symbols and end of sym talbe
PIMAGE_SYMBOL pFoundSym = NULL; //current best symbol match
ULONG ulAddr = 0x0; //address of the best match
LPSTR pStr;
PIMAGE_SECTION_HEADER pShdr;
PICE_SYMBOLFILE_HEADER* pSymbols;
ULONG ulSectionSize;
LPSTR pName;
ENTER_FUNC();
DPRINT((0,"In ScanExportsByAddress:\n"));
pSymbols = FindModuleSymbols(ulValue);
DPRINT((0,"pSymbols: %x\n", pSymbols));
if(BuildModuleList()){
if(pSymbols && pdebug_module_head)
{
PDEBUG_MODULE pdTemp;
DPRINT((0,"looking up symbols\n"));
pd = pdebug_module_head;
do
{
if(pd->size){
pdTemp = pd;
if(ulValue>=((ULONG)pdTemp->BaseAddress) && ulValue<((ULONG)pdTemp+pdTemp->size))
{
if(PICE_wcsicmp(pdTemp->name,pSymbols->name) == 0)
{
DPRINT((0,"ScanExportsByAddress(): found symbols for module %S @ %x \n",pdTemp->name,(ULONG)pSymbols));
pSym = (PIMAGE_SYMBOL)((ULONG)pSymbols+pSymbols->ulOffsetToGlobals);
pSymEnd = (PIMAGE_SYMBOL)((ULONG)pSym+pSymbols->ulSizeOfGlobals);
pStr = (LPSTR)((ULONG)pSymbols+pSymbols->ulOffsetToGlobalsStrings);
pShdr = (PIMAGE_SECTION_HEADER)((ULONG)pSymbols+pSymbols->ulOffsetToHeaders);
if(!IsRangeValid((ULONG)pSym,sizeof(IMAGE_SYMBOL) ) ) //should we actually check all the symbols here?
{
DPRINT((0,"ScanExportsByAddress(): pSym = %x is not a valid pointer\n",(ULONG)pSym));
return FALSE;
}
DPRINT((0,"ScanExportsByAddress(): pSym = %x\n",pSym));
DPRINT((0,"ScanExportsByAddress(): pStr = %x\n",pStr));
DPRINT((0,"ScanExportsByAddress(): pShdr = %x\n",pShdr));
DPRINT((0,"ScanExportsByAddress(): %S has %u symbols\n",pSymbols->name,pSymbols->ulSizeOfGlobals/sizeof(IMAGE_SYMBOL)));
/* go through all the global symbols and find the one with
the largest address which is less than ulValue */
while(pSym < pSymEnd)
{ //it seems only 0x0 and 0x20 are used for type and External or Static storage classes
if(((pSym->Type == 0x0) || (pSym->Type == 0x20) ) &&
((pSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) || (pSym->StorageClass==IMAGE_SYM_CLASS_STATIC)) &&
(pSym->SectionNumber > 0 ))
{
ULONG ulCurrAddr;
PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);
DPRINT((0,"ScanExportsByAddress(): pShdr[%x] = %x\n",pSym->SectionNumber,(ULONG)pShdrThis));
if(!IsRangeValid((ULONG)pShdrThis,sizeof(IMAGE_SECTION_HEADER)) )
{
DPRINT((0,"ScanExportsByAddress(): pElfShdr[%x] = %x is not a valid pointer\n",pSym->SectionNumber,(ULONG)pShdrThis));
return FALSE;
}
//to get address in the memory we base address of the module and
//add offset of the section and then add offset of the symbol from
//the begining of the section
ulCurrAddr = ((ULONG)pdTemp->BaseAddress+pShdrThis->VirtualAddress+pSym->Value);
DPRINT((0,"ScanExportsByAddress(): CurrAddr [1] = %x\n",ulCurrAddr));
if(ulCurrAddr<=ulValue && ulCurrAddr>ulAddr)
{
ulAddr = ulCurrAddr;
pFoundSym = pSym;
}
}
//skip the auxiliary symbols and get the next symbol
pSym += pSym->NumberOfAuxSymbols + 1;
}
*pFind = temp3;
if( pFoundSym->N.Name.Short ){
pName = pFoundSym->N.ShortName; //name is in the header
PICE_sprintf(temp3,"%S!%.8s",pdTemp->name,pName); //if name is in the header it may be nonzero terminated
}
else{
ASSERT(pFoundSym->N.Name.Long<=pSymbols->ulSizeOfGlobalsStrings); //sanity check
pName = pStr+pFoundSym->N.Name.Long;
if(!IsAddressValid((ULONG)pName))
{
DPRINT((0,"ScanExportsByAddress(): pName = %x is not a valid pointer\n",pName));
return FALSE;
}
PICE_sprintf(temp3,"%S!%s",pdTemp->name,pName);
}
DPRINT((0,"ScanExportsByAddress(): pName = %x\n",(ULONG)pName));
return TRUE;
}
}
}
}while((pd = pd->next));
}
}
// if haven't found in the symbols try ntoskrnl exports. (note: check that this is needed since we
// already checked ntoskrnl coff symbol table)
if(pExports && ulValue >= KERNEL_START && ulValue < kernel_end)
{
p = pExports;
// while we bound in System.map
while(p<((LPSTR)pExports+ulExportLen))
{
// make a temp ptr to the line we can change
pStartOfLine = p;
// will read the hex value and return a pointer to the symbol name
if(ScanExportLine(p,&ulCurrentValue,&pStartOfLine))
{
if(ulValue>=ulCurrentValue && (ulValue-ulCurrentValue)<ulMinValue)
{
// save away our info for later
ulMinValue = ulValue-ulCurrentValue;
pSymbolName = pStartOfLine;
bResult = TRUE;
*pFind = temp3;
if(ulMinValue==0)
break;
}
}
// increment pointer to next line
p = pStartOfLine;
while(*p!=0 && *p!=0x0a && *p!=0x0d)p++;
p++;
}
if(bResult)
{
int i;
// copy symbol name to temp string
for(i=0;pSymbolName[i]!=0 && pSymbolName[i]!=0x0a && pSymbolName[i]!=0x0d;i++)
temp[i] = pSymbolName[i];
temp[i] = 0;
// decide if we need to append an offset
if(ulMinValue)
PICE_sprintf(temp3,"ntoskrnl!%s+%.8X",temp,ulMinValue);
else
PICE_sprintf(temp3,"ntoskrnl!%s",temp);
}
}
LEAVE_FUNC();
return bResult;
}
//*************************************************************************
// FindFunctionByAddress()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -