⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symbols.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
//
//*************************************************************************
LPSTR FindFunctionByAddress(ULONG ulValue,PULONG pulstart,PULONG pulend)
{
	PIMAGE_SYMBOL pSym, pSymEnd, pFoundSym;
	LPSTR pStr;
	PIMAGE_SECTION_HEADER pShdr;
	PDEBUG_MODULE pd;
	PDEBUG_MODULE pdTemp;
    PICE_SYMBOLFILE_HEADER* pSymbols;
    ULONG start,end;
	static char temp4[256];
	LPSTR pName;

    pSymbols = FindModuleSymbols(ulValue);
    DPRINT((0,"FindFunctionByAddress(): symbols for %S @ %x \n",pSymbols->name,(ULONG)pSymbols));
	if(pSymbols && pdebug_module_head)
	{
		DPRINT((0,"looking up symbol\n"));
        pd = pdebug_module_head;
        do
        {
			ASSERT(pd->size);
            pdTemp = pd;

			//initial values for start and end.
            start = (ULONG)pdTemp->BaseAddress;
            end = start+pdTemp->size;

            DPRINT((0,"FindFunctionByAddress(): ulValue %x\n",ulValue));

			if(ulValue>=start && ulValue<end)
			{
                DPRINT((0,"FindFunctionByAddress(): address matches %S\n",(ULONG)pdTemp->name));
				if(PICE_wcsicmp(pdTemp->name,pSymbols->name) == 0)
				{
					DPRINT((0,"found symbols for module %S\n",pdTemp->name));
					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,"FindFunctionByAddress(): pSym = %x is not a valid pointer\n",(ULONG)pSym));
						return FALSE;
					}
					DPRINT((0,"pSym = %x\n",pSym));
					DPRINT((0,"pStr = %x\n",pStr));
					DPRINT((0,"pShdr = %x\n",pShdr));

					while( pSym < pSymEnd )
					{
						//symbol is a function is it's type is 0x20, and section>0
						if(( (pSym->Type == 0x20) &&
						   (pSym->SectionNumber > 0 )))
						{
							ULONG ulCurrAddr;
							PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);

							DPRINT((0,"FindFunctionByAddress(): 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,"FindFunctionByAddress(): CurrAddr [1] = %x\n",ulCurrAddr));
							DPRINT((0,"%x  ", ulCurrAddr));

							if(ulCurrAddr<=ulValue && ulCurrAddr>start)
							{
								start = ulCurrAddr;
								pFoundSym = pSym;
								//DPRINT((0,"FindFunctionByAddress(): CANDIDATE for start %x\n",start));
							}
							else if(ulCurrAddr>=ulValue && ulCurrAddr<end)
								 {
								   end = ulCurrAddr;
								   //DPRINT((0,"FindFunctionByAddress(): CANDIDATE for end %x\n",end));
								 }
							}
							//skip the auxiliary symbols and get the next symbol
							pSym += pSym->NumberOfAuxSymbols + 1;
						}
						//we went through all the symbols for this module
						//now start should point to the start of the function and
						//end to the start of the next (or end of section)
						if(pulstart)
                            *pulstart = start;

                        if(pulend){
							//just in case there is more than  one code section
							PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pFoundSym->SectionNumber-1);
							if( end > (ULONG)pdTemp->BaseAddress+pShdrThis->SizeOfRawData ){
								DPRINT((0,"Hmm: end=%d, end of section: %d\n", end, (ULONG)pdTemp->BaseAddress+pShdrThis->SizeOfRawData));
								end = (ULONG)pdTemp->BaseAddress+pShdrThis->SizeOfRawData;
							}
							*pulend = end;
						}

						if(pFoundSym->N.Name.Short){
							//name is in the header. it's not zero terminated. have to copy.
							PICE_sprintf(temp4,"%.8s", pFoundSym->N.ShortName);
							pName = temp4;
							DPRINT((0,"Function name: %S!%.8s",pdTemp->name,pName));
						}
						else{
							ASSERT(pFoundSym->N.Name.Long<=pSymbols->ulSizeOfGlobalsStrings); //sanity check
							pName = pStr+pFoundSym->N.Name.Long;
							if(!IsAddressValid((ULONG)pName))
							{
								DPRINT((0,"FindFunctionByAddress(): pName = %x is not a valid pointer\n",pName));
								return NULL;
							}
							DPRINT((0,"Function name: %S!%s",pdTemp->name,pName));
						}
						return pName;
					}
				}
        }while((pd = pd->next) != pdebug_module_tail);
	}
	return NULL;
}

