Created
October 24, 2025 13:48
-
-
Save hbouhadji/99735b386b29e8dc57a9b506f84d5453 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 java.io.ByteArrayInputStream; | |
| import java.io.ObjectInputStream; | |
| import java.nio.charset.StandardCharsets; | |
| import java.nio.file.Files; | |
| import java.nio.file.Path; | |
| import java.nio.file.Paths; | |
| import java.util.Arrays; | |
| import java.util.Base64; | |
| import java.util.Map; | |
| public class DecryptLoginInfo { | |
| private static final byte[][] DECRYPTION_MATRIX = { | |
| new byte[] { 1, 4, (byte)-1, (byte)-31, (byte)-9, 20, (byte)-1, 6 }, | |
| new byte[] { 0, (byte)-2, 0, (byte)-7, 2, 4, (byte)-1, 1 }, | |
| new byte[] { 0, (byte)-6, 1, (byte)-8, 2, 5, (byte)-3, 4 }, | |
| new byte[] { 0, (byte)-11, 2, (byte)-32, (byte)-1, 20, (byte)-6, 12 }, | |
| new byte[] { 0, 5, (byte)-1, 19, 1, (byte)-12, 3, (byte)-6 }, | |
| new byte[] { 0, 4, (byte)-1, (byte)-6, (byte)-3, 4, 1, 0 }, | |
| new byte[] { 0, 9, (byte)-1, 24, (byte)-2, (byte)-15, 5, (byte)-8 }, | |
| new byte[] { 0, 0, 0, (byte)-8, (byte)-1, 5, 0, 1 }, | |
| }; | |
| private static int byteToInt(byte[] data) { | |
| return (data[0] & 0xFF) | |
| | ((data[1] & 0xFF) << 8) | |
| | ((data[2] & 0xFF) << 16) | |
| | ((data[3] & 0xFF) << 24); | |
| } | |
| private static void transformBlock(byte[] src, int srcOffset, byte[] dst, int dstOffset, byte[][] matrix) { | |
| for (int col = 0; col < 8; col++) { | |
| int acc = 0; | |
| for (int row = 0; row < 8; row++) { | |
| int s = src[srcOffset + row]; | |
| int m = matrix[row][col]; | |
| acc = (byte) (acc + s * m); | |
| } | |
| dst[dstOffset + col] = (byte) acc; | |
| } | |
| } | |
| private static void transform(byte[] src, byte[] dst, int length, byte[][] matrix) { | |
| if (length % 8 != 0) { | |
| throw new IllegalArgumentException("length must be a multiple of 8"); | |
| } | |
| for (int offset = 0; offset < length; offset += 8) { | |
| transformBlock(src, offset, dst, offset, matrix); | |
| } | |
| } | |
| public static void main(String[] args) throws Exception { | |
| if (args.length == 0) { | |
| System.err.println("Usage: java DecryptLoginInfo <path-to-loginInfo.dat>"); | |
| System.exit(1); | |
| } | |
| Path path = Paths.get(args[0]); | |
| byte[] fileBytes = Files.readAllBytes(path); | |
| if (fileBytes.length < 4) { | |
| throw new IllegalArgumentException("File too short"); | |
| } | |
| int length = byteToInt(Arrays.copyOfRange(fileBytes, 0, 4)); | |
| int paddedLength = (length + 7) & ~7; | |
| if (4 + paddedLength > fileBytes.length) { | |
| throw new IllegalArgumentException("File truncated: expected " + paddedLength + " encrypted bytes"); | |
| } | |
| byte[] encrypted = Arrays.copyOfRange(fileBytes, 4, 4 + paddedLength); | |
| byte[] decryptedPadded = new byte[paddedLength]; | |
| transform(encrypted, decryptedPadded, paddedLength, DECRYPTION_MATRIX); | |
| byte[] decrypted = Arrays.copyOf(decryptedPadded, length); | |
| String base64 = new String(decrypted, StandardCharsets.UTF_8); | |
| String normalized = base64.replace("\r", "").replace("\n", ""); | |
| byte[] serialized = Base64.getDecoder().decode(normalized); | |
| ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(serialized)); | |
| Object obj = ois.readObject(); | |
| ois.close(); | |
| if (!(obj instanceof Map)) { | |
| throw new IllegalStateException("Expected a Map but got " + obj.getClass()); | |
| } | |
| Map<?, ?> map = (Map<?, ?>) obj; | |
| if (map.isEmpty()) { | |
| System.out.println("No entries found."); | |
| } else { | |
| for (Map.Entry<?, ?> entry : map.entrySet()) { | |
| System.out.println(entry.getKey() + " -> " + entry.getValue()); | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment