#include "StdAfx.h" #include "MapProcess.h" CMapProcess::CMapProcess(void) : LoadBaseAddress_(0x0000000) { FuntionList_.clear(); LineinfoList_.clear(); } CMapProcess::~CMapProcess(void) { Clean(); } bool CMapProcess::LoadFile( const TCHAR* SymbolName ) { FILE* fp = NULL; fp = _tfopen(SymbolName,L"rt"); if(fp == NULL) return false; if(!GetLoadBaseAddress(fp)) return false; if(!ReadAddress(fp)) return false; if(!ReadSourceLine(fp)) return false; return true; } void CMapProcess::Clean() { FuntionList_.clear(); LineinfoList_.clear(); LoadBaseAddress_ = 0x000000; } bool CMapProcess::OnSearch( const char* ExceptionAddr,sExceptionInfomation& ExceptionInfo ) { DWORD dwordExceptionAddr = GetHexValue(ExceptionAddr); return OnSearch(dwordExceptionAddr,ExceptionInfo); } bool CMapProcess::OnSearch( DWORD ExceptionAddr , sExceptionInfomation& ExceptionInfo ) { size_t funtioncount = FuntionList_.size(); for (size_t index = 0 ; index < funtioncount ; ++index) { if(ExceptionAddr < FuntionList_[index].FuntionAddress) { //ù functionÁÖ¼Ò´Â Çڵ鷯ÀÓ Ã³¸® ÇÏÁö ¾Ê¾Æµµ »ó°ü ¾øÀ½! if(index == 0) return false;; sFuntionInfo* pFunctionSelect = &FuntionList_[index -1]; wsprintf(ExceptionInfo.ExceptionFuntionName,L"%s",pFunctionSelect->FuntionName); ExceptionInfo.HeaderFile = pFunctionSelect->HeaderFile; size_t LineCount = LineinfoList_.size(); for (size_t lineindex = 0 ; lineindex < LineCount ; ++lineindex) { if (wcsstr(LineinfoList_[lineindex].ObjectFileName , pFunctionSelect->ObjectFileName)) { sLineInfo* pLineSelect = &LineinfoList_[lineindex]; wsprintf(ExceptionInfo.ExceptionFileName,L"%s",pLineSelect->SourceFileName); size_t AddressCount = pLineSelect->vAddressLineEntityList.size(); for (size_t AddrIndex = 0 ; AddrIndex < AddressCount ; ++AddrIndex) { sLineAndAddressEntity* pEntity = &pLineSelect->vAddressLineEntityList[AddrIndex]; if(pLineSelect->vAddressLineEntityList[AddrIndex].LineAddress > ExceptionAddr) { //À­ ÁÖ¼®°ú µ¿ÀÏ if(AddrIndex == 0) return false; sLineAndAddressEntity* lastSelect = &pLineSelect->vAddressLineEntityList[AddrIndex-1]; ExceptionInfo.FileSourceLine = lastSelect->SourceLine; return true; } } } } } } return false; } bool CMapProcess::ReadAddress( FILE* fp ) { //¸Þ¸ð¸® Æ÷ÇÔ°ªÀÌ 1024¸¦ ³Ñ¾ú´Ù! 2048ÀÌ ¾ÈÀüÇÔ. //¸¸¾à ÇÔ¼ö¸íÀÌ ±æ°í std::°ü·Ã function°ú iterator ±¸ºÐÀÌ °°ÀÌ µé¾î °£´Ù¸é. // ÀÌ ÀÌ»óÀÇ »çÀÌÁîµµ »ý°¢Çغ¼¼ö ÀÖÀ½! char LineString[2048]; while (!feof(fp)) { fgets(LineString,2048,fp); if(strstr(LineString,"Address Publics by Value Rva+Base Lib:Object")) { fgets(LineString,2048,fp); while (!feof(fp)) { fgets(LineString,2048,fp); if(LineString[5] != ':') return true; //ÇÔ¼ö À̸§ °Ë»ö 21ºÎÅÍÀÓ! UINT StringCntCount = 21; sFuntionInfo FuntionNode; memset(&FuntionNode,0,sizeof(sFuntionInfo)); char FuntionName[256]; memset(FuntionName,0,sizeof(char)*256); //ÇÔ¼ö À̸§ ¾ò±â if(!GetCutFunctionString(LineString + StringCntCount,FuntionName, sizeof(char)*256,StringCntCount)) { return false; } else { //¹®ÀÚ¿­ º¯È¯ multibyte -> unicode MultiByteToWideChar(CP_ACP,MB_COMPOSITE,FuntionName,-1,FuntionNode.FuntionName ,256); } //ÇÔ¼ö ÁÖ¼Ò ¾ò±âch if (!GetCutAddressString(LineString + StringCntCount , FuntionNode.FuntionAddress ,StringCntCount)) { return false; } StringCntCount++; if (LineString[StringCntCount] != 'f') { continue; } StringCntCount += 2; //i´Â Çì´õ Á¤º¸ÀÓ. FuntionNode.HeaderFile = (LineString[StringCntCount] == 'i'); StringCntCount += 2; memset(FuntionName,0,sizeof(char)*256); WideCharToMultiByte(CP_ACP,0,FuntionNode.FuntionName,-1,FuntionName,256,NULL,NULL); char FileName[256]; memset(FileName,0,sizeof(char)*256); //ÆÄÀÏ À̸§ °Ë»ö strncpy(FileName,LineString + StringCntCount,sizeof(char)* 256); size_t FileStringLen = strlen(FileName); FileName[FileStringLen -1] = NULL; MultiByteToWideChar(CP_ACP,MB_COMPOSITE,FileName,-1,FuntionNode.ObjectFileName ,256); FuntionList_.push_back(FuntionNode); } } } return true; } bool CMapProcess::ReadSourceLine( FILE* fp ) { char LineString[2048]; while (!feof(fp)) { fgets(LineString,2048,fp); if(strstr(LineString,"Line numbers for")) { sLineInfo LineNode; //¿ÀºêÁ§Æ® À̸§ÀÇ °Ë»öÀº 17¹øÂ° ºÎÅÍ ÀÓ. UINT StringCntCount = 17; char ObjectFileName[256]; memset(ObjectFileName,0,sizeof(char)*256); if (!GetLineObjectFileName(LineString + StringCntCount,ObjectFileName,sizeof(char)*256 ,StringCntCount)) { return false; } else { //¹®ÀÚ¿­ º¯È¯ multibyte -> unicode MultiByteToWideChar(CP_ACP,MB_COMPOSITE,ObjectFileName,-1,LineNode.ObjectFileName ,256); } StringCntCount++; char SourceFileName[256]; memset(SourceFileName,0,sizeof(char)*256); if (!GetLineSourceName(LineString + StringCntCount,SourceFileName,sizeof(char)*256 ,StringCntCount)) { return false; } else { //¹®ÀÚ¿­ º¯È¯ multibyte -> unicode MultiByteToWideChar(CP_ACP,MB_COMPOSITE,SourceFileName,-1,LineNode.SourceFileName ,256); } //»çÀÌ¿¡ °ø¹é ¶óÀÎ ÀÖÀ½! fgets(LineString,2048,fp); //ÇϳªÀÇ ¼Ò½º ¶óÀÎ Á¤º¸ while ( !feof(fp)) { fgets(LineString,2048,fp); if (strlen(LineString) < 2) break; //ÇϳªÀÇ ¶óÀÎ °£°Ý 20ÀÚ size_t LineSpaceLen = strlen(LineString); int stringcnt = static_cast(LineSpaceLen) / 20; //ÇÑÁÙ¿¡ ¼Ò½º ¶óÀÎ Á¤º¸´Â 4°³°¡ ³ÑÁö ¾ÊÀ½! for (int count = 0 ; count < 4 ; ++count) { sLineAndAddressEntity LineAddrEntity; if(!GetLineAndAddress(LineString,count,LineAddrEntity)) return false; LineNode.vAddressLineEntityList.push_back(LineAddrEntity); } } LineinfoList_.push_back(LineNode); } } return true; } bool CMapProcess::GetLoadBaseAddress( FILE* fp ) { char szLine[1024]; while (!feof(fp)) { fgets(szLine,1024,fp); if(strstr(szLine," Preferred load address is ")) { char Value[128]; size_t StringSize = strlen(" Preferred load address is "); strcpy(Value,szLine + StringSize); StringSize = strlen(Value); Value[StringSize-1] = NULL; LoadBaseAddress_ = GetHexValue(Value); return true; } } return false; } //////////////////////////////////////////////////////////////////////////////////////////////////// bool CMapProcess::GetCutFunctionString( const char* pStringLine, char* pString, size_t stringLen, UINT& CutStringCount ) { int count = 0; for (UINT index = 0 ; index < stringLen ; ++index) { if (pStringLine[index] == ' ' || pStringLine[index] == '@') { CutStringCount += index; pString[index] = NULL; return true; } else if (pStringLine[index] == '?' || pStringLine[index] == '$') { count = 0; continue; } pString[count] = pStringLine[index]; count++; } return false; } bool CMapProcess::GetCutAddressString( const char* pStringLine, DWORD& Address, UINT& CutStringCount ) { int count = 0; bool EndSpace = false; char AddressString[256]; UINT index = 0; for (index = 0 ; index < strlen(pStringLine) ; ++index) { if (EndSpace) { if(pStringLine[index] == ' ') break; AddressString[count] = pStringLine[index]; count++; } else if ( pStringLine[index] == ' ' && pStringLine[index + 1] == '0') { EndSpace = true; } } if(false == EndSpace) return false; CutStringCount += index; AddressString[count] = NULL; Address = GetHexValue(AddressString); return true; } bool CMapProcess::GetLineObjectFileName( const char* pStringLine, char* pString, size_t stringLen, UINT& CutStringCount ) { int count = 0; for (UINT index = 0 ; index < stringLen ; ++index) { if(pStringLine[index] == '(') { CutStringCount += index; pString[count] = NULL; return true; } pString[count] = pStringLine[index]; count++; } return true; } bool CMapProcess::GetLineSourceName( const char* pStringLine, char* pString, size_t stringLen, UINT& CutStringCount ) { int count = 0; for (UINT index = 0 ; index < stringLen ; ++index) { if(pStringLine[index] == ')') { CutStringCount += index; pString[count] = NULL; return true; } pString[count] = pStringLine[index]; count++; } return true; } bool CMapProcess::GetLineAndAddress( const char* pStringLine, int numCount, sLineAndAddressEntity& LineEntity ) { //ÇϳªÀÇ Á¤º¸ÀÓ char CutLineString[21]; int numStart = numCount * 20; int CutCount = -1; strncpy(CutLineString,pStringLine+numStart,sizeof(char)*21); CutLineString[20] = NULL; //¶óÀÎ ÁÖ¼Ò ¾ò±â for (int index = 0 ; index < 20 ; ++index) { if(CutLineString[index] == ':') { //¾îµå·¹½º °ª LineEntity.LineAddress = GetHexValue(CutLineString+index + 1); LineEntity.LineAddress += LoadBaseAddress_; LineEntity.LineAddress += 0x10000; for (int sourceIndex = index ; sourceIndex >= 0 ; --sourceIndex) { if(CutLineString[sourceIndex] == ' ') { CutLineString[sourceIndex] = NULL; LineEntity.SourceLine = atoi(CutLineString); return true; } } } } return true; } void CMapProcess::OnInitation() { }