Last active
December 27, 2021 07:32
-
-
Save betamaoIS/19611c110b9f1133ba04c28128d312a2 to your computer and use it in GitHub Desktop.
This file contains 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
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