mirror of
https://github.com/upx/upx
synced 2025-10-05 19:20:23 +08:00
Enhanced bin2h.py: added --ident=auto, added --compress=XXX.
This commit is contained in:
parent
cf704257b0
commit
62d8c69774
|
@ -28,10 +28,11 @@
|
|||
#
|
||||
|
||||
|
||||
import getopt, os, re, sys, zlib
|
||||
import getopt, os, re, struct, sys, zlib
|
||||
|
||||
|
||||
class opts:
|
||||
compress = None
|
||||
dry_run = 0
|
||||
ident = None
|
||||
mode = "c"
|
||||
|
@ -144,17 +145,32 @@ def w_data_nasm(w, data):
|
|||
w_eol(w, i)
|
||||
|
||||
|
||||
def encode_compressed_stub_header(method, idata, odata):
|
||||
assert 0 < method <= 255
|
||||
if len(idata) <= 65535:
|
||||
h = "UPX#" + struct.pack("<BHH", method, len(idata), len(odata))
|
||||
assert len(h) == 9
|
||||
else:
|
||||
h = "UPX#" + "\x00" + struct.pack("<BII", method, len(idata), len(odata))
|
||||
assert len(h) == 14
|
||||
assert len(h) + len(odata) < len(idata), "compression failed"
|
||||
return h
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // main
|
||||
# ************************************************************************/
|
||||
|
||||
def main(argv):
|
||||
shortopts, longopts = "qv", ["dry-run", "ident=", "mode=", "quiet", "verbose"]
|
||||
shortopts, longopts = "qv", [
|
||||
"compress=", "dry-run", "ident=", "mode=", "quiet", "verbose"
|
||||
]
|
||||
xopts, args = getopt.gnu_getopt(argv[1:], shortopts, longopts)
|
||||
for opt, optarg in xopts:
|
||||
if 0: pass
|
||||
elif opt in ["-q", "--quiet"]: opts.verbose = opts.verbose - 1
|
||||
elif opt in ["-v", "--verbose"]: opts.verbose = opts.verbose + 1
|
||||
elif opt in ["--compress"]: opts.compress = optarg
|
||||
elif opt in ["--dry-run"]: opts.dry_run = opts.dry_run + 1
|
||||
elif opt in ["--ident"]: opts.ident = optarg
|
||||
elif opt in ["--mode"]: opts.mode = optarg.lower()
|
||||
|
@ -169,38 +185,81 @@ def main(argv):
|
|||
if 1 and st.st_size <= 0:
|
||||
print >> sys.stderr, "%s: ERROR: emtpy file" % (ifile)
|
||||
sys.exit(1)
|
||||
if 1 and st.st_size > 64*1024:
|
||||
if 1 and st.st_size > 128*1024:
|
||||
print >> sys.stderr, "%s: ERROR: file is too big (%d bytes)" % (ifile, st.st_size)
|
||||
sys.exit(1)
|
||||
|
||||
# read ifile
|
||||
fp = open(ifile, "rb")
|
||||
data = fp.read()
|
||||
fp.close()
|
||||
assert len(data) == st.st_size
|
||||
ifp = open(ifile, "rb")
|
||||
idata = ifp.read()
|
||||
ifp.close()
|
||||
assert len(idata) == st.st_size
|
||||
|
||||
# compress
|
||||
if opts.compress in [None, "none"]:
|
||||
odata = idata
|
||||
elif opts.compress in ["zlib"]:
|
||||
# zlib with header and adler32 checksum
|
||||
odata = zlib.compress(idata, 9)
|
||||
assert zlib.decompress(odata) == idata
|
||||
elif opts.compress in ["upx-stub-deflate"]:
|
||||
odata = zlib.compress(idata, 9)
|
||||
# strip zlib-header and zlib-trailer (adler32)
|
||||
odata = odata[2:] + odata[-4:]
|
||||
assert zlib.decompress(odata, -15) == idata
|
||||
# encode upx stub header
|
||||
M_DEFLATE = 15
|
||||
odata = encode_compressed_stub_header(M_DEFLATE, idata, odata) + odata
|
||||
else:
|
||||
raise Exception, ("invalid --compress=", opts.compress)
|
||||
assert len(odata) <= len(idata), "compression failed"
|
||||
|
||||
# ident
|
||||
if opts.ident in ["auto", "auto-stub"]:
|
||||
s = os.path.basename(ifile)
|
||||
s = re.sub(r"\.(bin|out)$", "", s)
|
||||
s = re.sub(r"[-.]", "_", s)
|
||||
if opts.ident in ["auto-stub"]:
|
||||
s = "stub_" + s
|
||||
opts.ident = s
|
||||
if opts.ident:
|
||||
assert re.search(r"^[a-zA-Z]", opts.ident), opts.ident
|
||||
assert not re.search(r"[^a-zA-Z0-9_]", opts.ident), opts.ident
|
||||
|
||||
# write ofile
|
||||
fp = open(ofile, "wb")
|
||||
w = fp.write
|
||||
if opts.dry_run:
|
||||
ofp = None
|
||||
def dummy_write(s): pass
|
||||
w = dummy_write
|
||||
else:
|
||||
if ofile == "-":
|
||||
ofp = sys.stdout
|
||||
else:
|
||||
ofp = open(ofile, "wb")
|
||||
w = ofp.write
|
||||
if opts.verbose >= 0:
|
||||
if opts.mode == "c":
|
||||
w_header_c(w, ifile, ofile, len(data))
|
||||
w_header_c(w, ifile, ofile, len(idata))
|
||||
if opts.ident:
|
||||
if opts.mode == "c":
|
||||
w_checksum_c(w, opts.ident.upper(), data)
|
||||
w("unsigned char %s[%d] = {\n" % (opts.ident, len(data)))
|
||||
w_checksum_c(w, opts.ident.upper(), odata)
|
||||
w("unsigned char %s[%d] = {\n" % (opts.ident, len(odata)))
|
||||
if opts.mode == "c":
|
||||
w_data_c(w, data)
|
||||
w_data_c(w, odata)
|
||||
elif opts.mode == "gas":
|
||||
w_data_gas(w, data)
|
||||
w_data_gas(w, odata)
|
||||
elif opts.mode == "nasm":
|
||||
w_data_nasm(w, data)
|
||||
w_data_nasm(w, odata)
|
||||
else:
|
||||
assert 0, opts.mode
|
||||
if opts.ident:
|
||||
if opts.mode == "c":
|
||||
w("};\n")
|
||||
fp.close()
|
||||
if ofp:
|
||||
if ofp is sys.stdout:
|
||||
ofp.flush()
|
||||
else:
|
||||
ofp.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
Loading…
Reference in New Issue
Block a user