十三. JEB破解三


一.啟動環境
JEB 2.0Demo版本啟動后出現這樣一個界面


當前環境算出的許可證數據
48000000BDEAE192E4CEFC82B34C2AC67F3A85DF5C0E262E421772CF84F18EC0E4A9F41798FD1648BF2794B4545F6315D6AC21C3921172C29FA004FAE1A8127C585A37F27FC478F9187BD35BBD7BA0DE

根據經驗來看,肯定是機器碼和注冊碼經過特定的運算,運算通過就注冊成功


二. 分析過程
1. 定位關鍵點
在main函數我們發現啟動時會先回去License相關信息,我們跟進這個函數


在跟進的 AbstractClientContext 類中我們發現

這里比較像注冊碼比較的地方
上面的this.uomid 點擊不進去, 搜索也搜索不到, 一般情況這個成員的值定義可能在父類

我們父類跟蹤該值 this.uomid,果然找到相關初始化地方


跟蹤最終的初始化,發現其在該函數進行初始化過程

看起來很像算機器碼的地方, 我們可以高度懷疑上面的過程就是注冊碼檢查校驗的過程了

2. 先還原機器碼算法
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
public final class MachineHelper {
    private String GetWinSerialNum() {
        Process locProcess;
        String serial = null;
        Runtime locRuntime = Runtime.getRuntime();
        try {
            locProcess = locRuntime.exec("wmic bios get serialnumber".split(" "));
            Scanner scanner = new Scanner(locProcess.getInputStream());
            while (scanner.hasNext()) {
                if ("SerialNumber".equals(scanner.next())) {
                    serial = scanner.next().trim();
                    break;
                }
            }
            scanner.close();
        } catch (IOException e) {
        }
        return serial;
    }
    @SuppressWarnings("null")
    private String GetMacSerialNum() {
        Process locProcess;
        String serial = null;
        Runtime locRuntime = Runtime.getRuntime();
        try {
            locProcess = locRuntime.exec("/usr/sbin/system_profiler SPHardwareDataType".split(" "));
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(locProcess.getInputStream()));
            String buffer = null;
            while ((buffer = bufferedReader.readLine()) != null) {
                if (buffer.indexOf("Serial Number") >= 0) {
                    String buf1 = buffer.split("Serial Number")[1];
                    int iPoint = buf1.indexOf(":");
                    if (iPoint >= 0) {
                        serial = serial.substring(iPoint + 1).trim();
                    }
                    break;
                }
            }
        } catch (IOException e) {
        }
        return serial;
    }
    private String GetLinuxSerialNum() {
        String serial = null;
        try {
            BufferedReader midFilebuf = new BufferedReader(new InputStreamReader(new FileInputStream("/var/lib/dbus/machine-id")));
            String buffer = midFilebuf.readLine();
            midFilebuf.close();
            if (buffer != null) {
                serial = buffer.trim();
            }
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }
        return serial;
    }
    private String GetLinuxSerialNum2() {
        String serial = null;
        try {
            BufferedReader fstabFilebuf = new BufferedReader(new InputStreamReader(new FileInputStream("/etc/fstab")));
            String buffer = null;
            while ((buffer = fstabFilebuf.readLine()) != null) {
                buffer = buffer.trim();
                if (buffer.length() == 0) {
                    continue;
                }
                if (buffer.startsWith("#")) {
                    continue;
                }
                String[] Keyvalue = buffer.split("[ \\t]+");
                if (Keyvalue.length < 2) {
                    continue;
                }
                if (!Keyvalue[1].equals("/")) {
                    continue;
                }
                buffer = Keyvalue[0];
                if (buffer.startsWith("UUID=")) {
                    serial = buffer.substring(5);
                } else if (buffer.startsWith("LABEL=")) {
                    serial = buffer.substring(6);
                }
                if (serial != null) {
                    serial.toLowerCase();
                }
            }
            fstabFilebuf.close();
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
            e.printStackTrace();
        }
        return serial;
    }
    public long GetMachineID() {
        String osType = System.getProperty("os.name""");
        String SNKey = null;
        long machineId = 0;
        if (osType.startsWith("Windows")) {
            SNKey = GetWinSerialNum();
        } else if (osType.startsWith("Mac")) {
            SNKey = GetMacSerialNum();
        } else if (osType.startsWith("Linux")) {
            SNKey = GetLinuxSerialNum();
            if (SNKey == null) {
                SNKey = GetLinuxSerialNum2();
            }
        } else {
            SNKey = "LambdaLambda";
        }
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            ByteBuffer buffer = ByteBuffer.wrap(md.digest(SNKey.getBytes()));
            buffer.order(ByteOrder.LITTLE_ENDIAN);
            machineId = buffer.getLong() & 0xFFFFFFFF;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return machineId;
    }
    
    public static void main(String[] args) {
        MachineHelper helper = new MachineHelper();
        System.out.println(helper.GetMachineID());
    }
}

解密后


3. 注冊算法分析
當v2_1 != 0時 校驗通過


當v6 == v8時校驗通過


向上跟蹤發現v6 v8是根據licenseKey和machineKey分別計算出來的
那么還原licenseKey的算法即可
import java.nio.ByteBuffer;
public class Test {
    private static int sum(int i)
    {
        int j = 0;
        for(; i > 0i >>= 4)
            j += i & 0xf;
        return j % 10;
    }
    
    public static String getKey(long machineId,long unixTime) {
        int i = (int)(machineId & 0xFFFFFFFF);
        int j = (int)(machineId >> 32 & 0xFFFFFFFF);
        int i1 = i +  0x45F22A12 + 0x11223344 & 0xFFFFFFFF;
        int j1 = j - 0x1B0CB11 + 0x55667788 & 0x7FFFFFFF;
        ByteBuffer bb = ByteBuffer.allocateDirect(8);
        bb.putInt(j1);
        bb.putInt(i1);
        bb.rewind();
        long l = bb.getLong();
        int d = (int)unixTime ^ 0x56739ACD;
        
        return String.format("%dZ%d%d"ldsum(d));
    }
    
    public static void main(String[] args) {
        MachineHelper helper = new MachineHelper();
        long machineID = helper.GetMachineID();
        long unixTime = System.currentTimeMillis() / 1000L + 94608000L - 1123200L;
        
        String key = getKey(machineIDunixTime);
        System.out.println(helper.GetMachineID());
        System.out.println(key);
    }
}

計算出key


成功通過運算











免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM