//----------------------------------------------------------------------------- // Name: FreeApiInfo // Object: Free memory and events associated to pAPIInfo // Parameters : // in : API_INFO* pAPIInfo : pointer to APIInfo to free // Return : //----------------------------------------------------------------------------- BOOL FreeApiInfo(API_INFO* pAPIInfo) { FreeOptionalParametersMemory(pAPIInfo); // free allocated memory for string if (pAPIInfo->szAPIName) { HeapFree(ApiOverrideHeap, 0, pAPIInfo->szAPIName); pAPIInfo->szAPIName=NULL; } if (pAPIInfo->szModuleName) { HeapFree(ApiOverrideHeap, 0, pAPIInfo->szModuleName); pAPIInfo->szModuleName=NULL; } if (pAPIInfo->evtEndOfHook) { CloseHandle(pAPIInfo->evtEndOfHook); pAPIInfo->evtEndOfHook=NULL; } if (pAPIInfo->PostApiCallChain) { CLinkList* pTmp; // delete Call Chain // assign to null before destroying content (better for multi threading) pTmp=pAPIInfo->PostApiCallChain; pAPIInfo->PostApiCallChain=NULL; pTmp->Lock(); delete pTmp; } if (pAPIInfo->PreApiCallChain) { CLinkList* pTmp; // delete Call Chain // assign to null before destroying content (better for multi threading) pTmp=pAPIInfo->PreApiCallChain; pAPIInfo->PreApiCallChain=NULL; pTmp->Lock(); delete pTmp; } return TRUE; }
//----------------------------------------------------------------------------- // Name: FreeOptionalParametersMemory // Object: Free memory of optional parameters info from index FromIndex // Parameters : // in : API_INFO *pAPIInfo // BYTE FromIndex : index from which delete memory, !=0 only to remove // some too much allocated memory (see number parameter // correction from APIOverrideKernel) // BYTE ToIndex : index to delete memory, must be < MAX_PARAM // should be pAPIInfo->MonitoringParamCount // Return : //----------------------------------------------------------------------------- void FreeOptionalParametersMemory(API_INFO *pAPIInfo,BYTE FromIndex,BYTE ToIndex) { CLinkListItem* pItem; PMONITORING_PARAMETER_OPTIONS pParamOption; BYTE Cnt; CLinkList* pList; // remove all breaking or logging options // let it to avoid crash : when a flag is specified, it require memory that has been freed !!! memset(&pAPIInfo->LogBreakWay,0,sizeof(API_LOG_BREAK_WAY)); if (ToIndex>=MAX_PARAM) ToIndex=MAX_PARAM-1; // we have to free optional parameter allocated memory for(Cnt=FromIndex;Cnt<=ToIndex;Cnt++) { pAPIInfo->ParamList[Cnt].dwSizeOfData=0; pAPIInfo->ParamList[Cnt].dwSizeOfPointedData=0; pAPIInfo->ParamList[Cnt].dwType=0; if (pAPIInfo->ParamList[Cnt].pConditionalLogContent!=NULL) { // store list pointer pList=pAPIInfo->ParamList[Cnt].pConditionalLogContent; // set pAPIInfo list pointer to NULL pAPIInfo->ParamList[Cnt].pConditionalLogContent=NULL; // free memory pList->Lock(); for(pItem=pList->Head;pItem;pItem=pItem->NextItem) { pParamOption=(MONITORING_PARAMETER_OPTIONS*)pItem->ItemData; if (pParamOption->pbPointedValue!=0) HeapFree(ApiOverrideHeap,0,pParamOption->pbPointedValue); } pList->RemoveAllItems(TRUE); delete pList; } if (pAPIInfo->ParamList[Cnt].pConditionalBreakContent!=NULL) { // store list pointer pList=pAPIInfo->ParamList[Cnt].pConditionalBreakContent; // set pAPIInfo list pointer to NULL pAPIInfo->ParamList[Cnt].pConditionalBreakContent=NULL; // free memory pList->Lock(); for(pItem=pList->Head;pItem;pItem=pItem->NextItem) { pParamOption=(MONITORING_PARAMETER_OPTIONS*)pItem->ItemData; if (pParamOption->pbPointedValue!=0) HeapFree(ApiOverrideHeap,0,pParamOption->pbPointedValue); } pList->RemoveAllItems(TRUE); delete pList; } } }
//----------------------------------------------------------------------------- // Name: MakeStats // Object: compute statistics and add them to listview // Parameters : // in : // out : // return : //----------------------------------------------------------------------------- void CLogsStatsUI::MakeStats() { CLinkListItem* pItemLogList; CLinkListItem* pItemStatList; CLinkList* pStatList; LOG_LIST_ENTRY* pLogEntry; STATSTRUCT* pStat; STATSTRUCT Stat; BOOL bFoundInStatList; TCHAR** ppc=new TCHAR*[4]; TCHAR pszCallCount[12]; TCHAR pszAverageDuration[12]; DWORD AverageDuration; HCURSOR hOldCursor; // create a list of STATSTRUCT pStatList=new CLinkList(sizeof(STATSTRUCT)); // store original cursor hOldCursor=GetCursor(); // set cusor to wait cursor SetCursor(LoadCursor(NULL,IDC_WAIT)); // for each item in pLogList pLogList->Lock(TRUE); for (pItemLogList=pLogList->Head;pItemLogList;pItemLogList=pItemLogList->NextItem) { pLogEntry=(LOG_LIST_ENTRY*)pItemLogList->ItemData; // if pLogEntry is an user message, go to next entry if (pLogEntry->Type!=ENTRY_LOG) continue; bFoundInStatList=FALSE; // a function is defined by it's api name and module name // so try to find an item in pStatList with same api name and module name pStatList->Lock(); for (pItemStatList=pStatList->Head;pItemStatList;pItemStatList=pItemStatList->NextItem) { pStat=(STATSTRUCT*)pItemStatList->ItemData; // compare api and module name if (_tcsicmp(pStat->ApiName,pLogEntry->pLog->pszApiName)==0) { if(_tcsicmp(pStat->ModuleName,pLogEntry->pLog->pszModuleName)==0) { // the func is already in stat list, so update it's stat values // update count pStat->Count++; // update DurationSum (trying to avoid buffer overflow) if (0xFFFFFFFF-pLogEntry->pLog->pHookInfos->dwCallDuration<=pStat->DurationSum) pStat->DurationSum=0xFFFFFFFF; else pStat->DurationSum+=pLogEntry->pLog->pHookInfos->dwCallDuration; // we have found item bFoundInStatList=TRUE; break; } } } pStatList->Unlock(); // if item was not in state list, add it to stat list if (!bFoundInStatList) { _tcscpy(Stat.ApiName,pLogEntry->pLog->pszApiName); _tcscpy(Stat.ModuleName,pLogEntry->pLog->pszModuleName); Stat.Count=1; Stat.DurationSum=pLogEntry->pLog->pHookInfos->dwCallDuration; pStatList->AddItem(&Stat); } } pLogList->Unlock(); // for each item of pStatList pStatList->Lock(); for (pItemStatList=pStatList->Head;pItemStatList;pItemStatList=pItemStatList->NextItem) { // add item to list view pStat=(STATSTRUCT*)pItemStatList->ItemData; // api name ppc[0]=pStat->ApiName; // module name ppc[1]=pStat->ModuleName; // call count _stprintf(pszCallCount,_T("%u"),pStat->Count); ppc[2]=pszCallCount; // average duration AverageDuration=pStat->DurationSum/pStat->Count; if (pStat->DurationSum==0xFFFFFFFF) _stprintf(pszAverageDuration,_T(">%u"),AverageDuration); else _stprintf(pszAverageDuration,_T("%u"),AverageDuration); ppc[3]=pszAverageDuration; this->pListview->AddItemAndSubItems(4,ppc,FALSE); } pStatList->Unlock(); // free allocated memory delete[] ppc; delete pStatList; // restore original cursor SetCursor(hOldCursor); }