//*************************************************************************
// FindDataSectionOffset()
//
//*************************************************************************
/* ei: never used
ULONG FindDataSectionOffset(Elf32_Shdr* pSHdr)
{

    DPRINT((0,"FindDataSectionOffset()\n"));

    while(1)
    {
        DPRINT((0,"FindDataSectionOffset(): sh_offset %.8X sh_addr = %.8X\n",pSHdr->sh_offset,pSHdr->sh_addr));
        if((pSHdr->sh_flags & (SHF_WRITE|SHF_ALLOC)	) == (SHF_WRITE|SHF_ALLOC))
        {

            return pSHdr->sh_offset;
        }
        pSHdr++;
    }

    return 0;
}
*/

//*************************************************************************
// FindFunctionInModuleByNameViaKsyms()
//
//*************************************************************************
/* ei: not needed. no Ksyms!
ULONG FindFunctionInModuleByNameViaKsyms(struct module* pMod,LPSTR szFunctionname)
{
    ULONG i;

    ENTER_FUNC();

	if(pMod->nsyms)
    {
        DPRINT((0,"FindFunctionInModuleByNameViaKsyms(): %u symbols for module %s\n",pMod->nsyms,pMod->name));
        for(i=0;i<pMod->nsyms;i++)
        {
            DPRINT((0,"FindFunctionInModuleByNameViaKsyms(): %s\n",pMod->syms[i].name));
            if(PICE_strcmpi((LPSTR)pMod->syms[i].name,szFunctionname) == 0)
            {
                DPRINT((0,"FindFunctionInModuleByName(): symbol was in exports\n"));
                LEAVE_FUNC();
                return pMod->syms[i].value;
            }
        }
    }

    DPRINT((0,"FindFunctionInModuleByName(): symbol wasn't in exports\n"));
    LEAVE_FUNC();
    return 0;
}
*/

//*************************************************************************
// FindFunctionInModuleByName()
//
//*************************************************************************
ULONG FindFunctionInModuleByName(LPSTR szFunctionname, PDEBUG_MODULE pd)
{
    ULONG i,addr;
    PICE_SYMBOLFILE_HEADER* pSymbols=NULL;
	PIMAGE_SYMBOL pSym, pSymEnd;
	LPSTR pStr;
	PIMAGE_SECTION_HEADER pShdr;

    ENTER_FUNC();
    DPRINT((0,"FindFunctionInModuleByName(%s)\n",szFunctionname));
    DPRINT((0,"FindFunctionInModuleByName(): mod size = %x\n",pd->size));
    DPRINT((0,"FindFunctionInModuleByName(): module is %S\n",pd->name));

	addr = (ULONG)pd->BaseAddress;

    pSymbols = FindModuleSymbols(addr);
    if(pSymbols)
    {
        DPRINT((0,"FindFunctionInModuleByName(): found symbol table for %S\n",pSymbols->name));
		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);

		while( pSym < pSymEnd )
		{
			//symbol is a function is it's type is 0x20, storage class is external and section>0
			//if(( (pSym->Type == 0x20)  && (pSym->StorageClass==IMAGE_SYM_CLASS_EXTERNAL) &&
			//   (pSym->SectionNumber > 0 )))

			if(((pSym->Type == 0x0) || (pSym->Type == 0x20) )  &&
			   ((pSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) || (pSym->StorageClass==IMAGE_SYM_CLASS_STATIC)) &&
			   (pSym->SectionNumber > 0 ))

			{
                ULONG start;
                LPSTR pName;
				PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);

				start = ((ULONG)pd->BaseAddress+pShdrThis->VirtualAddress+pSym->Value);
				DPRINT((0,"FindFunctionInModuleByName(): %s @ %x\n",szFunctionname,start));

				if(pSym->N.Name.Short){ //if name is stored in the structure
					//name may be not zero terminated but 8 characters max
					DPRINT((0,"FindFunctionInModuleByName: %.8s\n", pSym->N.ShortName));
					pName = pSym->N.ShortName;  //name is in the header
			        if((PICE_fnncmp(pName,szFunctionname, 8) == 0) && start)
			        {
						DPRINT((0,"FindFunctionInModuleByName(): symbol was in symbol table, start: %x\n", start));
			            LEAVE_FUNC();
			            return start;
			        }
				}else{
					pName = pStr+pSym->N.Name.Long;
					DPRINT((0,"FindFunctionInModuleByName: %s\n", pName));
					if((PICE_fncmp(pName,szFunctionname) == 0) && start)
	                {
	                    DPRINT((0,"FindFunctionInModuleByName(): symbol was in string table, start: %x\n", start));
	                    LEAVE_FUNC();
	                    return start;
	                }
				}
        	}
			//skip the auxiliary symbols and get the next symbol
			pSym += pSym->NumberOfAuxSymbols + 1;
    	}
	}
    LEAVE_FUNC();
    return 0;
}

