|
|
#include <windows.h>
#include <stdio.h>
#include "dump.h"
#include "main.h"
PBASEINFO g_BaseHead = 0; PTHREADINFO g_ThreadHead = 0; DWORD g_dwThreadCount = 0; HANDLE g_MapInformation = INVALID_HANDLE_VALUE; HANDLE g_ErrorInformation = INVALID_HANDLE_VALUE;
int _cdecl main(int argc, char *argv[]) { PCHAR pszFile; PCHAR pszBaseFileName; BOOL bResult;
if (argc < 3) { return -1; }
pszFile = argv[1]; //1st parameter
pszBaseFileName = argv[2]; //2nd parameter
bResult = ProcessRuntimeData(pszFile, pszBaseFileName); if (FALSE == bResult) { return -1; }
//
// Close any open file handles
//
if (INVALID_HANDLE_VALUE != g_MapInformation) { CloseHandle(g_MapInformation); }
if (INVALID_HANDLE_VALUE != g_ErrorInformation) { CloseHandle(g_ErrorInformation); }
CloseThreadHandles();
return 0; }
BOOL ProcessRuntimeData(PCHAR pszFile, PCHAR pszBaseFileName) { HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hMap = 0; BOOL bResult = FALSE; PVOID pFileBits = 0; PBYTE pMappedBits; LONG lFileSize; //
// Get our file online and start the data processing
//
hFile = CreateFileA(pszFile, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (INVALID_HANDLE_VALUE == hFile) { bResult = FALSE;
goto HandleError; }
lFileSize = GetFileSize(hFile, 0);
//
// Process the data stream
//
hMap = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, 0, 0); if (0 == hMap) { bResult = FALSE;
goto HandleError; }
pFileBits = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0); if (0 == pFileBits) { bResult = FALSE;
goto HandleError; }
pMappedBits = (PBYTE)pFileBits;
//
// Process stream data
//
while (lFileSize > 0) { switch(*pMappedBits) { case ThreadStartId: bResult = AddThreadInformation(pszBaseFileName, (PTHREADSTART)pMappedBits); if (FALSE == bResult) { goto HandleError; }
lFileSize -= sizeof(THREADSTART); pMappedBits += sizeof(THREADSTART); break;
case ExeFlowId: bResult = AddExeFlowInformation((PEXEFLOW)pMappedBits); // if (FALSE == bResult) {
// goto HandleError;
// }
lFileSize -= sizeof(EXEFLOW); pMappedBits += sizeof(EXEFLOW); break;
case DllBaseInfoId: bResult = AddToBaseInformation((PDLLBASEINFO)pMappedBits); if (FALSE == bResult) { goto HandleError; } lFileSize -= sizeof(DLLBASEINFO); pMappedBits += sizeof(DLLBASEINFO); break;
case MapInfoId: bResult = AddMappedInformation(pszBaseFileName, (PMAPINFO)pMappedBits); if (FALSE == bResult) { goto HandleError; }
lFileSize -= sizeof(MAPINFO); pMappedBits += sizeof(MAPINFO); break;
case ErrorInfoId: bResult = AddErrorInformation(pszBaseFileName, (PERRORINFO)pMappedBits); if (FALSE == bResult) { goto HandleError; }
lFileSize -= sizeof(ERRORINFO); pMappedBits += sizeof(ERRORINFO); break;
default: 0; } }
//
// No problems in processing log
//
bResult = TRUE;
HandleError: if (pFileBits) { UnmapViewOfFile(pFileBits); }
if (hMap) { CloseHandle(hMap); }
if (INVALID_HANDLE_VALUE != hFile) { CloseHandle(hFile); } return bResult; }
BOOL AddThreadInformation(PCHAR pszBaseFileName, PTHREADSTART pThreadStart) { PTHREADINFO ptTemp = 0; BOOL bResult; DWORD dwBytesWritten; CHAR szBuffer[MAX_PATH]; CHAR szAddress[MAX_PATH];
//
// Allocate some memory for the new thread data
//
ptTemp = LocalAlloc(LPTR, sizeof(THREADINFO)); if (0 == ptTemp) { return FALSE; }
//
// Initialize file data
//
ptTemp->dwThreadId = pThreadStart->dwThreadId;
sprintf(szBuffer,"%s.thread%ld", pszBaseFileName, g_dwThreadCount); ptTemp->hFile = CreateFileA(szBuffer, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (INVALID_HANDLE_VALUE == ptTemp->hFile) { return FALSE; } //
// Add thread base information to new thread log
//
bResult = FillBufferWithRelocationInfo(szAddress, pThreadStart->dwStartAddress); if (FALSE == bResult) { return bResult; }
sprintf(szBuffer,"Thread started at %s\r\n", szAddress); bResult = WriteFile(ptTemp->hFile, szBuffer, strlen(szBuffer), &dwBytesWritten, 0); if (FALSE == bResult) { return FALSE; }
//
// Chain up thread data
//
if (0 == g_ThreadHead) { ptTemp->pNext = 0; g_ThreadHead = ptTemp; } else { ptTemp->pNext = g_ThreadHead; g_ThreadHead = ptTemp; }
return TRUE; }
VOID CloseThreadHandles(VOID) { PTHREADINFO ptTemp = 0;
ptTemp = g_ThreadHead;
while(ptTemp) { if (ptTemp->hFile != INVALID_HANDLE_VALUE) { CloseHandle(ptTemp->hFile); }
ptTemp = ptTemp->pNext; } }
BOOL AddExeFlowInformation(PEXEFLOW pExeFlow) { PTHREADINFO ptTemp = 0; BOOL bResult; DWORD dwBytesWritten; CHAR szAddress[MAX_PATH]; CHAR szBuffer[MAX_PATH];
//
// Locate thread for this point of execution
//
ptTemp = g_ThreadHead; while(ptTemp) { if (ptTemp->dwThreadId == pExeFlow->dwThreadId) { break; }
ptTemp = ptTemp->pNext; }
if (0 == ptTemp) { //
// Couldn't locate thread info
//
return FALSE; }
bResult = FillBufferWithRelocationInfo(szAddress, pExeFlow->dwAddress); if (FALSE == bResult) { return bResult; }
sprintf(szBuffer, "%s : %ld\r\n", szAddress, pExeFlow->dwCallLevel);
bResult = WriteFile(ptTemp->hFile, szBuffer, strlen(szBuffer), &dwBytesWritten, 0); if (FALSE == bResult) { return FALSE; }
return TRUE; }
BOOL AddErrorInformation(PCHAR pszBaseFileName, PERRORINFO pErrorInfo) { BOOL bResult; DWORD dwBytesWritten; CHAR szBuffer[MAX_PATH];
if (INVALID_HANDLE_VALUE == g_ErrorInformation) { strcpy(szBuffer, pszBaseFileName); strcat(szBuffer, ".err");
g_ErrorInformation = CreateFileA(szBuffer, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (INVALID_HANDLE_VALUE == g_ErrorInformation) { return FALSE; } }
//
// Write out error message
//
bResult = WriteFile(g_ErrorInformation, pErrorInfo->szMessage, strlen(pErrorInfo->szMessage), &dwBytesWritten, 0); if (FALSE == bResult) { return FALSE; }
return TRUE; }
BOOL AddMappedInformation(PCHAR pszBaseFileName, PMAPINFO pMapInfo) { BOOL bResult; CHAR szBuffer[MAX_PATH]; CHAR szAddress[MAX_PATH]; CHAR szAddress2[MAX_PATH]; DWORD dwBytesWritten;
if (INVALID_HANDLE_VALUE == g_MapInformation) { strcpy(szBuffer, pszBaseFileName); strcat(szBuffer, ".map");
g_MapInformation = CreateFileA(szBuffer, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (INVALID_HANDLE_VALUE == g_MapInformation) { return FALSE; } }
//
// Write out the mapping information
//
bResult = FillBufferWithRelocationInfo(szAddress, pMapInfo->dwAddress); if (FALSE == bResult) { return bResult; }
bResult = FillBufferWithRelocationInfo(szAddress2, pMapInfo->dwMaxMapLength); if (FALSE == bResult) { return bResult; }
sprintf(szBuffer, "%s -> %s\r\n", szAddress, szAddress2);
bResult = WriteFile(g_MapInformation, szBuffer, strlen(szBuffer), &dwBytesWritten, 0); if (FALSE == bResult) { return FALSE; }
return TRUE; }
BOOL FillBufferWithRelocationInfo(PCHAR pszDestination, DWORD dwAddress) { PBASEINFO pTemp;
//
// Find the address in the module info
//
pTemp = g_BaseHead; while (pTemp) { //
// Did we find the address?
//
if ((dwAddress >= pTemp->dwStartAddress) && (dwAddress <= pTemp->dwEndAddress)) { break; }
pTemp = pTemp->pNext; }
if (pTemp) { sprintf(pszDestination, "%s+%08X", pTemp->szModule, (dwAddress - pTemp->dwStartAddress)); } else { sprintf(pszDestination, "%08X", dwAddress); }
return TRUE; }
BOOL AddToBaseInformation(PDLLBASEINFO pDLLBaseInfo) { PBASEINFO pTemp;
if (0 == g_BaseHead) { //
// Store off the base information
//
pTemp = LocalAlloc(LPTR, sizeof(BASEINFO)); if (0 == pTemp) { return FALSE; } pTemp->dwStartAddress = pDLLBaseInfo->dwBase; pTemp->dwEndAddress = pTemp->dwStartAddress + pDLLBaseInfo->dwLength; strcpy(pTemp->szModule, pDLLBaseInfo->szDLLName); _strupr(pTemp->szModule);
pTemp->pNext = 0;
g_BaseHead = pTemp; } else { //
// See if our module has already been mapped, and if so update module base info
//
pTemp = g_BaseHead;
while(pTemp) { if (0 == _stricmp(pDLLBaseInfo->szDLLName, pTemp->szModule)) { break; }
pTemp = pTemp->pNext; }
if (pTemp) { //
// Found the DLL already in the list, update
//
pTemp->dwStartAddress = pDLLBaseInfo->dwBase; pTemp->dwEndAddress = pTemp->dwStartAddress + pDLLBaseInfo->dwLength; } else { //
// New DLL
//
pTemp = LocalAlloc(LPTR, sizeof(BASEINFO)); if (0 == pTemp) { return FALSE; }
pTemp->dwStartAddress = pDLLBaseInfo->dwBase; pTemp->dwEndAddress = pTemp->dwStartAddress + pDLLBaseInfo->dwLength; strcpy(pTemp->szModule, pDLLBaseInfo->szDLLName); _strupr(pTemp->szModule);
//
// Chain up the new DLL
//
pTemp->pNext = g_BaseHead; g_BaseHead = pTemp; } }
return TRUE; }
|