@@ -30,11 +30,12 @@ struct ArgumentManager {
30
30
void validateArguments (int argc, char * argv[]) {
31
31
32
32
namespace po = boost::program_options;
33
- std::string version = " v1.0.1 " ;
33
+ std::string version = " v1.0.2 " ;
34
34
po::options_description description (" Windows memory extractor " + version + " \n Usage" );
35
35
36
36
description.add_options ()
37
37
(" help,h" , " Display this help message" )
38
+ (" join,j" , " Generate an additional .dmp file with the contents of the other .dmp files joined" )
38
39
(" module,m" , po::value<std::string>(), " Module of the process" )
39
40
(" pid,p" , po::value<int >()->required (), " Process ID" )
40
41
(" protections,s" , po::value<std::string>(), " Memory protections" )
@@ -65,6 +66,13 @@ struct ArgumentManager {
65
66
module = suppliedModule;
66
67
isModuleOptionSupplied = true ;
67
68
}
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" };
68
76
}
69
77
70
78
if (vm.count (" pid" )) {
@@ -97,6 +105,10 @@ struct ArgumentManager {
97
105
return isProtectionsOptionSupplied;
98
106
}
99
107
108
+ bool getIsJoinOptionSupplied () {
109
+ return isJoinOptionSupplied;
110
+ }
111
+
100
112
private:
101
113
102
114
void validateProtections (std::string suppliedProtectionsAsString) {
@@ -137,6 +149,7 @@ struct ArgumentManager {
137
149
// Options
138
150
bool isModuleOptionSupplied;
139
151
bool isProtectionsOptionSupplied;
152
+ bool isJoinOptionSupplied;
140
153
141
154
};
142
155
@@ -192,7 +205,28 @@ struct MemoryExtractionManager {
192
205
}
193
206
194
207
}
208
+ if (argumentManager.getIsJoinOptionSupplied ()) {
209
+ using namespace CryptoPP ;
210
+ dmpFilesGeneratedCount++;
195
211
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
+ }
196
230
resultsFile << " Number of .dmp files generated: " << dmpFilesGeneratedCount << std::endl;
197
231
resultsFile.close ();
198
232
CloseHandle (processHandle);
@@ -298,7 +332,7 @@ struct MemoryExtractionManager {
298
332
299
333
if (ReadProcessMemory (processHandle, memInfo.BaseAddress , memoryContents.get (), memInfo.RegionSize , &numberOfBytesRead) != 0 ) {
300
334
301
- // Each .dmp file has a representative name
335
+ // Each .dmp file that corresponds to one memory region has a representative name
302
336
// Nomenclature: virtualAddress_sizeOfMemoryRegion
303
337
304
338
std::stringstream fileNameStream;
@@ -314,6 +348,13 @@ struct MemoryExtractionManager {
314
348
315
349
dmpFilesGeneratedCount++;
316
350
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
+ }
317
358
}
318
359
}
319
360
0 commit comments