summaryrefslogtreecommitdiff
path: root/library/Process-windows.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'library/Process-windows.cpp')
-rw-r--r--library/Process-windows.cpp136
1 files changed, 113 insertions, 23 deletions
diff --git a/library/Process-windows.cpp b/library/Process-windows.cpp
index 944a773c..7eb6ff5f 100644
--- a/library/Process-windows.cpp
+++ b/library/Process-windows.cpp
@@ -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))
+ temp.valid = true;
+
+ 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);
}
}