You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
256 lines
9.8 KiB
256 lines
9.8 KiB
|
|
#include <fstream> |
|
#include <iostream> |
|
#include <iomanip> |
|
#include <string> |
|
#include <sstream> |
|
#include <algorithm> |
|
#include <cstring> |
|
#include <vector> |
|
#include <bitset> |
|
|
|
#include <lzma.h> |
|
|
|
#include "SetupHeader.hpp" |
|
#include "SetupLoader.hpp" |
|
#include "Utils.hpp" |
|
#include "Output.hpp" |
|
#include "BlockReader.hpp" |
|
#include "LanguageEntry.hpp" |
|
|
|
using std::cout; |
|
using std::string; |
|
using std::endl; |
|
using std::setw; |
|
using std::setfill; |
|
using std::hex; |
|
using std::dec; |
|
|
|
#pragma pack(push,1) |
|
|
|
struct BlockHeader { |
|
u32 storedSize; // Total bytes written, including the CRCs |
|
u8 compressed; // True if data is compressed, False if not |
|
}; |
|
|
|
#pragma pack(pop) |
|
|
|
int main(int argc, char * argv[]) { |
|
|
|
if(argc <= 1) { |
|
std::cout << "usage: innoextract <Inno Setup installer>" << endl; |
|
return 1; |
|
} |
|
|
|
std::ifstream ifs(argv[1], strm::in | strm::binary | strm::ate); |
|
|
|
if(!ifs.is_open()) { |
|
error << "error opening file"; |
|
return 1; |
|
} |
|
|
|
u64 fileSize = ifs.tellg(); |
|
if(!fileSize) { |
|
error << "cannot read file or empty file"; |
|
return 1; |
|
} |
|
|
|
SetupLoader::Offsets offsets; |
|
if(!SetupLoader::getOffsets(ifs, offsets)) { |
|
error << "failed to load setup loader offsets"; |
|
// TODO try offset0 = 0 |
|
return 1; |
|
} |
|
|
|
cout << color::white; |
|
cout << "loaded offsets:" << endl; |
|
cout << "- total size: " << offsets.totalSize << endl; |
|
cout << "- exe: @ " << hex << offsets.exeOffset << dec << " compressed: " << offsets.exeCompressedSize << " uncompressed: " << offsets.exeUncompressedSize << endl; |
|
cout << "- exe checksum: " << hex << setfill('0') << setw(8) << offsets.exeChecksum << dec << " (" << (offsets.exeChecksumMode == ChecksumAdler32 ? "Alder32" : "CRC32") << ')' << endl; |
|
cout << "- messageOffset: " << hex << offsets.messageOffset << dec << endl; |
|
cout << "- offset: 0: " << hex << offsets.offset0 << " 1: " << offsets.messageOffset << dec << endl; |
|
cout << color::reset; |
|
|
|
ifs.seekg(offsets.offset0); |
|
|
|
InnoVersion version; |
|
version.load(ifs); |
|
if(ifs.fail()) { |
|
error << "error reading setup data version!"; |
|
return 1; |
|
} |
|
|
|
cout << "version: " << color::white << version << color::reset << endl; |
|
|
|
std::istream * _is = BlockReader::get(ifs, version); |
|
if(!_is) { |
|
error << "error reading block"; |
|
return 1; |
|
} |
|
std::istream & is = *_is; |
|
|
|
is.exceptions(strm::badbit | strm::failbit); |
|
|
|
/* |
|
std::ofstream ofs("dump.bin", strm::trunc | strm::out | strm::binary); |
|
|
|
do { |
|
char buf[4096]; |
|
size_t in = is.read(buf, ARRAY_SIZE(buf)).gcount(); |
|
cout << in << endl; |
|
ofs.write(buf, in); |
|
} while(!is.eof()); |
|
|
|
if(is.bad()) { |
|
error << "read error"; |
|
} else if(!is.eof()) { |
|
warning << "not eof"; |
|
} |
|
|
|
return 0;*/ |
|
|
|
SetupHeader header; |
|
header.load(is, version); |
|
if(is.fail()) { |
|
error << "error reading setup data header!"; |
|
return 1; |
|
} |
|
|
|
cout << IfNotEmpty("App name", header.appName); |
|
cout << IfNotEmpty("App ver name", header.appVerName); |
|
cout << IfNotEmpty("App id", header.appId); |
|
cout << IfNotEmpty("Copyright", header.appCopyright); |
|
cout << IfNotEmpty("Publisher", header.appPublisher); |
|
cout << IfNotEmpty("Publisher URL", header.appPublisherURL); |
|
cout << IfNotEmpty("Support phone", header.appSupportPhone); |
|
cout << IfNotEmpty("Support URL", header.appSupportURL); |
|
cout << IfNotEmpty("Updates URL", header.appUpdatesURL); |
|
cout << IfNotEmpty("Version", header.appVersion); |
|
cout << IfNotEmpty("Default dir name", header.defaultDirName); |
|
cout << IfNotEmpty("Default group name", header.defaultGroupName); |
|
cout << IfNotEmpty("Uninstall icon name", header.uninstallIconName); |
|
cout << IfNotEmpty("Base filename", header.baseFilename); |
|
cout << IfNotEmpty("Uninstall files dir", header.uninstallFilesDir); |
|
cout << IfNotEmpty("Uninstall display name", header.uninstallDisplayName); |
|
cout << IfNotEmpty("Uninstall display icon", header.uninstallDisplayIcon); |
|
cout << IfNotEmpty("App mutex", header.appMutex); |
|
cout << IfNotEmpty("Default user name", header.defaultUserInfoName); |
|
cout << IfNotEmpty("Default user org", header.defaultUserInfoOrg); |
|
cout << IfNotEmpty("Default user serial", header.defaultUserInfoSerial); |
|
cout << IfNotEmpty("Readme", header.appReadmeFile); |
|
cout << IfNotEmpty("Contact", header.appContact); |
|
cout << IfNotEmpty("Comments", header.appComments); |
|
cout << IfNotEmpty("Modify path", header.appModifyPath); |
|
cout << IfNotEmpty("Uninstall reg key", header.createUninstallRegKey); |
|
cout << IfNotEmpty("Uninstallable", header.uninstallable); |
|
cout << IfNotEmpty("License", header.licenseText); |
|
cout << IfNotEmpty("Info before text", header.infoBeforeText); |
|
cout << IfNotEmpty("Info after text", header.infoAfterText); |
|
cout << IfNotEmpty("Uninstaller signature", header.signedUninstallerSignature); |
|
cout << IfNotEmpty("Compiled code", header.compiledCodeText); |
|
|
|
cout << IfNotZero("Lead bytes", header.leadBytes); |
|
|
|
cout << IfNotZero("Language entries", header.numLanguageEntries); |
|
cout << IfNotZero("Custom message entries", header.numCustomMessageEntries); |
|
cout << IfNotZero("Permission entries", header.numPermissionEntries); |
|
cout << IfNotZero("Type entries", header.numTypeEntries); |
|
cout << IfNotZero("Component entries", header.numComponentEntries); |
|
cout << IfNotZero("Task entries", header.numTaskEntries); |
|
cout << IfNotZero("Dir entries", header.numDirEntries); |
|
cout << IfNotZero("File entries", header.numFileEntries); |
|
cout << IfNotZero("File location entries", header.numFileLocationEntries); |
|
cout << IfNotZero("Icon entries", header.numIconEntries); |
|
cout << IfNotZero("Ini entries", header.numIniEntries); |
|
cout << IfNotZero("Registry entries", header.numRegistryEntries); |
|
cout << IfNotZero("Delete entries", header.numInstallDeleteEntries); |
|
cout << IfNotZero("Uninstall delete entries", header.numUninstallDeleteEntries); |
|
cout << IfNotZero("Run entries", header.numRunEntries); |
|
cout << IfNotZero("Uninstall run entries", header.numUninstallRunEntries); |
|
|
|
cout << IfNotZero("License size", header.licenseSize); |
|
cout << IfNotZero("Info before size", header.infoBeforeSize); |
|
cout << IfNotZero("Info after size", header.infoAfterSize); |
|
|
|
cout << "Min version: " << header.minVersion << endl; |
|
if(header.onlyBelowVersion.winVersion || header.onlyBelowVersion.ntVersion || header.onlyBelowVersion.ntServicePack) { |
|
cout << "Only below version: " << header.onlyBelowVersion << endl; |
|
} |
|
|
|
cout << hex; |
|
cout << IfNotZero("Back color", header.backColor); |
|
cout << IfNotZero("Back color2", header.backColor2); |
|
cout << IfNotZero("Wizard image back color", header.wizardImageBackColor); |
|
cout << IfNotZero("Wizard small image back color", header.wizardSmallImageBackColor); |
|
cout << dec; |
|
|
|
if(header.options & (shPassword|shEncryptionUsed)) { |
|
cout << "Password type: " << color::cyan << header.passwordType << color::reset << endl; |
|
// TODO print password |
|
// TODO print salt |
|
} |
|
|
|
cout << IfNotZero("Extra disk space required", header.extraDiskSpaceRequired); |
|
cout << IfNotZero("Slices per disk", header.slicesPerDisk); |
|
|
|
cout << IfNot("Install mode", header.installMode, SetupHeader::NormalInstallMode); |
|
cout << "Uninstall log mode: " << color::cyan << header.uninstallLogMode << color::reset << endl; |
|
cout << "Uninstall style: " << color::cyan << header.uninstallStyle << color::reset << endl; |
|
cout << "Dir exists warning: " << color::cyan << header.dirExistsWarning << color::reset << endl; |
|
cout << IfNot("Privileges required", header.privilegesRequired, SetupHeader::NoPrivileges); |
|
cout << "Show language dialog: " << color::cyan << header.showLanguageDialog << color::reset << endl; |
|
cout << IfNot("Danguage detection", header.languageDetectionMethod, SetupHeader::NoLanguageDetection); |
|
cout << "Compression: " << color::cyan << header.compressMethod << color::reset << endl; |
|
cout << "Architectures allowed: " << color::cyan << header.architecturesAllowed << color::reset << endl; |
|
cout << "Architectures installed in 64-bit mode: " << color::cyan << header.architecturesInstallIn64BitMode << color::reset << endl; |
|
|
|
if(header.options & shSignedUninstaller) { |
|
cout << IfNotZero("Size before signing uninstaller", header.signedUninstallerOrigSize); |
|
cout << IfNotZero("Uninstaller header checksum", header.signedUninstallerHdrChecksum); |
|
} |
|
|
|
cout << "Disable dir page: " << color::cyan << header.disableDirPage << color::reset << endl; |
|
cout << "Disable program group page: " << color::cyan << header.disableProgramGroupPage << color::reset << endl; |
|
|
|
cout << IfNotZero("Uninstall display size", header.uninstallDisplaySize); |
|
|
|
cout << "Options: " << color::green << header.options << color::reset << endl; |
|
|
|
cout << color::reset; |
|
|
|
if(header.numLanguageEntries) { |
|
cout << "Language entries:" << endl; |
|
} |
|
for(size_t i = 0; i < header.numLanguageEntries; i++) { |
|
|
|
LanguageEntry entry; |
|
entry.load(is, version); |
|
if(is.fail()) { |
|
error << "error reading language entry #" << i; |
|
} |
|
|
|
cout << " - " << Quoted(entry.name) << ':' << endl; |
|
cout << IfNotEmpty(" Language name", entry.languageName); |
|
cout << IfNotEmpty(" Dialog font", entry.dialogFontName); |
|
cout << IfNotEmpty(" Title font", entry.titleFontName); |
|
cout << IfNotEmpty(" Welcome font", entry.welcomeFontName); |
|
cout << IfNotEmpty(" Copyright font", entry.copyrightFontName); |
|
cout << IfNotEmpty(" Data", entry.data); |
|
cout << IfNotEmpty(" License", entry.licenseText); |
|
cout << IfNotEmpty(" Info before text", entry.infoBeforeText); |
|
cout << IfNotEmpty(" Info after text", entry.infoAfterText); |
|
|
|
cout << " Language id: " << hex << entry.languageId << dec << endl; |
|
|
|
cout << IfNotZero(" Codepage", entry.languageCodePage); |
|
cout << IfNotZero(" Dialog font size", entry.dialogFontSize); |
|
cout << IfNotZero(" Dialog font standard height", entry.dialogFontStandardHeight); |
|
cout << IfNotZero(" Title font size", entry.titleFontSize); |
|
cout << IfNotZero(" Welcome font size", entry.welcomeFontSize); |
|
cout << IfNotZero(" Copyright font size", entry.copyrightFontSize); |
|
cout << IfNot(" Right to left", entry.rightToLeft, false); |
|
|
|
}; |
|
|
|
return 0; |
|
}
|
|
|