Hook线程(5)

x33g5p2x  于2021-08-23 转载在 Java  
字(1.9k)|赞(0)|评价(0)|浏览(138)

一Hook线程介绍

我们的许多软件都存在Hook线程的一个校验机制,其目的是校验进程是否已经启动,防止进程重复启动;Hook线程又称为钩子线程,在jvm退出的时候会执行Hook线程;比如mysql在启动的时候就会创建一个.lock文件,用.lock文件校验进程是否启动;Hook线程除了防止重新启动进程之外,还可以用做资源释放;尽量不要在Hook线程中进行复杂的操作以免影响性能;

二 Hook线程执行流程图

在这里插入图片描述

三 Hook防止重启案例

在linux上要注意的是执行权限,按照文件的权限设计permission字符串位数必须是9位,每前三位都是rwx,分别代表可读,可写。可执行;前三位代表文件的属主,中三位代表文件的属组,后三位代表其他用户对此文件的权限,有兴趣的朋友可以点源码进去看看,注意不同的​系统路径不一样

/**
 * @Author lsc
 * @Description <p> HOOK线程 </p>
 * @Date 2019/11/3 14:54
 */
public class Hook {

    // 文件路径
    private static final String HOOK_PATH = "C:\\mydata\\generator";
    // 文件名称
    private static final String HOOK_FILE = ".lock";
    // linux执行权限
    private static final String PERMS = "rwx------";

    public static void main(String[] args) {
        
        // 1 检查程序是否在运行,是异常提示,否创建lock文件
        checkRunningForWindows();
        // 2 注入hook线程,程序退出的时候执行删除lock文件
        registerHook();
        // 3 模拟程序在运行
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    // windows系统上
    private static void checkRunningForWindows(){
        // 获得path
        Path path = getPath();
        // lock文件如果已经存在则异常
        if (path.toFile().exists())
            throw new RuntimeException("程序已经在运行");
        // lock文件不存在则创建
        try {
            path.toFile().createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    // linux系统上检查程序是否在运行
    private static void checkRunningForLinux(){
        // 获得path
        Path path = getPath();
        // lock文件如果已经存在则异常
        if (path.toFile().exists())
            throw new RuntimeException("程序已经在运行");
        // lock文件不存在则创建
        Set<PosixFilePermission> posixFilePermissions = PosixFilePermissions.fromString(PERMS);
        try {
            Files.createFile(path, PosixFilePermissions.asFileAttribute(posixFilePermissions));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    // 注入hook
    private static void registerHook(){
        Runtime.getRuntime().addShutdownHook(new Thread( ()-> {
            // 退出提示
            System.out.println("程序即将退出");
            // 删除lock文件
            deleteLock();
        }));
    }

    // 删除lock文件
    private static void deleteLock(){
        // 获得path
        Path path = getPath();
        // 删除lock文件
        path.toFile().delete();
    }


    // 获得Path
    private static Path getPath(){
        // 文件路劲拼接返回一个Path对象
        Path path = Paths.get(HOOK_PATH, HOOK_FILE);
        return path;
    }
}

相关文章

热门文章

更多