-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathclassfile.py
More file actions
59 lines (51 loc) · 2.18 KB
/
classfile.py
File metadata and controls
59 lines (51 loc) · 2.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from typing import List
from attribute import Attribute, AttributeMixin
from base import Object
from const import Constant, CONSTANTS, DoubleInfo, LongInfo
from stream import Stream
class ClassFile(Object, AttributeMixin):
def __init__(self, stream: Stream):
magic = stream.read_u4()
if magic != 0xCAFEBABE:
raise Exception('Wrong magic')
self.minor_version = stream.read_u2()
self.major_version = stream.read_u2()
self.constants: List[Constant] = self.read_constants(stream)
self.access_flags = stream.read_u2()
self.this_class = stream.read_u2()
self.super_class = stream.read_u2()
self.interfaces = [stream.read_u2() for _ in range(stream.read_u2())]
self.fields: List[FieldMethodInfo] = [FieldMethodInfo(self, stream) for _ in range(stream.read_u2())]
self.methods: List[FieldMethodInfo] = [FieldMethodInfo(self, stream) for _ in range(stream.read_u2())]
self.attributes: List[Attribute] = [Attribute.read(self, stream) for _ in range(stream.read_u2())]
print(self.attributes)
# noinspection PyMethodMayBeStatic
def read_constants(self, stream: Stream) -> List[Constant]:
values = [None]
count = stream.read_u2()
i = 0
while i < count - 1:
tag = stream.read_u1()
const = CONSTANTS[tag](stream)
values.append(const)
if isinstance(const, (LongInfo, DoubleInfo)):
i += 1
values.append(None)
i += 1
return values
class FieldMethodInfo(Object, AttributeMixin):
def __init__(self, class_file: ClassFile, stream: Stream):
self.access_flags = stream.read_u2()
self.name_index = stream.read_u2()
self.descriptor_index = stream.read_u2()
self.attributes: List[Attribute] = [Attribute.read(class_file, stream) for _ in range(stream.read_u2())]
print(class_file.constants[self.name_index], self.attributes)
class AccessFlag(object):
ACC_PUBLIC = 0x0001
ACC_FINAL = 0x0010
ACC_SUPER = 0x0020
ACC_INTERFACE = 0x0200
ACC_ABSTRACT = 0x0400
ACC_SYNTHETIC = 0x1000
ACC_ANNOTATION = 0x2000
ACC_ENUM = 0x4000