mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-26 07:17:01 +00:00
8c3db51c48
* Use HTTPS for Microsoft symbol server URL Update Microsoft symbol server URL to https://msdl.microsoft.com/download/symbols. This is the default sympath in WinDbg 10.0.14321. * Use HTTPS in cconfig.c
178 lines
5.0 KiB
JavaScript
178 lines
5.0 KiB
JavaScript
var fs = require('fs');
|
|
var spawn = require('child_process').spawn;
|
|
var os = require('os');
|
|
var path = require('path');
|
|
var curl = require('node-curl').Curl;
|
|
|
|
const INPUT_FOLDER_ARG = 2;
|
|
const OUTPUT_FOLDER_ARG = 3;
|
|
|
|
const SYMBOL_SERVER = 'Microsoft-Symbol-Server/6.11.0001.402';
|
|
const DOWNLOABLE_LINK = 'https://msdl.microsoft.com/download/symbols';
|
|
const GUID = 'guid';
|
|
const DBG_FNAME = 'dbg_file';
|
|
const CURL = 'curl';
|
|
const CABEXTRACTOR = (os.platform() != 'win32') ? 'cabextract' : 'expand';
|
|
const RABIN = 'rabin2'
|
|
var IN_FOLDER = '';
|
|
var OUT_FOLDER = '';
|
|
const EOL = os.EOL;
|
|
|
|
var print_usage = function() {
|
|
console.log("usage: node pdb_downloader.js INPUT_FOLDER [OUT_FOLDER]");
|
|
console.log("*if OUT_FOLDER is not set than OUT_FOLDER equal to INPUT_FOLDER");
|
|
}
|
|
|
|
var walk = function (dir, done) {
|
|
var results = [];
|
|
fs.readdir(dir, function (err, list) {
|
|
if (err) return done(err);
|
|
var pending = list.length;
|
|
if (!pending) return done(null, results);
|
|
list.forEach(function (file) {
|
|
file = path.join(dir, file);
|
|
fs.stat(file, function (err, stat) {
|
|
if (stat && stat.isDirectory()) {
|
|
walk(file, function (err, res) {
|
|
results = results.concat(res);
|
|
if (!--pending) done(null, results);
|
|
});
|
|
} else {
|
|
results.push(file);
|
|
if (!--pending) done(null, results);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
var extract_pdb_file = function (archive_name, dbg_fname) {
|
|
var spawn = require('child_process').spawn;
|
|
|
|
if (os.platform() == 'win32') {
|
|
cab_extractor_cmd = spawn(CABEXTRACTOR, [archive_name, OUT_FOLDER + dbg_fname]);
|
|
} else {
|
|
cab_extractor_cmd = spawn(CABEXTRACTOR, ['-d', OUT_FOLDER, archive_name]);
|
|
}
|
|
|
|
cab_extractor_cmd.on('error', function (err) {
|
|
console.log(CABEXTRACTOR + 'error', err);
|
|
console.log('check if cabextract is installed');
|
|
process.exit(1);
|
|
});
|
|
|
|
cab_extractor_cmd.on('exit', function (code) {
|
|
if (code != 0) {
|
|
console.log("Failed to extract with code: " + code);
|
|
} else {
|
|
fs.unlink(archive_name);
|
|
console.log("File " + archive_name + " has been uncompressed successfully");
|
|
}
|
|
});
|
|
};
|
|
|
|
var curl_start = function(guid, dbg_fname) {
|
|
var archive_name = dbg_fname;
|
|
var link_end = '';
|
|
var spawn = require('child_process').spawn;
|
|
|
|
archive_name = archive_name.substring(0, archive_name.length - 1) + '_';
|
|
link_end = '/' + dbg_fname + '/' + guid + '/' + archive_name;
|
|
|
|
var stream = fs.createWriteStream(archive_name, {flags:'a'});
|
|
|
|
console.log("downloading file: " + archive_name);
|
|
|
|
var curl_ = new curl(DOWNLOABLE_LINK + link_end, {RAW:0}, function(err) {
|
|
console.info(this);
|
|
return;
|
|
});
|
|
|
|
curl_.setOpt('URL', DOWNLOABLE_LINK + link_end);
|
|
curl_.setOpt('USERAGENT', SYMBOL_SERVER);
|
|
|
|
curl_.on('data', function(chunk) {
|
|
stream.write(chunk);
|
|
return chunk.length;
|
|
});
|
|
|
|
curl_.on('error', function(e) {
|
|
console.log('File: ' + archive_name + 'has not been downloaded successfully');
|
|
curl_.close();
|
|
return;
|
|
});
|
|
|
|
curl_.on('end', function() {
|
|
console.log('File ' + archive_name + 'has been downloaded and saved successfully');
|
|
console.log('Decompress of file: ' + archive_name);
|
|
extract_pdb_file(archive_name, dbg_fname);
|
|
|
|
this.close();
|
|
});
|
|
|
|
curl_.perform();
|
|
};
|
|
|
|
var downloader = function (currentValue, index, array) {
|
|
var curr_guid = '';
|
|
var curr_dbg_fname = '';
|
|
var saved_guid_and_dbg_fname = [];
|
|
var spawn = require('child_process').spawn;
|
|
|
|
rabin2_cmd = spawn(RABIN, ['-I', currentValue]);
|
|
|
|
// skip pdb files
|
|
if (currentValue.indexOf('pdb') != -1) {
|
|
return;
|
|
}
|
|
|
|
rabin2_cmd.stdout.on('error', function (err) {
|
|
console.log('check if rabin is installed');
|
|
process.exit(1);
|
|
});
|
|
|
|
rabin2_cmd.stdout.on('data', function (data) {
|
|
data.toString().split(EOL).map(function (str) {
|
|
var parts = str.split(' ');
|
|
|
|
if (parts[0].indexOf(GUID) != -1) {
|
|
curr_guid = parts.pop(); //parts[0].substring(GUID.length).trim();
|
|
} else if (parts[0].indexOf(DBG_FNAME) != -1) {
|
|
curr_dbg_fname = parts.pop(); //[0].substring(DBG_FNAME.length).trim();
|
|
if (curr_guid != '' && curr_dbg_fname != '') {
|
|
curl_start(curr_guid, curr_dbg_fname);
|
|
} else {
|
|
console.log('there is no guid and debug file information in binary');
|
|
console.log('check version of rabin2 or maybe this is not PE binary');
|
|
process.exit(1);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
IN_FOLDER = process.argv[INPUT_FOLDER_ARG];
|
|
OUT_FOLDER = process.argv[OUTPUT_FOLDER_ARG];
|
|
|
|
// TODO: does not correct work if write like if (IN_FOLDER) {
|
|
if (IN_FOLDER === undefined || IN_FOLDER === null) {
|
|
console.log("set please input folder");
|
|
print_usage();
|
|
process.exit(1);
|
|
}
|
|
|
|
// TODO: does not correct work if write like if (OUT_FOLDER) {
|
|
if (OUT_FOLDER === undefined || OUT_FOLDER === null) {
|
|
OUT_FOLDER = IN_FOLDER;
|
|
}
|
|
|
|
walk(IN_FOLDER, function(err, results) {
|
|
if (err) {
|
|
console.log('Error while walking the directory.Error: ' + err);
|
|
process.exit(1);
|
|
}
|
|
|
|
results.forEach(downloader);
|
|
});
|
|
|