@@ -30,12 +30,13 @@ struct ArgumentManager {
3030 void validateArguments (int argc, char * argv[]) {
3131
3232 namespace po = boost::program_options;
33- std::string version = " v1.0.2 " ;
33+ std::string version = " v1.0.3 " ;
3434 po::options_description description (" Windows memory extractor " + version + " \n Usage" );
3535
3636 description.add_options ()
3737 (" help,h" , " Display this help message" )
3838 (" join,j" , " Generate an additional .dmp file with the contents of the other .dmp files joined" )
39+ (" output-directory,o" , po::value<std::string>(), " Directory where the output will be stored" )
3940 (" module,m" , po::value<std::string>(), " Module of the process" )
4041 (" pid,p" , po::value<int >()->required (), " Process ID" )
4142 (" protections,s" , po::value<std::string>(), " Memory protections" )
@@ -83,6 +84,16 @@ struct ArgumentManager {
8384 validateProtections (vm[" protections" ].as <std::string>());
8485 }
8586
87+ if (vm.count (" output-directory" )) {
88+ if (directoryExists (vm[" output-directory" ].as <std::string>())) {
89+ outputDirectory = vm[" output-directory" ].as <std::string>();
90+ isOutputDirectoryOptionSupplied = true ;
91+ }
92+ else {
93+ throw std::invalid_argument{ " The directory supplied does not exist" };
94+ }
95+ }
96+
8697 }
8798
8899 int getPid () {
@@ -97,6 +108,10 @@ struct ArgumentManager {
97108 return protections;
98109 }
99110
111+ std::string& getOutputDirectory () {
112+ return outputDirectory;
113+ }
114+
100115 bool getIsModuleOptionSupplied () {
101116 return isModuleOptionSupplied;
102117 }
@@ -109,6 +124,10 @@ struct ArgumentManager {
109124 return isJoinOptionSupplied;
110125 }
111126
127+ bool getIsOutputDirectoryOptionSupplied () {
128+ return isOutputDirectoryOptionSupplied;
129+ }
130+
112131private:
113132
114133 void validateProtections (std::string suppliedProtectionsAsString) {
@@ -141,15 +160,32 @@ struct ArgumentManager {
141160 isProtectionsOptionSupplied = true ;
142161 }
143162
163+ bool directoryExists (const std::string& suppliedDirectoryAsString)
164+ {
165+ DWORD fileAttributes = GetFileAttributesA (suppliedDirectoryAsString.c_str ());
166+
167+ if (fileAttributes == INVALID_FILE_ATTRIBUTES) {
168+ return false ; // Something is wrong with the path
169+ }
170+
171+ if (fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
172+ return true ; // The path corresponds with a directory
173+ }
174+
175+ return false ; // The path does not correspond with a directory
176+ }
177+
144178 // Arguments
145179 int pid;
146180 std::string module ;
147181 std::vector<std::string> protections;
182+ std::string outputDirectory;
148183
149184 // Options
150185 bool isModuleOptionSupplied;
151186 bool isProtectionsOptionSupplied;
152187 bool isJoinOptionSupplied;
188+ bool isOutputDirectoryOptionSupplied;
153189
154190};
155191
@@ -279,6 +315,9 @@ struct MemoryExtractionManager {
279315 struct tm buf;
280316 gmtime_s (&buf, ×tamp);
281317 std::stringstream directoryNameStream;
318+ if (argumentManager.getIsOutputDirectoryOptionSupplied ()) {
319+ directoryNameStream << argumentManager.getOutputDirectory () << " /" ;
320+ }
282321 directoryNameStream << std::dec << argumentManager.getPid () << " _" << std::put_time (&buf, " %d-%m-%Y_%H-%M-%S_UTC" );
283322 CreateDirectoryA (directoryNameStream.str ().c_str (), NULL );
284323 return directoryNameStream.str ();
@@ -427,11 +466,11 @@ struct ExecutionManager {
427466 }
428467 catch (const std::exception& ex) {
429468 std::cerr << " Error: " << ex.what () << " ." << std::endl;
430- exit (1 );
469+ exit (GetLastError () );
431470 }
432471 catch (...) {
433472 std::cerr << " Error: An unexpected error has occurred." << std::endl;
434- exit (1 );
473+ exit (GetLastError () );
435474 }
436475 }
437476
0 commit comments