26 #include <boost/cstdint.hpp> 27 #include <boost/static_assert.hpp> 28 #include <boost/range/size.hpp> 43 struct setup_loader_version {
52 const setup_loader_version known_setup_loader_versions[] = {
53 { {
'r',
'D',
'l',
'P',
't',
'S',
'0',
'2', 0x87,
'e',
'V',
'x' },
INNO_VERSION(1, 2, 10) },
54 { {
'r',
'D',
'l',
'P',
't',
'S',
'0',
'4', 0x87,
'e',
'V',
'x' },
INNO_VERSION(4, 0, 0) },
55 { {
'r',
'D',
'l',
'P',
't',
'S',
'0',
'5', 0x87,
'e',
'V',
'x' },
INNO_VERSION(4, 0, 3) },
56 { {
'r',
'D',
'l',
'P',
't',
'S',
'0',
'6', 0x87,
'e',
'V',
'x' },
INNO_VERSION(4, 0, 10) },
57 { {
'r',
'D',
'l',
'P',
't',
'S',
'0',
'7', 0x87,
'e',
'V',
'x' },
INNO_VERSION(4, 1, 6) },
58 { {
'r',
'D',
'l',
'P',
't',
'S', 0xcd, 0xe6, 0xd7,
'{', 0x0b,
'*' },
INNO_VERSION(5, 1, 5) },
59 { {
'n',
'S',
'5',
'W',
'7',
'd',
'T', 0x83, 0xaa, 0x1b, 0x0f,
'j' },
INNO_VERSION(5, 1, 5) },
62 const int ResourceNameInstaller = 11111;
64 const boost::uint32_t SetupLoaderHeaderOffset = 0x30;
65 const boost::uint32_t SetupLoaderHeaderMagic = 0x6f6e6e49;
69 bool offsets::load_from_exe_file(std::istream & is) {
71 is.seekg(SetupLoaderHeaderOffset);
73 boost::uint32_t
magic = util::load<boost::uint32_t>(is);
74 if(is.fail() ||
magic != SetupLoaderHeaderMagic) {
79 boost::uint32_t offset_table_offset = util::load<boost::uint32_t>(is);
80 boost::uint32_t not_offset_table_offset = util::load<boost::uint32_t>(is);
81 if(is.fail() || offset_table_offset != ~not_offset_table_offset) {
86 return load_offsets_at(is, offset_table_offset);
89 bool offsets::load_from_exe_resource(std::istream & is) {
97 return load_offsets_at(is, resource.offset);
100 bool offsets::load_offsets_at(std::istream & is, boost::uint32_t pos) {
102 if(is.seekg(pos).fail()) {
108 if(is.read(
magic, std::streamsize(
sizeof(
magic))).fail()) {
114 for(
size_t i = 0; i < size_t(boost::size(known_setup_loader_versions)); i++) {
115 BOOST_STATIC_ASSERT(
sizeof(known_setup_loader_versions[i].
magic) ==
sizeof(
magic));
116 if(!memcmp(
magic, known_setup_loader_versions[i].
magic,
sizeof(
magic))) {
117 version = known_setup_loader_versions[i].version;
123 version = std::numeric_limits<setup::version_constant>::max();
131 boost::uint32_t revision = checksum.
load<boost::uint32_t>(is);
135 }
else if(revision != 1) {
136 log_warning <<
"Unexpected setup loader revision: " << revision;
140 (void)checksum.
load<boost::uint32_t>(is);
174 boost::uint32_t expected = util::load<boost::uint32_t>(is);
179 if(checksum.
finalize() != expected) {
193 if(load_from_exe_file(is)) {
201 if(load_from_exe_resource(is)) {
Output utility functions.
Utility function to load stored data while properly handling encodings and endianness.
boost::uint32_t data_offset
Offset of embedded setup-1.bin data.
boost::uint32_t exe_compressed_size
Size of setup.e32 after compression, in bytes.
boost::uint32_t version_constant
Functions to find resources in Windows executables.
boost::uint32_t exe_offset
Offset of compressed setup.e32 (the actual installer code)
void load(std::istream &is)
Find the setup loader offsets in a file.
detail::print_hex< T > print_hex(T value)
boost::uint32_t exe_uncompressed_size
Size of setup.e32 before compression, in bytes.
boost::uint32_t message_offset
Offset of embedded setup messages.
boost::uint32_t header_offset
Offset of embedded setup-0.bin data (the setup headers)
#define INNO_VERSION(a, b, c)
static resource find_resource(std::istream &is, boost::uint32_t name, boost::uint32_t type=TypeData, boost::uint32_t language=Default)
Find where a resource with a given ID is stored in a NE or PE binary.
boost::uint32_t finalize() const
T load(std::istream &is)
Load the data and process it.
Functions to find Inno Setup data inside an executable.
void update(const char *data, size_t length)
crypto::checksum exe_checksum
Checksum of setup.e32 before compression.
CRC32 checksum calculation.
Inno Setup version number utilities.
setup::version_constant version