//*************************************************************************
// ExtractTypeNumber()
//
//*************************************************************************
ULONG ExtractTypeNumber(LPSTR p)
{
	LPSTR pTypeNumber;
	ULONG ulTypeNumber = 0;

    DPRINT((0,"ExtractTypeNumber(%s)\n",p));

	pTypeNumber = PICE_strchr(p,'(');

	if(pTypeNumber)
	{
		pTypeNumber++;
		ulTypeNumber = ExtractNumber(pTypeNumber);
		ulTypeNumber <<= 16;
		pTypeNumber = PICE_strchr(p,',');
        if(pTypeNumber)
        {
		    pTypeNumber++;
		    ulTypeNumber += ExtractNumber(pTypeNumber);
        }
        else
        {
            ulTypeNumber = 0;
        }
	}
	return ulTypeNumber;
}

//*************************************************************************
// FindTypeDefinitionForCombinedTypes()
//
//*************************************************************************
LPSTR FindTypeDefinitionForCombinedTypes(PICE_SYMBOLFILE_HEADER* pSymbols,ULONG ulTypeNumber,ULONG ulFileNumber)
{
    ULONG i;
    PSTAB_ENTRY pStab;
    LPSTR pStr,pName,pTypeNumber,pTypeDefIncluded,pNameTemp;
    int nStabLen;
    int nOffset=0,nNextOffset=0,nLen;
	static char szAccumulatedName[2048];
	ULONG ulCurrentTypeNumber,ulCurrentFileNumber=0;
    static char szCurrentPath[256];

    ENTER_FUNC();

	*szAccumulatedName = 0;

    pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
    nStabLen = pSymbols->ulSizeOfStabs;
    pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);

	DPRINT((0,"FindTypeDefinitionForCombinedTypes()\n"));

    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((nLen = PICE_strlen(pName)))
                {
                    if(pName[nLen-1]!='/')
                    {
						ulCurrentFileNumber++;
                        if(PICE_strlen(szCurrentPath))
                        {
                            PICE_strcat(szCurrentPath,pName);
                            DPRINT((0,"FindTypeDefinitionForCombinedTypes(): changing source file %s\n",szCurrentPath));
                        }
                        else
                        {
                            DPRINT((0,"FindTypeDefinitionForCombinedTypes(): changing source file %s\n",pName));
                        }
                    }
                    else
                        PICE_strcpy(szCurrentPath,pName);
                }
                else
				{
                    szCurrentPath[0]=0;
				}
				break;
			case N_GSYM:
				//ei File number count is not reliable
				if( 1 /*ulCurrentFileNumber == ulFileNumber*/)
                {
                    DPRINT((0,"FindTypeDefinitionForCombinedTypes(): %s\n",pName));

					// handle multi-line symbols
					if(PICE_strchr(pName,'\\'))
					{
						if(PICE_strlen(szAccumulatedName))
						{
							PICE_strcat(szAccumulatedName,pName);
						}
						else
						{
							PICE_strcpy(szAccumulatedName,pName);
						}
                        szAccumulatedName[PICE_strlen(szAccumulatedName)-1]=0;
                        //DPRINT((0,"accum. %s\n",szAccumulatedName));
					}
                    else
                    {
						if(PICE_strlen(szAccumulatedName)==0)
                        {
                            PICE_strcpy(szAccumulatedName,pName);
                        }
                        else
                        {
                            PICE_strcat(szAccumulatedName,pName);
                        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -