Created
December 7, 2018 08:13
-
-
Save dkw72n/4a66672b5e57f7fcecd3173a2078d7f2 to your computer and use it in GitHub Desktop.
no description
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #coding: utf8 | |
| import sys | |
| import os | |
| from collections import Counter | |
| import argparse | |
| VERBOSE = 1 | |
| STDERR = sys.stderr | |
| def excepthook(*args): | |
| print >> STDERR, 'caught' | |
| print >> STDERR, args | |
| sys.excepthook = excepthook | |
| def readInt16(buf, off): | |
| return buf[off+1] * 0x100 + buf[off] | |
| def readInt32(buf, off): | |
| return buf[off+3] * 0x1000000 + buf[off+2]* 0x10000 + buf[off+1] * 0x100 + buf[off] | |
| def readString(buf, off): | |
| pos = buf[off:].index(0) | |
| return ''.join(map(chr, buf[off: off + pos])) | |
| def ProgramHeaders(elf): | |
| phoff = readInt32(elf, 0x1c) | |
| phnum = readInt16(elf, 0x2c) | |
| #print "phoff", phoff | |
| #print "phnum", phnum | |
| for i in range(phnum): | |
| yield elf[phoff + i * 32: phoff + i * 32 + 32] | |
| def SectionHeaders(elf): | |
| e_shoff = readInt32(elf, 0x20) | |
| e_shentsize = readInt16(elf, 0x2E) | |
| e_shnum = readInt16(elf, 0x30) | |
| if VERBOSE > 1: print "e_shoff", e_shoff, "e_shnum", e_shnum | |
| for i in range(e_shnum): | |
| ret = elf[e_shoff + i * e_shentsize: e_shoff + i * e_shentsize + e_shentsize] | |
| if VERBOSE > 1: print ret | |
| yield ret | |
| def PrintProgramHeaders(): | |
| for ph in ProgramHeaders(elf): | |
| ty = readInt32(ph, 0x00) | |
| offset = readInt32(ph, 0x04) | |
| vaddr = readInt32(ph, 0x08) | |
| filesz = readInt32(ph, 0x10) | |
| memsz = readInt32(ph, 0x14) | |
| flag = readInt32(ph, 0x18) | |
| # print "%6d %08x %d %d %d" % (ty, offset, filesz, memsz, flag & 2) | |
| if VERBOSE > 1: print "from %08x to %08x" % (offset, offset + filesz) | |
| def arg_file(fn): | |
| assert os.path.isfile(fn) | |
| return fn | |
| def main(opts): | |
| with open(opts.input, "rb") as fp: | |
| elf = map(ord, fp.read()) | |
| shs = [] | |
| shstrtab = None | |
| for sh in SectionHeaders(elf): | |
| sh_name = readInt32(sh, 0x0) | |
| sh_type = readInt32(sh, 0x4) | |
| sh_offset = readInt32(sh, 0x10) | |
| sh_size = readInt32(sh, 0x14) | |
| # print sh | |
| if VERBOSE > 1: print "name:", sh_name, "type: %x" % sh_type | |
| shs.append([sh_name, sh_type, sh_offset, sh_size]) | |
| if sh_type == 3 and sh_name == 1: # shstrtab | |
| if VERBOSE > 1: print ''.join(map(chr, elf[sh_offset: sh_offset + sh_size])) | |
| shstrtab = elf[sh_offset: sh_offset + sh_size] | |
| #print shstrtab | |
| for sh in shs: | |
| name = readString(shstrtab, sh[0]) | |
| if name == '.text' or name == '.rodata': | |
| if VERBOSE > 0: print name, "%08x: len=%d" % (sh[2], sh[3]) | |
| c = Counter() | |
| for j in range(sh[2], sh[2] + sh[3]): | |
| c[elf[j]] += 1 | |
| #elf[j] ^= 0xe9 | |
| key = c.most_common(1)[0][0] | |
| if VERBOSE > 0: print "key = 0x%x" % key | |
| for j in range(sh[2], sh[2] + sh[3]): | |
| elf[j] ^= key | |
| if os.path.exists(opts.output) and not opts.force: | |
| print u"已存在, 确认覆盖请输入 Y" | |
| comfirmation = raw_input() | |
| if comfirmation != "Y": | |
| #print "%r" % comfirmation | |
| print "Abort" | |
| return | |
| with open(opts.output, "wb") as fp: | |
| fp.write(''.join(map(chr, elf))) | |
| print "successful" | |
| if __name__ == '__main__': | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument('-i', '--input', type=arg_file, required=True) | |
| parser.add_argument('-o', '--output', default='dump.so') | |
| parser.add_argument('-f', '--force', action='store_true') | |
| opts = parser.parse_args() | |
| main(opts) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment