import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.math.BigInteger; import java.util.Random; import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; /** * Created by rover12421 on 4/6/15. */ public class Main { public enum Product { RubyMine(1, "RubyMine", GenericKeyMaker.PRODUCTID_RubyMine, "BB62FBB57F105CD61B47AE2290FCB3CE1179942DE171BEDDF6BAA1A521B9368B735C7C931902EBA8DE6D160711A6ECC40F4A5E766E9FCDEE8A38715DB572AD3D", "7BFADCB153F59E86E69BC1820B4DB72573786E6B00CB824E57AD59BFE915231972746F47C6FBE0D8D88809DA313C1E4BEAD305AD8AFD31AE116ABCB181FF4F21", true), PyCharm(2, "PyCharm", GenericKeyMaker.PRODUCTID_PyCharm, "D57B0596A03949D9A3BB0CD1F7931E405AE27D0E0AF4E562072B487B0DAB7F0874AA982E5383E75FF13D36CA9D8531AC1FA2ED7B11C8858E821C2D5FB48002DD", "406047D02363033D295DB7C0FD8A94DDCD4A6D71B5A622220C8D65DF0DC1409E0BDE26AF66B0AD717406C22FC8BEC3ED88C1B7091BA3443B6BFBA26120DE6A15", true), WebStorm(3, "WebStorm", GenericKeyMaker.PRODUCTID_WebStorm, "BB62FBB57F105CD61B47AE2290FCB3CE1179942DE171BEDDF6BAA1A521B9368B735C7C931902EBA8DE6D160711A6ECC40F4A5E766E9FCDEE8A38715DB572AD3D", "7BFADCB153F59E86E69BC1820B4DB72573786E6B00CB824E57AD59BFE915231972746F47C6FBE0D8D88809DA313C1E4BEAD305AD8AFD31AE116ABCB181FF4F21", true), PhpStorm(4, "PhpStorm", GenericKeyMaker.PRODUCTID_PhpStorm, "BB62FBB57F105CD61B47AE2290FCB3CE1179942DE171BEDDF6BAA1A521B9368B735C7C931902EBA8DE6D160711A6ECC40F4A5E766E9FCDEE8A38715DB572AD3D", "7BFADCB153F59E86E69BC1820B4DB72573786E6B00CB824E57AD59BFE915231972746F47C6FBE0D8D88809DA313C1E4BEAD305AD8AFD31AE116ABCB181FF4F21", true), AppCode(5, "AppCode", GenericKeyMaker.PRODUCTID_AppCode, "F0DD6995C4BD3223641C79C8608D74F32ED54A8BDAE468EB5AC53F1F1C8925E263F82317356BC73B1C82B520630250212416C99CB39A8B7C2611E35552E166B9", "81B5EAEF61A4B584839C26253781D63243CD4F38E3A74FAD3713B3FB7025978538F10E743456F24BB20D5792BFDCB76DB6162C3D5C77DB7B29906CBFC9114EA5", true), Clion(6, "Clion", GenericKeyMaker.PRODUCTID_CLION, "C4AD4C091E08E5688B81B837506EB84D103FB3B2165F62E61C74B345D28C4A0CD0BE2FADF485883D0DDD4E24AAB758716027E84D420DE525B042A70FF8174031", "6FAADD5307E4912C4C993858DFA81DA853A3778993BE50CECA35505C427138D112D75AA22924E9317270C88B164C31C17C5A43B359F21DABFE923A7482DD7401", true), Idea(7, "Idea", GenericKeyMaker.PRODUCTID_IDEA, "430D187DE8BB3F18FB0A986E6B7163BD", "86F71688CDD2612CA117D1F54BDAE029", false),; private int id; private String name; private int productId; private String pubKey; private String privKey; private boolean isRSA; Product(int id, String name, int productId, String pubKey, String privKey, boolean isRSA) { this.id = id; this.name = name; this.pubKey = pubKey; this.privKey = privKey; this.productId = productId; this.isRSA = isRSA; } public int getId() { return id; } public String getName() { return name; } public BigInteger getPubKey() { return new BigInteger(pubKey, 16); } public BigInteger getPrivKey() { return new BigInteger(privKey, 16); } public int getProductId() { return productId; } public boolean isRSA() { return isRSA; } public static Product valueOf(int id) { for (Product product : Product.values()) { if (product.getId() == id) { return product; } } return null; } @Override public String toString() { return id + ". " + name; } } public static void main(String[] args) throws IOException { // System.out.println("Jetbrains's Product Patch or Keygen."); // System.out.println("Crack by Rover12421."); // System.out.println("Http://Www.Rover12421.Com"); // System.out.println("Please support genuine(https://www.jetbrains.com)."); // printSelectProduct(); // int sel; // Product product = null; // while (true) { // try { // sel = Integer.parseInt(readLine()); // if ((product = Product.valueOf(sel)) != null) { // break; // } // } catch (Throwable e) { // } // // System.out.println("Enter err!"); // printSelectProduct(); // } // // System.out.println("Please enter your username :"); // String userName = readLine(); String userName = "cylee"; Product product = Product.Clion; if (product == product.Clion) { System.out.println("Clion need patch"); System.out.println("Please enter your Clion install path or clion.jar path :"); // String path = readLine(); // while (!ClionPatch.patch(path)) { // System.out.println("Clion install path or clion.jar path error!"); // System.out.println("Please re-enter!"); // path = readLine(); // } String path = "D:\\Program Files (x86)\\JetBrains\\CLion 2016.1.2"; System.out.println(ClionPatch.patch(path)); } System.out.println("---------------------------------------"); GenericKeyMaker keyMaker = new GenericKeyMaker(); if (product.isRSA) { System.out.println(keyMaker.generateRSAKey(product.getPrivKey(), product.getPubKey(), GenericKeyMaker.LICENSETYPE_NON_COMMERCIAL, product.getProductId(), 1, 13, userName)); } else { System.out.println(keyMaker.generateNoRSAKey(product.getPrivKey(), product.getPubKey(), GenericKeyMaker.LICENSETYPE_NON_COMMERCIAL, product.getProductId(), 1, 14, userName)); } } private static void printSelectProduct() { System.out.println(); System.out.println("Please select product:"); for (Product product : Product.values()) { System.out.println(product); } } private static String readLine() throws IOException { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); return br.readLine(); } public static class ClionPatch { public static boolean patch(String src) throws IOException { File file = new File(src); if (file.isDirectory()) { File f = new File(file, "lib/clion.jar"); if (f.exists()) { file = f; } else { f = new File(file, "clion.jar"); if (f.exists()) { file = f; } } } if (file.isDirectory() || !file.exists()) { System.out.println("Err : Not found clion.jar."); return false; } File patch = File.createTempFile("clion", "_patch.jar", file.getParentFile()); byte[] srcKey = "8eeb1420b7d8b90aa3b95c7ff73628e46e12c19dc91531be5f517a54b042e99c17445ce7b23834a3ec80d2691b463231be43aab7e897cc334bc9b8bb9f0d55f5".getBytes(); byte[] desKey = "c4ad4c091e08e5688b81b837506eb84d103fb3b2165f62e61c74b345d28c4a0cd0be2fadf485883d0ddd4e24aab758716027e84d420de525b042a70ff8174031".getBytes(); boolean isPatch = false; boolean patched = false; try { FileInputStream fis = new FileInputStream(file); ZipInputStream zis = new ZipInputStream(fis); ZipFile zipFile = new ZipFile(file); FileOutputStream fos = new FileOutputStream(patch); ZipOutputStream zos = new ZipOutputStream(fos); ZipEntry entry; while ((entry = zis.getNextEntry()) != null) { ZipEntry outEntry = new ZipEntry(entry); try { InputStream is = zipFile.getInputStream(entry); if (entry.getName().endsWith(".class")) { byte[] buff = readInputStream(is); int index = indexOf(buff, srcKey); if (index > 0) { System.out.println("Find Key. Patch..."); System.arraycopy(desKey, 0, buff, index, desKey.length); CRC32 crc32 = new CRC32(); crc32.update(buff); outEntry.setCrc(crc32.getValue()); isPatch = true; } else { if (indexOf(buff, desKey) > 0) { System.out.println("Patched!"); patched = true; break; } } zos.putNextEntry(outEntry); zos.write(buff); zos.closeEntry(); } else { zos.putNextEntry(outEntry); copyStream(is, zos); zos.closeEntry(); } } catch (Exception e) { } } } catch (Exception e) { } if (patched) { patch.delete(); return true; } if (isPatch) { file.renameTo(new File(file.getAbsolutePath() + ".bak")); patch.renameTo(file); } else { patch.delete(); } return isPatch; } public static void copyStream(InputStream is, OutputStream os) throws IOException { final int BUFFER_SIZE = 8 * 1024; if (is == null || os == null) { throw new IOException("Argument is null."); } byte[] bytes = new byte[BUFFER_SIZE]; while (true) { int count = is.read(bytes, 0, BUFFER_SIZE); if (count == -1) { break; } os.write(bytes, 0, count); } } public static byte[] readInputStream(InputStream input) { byte[] data = null; try { ByteArrayOutputStream output = new ByteArrayOutputStream(); final byte[] buffer = new byte[1024]; int len = 0; while ((len = input.read(buffer)) != -1) { output.write(buffer, 0, len); } data = output.toByteArray(); output.close(); input.close(); } catch (IOException e) { e.printStackTrace(); } return data; } /** * Search the data byte array for the first occurrence * of the byte array pattern. */ public static int indexOf(byte[] data, byte[] pattern) { int[] failure = computeFailure(pattern); int j = 0; for (int i = 0; i < data.length; i++) { while (j > 0 && pattern[j] != data[i]) { j = failure[j - 1]; } if (pattern[j] == data[i]) { j++; } if (j == pattern.length) { return i - pattern.length + 1; } } return -1; } /** * Computes the failure function using a boot-strapping process, * where the pattern is matched against itself. */ private static int[] computeFailure(byte[] pattern) { int[] failure = new int[pattern.length]; int j = 0; for (int i = 1; i < pattern.length; i++) { while (j > 0 && pattern[j] != pattern[i]) { j = failure[j - 1]; } if (pattern[j] == pattern[i]) { j++; } failure[i] = j; } return failure; } } public static class GenericKeyMaker { public static final int LICENSETYPE_NON_COMMERCIAL = 1; public static final int PRODUCTID_IDEA = 1; public static final int PRODUCTID_RubyMine = 4; public static final int PRODUCTID_PyCharm = 5; public static final int PRODUCTID_WebStorm = 6; public static final int PRODUCTID_PhpStorm = 7; public static final int PRODUCTID_AppCode = 8; public static final int PRODUCTID_CLION = 10; private Random random = new Random(); private String getLicenseId() { return String.format("D%sT", Integer.toString(random.nextInt(90000) + 10000)); } private short getCRC(String s, int i, byte bytes[]) { CRC32 crc32 = new CRC32(); if (s != null) { for (int j = 0; j < s.length(); j++) { char c = s.charAt(j); crc32.update(c); } } crc32.update(i); crc32.update(i >> 8); crc32.update(i >> 16); crc32.update(i >> 24); for (int k = 0; k < bytes.length - 2; k++) { byte byte0 = bytes[k]; crc32.update(byte0); } return (short) (int) crc32.getValue(); } private byte[] generateKeyBytes14(int licenseType, int productId, int minorVersion, int majorVersion, String userName, int customerId) { byte[] keyBytes = new byte[14]; keyBytes[0] = (byte) ((licenseType << 4) + (productId & 0xFF)); keyBytes[1] = (byte) ((minorVersion << 4) + (majorVersion & 0xFF)); long time = System.currentTimeMillis() >> 16; keyBytes[2] = (byte) (int) (time & 0xFF); keyBytes[3] = (byte) (int) (time >> 8 & 0xFF); keyBytes[4] = (byte) (int) (time >> 16 & 0xFF); keyBytes[5] = (byte) (int) (time >> 24 & 0xFF); long timeDiff = Long.MAX_VALUE; keyBytes[6] = (byte) (int) (timeDiff & 0xFF); keyBytes[7] = (byte) (int) (timeDiff >> 8 & 0xFF); keyBytes[8] = 0; keyBytes[9] = 1; keyBytes[10] = 2; keyBytes[11] = 3; int crc32 = getCRC(userName, customerId, keyBytes); keyBytes[12] = (byte) (crc32 & 0xFF); keyBytes[13] = (byte) (crc32 >> 8 & 0xFF); return keyBytes; } private byte[] generateKeyBytes12(int licenseType, int productId, int minorVersion, int majorVersion, String userName, int customerId) { byte[] keyBytes = new byte[12]; keyBytes[0] = (byte) ((licenseType << 4) + (productId & 0xFF)); keyBytes[1] = (byte) ((minorVersion << 4) + (majorVersion & 0xFF)); long time = System.currentTimeMillis() >> 16; keyBytes[2] = (byte) (int) (time & 0xFF); keyBytes[3] = (byte) (int) (time >> 8 & 0xFF); keyBytes[4] = (byte) (int) (time >> 16 & 0xFF); keyBytes[5] = (byte) (int) (time >> 24 & 0xFF); long timeDiff = Long.MAX_VALUE; keyBytes[6] = (byte) (int) (timeDiff & 0xFF); keyBytes[7] = (byte) (int) (timeDiff >> 8 & 0xFF); keyBytes[8] = 105; keyBytes[9] = -59; int crc32 = getCRC(userName, customerId, keyBytes); keyBytes[10] = (byte) (crc32 & 0xFF); keyBytes[11] = (byte) (crc32 >> 8 & 0xFF); return keyBytes; } /** * @param biginteger * @return String */ public static String encodeGroups(BigInteger biginteger) { BigInteger beginner1 = BigInteger.valueOf(0x39aa400L); StringBuilder sb = new StringBuilder(); for (int i = 0; biginteger.compareTo(BigInteger.ZERO) != 0; i++) { int j = biginteger.mod(beginner1).intValue(); String s1 = encodeGroup(j); if (i > 0) { sb.append("-"); } sb.append(s1); biginteger = biginteger.divide(beginner1); } return sb.toString(); } /** * @param i * @return */ public static String encodeGroup(int i) { StringBuilder sb = new StringBuilder(); for (int j = 0; j < 5; j++) { int k = i % 36; char c; if (k < 10) { c = (char) (48 + k); } else { c = (char) ((65 + k) - 10); } sb.append(c); i /= 36; } return sb.toString(); } public String generateRSAKey(BigInteger privKey, BigInteger pubKey, int licenseType, int productId, int minorVersion, int majorVersion, String userName) { int customerId = random.nextInt(9000) + 1000; byte[] keyBytes = generateKeyBytes14(licenseType, productId, minorVersion, majorVersion, userName, customerId); RSAEncoder encoder = new RSAEncoder(privKey, pubKey, 64, false); String serial = encoder.encode(keyBytes); serial = "===== LICENSE BEGIN =====\n" + customerId + "-" + getLicenseId() + "\n" + serial + "\n===== LICENSE END ====="; return serial; } public String generateNoRSAKey(BigInteger privKey, BigInteger pubKey, int licenseType, int productId, int minorVersion, int majorVersion, String userName) { int customerId = random.nextInt(9000) + 1000; byte[] keyBytes = generateKeyBytes12(licenseType, productId, minorVersion, majorVersion, userName, customerId); BigInteger k0 = new BigInteger(keyBytes); BigInteger k1 = k0.modPow(pubKey, privKey); String s0 = Integer.toString(customerId); String sz = "0"; while (s0.length() != 5) { s0 = sz.concat(s0); } s0 = s0.concat("-"); String s1 = encodeGroups(k1); s0 = s0.concat(s1); return s0; } } // ================================ // public static class RSAEncoder { private final BigInteger privKey; private final BigInteger pubKey; private final int c; private final int d; private int e = 0; private final BigInteger f; private final boolean g; public RSAEncoder(BigInteger privKey, BigInteger pubKey, int len, boolean newLine) { this.privKey = privKey; this.pubKey = pubKey; this.g = newLine; int privKeyLen = privKey.bitLength(); this.f = new BigInteger(String.valueOf(len)); int i = (int) Math.ceil(privKeyLen / Math.log(len) * Math.log(2.0D)); if (i % 5 != 0) { i = (i / 5 + 1) * 5; } this.d = i; this.c = (privKeyLen / 8 - 1); } public String encode(byte[] bytes) { int i = bytes.length % this.c; byte[] arrayOfByte = new byte[i == 0 ? bytes.length : bytes.length + this.c - i]; System.arraycopy(bytes, 0, arrayOfByte, this.c - i, bytes.length); StringBuffer stringBuffer = new StringBuffer(); for (int j = 0; j < arrayOfByte.length; j += this.c) { encode(arrayOfByte, stringBuffer, j, this.c); } return stringBuffer.toString(); } private void encode(byte[] bytes, StringBuffer stringBuffer, int off, int len) { if (len == 0) { return; } byte[] arrayOfByte = new byte[this.c]; System.arraycopy(bytes, off, arrayOfByte, 0, len); BigInteger localBigInteger1 = new BigInteger(1, arrayOfByte); if (localBigInteger1.compareTo(this.pubKey) >= 0) { throw new IllegalArgumentException("result is too long"); } BigInteger localBigInteger2 = localBigInteger1.modPow(this.privKey, this.pubKey); stringBuffer.append(a(a(localBigInteger2))); } private String a(String paramString) { StringBuffer localStringBuffer = new StringBuffer(); for (int i = 0; i < paramString.length(); i++) { a(localStringBuffer); localStringBuffer.append(paramString.charAt(i)); } return localStringBuffer.toString(); } private String a(BigInteger paramBigInteger) { StringBuffer localStringBuffer = new StringBuffer(); for (int i = 0; i < this.d; i++) { localStringBuffer.insert(0, b(paramBigInteger.mod(this.f))); paramBigInteger = paramBigInteger.divide(this.f); } return localStringBuffer.toString(); } private void a(StringBuffer paramStringBuffer) { if ((this.e > 0) && (this.e % 5 == 0)) { if (this.e % 30 == 0) paramStringBuffer.append('\n'); else if (this.g) { paramStringBuffer.append('-'); } } this.e += 1; } private static char b(BigInteger paramBigInteger) { int i = paramBigInteger.intValue(); char c1; if (i < 10) { c1 = (char) (48 + i); } else { if (i < 36) { c1 = (char) (65 + i - 10); } else { if (i < 62) c1 = (char) (97 + i - 36); else { c1 = (char) (33 + i - 62); } } } return c1; } } }