📄 symbols.c
字号:
DPRINT((0,"changing source file %s\n",pName));
// if filename has a length record it
if((strLen = PICE_strlen(pName)))
{
PICE_strcpy(szCurrentPath,pName);
}
// else empty filename
else
{
szCurrentPath[0]=0;
}
break;
// sub-source file change
case N_SOL:
DPRINT((0,"changing sub source file %s\n",pName));
// if filename has a length record it
if((strLen = PICE_strlen(pName)))
{
PICE_strcpy(szCurrentPath,pName);
}
// else empty filename
else
{
szCurrentPath[0]=0;
}
break;
// a function symbol
case N_FUN:
if(!PICE_strlen(pName))
{// it's the end of a function
DPRINT((0,"END of function %s\n",szCurrentFunction));
szCurrentFunction[0]=0;
// in case we haven't had a zero delta match we return from here
if(pSrcLine)
return pSrcLine;
break;
}
else
{// if it has a length it's the start of a function
ULONG len;
// extract the name only, the type string is of no use here
len=StrLenUpToWhiteChar(pName,":");
PICE_strncpy(szCurrentFunction,pName,len);
szCurrentFunction[len]=0;
DPRINT((0,"function %s\n",szCurrentFunction));
}
//intentional fall through
// line number
case N_SLINE:
// if we're in the function we're looking for
if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
{
DPRINT((0,"cslnum#%u for addr.%x (fn @ %x) ulMinVal=%x ulDelta=%x\n",pStab->n_desc,start+pStab->n_value,start,ulMinValue,(addr-(start+pStab->n_value))));
if(bFirstOccurence)
{
PICE_strcpy(szWantedPath,szCurrentPath);
DPRINT((0,"source file must be %s\n",szWantedPath));
bFirstOccurence = FALSE;
}
DPRINT((0,"wanted %s, current: %s\n",szWantedPath, szCurrentPath));
// we might have a match if our address is greater than the one in the STAB
// and we're lower or equal than minimum value
if(addr>=start+pStab->n_value &&
(addr-(start+pStab->n_value))<=ulMinValue &&
PICE_strcmpi(szWantedPath,szCurrentPath)==0 )
{
ULONG j;
PICE_SYMBOLFILE_SOURCE* pSrc = (PICE_SYMBOLFILE_SOURCE*)((ULONG)pSymbols+pSymbols->ulOffsetToSrcFiles);
DPRINT((0,"code source line number #%u for addr. %x found!\n",pStab->n_desc,start+pStab->n_value));
// compute new minimum
ulMinValue = addr-(start+pStab->n_value);
// if we have a pointer for storage of line number, store it
if(pulLineNumber)
*pulLineNumber = pStab->n_desc;
// NB: should put this somewhere else so that it's not done all the time
// if we have source files at all
DPRINT((0,"%u source files @ %x\n",pSymbols->ulNumberOfSrcFiles,pSrc));
// for all source files in this module
for(j=0;j<pSymbols->ulNumberOfSrcFiles;j++)
{
LPSTR pSlash;
ULONG currlen, fnamelen;
currlen = PICE_strlen( szCurrentPath );
fnamelen = PICE_strlen( pSrc->filename );
pSlash = pSrc->filename + fnamelen - currlen;
//DPRINT((0,"pSlash: %s, szCurrentPath: %s\n", pSlash, szCurrentPath));
// if base name matches current path we have found the correct source file
if(PICE_strcmpi(pSlash,szCurrentPath)==0)
{
// the linenumber
ULONG k = pStab->n_desc;
DPRINT((0,"found src file %s @ %x\n",pSrc->filename,pSrc));
// store the pointer to the filename
if(ppFilename)
*ppFilename = pSrc->filename;
if(pSrc->ulOffsetToNext > sizeof(PICE_SYMBOLFILE_SOURCE))
{
// get a pointer to the source file (right after the file header)
pSrcLine = (LPSTR)((ULONG)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE));
// store the source start and end address
if(ppSrcStart)
*ppSrcStart = pSrcLine;
if(ppSrcEnd)
*ppSrcEnd = pSrcLine+pSrc->ulOffsetToNext-sizeof(PICE_SYMBOLFILE_SOURCE);
// goto to the right line
while(--k)
{
while(*pSrcLine!=0 && *pSrcLine!=0x0a && *pSrcLine!=0x0d)
pSrcLine++;
if(!IsAddressValid((ULONG)pSrcLine))
return NULL;
pSrcLine++;
}
if(ulMinValue == 0)
return pSrcLine;
}
else
{
DPRINT((0,"src file descriptor found, but contains no source\n"));
}
break;
}
(ULONG)pSrc += pSrc->ulOffsetToNext;
}
}
}
break;
}
pStab++;
}
}
}
DPRINT((0,"FindSourceLineForAddress: exit 1\n"));
return NULL;
}
//*************************************************************************
// FindAddressForSourceLine()
//
//*************************************************************************
BOOLEAN FindAddressForSourceLine(ULONG ulLineNumber,LPSTR pFilename,PDEBUG_MODULE pMod,PULONG pValue)
{
ULONG i;
PSTAB_ENTRY pStab;
LPSTR pStr,pName;
int nStabLen;
int nOffset=0,nNextOffset=0;
PICE_SYMBOLFILE_HEADER* pSymbols;
static char szCurrentFunction[256];
static char szCurrentPath[256];
ULONG strLen,addr,ulMinValue=0xFFFFFFFF;
BOOLEAN bFound = FALSE;
DPRINT((0,"FindAddressForSourceLine(%u,%s,%x)\n",ulLineNumber,pFilename,(ULONG)pMod));
addr = (ULONG)pMod->BaseAddress;
pSymbols = FindModuleSymbols(addr);
if(pSymbols)
{
pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
nStabLen = pSymbols->ulSizeOfStabs;
pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
{
pName = &pStr[pStab->n_strx + nOffset];
switch(pStab->n_type)
{
case N_UNDF:
nOffset += nNextOffset;
nNextOffset = pStab->n_value;
break;
case N_SO:
if((strLen = PICE_strlen(pName)))
{
if(pName[strLen-1]!='/')
{
if(PICE_strlen(szCurrentPath))
{
PICE_strcat(szCurrentPath,pName);
DPRINT((0,"changing source file %s\n",szCurrentPath));
}
else
{
DPRINT((0,"changing source file %s\n",pName));
PICE_strcpy(szCurrentPath,pName);
}
}
else
PICE_strcpy(szCurrentPath,pName);
}
else
{
szCurrentPath[0]=0;
}
break;
case N_SLINE:
// if we're in the function we're looking for
if(PICE_strcmpi(pFilename,szCurrentPath)==0)
{
if(pStab->n_desc>=ulLineNumber && (pStab->n_desc-ulLineNumber)<=ulMinValue)
{
ulMinValue = pStab->n_desc-ulLineNumber;
DPRINT((0,"code source line number #%u for offset %x in function @ %s)\n",pStab->n_desc,pStab->n_value,szCurrentFunction));
addr = FindFunctionInModuleByName(szCurrentFunction,pMod);
if(addr)
{
*pValue = addr + pStab->n_value;
bFound = TRUE;
}
}
}
break;
case N_FUN:
if(PICE_strlen(pName))
{
ULONG len;
len=StrLenUpToWhiteChar(pName,":");
PICE_strncpy(szCurrentFunction,pName,len);
szCurrentFunction[len]=0;
DPRINT((0,"function %s\n",szCurrentFunction));
}
else
{
DPRINT((0,"END of function %s\n",szCurrentFunction));
szCurrentFunction[0]=0;
}
break;
}
pStab++;
}
}
return bFound;
}
//*************************************************************************
// ListSymbolStartingAt()
// iterate through the list of module symbols (both functions and variables)
//*************************************************************************
ULONG ListSymbolStartingAt(PDEBUG_MODULE pMod,PICE_SYMBOLFILE_HEADER* pSymbols,ULONG index,LPSTR pOutput)
{
PIMAGE_SYMBOL pSym, pSymEnd;
LPSTR pStr;
PIMAGE_SECTION_HEADER pShdr;
DPRINT((0,"ListSymbolStartingAt(%x,%u)\n",(ULONG)pSymbols,index));
DPRINT((0,"ListSymbolStartingAt(): ulOffsetToGlobals = %x ulSizeofGlobals = %x\n",pSymbols->ulOffsetToGlobals,pSymbols->ulSizeOfGlobals));
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);
pSym += index;
while( pSym < pSymEnd )
{
LPSTR pName;
if(((pSym->Type == 0x0) || (pSym->Type == 0x20) ) &&
((pSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) /*|| (pSym->StorageClass==IMAGE_SYM_CLASS_STATIC)*/) &&
(pSym->SectionNumber > 0 ))
{
PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);
ULONG section_flags;
ULONG start;
DPRINT((0,"ListSymbolStartingAt(): pShdr[%x] = %x\n",pSym->SectionNumber,(ULONG)pShdrThis));
if(!IsRangeValid((ULONG)pShdrThis,sizeof(IMAGE_SECTION_HEADER)) )
{
DPRINT((0,"ListSymbolStartingAt(): pShdr[%x] = %x is not a valid pointer\n",pSym->SectionNumber,(ULONG)pShdrThis));
return FALSE;
}
section_flags = pShdrThis->Characteristics;
//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
start = ((ULONG)pMod->BaseAddress+pShdrThis->VirtualAddress+pSym->Value);
if(pSym->N.Name.Short){
//name is in the header. it's not zero terminated. have to copy.
PICE_sprintf(pOutput,"%.8X (%s) %.8s\n",start,(section_flags&IMAGE_SCN_CNT_CODE)?"TEXT":"DATA",pSym->N.ShortName);
}
else{
ASSERT(pSym->N.Name.Long<=pSymbols->ulSizeOfGlobalsStrings); //sanity check
pName = pStr+pSym->N.Name.Long;
if(!IsAddressValid((ULONG)pName))
{
DPRINT((0,"ListSymbolStartingAt(): pName = %x is not a valid pointer\n",pName));
return 0;
}
PICE_sprintf(pOutput,"%.8X (%s) %s\n",start,(section_flags&IMAGE_SCN_CNT_CODE)?"TEXT":"DATA",pName);
}
if((pSym+pSym->NumberOfAuxSymbols+1)<(pSymEnd))
return (index+pSym->NumberOfAuxSymbols+1);
}
index += pSym->NumberOfAuxSymbols + 1;
pSym += pSym->NumberOfAuxSymbols + 1;
}
return 0;
}
//*************************************************************************
// SanityCheckExports()
//
//*************************************************************************
BOOLEAN SanityCheckExports(void)
{
BOOLEAN bResult = FALSE;
ULONG i,ulValue,incr;
Print(OUTPUT_WINDOW,"pICE: sanity-checking exports...\n");
return TRUE;
/* fix later!!! do we really need to cross reference two kinds of symbolic info?
if(fake_kernel_module.nsyms && fake_kernel_module.syms)
{
incr = (fake_kernel_module.nsyms/4);
if(!incr)incr = 1;
for(i=0;i<fake_kernel_module.nsyms;i+=incr)
{
if(ScanExports((char*)fake_kernel_module.syms[i].name,&ulValue) )
{
if(!(i%25))
{
ClrLine(wWindow[OUTPUT_WINDOW].y + wWindow[OUTPUT_WINDOW].usCurY);
PICE_sprintf(tempSym,"pICE: sanity-checking exports %u/%u",
i,
fake_kernel_module.nsyms);
PutChar(tempSym,1,wWindow[OUTPUT_WINDOW].y + wWindow[OUTPUT_WINDOW].usCurY);
}
if(fake_kernel_module.syms[i].value != ulValue)
{
PICE_sprintf(tempSym,"pICE: %s doesn't match (%.8X != %.8X)\n",
fake_kernel_module.syms[i].name,
fake_kernel_module.syms[i].value,
ulValue);
Print(OUTPUT_WINDOW,tempSym);
return FALSE;
}
}
}
bResult = TRUE;
}
return bResult;
*/
}
//*************************************************************************
// LoadExports()
//
//*******************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -