|
|
|
@ -233,19 +233,55 @@ struct HeapBlock
|
|
|
|
|
ULONG reserved;
|
|
|
|
|
};
|
|
|
|
|
*/
|
|
|
|
|
// FIXME: NEEDS TESTING!
|
|
|
|
|
// FIXME: <warmist> i noticed that if you enumerate it twice, second time it returns wrong .text region size
|
|
|
|
|
|
|
|
|
|
static void GetDosNames(std::map<string, string> &table)
|
|
|
|
|
{
|
|
|
|
|
// Partially based on example from msdn:
|
|
|
|
|
// Translate path with device name to drive letters.
|
|
|
|
|
TCHAR szTemp[512];
|
|
|
|
|
szTemp[0] = '\0';
|
|
|
|
|
|
|
|
|
|
if (GetLogicalDriveStrings(sizeof(szTemp)-1, szTemp))
|
|
|
|
|
{
|
|
|
|
|
TCHAR szName[MAX_PATH];
|
|
|
|
|
TCHAR szDrive[3] = " :";
|
|
|
|
|
BOOL bFound = FALSE;
|
|
|
|
|
TCHAR* p = szTemp;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
// Copy the drive letter to the template string
|
|
|
|
|
*szDrive = *p;
|
|
|
|
|
|
|
|
|
|
// Look up each device name
|
|
|
|
|
if (QueryDosDevice(szDrive, szName, MAX_PATH))
|
|
|
|
|
table[szName] = szDrive;
|
|
|
|
|
|
|
|
|
|
// Go to the next NULL character.
|
|
|
|
|
while (*p++);
|
|
|
|
|
} while (*p); // end of string
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Process::getMemRanges( vector<t_memrange> & ranges )
|
|
|
|
|
{
|
|
|
|
|
MEMORY_BASIC_INFORMATION MBI;
|
|
|
|
|
//map<char *, unsigned int> heaps;
|
|
|
|
|
uint64_t movingStart = 0;
|
|
|
|
|
PVOID LastAllocationBase = 0;
|
|
|
|
|
map <char *, string> nameMap;
|
|
|
|
|
map <string,string> dosDrives;
|
|
|
|
|
|
|
|
|
|
// get page size
|
|
|
|
|
SYSTEM_INFO si;
|
|
|
|
|
GetSystemInfo(&si);
|
|
|
|
|
uint64_t PageSize = si.dwPageSize;
|
|
|
|
|
|
|
|
|
|
// get dos drive names
|
|
|
|
|
GetDosNames(dosDrives);
|
|
|
|
|
|
|
|
|
|
ranges.clear();
|
|
|
|
|
|
|
|
|
|
// enumerate heaps
|
|
|
|
|
// HeapNodes(d->my_pid, heaps);
|
|
|
|
|
// go through all the VM regions, convert them to our internal format
|
|
|
|
@ -254,52 +290,106 @@ void Process::getMemRanges( vector<t_memrange> & ranges )
|
|
|
|
|
movingStart = ((uint64_t)MBI.BaseAddress + MBI.RegionSize);
|
|
|
|
|
if(movingStart % PageSize != 0)
|
|
|
|
|
movingStart = (movingStart / PageSize + 1) * PageSize;
|
|
|
|
|
// skip empty regions and regions we share with other processes (DLLs)
|
|
|
|
|
if( !(MBI.State & MEM_COMMIT) /*|| !(MBI.Type & MEM_PRIVATE)*/ )
|
|
|
|
|
|
|
|
|
|
// Skip unallocated address space
|
|
|
|
|
if (MBI.State & MEM_FREE)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Find range and permissions
|
|
|
|
|
t_memrange temp;
|
|
|
|
|
memset(&temp, 0, sizeof(temp));
|
|
|
|
|
|
|
|
|
|
temp.start = (char *) MBI.BaseAddress;
|
|
|
|
|
temp.end = ((char *)MBI.BaseAddress + (uint64_t)MBI.RegionSize);
|
|
|
|
|
temp.read = MBI.Protect & PAGE_EXECUTE_READ || MBI.Protect & PAGE_EXECUTE_READWRITE || MBI.Protect & PAGE_READONLY || MBI.Protect & PAGE_READWRITE;
|
|
|
|
|
temp.write = MBI.Protect & PAGE_EXECUTE_READWRITE || MBI.Protect & PAGE_READWRITE;
|
|
|
|
|
temp.execute = MBI.Protect & PAGE_EXECUTE_READ || MBI.Protect & PAGE_EXECUTE_READWRITE || MBI.Protect & PAGE_EXECUTE;
|
|
|
|
|
temp.valid = true;
|
|
|
|
|
if(!GetModuleBaseName(d->my_handle, (HMODULE) temp.start, temp.name, 1024))
|
|
|
|
|
|
|
|
|
|
if (!(MBI.State & MEM_COMMIT))
|
|
|
|
|
temp.valid = false; // reserved address space
|
|
|
|
|
else if (MBI.Protect & PAGE_EXECUTE)
|
|
|
|
|
temp.execute = true;
|
|
|
|
|
else if (MBI.Protect & PAGE_EXECUTE_READ)
|
|
|
|
|
temp.execute = temp.read = true;
|
|
|
|
|
else if (MBI.Protect & PAGE_EXECUTE_READWRITE)
|
|
|
|
|
temp.execute = temp.read = temp.write = true;
|
|
|
|
|
else if (MBI.Protect & PAGE_EXECUTE_WRITECOPY)
|
|
|
|
|
temp.execute = temp.read = temp.write = true;
|
|
|
|
|
else if (MBI.Protect & PAGE_READONLY)
|
|
|
|
|
temp.read = true;
|
|
|
|
|
else if (MBI.Protect & PAGE_READWRITE)
|
|
|
|
|
temp.read = temp.write = true;
|
|
|
|
|
else if (MBI.Protect & PAGE_WRITECOPY)
|
|
|
|
|
temp.read = temp.write = true;
|
|
|
|
|
|
|
|
|
|
// Merge areas with the same properties
|
|
|
|
|
if (!ranges.empty() && LastAllocationBase == MBI.AllocationBase)
|
|
|
|
|
{
|
|
|
|
|
if(nameMap.count((char *)temp.start))
|
|
|
|
|
auto &last = ranges.back();
|
|
|
|
|
|
|
|
|
|
if (last.end == temp.start &&
|
|
|
|
|
last.valid == temp.valid && last.execute == temp.execute &&
|
|
|
|
|
last.read == temp.read && last.write == temp.write)
|
|
|
|
|
{
|
|
|
|
|
// potential buffer overflow...
|
|
|
|
|
strcpy(temp.name, nameMap[(char *)temp.start].c_str());
|
|
|
|
|
last.end = temp.end;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
// Find the mapped file name
|
|
|
|
|
if (GetMappedFileName(d->my_handle, temp.start, temp.name, 1024))
|
|
|
|
|
{
|
|
|
|
|
int vsize = strlen(temp.name);
|
|
|
|
|
|
|
|
|
|
// Translate NT name to DOS name
|
|
|
|
|
for (auto it = dosDrives.begin(); it != dosDrives.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
// filter away shared segments without a name.
|
|
|
|
|
if( !(MBI.Type & MEM_PRIVATE) )
|
|
|
|
|
int ksize = it->first.size();
|
|
|
|
|
if (strncmp(temp.name, it->first.data(), ksize) != 0)
|
|
|
|
|
continue;
|
|
|
|
|
else
|
|
|
|
|
temp.name[0]=0;
|
|
|
|
|
|
|
|
|
|
memcpy(temp.name, it->second.data(), it->second.size());
|
|
|
|
|
memmove(temp.name + it->second.size(), temp.name + ksize, vsize + 1 - ksize);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
temp.name[0] = 0;
|
|
|
|
|
#else
|
|
|
|
|
// Find the executable name
|
|
|
|
|
char *base = (char*)MBI.AllocationBase;
|
|
|
|
|
|
|
|
|
|
if(nameMap.count(base))
|
|
|
|
|
{
|
|
|
|
|
strncpy(temp.name, nameMap[base].c_str(), 1023);
|
|
|
|
|
}
|
|
|
|
|
else if(GetModuleBaseName(d->my_handle, (HMODULE)base, temp.name, 1024))
|
|
|
|
|
{
|
|
|
|
|
std::string nm(temp.name);
|
|
|
|
|
|
|
|
|
|
nameMap[base] = nm;
|
|
|
|
|
|
|
|
|
|
// this is our executable! (could be generalized to pull segments from libs, but whatever)
|
|
|
|
|
if(d->base == temp.start)
|
|
|
|
|
if(d->base == base)
|
|
|
|
|
{
|
|
|
|
|
for(int i = 0; i < d->pe_header.FileHeader.NumberOfSections; i++)
|
|
|
|
|
{
|
|
|
|
|
char sectionName[9];
|
|
|
|
|
/*char sectionName[9];
|
|
|
|
|
memcpy(sectionName,d->sections[i].Name,8);
|
|
|
|
|
sectionName[8] = 0;
|
|
|
|
|
string nm;
|
|
|
|
|
nm.append(temp.name);
|
|
|
|
|
nm.append(" : ");
|
|
|
|
|
nm.append(sectionName);
|
|
|
|
|
nameMap[(char *)temp.start + d->sections[i].VirtualAddress] = nm;
|
|
|
|
|
nm.append(sectionName);*/
|
|
|
|
|
nameMap[base + d->sections[i].VirtualAddress] = nm;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
temp.name[0] = 0;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Push the entry
|
|
|
|
|
LastAllocationBase = MBI.AllocationBase;
|
|
|
|
|
ranges.push_back(temp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|