@@ -30,11 +30,12 @@ struct ArgumentManager {
3030 void validateArguments (int argc, char * argv[]) {
3131
3232 namespace po = boost::program_options;
33- std::string version = " v1.0.1 " ;
33+ std::string version = " v1.0.2 " ;
3434 po::options_description description (" Windows memory extractor " + version + " \n Usage" );
3535
3636 description.add_options ()
3737 (" help,h" , " Display this help message" )
38+ (" join,j" , " Generate an additional .dmp file with the contents of the other .dmp files joined" )
3839 (" module,m" , po::value<std::string>(), " Module of the process" )
3940 (" pid,p" , po::value<int >()->required (), " Process ID" )
4041 (" protections,s" , po::value<std::string>(), " Memory protections" )
@@ -65,6 +66,13 @@ struct ArgumentManager {
6566 module = suppliedModule;
6667 isModuleOptionSupplied = true ;
6768 }
69+
70+ if (vm.count (" join" )) {
71+ isJoinOptionSupplied = true ;
72+ }
73+ }
74+ else if (vm.count (" join" )) {
75+ throw std::invalid_argument{ " The --join option can only be used alongside the --module option" };
6876 }
6977
7078 if (vm.count (" pid" )) {
@@ -97,6 +105,10 @@ struct ArgumentManager {
97105 return isProtectionsOptionSupplied;
98106 }
99107
108+ bool getIsJoinOptionSupplied () {
109+ return isJoinOptionSupplied;
110+ }
111+
100112private:
101113
102114 void validateProtections (std::string suppliedProtectionsAsString) {
@@ -137,6 +149,7 @@ struct ArgumentManager {
137149 // Options
138150 bool isModuleOptionSupplied;
139151 bool isProtectionsOptionSupplied;
152+ bool isJoinOptionSupplied;
140153
141154};
142155
@@ -192,7 +205,28 @@ struct MemoryExtractionManager {
192205 }
193206
194207 }
208+ if (argumentManager.getIsJoinOptionSupplied ()) {
209+ using namespace CryptoPP ;
210+ dmpFilesGeneratedCount++;
195211
212+ // Calculate the SHA-256 of the file joinedModuleContents.dmp
213+ std::ifstream joinedModuleContentsStream (directoryName + " /joinedModuleContents.dmp" , std::ios::in | std::ios::binary);
214+ std::string contents ((std::istreambuf_iterator<char >(joinedModuleContentsStream)),
215+ (std::istreambuf_iterator<char >()));
216+ HexEncoder hexEncoder (new FileSink (resultsFile), false );
217+ std::string sha256Digest;
218+ SHA256 hash;
219+ hash.Update ((const byte*)contents.c_str (), contents.length ());
220+ sha256Digest.resize (hash.DigestSize ());
221+ hash.Final ((byte*)&sha256Digest[0 ]);
222+
223+ // Create an entry in the results file for the joinedModuleContents.dmp file
224+ resultsFile << " Filename: " << " joinedModuleContents.dmp" << " , SHA-256: " ;
225+ StringSource (sha256Digest, true , new Redirector (hexEncoder));
226+ resultsFile << " \n " ;
227+
228+ joinedModuleContentsStream.close ();
229+ }
196230 resultsFile << " Number of .dmp files generated: " << dmpFilesGeneratedCount << std::endl;
197231 resultsFile.close ();
198232 CloseHandle (processHandle);
@@ -298,7 +332,7 @@ struct MemoryExtractionManager {
298332
299333 if (ReadProcessMemory (processHandle, memInfo.BaseAddress , memoryContents.get (), memInfo.RegionSize , &numberOfBytesRead) != 0 ) {
300334
301- // Each .dmp file has a representative name
335+ // Each .dmp file that corresponds to one memory region has a representative name
302336 // Nomenclature: virtualAddress_sizeOfMemoryRegion
303337
304338 std::stringstream fileNameStream;
@@ -314,6 +348,13 @@ struct MemoryExtractionManager {
314348
315349 dmpFilesGeneratedCount++;
316350 registerDmpFileCreation (fileName, memoryContents.get (), memInfo, resultsFile);
351+
352+ if (argumentManager.getIsJoinOptionSupplied ()) {
353+ std::string fullModuleFilePath = directoryName + " /" + " joinedModuleContents.dmp" ;
354+ std::ofstream fullModuleDataFile (fullModuleFilePath, std::ofstream::app | std::ofstream::binary);
355+ fullModuleDataFile.write (memoryContents.get (), memInfo.RegionSize );
356+ fullModuleDataFile.close ();
357+ }
317358 }
318359 }
319360
0 commit comments