diff --git a/src/p_exe.cpp b/src/p_exe.cpp index 21549482..906e6f0a 100644 --- a/src/p_exe.cpp +++ b/src/p_exe.cpp @@ -453,7 +453,8 @@ void PackExe::pack(OutputFile *fo) } putPackHeader(loader,lsize); - upx_bytep p = find_le32(loader,lsize,get_le32("IPCS")); +// upx_bytep p = find_le32(loader,lsize,get_le32("IPCS")); + upx_bytep p = NULL; if (p == NULL) throwBadLoader(); if (flag & USEJUMP) diff --git a/src/p_sys.cpp b/src/p_sys.cpp index 75e4bcf6..aed7d9f2 100644 --- a/src/p_sys.cpp +++ b/src/p_sys.cpp @@ -89,8 +89,7 @@ void PackSys::patchLoader(OutputFile *fo, patch_le16(loader,lsize,"CT",calls); } - unsigned jmp_pos; - jmp_pos = find_le16(loader,e_len,get_le16("JM")) - loader; + const unsigned jmp_pos = find_le16(loader,e_len,get_le16("JM")); patch_le16(loader,e_len,"JM",ph.u_len+overlapoh+2-jmp_pos-2); loader[getLoaderSection("SYSSUBSI") - 1] = (upx_byte) -e_len; patch_le16(loader,e_len,"DI",copy_to); diff --git a/src/p_tmt.cpp b/src/p_tmt.cpp index abceab32..73e20139 100644 --- a/src/p_tmt.cpp +++ b/src/p_tmt.cpp @@ -232,7 +232,7 @@ void PackTmt::pack(OutputFile *fo) patch_le32(loader,lsize,"TEXL",(ft.id & 0xf) % 3 == 0 ? ft.calls : ft.lastcall - ft.calls * 4); } - const unsigned jmp_pos = find_le32(loader,e_len,get_le32("JMPD")) - loader; + const unsigned jmp_pos = find_le32(loader,e_len,get_le32("JMPD")); patch_le32(loader,e_len,"JMPD",ph.u_len+overlapoh-jmp_pos-4); patch_le32(loader,e_len,"ECX0",ph.c_len+d_len); diff --git a/src/p_tos.cpp b/src/p_tos.cpp index fb9a668a..5fa08f07 100644 --- a/src/p_tos.cpp +++ b/src/p_tos.cpp @@ -180,20 +180,21 @@ bool PackTos::checkFileHeader() // **************************************************************************/ -unsigned PackTos::patch_d0_subq(void *l, int llen, unsigned d0, +unsigned PackTos::patch_d0_subq(void *b, int blen, unsigned d0, const char *subq_marker) { // patch a "subq.l #1,d0" or "subq.w #1,d0". // also convert into "dbra" if possible - upx_byte *p; - assert((int)d0 > 0); - p = find_be16(l, llen, get_be16(subq_marker)); + int boff = find_be16(b, blen, get_be16(subq_marker)); + if (boff < 0) + throwBadLoader(); + unsigned char *p = (unsigned char *)b + boff; if (p[2] == 0x66) // bne.b XXX - checkPatch(l, p, 4); + checkPatch(b, blen, boff, 4); else - checkPatch(l, p, 2); + checkPatch(b, blen, boff, 2); if (d0 > 65536) { @@ -220,17 +221,18 @@ unsigned PackTos::patch_d0_subq(void *l, int llen, unsigned d0, } -unsigned PackTos::patch_d0_loop(void *l, int llen, unsigned d0, +unsigned PackTos::patch_d0_loop(void *b, int blen, unsigned d0, const char *d0_marker, const char *subq_marker) { - upx_byte *p; + d0 = patch_d0_subq(b, blen, d0, subq_marker); - d0 = patch_d0_subq(l, llen, d0, subq_marker); + int boff = find_be32(b, blen, get_be32(d0_marker)); + checkPatch(b, blen, boff, 4); - p = find_be32(l, llen, get_be32(d0_marker)); + unsigned char *p = (unsigned char *)b + boff; assert(get_be16(p - 2) == 0x203c); // move.l #XXXXXXXX,d0 - checkPatch(l, p, 4); set_be32(p, d0); + return d0; } diff --git a/src/p_tos.h b/src/p_tos.h index 5bbfc922..f58785ad 100644 --- a/src/p_tos.h +++ b/src/p_tos.h @@ -73,8 +73,8 @@ protected: } ih, oh; protected: - unsigned patch_d0_subq(void *l, int llen, unsigned, const char*); - unsigned patch_d0_loop(void *l, int llen, unsigned, const char*, const char*); + unsigned patch_d0_subq(void *b, int blen, unsigned, const char*); + unsigned patch_d0_loop(void *b, int blen, unsigned, const char*, const char*); }; diff --git a/src/p_w32pe.cpp b/src/p_w32pe.cpp index 6d4e12f9..7353b233 100644 --- a/src/p_w32pe.cpp +++ b/src/p_w32pe.cpp @@ -1708,8 +1708,7 @@ void PackW32Pe::pack(OutputFile *fo) // patch loader if (ih.entry) { - unsigned jmp_pos; - jmp_pos = ptr_diff(find_le32(loader,codesize + 4,get_le32("JMPO")),loader); + unsigned jmp_pos = find_le32(loader,codesize + 4,get_le32("JMPO")); patch_le32(loader,codesize + 4,"JMPO",ih.entry - upxsection - jmp_pos - 4); } if (big_relocs & 6) @@ -1957,8 +1956,8 @@ int PackW32Pe::canUnpack() static const char magic[] = "\x8b\x1e\x83\xee\xfc\x11\xdb"; // mov ebx, [esi]; sub esi, -4; adc ebx,ebx - unsigned char *p = find(buf, sizeof(buf), magic, 7); - if (p && find(p + 1, buf - p + sizeof(buf) - 1, magic, 7)) + int offset = find(buf, sizeof(buf), magic, 7); + if (offset >= 0 && find(buf + offset + 1, sizeof(buf) - offset - 1, magic, 7) >= 0) x = true; } catch (...) { //x = true; diff --git a/src/p_wcle.cpp b/src/p_wcle.cpp index 607c4937..6c914c8f 100644 --- a/src/p_wcle.cpp +++ b/src/p_wcle.cpp @@ -526,7 +526,7 @@ void PackWcle::pack(OutputFile *fo) } patch_le32(p,d_len,"RELO",mps*pages); - unsigned jpos = find_le32(oimage,e_len,get_le32("JMPD")) - oimage; + unsigned jpos = find_le32(oimage,e_len,get_le32("JMPD")); patch_le32(oimage,e_len,"JMPD",ic-jpos-4); jpos = (((ph.c_len+3)&~3) + d_len+3)/4; diff --git a/src/packer.cpp b/src/packer.cpp index 7cef9152..8f3ea479 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -630,113 +630,138 @@ bool Packer::readPackHeader(unsigned len, off_t seek_offset, upx_byte *buf) // patch util for loader **************************************************************************/ -void Packer::checkPatch(void *l, void *p, int size) +void Packer::checkPatch(void *b, int blen, int boff, int size) { - if (l == NULL && p == NULL && size == 0) + if (b == NULL && blen == 0 && boff == 0 && size == 0) { // reset last_patch = NULL; last_patch_offset = 0; return; } - if (l == NULL || p == NULL || p < l || size <= 0) + if (b == NULL || blen <= 0 || boff < 0 || size <= 0) throwBadLoader(); - ptrdiff_t offset = (upx_bytep) p - (upx_bytep) l; - //printf("checkPatch: %p %5ld %d\n", l, offset, size); - if (l == last_patch) + if (boff + size < 0 || boff + size > blen) + throwBadLoader(); + //printf("checkPatch: %p %5d %5d %d\n", b, blen, boff, size); + if (b == last_patch) { - if (offset + size > last_patch_offset) + if (boff + size > last_patch_offset) throwInternalError("invalid patch order"); } else - last_patch = l; - last_patch_offset = offset; + last_patch = b; + last_patch_offset = boff; } -unsigned Packer::patch_be16(void *l, int llen, unsigned old, unsigned new_) +int Packer::patch_be16(void *b, int blen, unsigned old, unsigned new_) { - void *p = find_be16(l,llen,old); - checkPatch(l,p,2); + int boff = find_be16(b,blen,old); + checkPatch(b, blen, boff, 2); + + unsigned char *p = (unsigned char *)b + boff; set_be16(p,new_); - return (unsigned) last_patch_offset; + + return boff; } -unsigned Packer::patch_be16(void *l, int llen, const void * old, unsigned new_) +int Packer::patch_be16(void *b, int blen, const void *old, unsigned new_) { - void *p = find(l,llen,old,2); - checkPatch(l,p,2); + int boff = find(b,blen,old,2); + checkPatch(b, blen, boff, 2); + + unsigned char *p = (unsigned char *)b + boff; set_be16(p,new_); - return (unsigned) last_patch_offset; + + return boff; } -unsigned Packer::patch_be32(void *l, int llen, unsigned old, unsigned new_) +int Packer::patch_be32(void *b, int blen, unsigned old, unsigned new_) { - void *p = find_be32(l,llen,old); - checkPatch(l,p,4); + int boff = find_be32(b,blen,old); + checkPatch(b, blen, boff, 4); + + unsigned char *p = (unsigned char *)b + boff; set_be32(p,new_); - return (unsigned) last_patch_offset; + + return boff; } -unsigned Packer::patch_be32(void *l, int llen, const void * old, unsigned new_) +int Packer::patch_be32(void *b, int blen, const void *old, unsigned new_) { - void *p = find(l,llen,old,4); - checkPatch(l,p,4); + int boff = find(b,blen,old,4); + checkPatch(b, blen, boff, 4); + + unsigned char *p = (unsigned char *)b + boff; set_be32(p,new_); - return (unsigned) last_patch_offset; + + return boff; } -unsigned Packer::patch_le16(void *l, int llen, unsigned old, unsigned new_) +int Packer::patch_le16(void *b, int blen, unsigned old, unsigned new_) { - void *p = find_le16(l,llen,old); - checkPatch(l,p,2); + int boff = find_le16(b,blen,old); + checkPatch(b, blen, boff, 2); + + unsigned char *p = (unsigned char *)b + boff; set_le16(p,new_); - return (unsigned) last_patch_offset; + + return boff; } -unsigned Packer::patch_le16(void *l, int llen, const void * old, unsigned new_) +int Packer::patch_le16(void *b, int blen, const void *old, unsigned new_) { - void *p = find(l,llen,old,2); - checkPatch(l,p,2); + int boff = find(b,blen,old,2); + checkPatch(b, blen, boff, 2); + + unsigned char *p = (unsigned char *)b + boff; set_le16(p,new_); - return (unsigned) last_patch_offset; + + return boff; } -unsigned Packer::patch_le32(void *l, int llen, unsigned old, unsigned new_) +int Packer::patch_le32(void *b, int blen, unsigned old, unsigned new_) { - void *p = find_le32(l,llen,old); - checkPatch(l,p,4); + int boff = find_le32(b,blen,old); + checkPatch(b, blen, boff, 2); + + unsigned char *p = (unsigned char *)b + boff; set_le32(p,new_); - return (unsigned) last_patch_offset; + + return boff; } -unsigned Packer::patch_le32(void *l, int llen, const void * old, unsigned new_) +int Packer::patch_le32(void *b, int blen, const void *old, unsigned new_) { - void *p = find(l,llen,old,4); - checkPatch(l,p,4); + int boff = find(b,blen,old,4); + checkPatch(b, blen, boff, 2); + + unsigned char *p = (unsigned char *)b + boff; set_le32(p,new_); - return (unsigned) last_patch_offset; + + return boff; } // patch version into stub/ident_n.ash -unsigned Packer::patchVersion(void *l, int llen) +int Packer::patchVersion(void *b, int blen) { - upx_byte *p = find(l,llen,"$Id: UPX UPXV ",14); - checkPatch(l,p,14); - unsigned char buf[4+1]; - memset(buf, ' ', 4); - size_t len = UPX_MIN(strlen(UPX_VERSION_STRING), 4); - memcpy(buf, UPX_VERSION_STRING, len); - memcpy(p + 9, buf, 4); - return (unsigned) last_patch_offset; + int boff = find(b,blen,"$Id: UPX UPXV ",14); + checkPatch(b, blen, boff, 14); + + unsigned char *p = (unsigned char *)b + boff + 9; + memset(p, ' ', 4); + memcpy(p, UPX_VERSION_STRING, UPX_MIN(strlen(UPX_VERSION_STRING), 4)); + + return boff; } diff --git a/src/packer.h b/src/packer.h index 833bb731..651c5701 100644 --- a/src/packer.h +++ b/src/packer.h @@ -207,16 +207,16 @@ protected: virtual unsigned getRandomId() const; // patch util - unsigned patch_be16(void *l, int llen, unsigned old, unsigned new_); - unsigned patch_be16(void *l, int llen, const void * old, unsigned new_); - unsigned patch_be32(void *l, int llen, unsigned old, unsigned new_); - unsigned patch_be32(void *l, int llen, const void * old, unsigned new_); - unsigned patch_le16(void *l, int llen, unsigned old, unsigned new_); - unsigned patch_le16(void *l, int llen, const void * old, unsigned new_); - unsigned patch_le32(void *l, int llen, unsigned old, unsigned new_); - unsigned patch_le32(void *l, int llen, const void * old, unsigned new_); - unsigned patchVersion(void *l, int llen); - void checkPatch(void *l, void *p, int size); + int patch_be16(void *b, int blen, unsigned old, unsigned new_); + int patch_be16(void *b, int blen, const void * old, unsigned new_); + int patch_be32(void *b, int blen, unsigned old, unsigned new_); + int patch_be32(void *b, int blen, const void * old, unsigned new_); + int patch_le16(void *b, int blen, unsigned old, unsigned new_); + int patch_le16(void *b, int blen, const void * old, unsigned new_); + int patch_le32(void *b, int blen, unsigned old, unsigned new_); + int patch_le32(void *b, int blen, const void * old, unsigned new_); + int patchVersion(void *b, int blen); + void checkPatch(void *b, int blen, int boff, int size); protected: // relocation util @@ -240,13 +240,14 @@ protected: int ui_pass; int ui_total_passes; +private: // linker Linker *linker; private: // private to checkPatch() void *last_patch; - ptrdiff_t last_patch_offset; + int last_patch_offset; private: // disable copy and assignment diff --git a/src/packhead.cpp b/src/packhead.cpp index e2d9008d..af4f614e 100644 --- a/src/packhead.cpp +++ b/src/packhead.cpp @@ -101,9 +101,10 @@ void PackHeader::putPackHeader(upx_bytep buf, unsigned len) #if defined(UNUPX) throwBadLoader(); #else - upx_bytep l = find_le32(buf,len,magic); - if (l == 0) + int offset = find_le32(buf,len,magic); + if (offset < 0) throwBadLoader(); + upx_bytep l = buf + offset; l[4] = (unsigned char) version; l[5] = (unsigned char) format; @@ -163,14 +164,16 @@ void PackHeader::putPackHeader(upx_bytep buf, unsigned len) bool PackHeader::fillPackHeader(upx_bytep buf, unsigned len) { - upx_bytep l = find_le32(buf,len,magic); - if (l == 0) + int offset = find_le32(buf,len,magic); + if (offset < 0) return false; - buf_offset = l - buf; - const int hlen = len - buf_offset; + const int hlen = len - offset; if (hlen < 8) return false; + upx_bytep l = buf + offset; + buf_offset = offset; + version = l[4]; format = l[5]; method = l[6]; diff --git a/src/util.cpp b/src/util.cpp index abe33f1e..a45bdbdd 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -31,7 +31,7 @@ /************************************************************************* -// +// qsort() util **************************************************************************/ int be16_compare(const void *e1, const void *e2) @@ -64,24 +64,27 @@ int le32_compare(const void *e1, const void *e2) /************************************************************************* -// +// find util **************************************************************************/ -upx_bytep find(const void *b, int blen, const void *what, int wlen) +int find(const void *b, int blen, const void *what, int wlen) { + if (b == NULL || what == NULL || wlen <= 0) + return -1; + int i; - const upx_bytep base = (const upx_bytep) b; - unsigned char firstc = * (const upx_bytep) what; + const unsigned char *base = (const unsigned char *) b; + unsigned char firstc = * (const unsigned char *) what; for (i = 0; i <= blen - wlen; i++, base++) if (*base == firstc && memcmp(base,what,wlen) == 0) - return const_cast(base); + return i; - return NULL; + return -1; } -upx_bytep find_be16(const void *b, int blen, unsigned what) +int find_be16(const void *b, int blen, unsigned what) { unsigned char w[2]; set_be16(w,what); @@ -89,7 +92,7 @@ upx_bytep find_be16(const void *b, int blen, unsigned what) } -upx_bytep find_be32(const void *b, int blen, unsigned what) +int find_be32(const void *b, int blen, unsigned what) { unsigned char w[4]; set_be32(w,what); @@ -97,7 +100,7 @@ upx_bytep find_be32(const void *b, int blen, unsigned what) } -upx_bytep find_le16(const void *b, int blen, unsigned what) +int find_le16(const void *b, int blen, unsigned what) { unsigned char w[2]; set_le16(w,what); @@ -105,7 +108,7 @@ upx_bytep find_le16(const void *b, int blen, unsigned what) } -upx_bytep find_le32(const void *b, int blen, unsigned what) +int find_le32(const void *b, int blen, unsigned what) { unsigned char w[4]; set_le32(w,what); @@ -330,7 +333,7 @@ bool file_exists(const char *name) struct stat st; /* return true if we can open it */ - fd = open(name,O_RDONLY); + fd = open(name, O_RDONLY); if (fd >= 0) { (void) close(fd); @@ -338,15 +341,19 @@ bool file_exists(const char *name) } /* return true if we can stat it */ - memset(&st, 0, sizeof(st)); -#if defined(HAVE_LSTAT) - r = lstat(name,&st); -#else - r = stat(name,&st); -#endif + //memset(&st, 0, sizeof(st)); + r = stat(name, &st); if (r != -1) return true; + /* return true if we can lstat it */ +#if defined(HAVE_LSTAT) + //memset(&st, 0, sizeof(st)); + r = lstat(name, &st); + if (r != -1) + return true; +#endif + return false; } @@ -375,6 +382,8 @@ bool maketempname(char *ofilename, const char *ifilename, if (!file_exists(ofilename)) return true; } + + ofilename[0] = 0; return false; } @@ -408,6 +417,8 @@ bool makebakname(char *ofilename, const char *ifilename, bool force) if (!file_exists(ofilename)) return true; } + + ofilename[0] = 0; return false; } diff --git a/src/util.h b/src/util.h index 63ecbe74..ee214f06 100644 --- a/src/util.h +++ b/src/util.h @@ -53,11 +53,11 @@ unsigned get_ratio(unsigned long packedsize, unsigned long size, char *center_string(const char *name, size_t s); -unsigned char *find(const void *b, int blen, const void *what, int wlen); -unsigned char *find_be16(const void *b, int blen, unsigned what); -unsigned char *find_be32(const void *b, int blen, unsigned what); -unsigned char *find_le16(const void *b, int blen, unsigned what); -unsigned char *find_le32(const void *b, int blen, unsigned what); +int find(const void *b, int blen, const void *what, int wlen); +int find_be16(const void *b, int blen, unsigned what); +int find_be32(const void *b, int blen, unsigned what); +int find_le16(const void *b, int blen, unsigned what); +int find_le32(const void *b, int blen, unsigned what); inline ptrdiff_t ptr_diff(const void *p1, const void *p2)