Skip to content

Instantly share code, notes, and snippets.

@betamaoIS
Last active December 27, 2021 07:32
Show Gist options
  • Save betamaoIS/19611c110b9f1133ba04c28128d312a2 to your computer and use it in GitHub Desktop.
Save betamaoIS/19611c110b9f1133ba04c28128d312a2 to your computer and use it in GitHub Desktop.
import os.path
from zipfile import ZipFile
from struct import unpack
from os import walk
CONSTANT_POOL_COUNT_INDEX = 8
CONSTANT_Utf8_info = 1
CONSTANT_Methodref_info = 0x0A
CONSTANT_ITEM_SIZE = 0x13
CONSTANT_ITEM_LENGTH = (0, 0, 0, 5, 5, 9, 9, 3, 3, 5, 5, 5, 5, 0, 0, 4, 3, 0, 5)
def bytes2int(data: bytes, start: int, size: int) -> int:
if size == 2:
return unpack('>H', data[start:start + 2])[0]
elif size == 1:
return data[start]
def decode(class_data: bytes) -> bytes:
new_class_data = bytearray(class_data)
constant_pool_size = bytes2int(class_data, CONSTANT_POOL_COUNT_INDEX, 2)
cur = CONSTANT_POOL_COUNT_INDEX + 2
for i in range(0, constant_pool_size):
constant_type = bytes2int(class_data, cur, 1)
cur += 1
if constant_type == CONSTANT_Utf8_info:
cur += bytes2int(class_data, cur, 2) + 2
elif constant_type == CONSTANT_Methodref_info:
for idx in range(cur, cur + 4):
new_class_data[idx] = 0xff & (new_class_data[idx] + 1)
cur += 4
elif constant_type > CONSTANT_ITEM_SIZE:
print('???? ERROR ???')
break
else:
cur += CONSTANT_ITEM_LENGTH[constant_type] - 1
return bytes(new_class_data)
def decode_file(path: str):
try:
with open(path, 'rb+') as f:
class_data = f.read()
new_class_data = decode(class_data)
f.seek(0)
f.write(new_class_data)
f.truncate()
except Exception as e:
print(f'{path}: {e}')
def need_decode(name: str) -> bool:
if not name.endswith('.class'):
return False
if name.startswith(('com/leagsoft/emm/', 'com/leagsoft/sdp/')):
if '$$FastClassBySpringCGLIB$$' not in name and '$$EnhancerBySpringCGLIB$$' not in name:
return True
elif name in ('org/springframework/core/type/classreading/SimpleMetadataReader',
'org/springframework/core/LocalVariableTableParameterNameDiscoverer'):
return True
return False
def decode_all_class(classes_path: str):
for root, _, files in walk(classes_path):
for fn in files:
path = os.path.join(root, fn)
name = path[len(classes_path) + 1:]
name = name.replace('\\', '/')
if not need_decode(name):
continue
decode_file(path)
def decode_jar(jar_path: str):
jar = ZipFile(jar_path, 'a')
for filename in jar.namelist():
if not need_decode(filename):
continue
class_data = jar.read(filename)
new_class_data = decode(class_data)
jar.writestr(filename, new_class_data)
def decode_all_lib(lib_path: str):
for root, _, files in walk(lib_path):
for fn in files:
path = os.path.join(root, fn)
try:
decode_jar(path)
except Exception as err:
print(err)
def main():
webapp_path = r'D:\leagsoft\LeagView\tomcat-service\webapps\emm-api'
classes_path = os.path.join(webapp_path, r'WEB-INF\lib')
decode_all_lib(classes_path)
lib_path = os.path.join(webapp_path, r'WEB-INF\classes')
decode_all_class(lib_path)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment