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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| package org.example;
import java.io.*; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap;
public class CustomObjectOutputStream extends ObjectOutputStream {
private static HashMap<Character, int[]> map; static { map = new HashMap<>(); map.put('.', new int[]{0xc0, 0xae}); map.put(';', new int[]{0xc0, 0xbb}); map.put('$', new int[]{0xc0, 0xa4}); map.put('[', new int[]{0xc1, 0x9b}); map.put(']', new int[]{0xc1, 0x9d}); map.put('a', new int[]{0xc1, 0xa1}); map.put('b', new int[]{0xc1, 0xa2}); map.put('c', new int[]{0xc1, 0xa3}); map.put('d', new int[]{0xc1, 0xa4}); map.put('e', new int[]{0xc1, 0xa5}); map.put('f', new int[]{0xc1, 0xa6}); map.put('g', new int[]{0xc1, 0xa7}); map.put('h', new int[]{0xc1, 0xa8}); map.put('i', new int[]{0xc1, 0xa9}); map.put('j', new int[]{0xc1, 0xaa}); map.put('k', new int[]{0xc1, 0xab}); map.put('l', new int[]{0xc1, 0xac}); map.put('m', new int[]{0xc1, 0xad}); map.put('n', new int[]{0xc1, 0xae}); map.put('o', new int[]{0xc1, 0xaf}); map.put('p', new int[]{0xc1, 0xb0}); map.put('q', new int[]{0xc1, 0xb1}); map.put('r', new int[]{0xc1, 0xb2}); map.put('s', new int[]{0xc1, 0xb3}); map.put('t', new int[]{0xc1, 0xb4}); map.put('u', new int[]{0xc1, 0xb5}); map.put('v', new int[]{0xc1, 0xb6}); map.put('w', new int[]{0xc1, 0xb7}); map.put('x', new int[]{0xc1, 0xb8}); map.put('y', new int[]{0xc1, 0xb9}); map.put('z', new int[]{0xc1, 0xba}); map.put('A', new int[]{0xc1, 0x81}); map.put('B', new int[]{0xc1, 0x82}); map.put('C', new int[]{0xc1, 0x83}); map.put('D', new int[]{0xc1, 0x84}); map.put('E', new int[]{0xc1, 0x85}); map.put('F', new int[]{0xc1, 0x86}); map.put('G', new int[]{0xc1, 0x87}); map.put('H', new int[]{0xc1, 0x88}); map.put('I', new int[]{0xc1, 0x89}); map.put('J', new int[]{0xc1, 0x8a}); map.put('K', new int[]{0xc1, 0x8b}); map.put('L', new int[]{0xc1, 0x8c}); map.put('M', new int[]{0xc1, 0x8d}); map.put('N', new int[]{0xc1, 0x8e}); map.put('O', new int[]{0xc1, 0x8f}); map.put('P', new int[]{0xc1, 0x90}); map.put('Q', new int[]{0xc1, 0x91}); map.put('R', new int[]{0xc1, 0x92}); map.put('S', new int[]{0xc1, 0x93}); map.put('T', new int[]{0xc1, 0x94}); map.put('U', new int[]{0xc1, 0x95}); map.put('V', new int[]{0xc1, 0x96}); map.put('W', new int[]{0xc1, 0x97}); map.put('X', new int[]{0xc1, 0x98}); map.put('Y', new int[]{0xc1, 0x99}); map.put('Z', new int[]{0xc1, 0x9a}); } public CustomObjectOutputStream(OutputStream out) throws IOException { super(out); }
@Override protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException { String name = desc.getName();
writeShort(name.length() * 2); for (int i = 0; i < name.length(); i++) { char s = name.charAt(i);
write(map.get(s)[0]); write(map.get(s)[1]); } writeLong(desc.getSerialVersionUID()); try { byte flags = 0; if ((boolean)getFieldValue(desc,"externalizable")) { flags |= ObjectStreamConstants.SC_EXTERNALIZABLE; Field protocolField = ObjectOutputStream.class.getDeclaredField("protocol"); protocolField.setAccessible(true); int protocol = (int) protocolField.get(this); if (protocol != ObjectStreamConstants.PROTOCOL_VERSION_1) { flags |= ObjectStreamConstants.SC_BLOCK_DATA; } } else if ((boolean)getFieldValue(desc,"serializable")){ flags |= ObjectStreamConstants.SC_SERIALIZABLE; } if ((boolean)getFieldValue(desc,"hasWriteObjectData")) { flags |= ObjectStreamConstants.SC_WRITE_METHOD; } if ((boolean)getFieldValue(desc,"isEnum") ) { flags |= ObjectStreamConstants.SC_ENUM; } writeByte(flags); ObjectStreamField[] fields = (ObjectStreamField[]) getFieldValue(desc,"fields"); writeShort(fields.length); for (int i = 0; i < fields.length; i++) { ObjectStreamField f = fields[i]; writeByte(f.getTypeCode()); writeUTF(f.getName()); if (!f.isPrimitive()) { Method writeTypeString = ObjectOutputStream.class.getDeclaredMethod("writeTypeString",String.class); writeTypeString.setAccessible(true); writeTypeString.invoke(this,f.getTypeString());
} } } catch (NoSuchFieldException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } }
public static Object getFieldValue(Object object, String fieldName) throws NoSuchFieldException, IllegalAccessException { Class<?> clazz = object.getClass(); Field field = clazz.getDeclaredField(fieldName); field.setAccessible(true); Object value = field.get(object);
return value; } }
|