Skip to content

Instantly share code, notes, and snippets.

@Luavis
Created June 27, 2017 17:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Luavis/3bd701c662eec80a2a6de7b59ee3a779 to your computer and use it in GitHub Desktop.
Save Luavis/3bd701c662eec80a2a6de7b59ee3a779 to your computer and use it in GitHub Desktop.
import binascii
import struct
CONSTANT_UTF8 = 1
CONSTANT_INTEGER = 3
CONSTANT_FLOAT = 4
CONSTANT_LONG = 5
CONSTANT_CLASS = 7
CONSTANT_DOUBLE = 6
CONSTANT_STRING = 8
CONSTANT_FIELDREF = 9
CONSTANT_METHODREF = 10
CONSTANT_INTERFACEMETHODREF = 11
CONSTANT_NAMEANDTYPE = 12
CONSTANT_METHODHANDLE = 15
CONSTANT_METHODTYPE = 16
CONSTANT_INVOKEDYNAMIC = 18
def print_byte(b):
hex = str(binascii.hexlify(b), 'ascii')
print(':'.join(hex[i:i+2] for i in range(0, len(hex), 2)))
def read_short(f):
return struct.unpack('>H', f.read(2))[0]
def read_long(f):
return struct.unpack('>I', f.read(4))[0]
def print_class_acc(acc):
ACC_PUBLIC = 0x0001
ACC_FINAL = 0x0010
ACC_SUPER = 0x0020
ACC_INTERFACE = 0x0200
ACC_ABSTRACT = 0x0400
ACC_SYNTHETIC = 0x1000
ACC_ANNOTATION = 0x2000
ACC_ENUM = 0x4000
if acc & ACC_PUBLIC:
print('PUBLIC', end=' ')
if acc & ACC_FINAL:
print('FINAL', end=' ')
if acc & ACC_SUPER:
print('SUPER', end=' ')
if acc & ACC_INTERFACE:
print('INTERFACE', end=' ')
if acc & ACC_ABSTRACT:
print('ABSTRACT', end=' ')
if acc & ACC_SYNTHETIC:
print('SYNTHETIC', end=' ')
if acc & ACC_ANNOTATION:
print('ANNOTATION', end=' ')
if acc & ACC_ENUM:
print('ENUM', end=' ')
def print_method_acc(acc):
ACC_PUBLIC = 0x0001
ACC_PRIVATE = 0x0002
ACC_PROTECTED = 0x0004
ACC_STATIC = 0x0008
ACC_FINAL = 0x0010
ACC_SYNCHRONIZED = 0x0020
ACC_BRIDGE = 0x0040
ACC_VARARGS = 0x0080
ACC_NATIVE = 0x0100
ACC_ABSTRACT = 0x0400
ACC_STRICT = 0x0800
ACC_SYNTHETIC = 0x1000
if acc & ACC_PUBLIC:
print('PUBLIC', end=' ')
if acc & ACC_PRIVATE:
print('PRIVATE', end=' ')
if acc & ACC_PROTECTED:
print('PROTECTED', end=' ')
if acc & ACC_STATIC:
print('STATIC', end=' ')
if acc & ACC_FINAL:
print('FINAL', end=' ')
if acc & ACC_SYNCHRONIZED:
print('SYNCHRONIZED', end=' ')
if acc & ACC_BRIDGE:
print('BRIDGE', end=' ')
if acc & ACC_VARARGS:
print('VARARGS', end=' ')
if acc & ACC_NATIVE:
print('NATIVE', end=' ')
if acc & ACC_ABSTRACT:
print('ABSTRACT', end=' ')
if acc & ACC_STRICT:
print('STRICT', end=' ')
if acc & ACC_SYNTHETIC:
print('SYNTHETIC', end=' ')
def parse_attr(f):
attr_count = read_short(f)
print('attr count', attr_count)
for j in range(attr_count):
name = constants[read_short(f)]['contents'].decode('utf-8')
print(' name', name)
length = read_long(f)
print(' length', length)
if name == 'Code':
f.read(4) # max_stack + max_locals
code_length = read_long(f)
code = f.read(code_length)
print(' code', end=' ')
print_byte(code)
print(' execption ', read_short(f))
parse_attr(f)
else:
f.read(length)
f = open('Simple.class', 'rb')
magic = f.read(4)
minor_ver = read_short(f)
major_ver = read_short(f)
constant_pool = read_short(f)
constants = [None] * constant_pool
for i in range(1, constant_pool):
t = struct.unpack('>B', f.read(1))[0]
if t == CONSTANT_CLASS:
name = read_short(f)
constants[i] = {
'type': 'class ref',
'name': name,
}
elif t == CONSTANT_UTF8:
size = read_short(f)
constants[i] = {
'type': 'literal',
'contents': f.read(size),
}
elif t == CONSTANT_STRING:
constants[i] = {
'type': 'string',
'value': read_short(f),
}
elif t == CONSTANT_METHODREF:
constants[i] = {
'type': 'method',
'class': read_short(f),
'name_and_type': read_short(f),
}
elif t == CONSTANT_FIELDREF:
constants[i] = {
'type': 'field',
'class': read_short(f),
'name_and_type': read_short(f),
}
elif t == CONSTANT_NAMEANDTYPE:
constants[i] = {
'type': 'name_and_type',
'name': read_short(f),
'_type': read_short(f),
}
else:
print(t)
# [print(i, x) for i, x in enumerate(constants)]
acc = read_short(f)
print_class_acc(acc)
this = read_short(f)
print('Class', constants[constants[this]['name']]['contents'])
extends = read_short(f)
print('Super Class', constants[constants[extends]['name']]['contents'])
print('=====================')
print('interface count', read_short(f))
print('field count', read_short(f))
print('\nMethods: ')
print('--------------------\n')
for i in range(read_short(f)):
print_method_acc(read_short(f))
print(constants[read_short(f)]['contents'])
print(' descriptor', constants[read_short(f)]['contents'])
parse_attr(f)
print('\n')
parse_attr(f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment