diff --git a/src/linker.h b/src/linker.h index 755ec232..d29c6d31 100644 --- a/src/linker.h +++ b/src/linker.h @@ -78,31 +78,38 @@ public: ElfLinker(); virtual ~ElfLinker(); - virtual void init(const void *pdata, int plen, unsigned pxtra = 0); + void init(const void *pdata, int plen, unsigned pxtra = 0); // virtual void setLoaderAlignOffset(int phase); - virtual int addLoader(const char *sname); + int addLoader(const char *sname); void addLoader(const char *s, va_list ap); #if (ACC_CC_CLANG || ACC_CC_GNUC) void addLoaderVA(const char *s, ...) __attribute__((__sentinel__)); #else void addLoaderVA(const char *s, ...); #endif - virtual Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align); - virtual int getSection(const char *sname, int *slen = nullptr) const; - virtual int getSectionSize(const char *sname) const; - virtual upx_byte *getLoader(int *llen = nullptr) const; - virtual void defineSymbol(const char *name, upx_uint64_t value); - virtual upx_uint64_t getSymbolOffset(const char *) const; + Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align); + int getSection(const char *sname, int *slen = nullptr) const; + int getSectionSize(const char *sname) const; + upx_byte *getLoader(int *llen = nullptr) const; + void defineSymbol(const char *name, upx_uint64_t value); + upx_uint64_t getSymbolOffset(const char *) const; - virtual void dumpSymbol(const Symbol *, unsigned flags, FILE *fp) const; - virtual void dumpSymbols(unsigned flags = 0, FILE *fp = nullptr) const; + void dumpSymbol(const Symbol *, unsigned flags, FILE *fp) const; + void dumpSymbols(unsigned flags = 0, FILE *fp = nullptr) const; void alignWithByte(unsigned len, unsigned char b); virtual void alignCode(unsigned len) { alignWithByte(len, 0); } virtual void alignData(unsigned len) { alignWithByte(len, 0); } + // provide overloads to pacify GitHub CodeQL + void defineSymbol(const char *name, int value) { defineSymbol(name, upx_uint64_t(value)); } + void defineSymbol(const char *name, unsigned value) { defineSymbol(name, upx_uint64_t(value)); } + void defineSymbol(const char *name, unsigned long value) { + defineSymbol(name, upx_uint64_t(value)); + } + protected: - virtual void relocate(); + void relocate(); virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, const char *type); diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 3bc12678..63f826e9 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -62,6 +62,8 @@ unsigned char PackLinuxElf::o_shstrtab[] = { \ /*offset 20*/ '.','s','h','s','t','r','t','a','b','\0' }; +#define usizeof(x) ((unsigned) sizeof(x)) + static unsigned umin(unsigned a, unsigned b) { @@ -267,14 +269,14 @@ PackLinuxElf32::PackLinuxElf32help1(InputFile *f) } if (0==e_phnum) throwCantUnpack("0==e_phnum"); e_phoff = get_te32(&ehdri.e_phoff); - unsigned const last_Phdr = e_phoff + e_phnum * sizeof(Elf32_Phdr); + unsigned const last_Phdr = e_phoff + e_phnum * usizeof(Elf32_Phdr); if (last_Phdr < e_phoff // wrap-around || e_phoff != sizeof(Elf32_Ehdr) // must be contiguous || (unsigned long)file_size < last_Phdr) { throwCantUnpack("bad e_phoff"); } e_shoff = get_te32(&ehdri.e_shoff); - unsigned const last_Shdr = e_shoff + e_shnum * sizeof(Elf32_Shdr); + unsigned const last_Shdr = e_shoff + e_shnum * usizeof(Elf32_Shdr); if (last_Shdr < e_shoff // wrap-around || (e_shnum && e_shoff < last_Phdr) || (unsigned long)file_size < last_Shdr) { @@ -346,7 +348,7 @@ off_t PackLinuxElf::pack3(OutputFile *fo, Filter &ft) // return length of output fo->write(&zero, t); len += t; // force sz_pack2 (0 mod 8) [see below] - set_te32(&disp, sz_elf_hdrs + sizeof(p_info) + sizeof(l_info) + + set_te32(&disp, sz_elf_hdrs + usizeof(p_info) + usizeof(l_info) + (!!xct_off & !!opt->o_unix.android_shlib)); // |1 iff android shlib fo->write(&disp, sizeof(disp)); // offset(b_info) len += sizeof(disp); @@ -1182,7 +1184,7 @@ PackLinuxElf32::buildLinuxLoader( struct b_info h; memset(&h, 0, sizeof(h)); unsigned fold_hdrlen = 0; cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold; - fold_hdrlen = umax(0x80, sizeof(hf->ehdr) + + fold_hdrlen = umax(0x80, usizeof(hf->ehdr) + get_te16(&hf->ehdr.e_phentsize) * get_te16(&hf->ehdr.e_phnum) + sizeof(l_info) ); h.sz_unc = ((szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen)); @@ -1252,7 +1254,7 @@ PackLinuxElf64::buildLinuxLoader( struct b_info h; memset(&h, 0, sizeof(h)); unsigned fold_hdrlen = 0; cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold; - fold_hdrlen = umax(0x80, sizeof(hf->ehdr) + + fold_hdrlen = umax(0x80, usizeof(hf->ehdr) + get_te16(&hf->ehdr.e_phentsize) * get_te16(&hf->ehdr.e_phnum) + sizeof(l_info) ); h.sz_unc = ((szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen)); diff --git a/src/p_lx_exc.cpp b/src/p_lx_exc.cpp index fa878993..210f00d1 100644 --- a/src/p_lx_exc.cpp +++ b/src/p_lx_exc.cpp @@ -49,6 +49,8 @@ #define DT_STRSZ Elf32_Dyn::DT_STRSZ #endif +#define usizeof(x) ((unsigned) sizeof(x)) + /************************************************************************* // linux/386 (generic "execve" format) @@ -307,8 +309,8 @@ PackLinuxI386::buildLinuxLoader( unsigned fold_hdrlen = 0; if (0 < szfold) { cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold; - fold_hdrlen = sizeof(hf->ehdr) + hf->ehdr.e_phentsize * hf->ehdr.e_phnum + - sizeof(l_info); + fold_hdrlen = usizeof(hf->ehdr) + hf->ehdr.e_phentsize * hf->ehdr.e_phnum + + usizeof(l_info); if (0 == get_le32(fold_hdrlen + fold)) { // inconsistent SIZEOF_HEADERS in *.lds (ld, binutils) fold_hdrlen = umax(0x80, fold_hdrlen); diff --git a/src/p_vmlinx.cpp b/src/p_vmlinx.cpp index 2cb4db4b..b2bb9948 100644 --- a/src/p_vmlinx.cpp +++ b/src/p_vmlinx.cpp @@ -106,8 +106,8 @@ typename T::Shdr const *PackVmlinuxBase::getElfSections() { unsigned const e_shnum = ehdri.e_shnum; if (ehdri.e_shentsize != sizeof(*shdri) - || (unsigned long)file_size < ehdri.e_shoff - || (unsigned long)file_size < ehdri.e_shoff + ehdri.e_shentsize * e_shnum) { + || file_size_u < ehdri.e_shoff + || file_size_u < ehdri.e_shoff + ehdri.e_shentsize * e_shnum) { throwCantPack("bad ElfXX_Shdrs"); } shdri = new Shdr[(unsigned) e_shnum]; @@ -121,10 +121,10 @@ typename T::Shdr const *PackVmlinuxBase::getElfSections() } Shdr const *p = &shdri[e_shstrndx]; if (Shdr::SHT_STRTAB==p->sh_type - && p->sh_offset <= ((unsigned long)file_size - sizeof(*shdri)) - && p->sh_size <= ((unsigned long)file_size - p->sh_offset) - && p->sh_name <= ((unsigned long)file_size - p->sh_offset) - && 10 <= ((unsigned long)file_size - p->sh_name) + && p->sh_offset <= (file_size_u - sizeof(*shdri)) + && p->sh_size <= (file_size_u - p->sh_offset) + && p->sh_name <= (file_size_u - p->sh_offset) + && 10 <= (file_size_u - p->sh_name) // 10 == (1+ strlen(".shstrtab")) ) { if (p->sh_size <= p->sh_name) { diff --git a/src/util/membuffer.h b/src/util/membuffer.h index d509d780..9e516a75 100644 --- a/src/util/membuffer.h +++ b/src/util/membuffer.h @@ -128,4 +128,11 @@ inline T *raw_bytes(const MemBufferBase &a, size_t size_in_bytes) { return a.raw_bytes(size_in_bytes); } +// global operators +// rewrite "n + membuffer" to "membuffer + n" so that this will get checked above +template ::value, U>::type> +typename MemBuffer::pointer operator+(U n, const MemBuffer &mb) { + return mb + n; +} + /* vim:set ts=4 sw=4 et: */