V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
wzt
V2EX  ›  Linux

逆向分析 360 for linux 版本

  •  7
     
  •   wzt · 2015-02-04 14:40:58 +08:00 · 8036 次点击
    这是一个创建于 3376 天前的主题,其中的信息可能已经有所发展或是发生改变。

    360已经开始抢占linux市场, 于是推出了360 for linux版本。 楼主分析的是pc版本,android版本底层功能应该类似。安装360后, 你会发现即使是root也kill不掉start360进程,360使用的所有文件也删不掉。 原因是它加载了两个内核保护模块360safe.ko和immu.ko, 360safe.ko用来保护其进程不被杀掉, immu.ko保护其文件不被删除掉。
    欢迎访问我的github: [https://github.com/cloudsec]

    360safe.ko
    
    .text.unlikely:0000000000000046 unkill_get_signal_from_task proc near   ; CODE XREF: unkill_init+3F p
    .text.unlikely:0000000000000046                                         ; unkill_exit+3F p
    .text.unlikely:0000000000000046                                         ; DATA XREF: ...
    .text.unlikely:0000000000000046                 call    __fentry__
    .text.unlikely:000000000000004B                 push    rbp
    .text.unlikely:000000000000004C                 mov     rbp, rsp
    .text.unlikely:000000000000004F                 push    r12
    .text.unlikely:0000000000000051                 push    rbx
    .text.unlikely:0000000000000052                 mov     rbx, rdi
    .text.unlikely:0000000000000055                 mov     rdi, offset aGet_files_stru ; "get_files_struct"
    .text.unlikely:000000000000005C                 call    kallsyms_lookup_name
    .text.unlikely:0000000000000061                 mov     rdi, offset aPut_files_stru ; "put_files_struct"
    .text.unlikely:0000000000000068                 mov     cs:unkill_get_files_struct, rax
    .text.unlikely:000000000000006F                 call    kallsyms_lookup_name
    .text.unlikely:0000000000000074                 mov     rdi, rbx
    .text.unlikely:0000000000000077                 mov     cs:unkill_put_files_struct, rax
    .text.unlikely:000000000000007E                 call    cs:unkill_get_files_struct
    .text.unlikely:0000000000000084                 test    rax, rax
    .text.unlikely:0000000000000087                 mov     r12, rax
    .text.unlikely:000000000000008A                 jz      short loc_D0
    .text.unlikely:000000000000008C                 xor     edx, edx
    .text.unlikely:000000000000008E
    .text.unlikely:000000000000008E loc_8E:                                 ; CODE XREF: unkill_get_signal_from_task+78 j
    .text.unlikely:000000000000008E                 mov     rcx, [rbx+rdx*8]
    .text.unlikely:0000000000000092                 test    rcx, rcx
    .text.unlikely:0000000000000095                 jz      short loc_B4
    .text.unlikely:0000000000000097                 cmp     r12, rcx
    .text.unlikely:000000000000009A                 jnz     short loc_B4
    .text.unlikely:000000000000009C                 mov     rbx, [rbx+rdx*8+10h]
    .text.unlikely:00000000000000A1                 mov     rdi, offset aSignalAddrLx ; "signal addr %lx\n"
    .text.unlikely:00000000000000A8                 xor     eax, eax
    .text.unlikely:00000000000000AA                 mov     rsi, rbx
    .text.unlikely:00000000000000AD                 call    printk
    .text.unlikely:00000000000000B2                 jmp     short loc_C2
    .text.unlikely:00000000000000B4 ; ---------------------------------------------------------------------------
    .text.unlikely:00000000000000B4
    .text.unlikely:00000000000000B4 loc_B4:                                 ; CODE XREF: unkill_get_signal_from_task+4F j
    .text.unlikely:00000000000000B4                                         ; unkill_get_signal_from_task+54 j
    .text.unlikely:00000000000000B4                 inc     rdx
    .text.unlikely:00000000000000B7                 cmp     rdx, 31Ch
    .text.unlikely:00000000000000BE                 jnz     short loc_8E
    .text.unlikely:00000000000000C0                 xor     ebx, ebx
    .text.unlikely:00000000000000C2
    .text.unlikely:00000000000000C2 loc_C2:                                 ; CODE XREF: unkill_get_signal_from_task+6C j
    .text.unlikely:00000000000000C2                 mov     rdi, r12
    .text.unlikely:00000000000000C5                 call    cs:unkill_put_files_struct
    .text.unlikely:00000000000000CB                 mov     rax, rbx
    .text.unlikely:00000000000000CE                 jmp     short loc_D2
    .text.unlikely:00000000000000D0 ; ---------------------------------------------------------------------------
    .text.unlikely:00000000000000D0
    .text.unlikely:00000000000000D0 loc_D0:                                 ; CODE XREF: unkill_get_signal_from_task+44 j
    .text.unlikely:00000000000000D0                 xor     eax, eax
    .text.unlikely:00000000000000D2
    .text.unlikely:00000000000000D2 loc_D2:                                 ; CODE XREF: unkill_get_signal_from_task+88 j
    .text.unlikely:00000000000000D2                 pop     rbx
    .text.unlikely:00000000000000D3                 pop     r12
    .text.unlikely:00000000000000D5                 pop     rbp
    .text.unlikely:00000000000000D6                 retn
    .text.unlikely:00000000000000D6 unkill_get_signal_from_task endp
    
    还原为c源码:
    
    void *unkill_get_signal_from_task(struct task_struct *tsk)
    {
        void *tmp_addr;
        long idx;
    
        unkill_get_files_struct=kallsyms_lookup_name(aGet_files_stru);
        unkill_put_files_struct=kallsyms_lookup_name(aPut_files_stru);
    
        tmp_addr=unkill_get_files_struct(tsk);
        if (!tmp_addr) {
            goto out;
        }
    
        for (idx = 0; idx <= 0x31c; idx++) {
            if (*(tsk + idx * 8) == 0)
                continue;
            if (tmp_addr = *(tsk + idx * 8)) {
                printk("signal addr %lx\n", *(tsk + idx * 8 + 0x10));
                unkill_put_files_struct(tmp_addr);
                return *(tsk + idx * 8 + 0x10);
            }
        }
    
    out:
        return NULL;
    }
    
    .text:0000000000000000                 public unkill_get_flags_from_sig_task
    .text:0000000000000000 unkill_get_flags_from_sig_task proc near ; CODE XREF: unkill_init+4F p
    .text:0000000000000000                                         ; unkill_exit+4F p
    .text:0000000000000000                                         ; DATA XREF: ...
    .text:0000000000000000                 call    __fentry__
    .text:0000000000000005                 push    rbp
    .text:0000000000000006                 xor     eax, eax
    .text:0000000000000008                 mov     rbp, rsp
    .text:000000000000000B                 push    rbx
    .text:000000000000000C                 nop     dword ptr [rax+00h]
    .text:0000000000000010
    .text:0000000000000010 loc_10:                                 ; CODE XREF: unkill_get_flags_from_sig_task+25 j
    .text:0000000000000010                 mov     edx, [rdi+rax*4]
    .text:0000000000000013                 test    edx, edx
    .text:0000000000000015                 jz      short loc_1B
    .text:0000000000000017                 cmp     edx, esi
    .text:0000000000000019                 jz      short loc_2F
    .text:000000000000001B
    .text:000000000000001B loc_1B:                                 ; CODE XREF: unkill_get_flags_from_sig_task+15 j
    .text:000000000000001B                 add     rax, 1
    .text:000000000000001F                 cmp     rax, 110h
    .text:0000000000000025                 jnz     short loc_10
    .text:0000000000000027                 xor     ebx, ebx
    .text:0000000000000029
    .text:0000000000000029 loc_29:                                 ; CODE XREF: unkill_get_flags_from_sig_task+44 j
    .text:0000000000000029                 mov     rax, rbx
    .text:000000000000002C                 pop     rbx
    .text:000000000000002D                 pop     rbp
    .text:000000000000002E                 retn
    .text:000000000000002F ; ---------------------------------------------------------------------------
    .text:000000000000002F
    .text:000000000000002F loc_2F:                                 ; CODE XREF: unkill_get_flags_from_sig_task+19 j
    .text:000000000000002F                 lea     rbx, [rdi+rax*4+34h]
    .text:0000000000000034                 mov     rdi, offset aFlagsAddrX ; "flags addr %x\n"
    .text:000000000000003B                 xor     eax, eax
    .text:000000000000003D                 mov     esi, ebx
    .text:000000000000003F                 call    printk
    .text:0000000000000044                 jmp     short loc_29
    .text:0000000000000044 unkill_get_flags_from_sig_task endp
    
    还原c源码:
    
    void *unkill_get_flags_from_sig_task(struct sighand_struct *sig, struct task_struct *tsk){
        int idx;
    
        for (idx = 0; idx <= 0x110; idx++)) {
            if (*(sig + idx * 4) == (unsigned int *)tsk) {
                printk("flags addr %x\n", *(sig + idx * 4 + 0x34));
                return  *(sig + idx * 4 + 0x34);
            }
        }
    
        return NULL;
    }
    
    进程不被杀掉的主要原因是修改了其保护进程的signal处理函数, 对SIG_SEGV进行了忽略。
    immu.ko同理, 把其保护文件的inode->flags设置为一个不存在的模式,vfs不认识,所以对其进行忽略。
    
    360safe.ko
    
    #include <linux/kernel.h>
    #include <linux/sched.h>
    #include <linux/fs.h>
    
    void const *aGet_files_stru="get_files_struct";
    void const *aPut_files_stru="put_files_struct";
    void *unkill_get_files_struct;
    void *unkill_put_files_struct;
    void const *aUnKillablePidU="un killable pid %u\n";
    void const *aUnKillablePi="un killable pid %u done!\n";
    void const *aKillablePidU="killable pid %u\n";
    void const *aKillablePidUDo="killable pid %u done!\n"
    
    pidt_t g_pid;
    
    void *unkill_get_flags_from_sig_task(struct sighand_struct *sig, struct task_struct *tsk){
        int idx;
    
        for (idx = 0; idx <= 0x110; idx++)) {
            if (*(sig + idx * 4) == (unsigned int *)tsk) {
                printk("flags addr %x\n", *(sig + idx * 4 + 0x34));
                return  *(sig + idx * 4 + 0x34);
            }
        }
    
        return NULL;
    }
    
    
    void *unkill_get_signal_from_task(struct task_struct *tsk)
    {
        void *tmp_addr;
        long idx;
    
        unkill_get_files_struct=kallsyms_lookup_name(aGet_files_stru);
        unkill_put_files_struct=kallsyms_lookup_name(aPut_files_stru);
    
        tmp_addr=unkill_get_files_struct(tsk);
        if (!tmp_addr) {
            goto out;
        }
    
        for (idx = 0; idx <= 0x31c; idx++) {
            if (*(tsk + idx * 8) == 0)
                continue;
            if (tmp_addr = *(tsk + idx * 8)) {
                printk("signal addr %lx\n", *(tsk + idx * 8 + 0x10));
                unkill_put_files_struct(tmp_addr);
                return *(tsk + idx * 8 + 0x10);
            }
        }
    
    out:
        return NULL;
    }
    
    int unkill_init(void)
    {
        struct pid *tmp_pid;
        struct task_struct *tmp_tsk;
        void *tmp_addr;
    
        printk(aUnKillablePidU, g_pid);
    
        tmp_pid=find_get_pid(g_pid);
        if (!tmp_pid)
            goto out;
    
        tmp_tsk=pid_task(tmp_pid, 0);
        if (!tmp_tsk)
            goto out;
    
        tmp_addr=unkill_get_signal_from_task(tmp_tsk);
        if (!tmp_addr)
            goto out;
    
        tmp_addr=unkill_get_flags_from_sig_task(tmp_addr, tmp_tsk);
        if (!tmp_addr)
            goto out;
    
        if (*(tmp_addr) | 0x40))
            printk(aUnKillablePi, g_pid);
    out:
        return 0;
    }
    
    int unkill_exit(void)
    {
        struct pid *tmp_pid;
        struct task_struct *tmp_tsk;
        void *tmp_addr;
    
        printk(aKillablePidU, g_pid);
    
        tmp_pid=find_get_pid(g_pid);
        if (!tmp_pid)
            goto out;
    
        tmp_tsk=pid_task(tmp_pid, 0);
        if (!tmp_tsk)
            goto out;
    
        tmp_addr=unkill_get_signal_from_task(tmp_tsk);
        if (!tmp_addr)
            goto out;
    
        tmp_addr=unkill_get_flags_from_sig_task(tmp_addr, tmp_tsk);
        if (!tmp_addr)
            goto out;
    
        if (*(tmp_addr) & 0FFFFFFBFh)
            printk(aKillablePidUDo, g_pid);
    out:
        return 0;
    }
    
    
    immu.ko
    
    /*
     * immu.ko  - 360 for linux kernel module.
     *
     * disassemberd by wzt
     * 
     * hooked_syms:
     * 0 &hooked_syms
     * 8 addr + 32
     *                                 hooked_syms  
     * 0        |   8    | 16     |20 |28 |     32         |   40      |
     * orig_addr|orig_op1|orig_op2|op2|op1|orig_hooked_syms|hooked_syms|
     *
     * *orig_addr           ->rbp - 56
     * *(orig_addr + 8)     ->rbp - 48
     * 0B848            ->rbp - 44
     * 0E0FF0000        ->rbp - 36
     * gs:28h       ->rbp - 32
     * rbx
     * r12
     * r13              
     * rbp                  ->rbp
    */
    
    #include <linux/kernel.h>
    #include <linux/sched.h>
    #include <linux/fs.h>
    
    int os_index = -1;
    char *os_version;
    const char *unk_75D = "/";
    void *unlocked_ioctl;
    void *compat_ioctl;
    
    char *vesions[] = {"3.7", "3.8", "3,9", "3.10", "3.11", "3.12", "3.13", "3.14", "3.15", "3.16", "3.17"};
    
    char *g_files[] = {"/etc/360safe/360safe.xml",
                "/etc/360safe/7z.so",
                "/etc/360safe/qex/MacroDef.enc",
                "/etc/360safe/qex/patt.enc",
                "/etc/360safe/qex/qex.vdb.enc",
                "/etc/360safe/Rar29.so",
                "/opt/360safeforlinux/start360"};
    
    int hijack_start(void *orig_addr, void *new_addr)
    {
        long gs_v;
        int op1=0x0E0FF0000;
        long op2=0x0B848;
        long orig_op2=*(long *)(orig_addr + 8);
        long orig_op1=*(long *)(orig_addr);
        void *addr;
        void *tmp;
        void *orig_hooked_syms;
    
        asm("movq %gs:0x28 %0":"=(&gs_v)":);
    
        addr=*(void *)kmalloc_caches();
        tmp=addr;
        tmp = tmp & 0x0FFFFFFFFFFFEFFFF;
    
        *(void *)(0x15ec)(tmp);
    
        *(long *)(&op2 + 2) = new_addr;
        *(long *)orig_addr = *(long *)&op2;
        *(int *)(orig_addr + 8) = *(int *)&op1;
    
        *(void *)(0x15ec)(addr);
    
        addr=kmem_cache_alloc_trace(kmalloc_caches[0x30], 0x30, 0xd0);
        if (!addr) {
            out;
        }
    
        *(long *)(&op2 + 2) = new_addr;
        *(long *)addr = orig_addr;
        *(long *)(addr + 8) = orig_op1;
        *(int *)(addr + 16) = orig_op2;
        *(long *)(addr + 20) = *(long *)&op2;
        *(int *)(addr + 28) = *(int *)&op1;
    
        orig_hooked_syms = hooked_syms;
        *(long *)(hooked_syms + 8) = addr + 32;
    
        hooked_syms = addr + 32;
        *(long *)(addr + 32) = orig_hooked_syms;
        *(long *)(addr + 40) = hooked_syms;
    
    out:
        long tmp1;
        asm("movq %gs:0x28 %0":"=(&tmp1)":);
        if (tmp1 != gs_v)
            __stack_chk_fail();
        return gs_v;
    }
    
    void *hijack_pause(void *orig_addr)
    {
        void *tmp_hooked_syms = hooked_syms;
        void *tmp_addr = (void *)(*(long *)(tmp_hooked_syms - 32));
        void *addr, *addr1;
    
    loc_4A8:
        if ((long *)tmp_hooked_syms == *(long *)hooked_syms)
            return tmp_hooked_syms;
    
        if (tmp_addr != orig_addr) {
            if (*(long *)tmp_hooked_syms != *(long *)hooked_syms) {
                tmp_hooked_syms = *(long *)hooked_syms - 32;
                goto loc_4A8;
        }
    
        addr = kmalloc_caches;
        addr1 = addr;
        addr1 = addr1 & 0xFFFFFFFFFFFEFFFF;
    
        *(void *)(0x15ec)(tmp);
    
        *(long *)orig_addr = *(long *)(tmp_hooked_syms + 8);
        *(long *)(orig_addr + 8)= *(long *)(tmp_hooked_syms + 16);
    
        *(void *)(0x15ec)(addr);
        goto loc_42D;
    }
    
    void *hijack_resume(void *orig_addr)
    {
        void *tmp_hooked_syms = hooked_syms;
        void *tmp_addr = (void *)(*(long *)(tmp_hooked_syms - 32));
        void *addr, *addr1;
    
    loc_42D:
        if ((long *)tmp_hooked_syms == *(long *)hooked_syms)
            return tmp_hooked_syms;
    
        if (tmp_addr != orig_addr) {
            if (*(long *)tmp_hooked_syms != *(long *)hooked_syms) {
                tmp_hooked_syms = *(long *)hooked_syms - 32;
                goto loc_42D;
        }
    
        addr = kmalloc_caches;
        addr1 = addr;
        addr1 = addr1 & 0xFFFFFFFFFFFEFFFF;
    
        *(void *)(0x15ec)(tmp);
    
        *(long *)orig_addr = *(long *)(tmp_hooked_syms + 20);
        *(long *)(orig_addr + 8)= *(long *)(tmp_hooked_syms + 28);
    
    
        *(void *)(0x15ec)(addr);
        goto loc_42D;
    }
    
    void hijack_stop(void *orig_addr)
    {
        void *tmp_hooked_syms = hooked_syms;
        void *tmp_addr = (void *)(*(long *)(tmp_hooked_syms - 32));
        void *addr, *addr1;
    
        if ((long *)tmp_hooked_syms == *(long *)hooked_syms)
            return tmp_hooked_syms;
    
    loc_42D:
        if (tmp_addr != orig_addr) {
            if (*(long *)tmp_hooked_syms != *(long *)hooked_syms) {
                tmp_hooked_syms = *(long *)hooked_syms - 32;
                goto loc_42D;
            }
        }
    
        addr = kmalloc_caches;
        addr1 = addr;
        addr1 = addr1 & 0xFFFFFFFFFFFEFFFF;
    
        *(void *)(0x15ec)(tmp);
    
        *(long *)orig_addr = *(long *)(tmp_hooked_syms + 8);
        *(long *)(orig_addr + 8)= *(long *)(tmp_hooked_syms + 16);
    
        *(void *)(0x15ec)(addr);
    
        long v1,v2;
    
        v1 = *(long *)(tmp_hooked_syms + 0x28)
        v2 = *(long *)(tmp_hooked_syms + 0x20)
    
        *(long *)(v2 + 8) = v1;
        *(long *)v1 = v2;
    
        *(long *)(tmp_hooked_syms + 0x20) = 0xDEAD000000100100;
        *(long *)(tmp_hooked_syms + 0x28) = 0xDEAD000000100200;
    
        kfree(tmp_hooked_syms);
    }
    
    void *n_unlocked_ioctl(void *addr, long cmd, long arg)
    {
        void *tmp_addr = addr;
        long tmp_cmd = cmd, tmp_arg = arg;
        long ret;
        int flag;
    
        hijack_pasue(unlocked_ioctl);
        ret = unlokced_ioctl(addr, cmd, arg);
        hijack_resume(unlocked_ioctl);
    
        if ( *(long *)(*(long *)(addr + 0x18) + 0x30) == NULL)
            return cmd;
    
        flag =  *(long *)(*(long *)(*(long *)(addr + 0x18) + 0x30) + 0xc);
        if (!(flag & 0x1000000))
            return cmd;
    
        flag = flag | 0x8;
        *(long *)(*(long *)(*(long *)(addr + 0x18) + 0x30) + 0xc) = flag;
    
        return cmd;
    }
    
    void *n_compat_ioctl(void *addr, long cmd, long arg)
    {
        void *tmp_addr = addr;
        long tmp_cmd = cmd, tmp_arg = arg;
        long ret;
        int flag;
    
        hijack_pasue(compat_ioctl);
        ret = compat_ioctl(addr, cmd, arg);
        hijack_resume(compat_ioctl);
    
        if ( *(long *)(*(long *)(addr + 0x18) + 0x30) == NULL)
            return cmd;
    
        flag =  *(long *)(*(long *)(*(long *)(addr + 0x18) + 0x30) + 0xc);
        if (!(flag & 0x1000000))
            return cmd;
    
        flag = flag | 0x8;
        *(long *)(*(long *)(*(long *)(addr + 0x18) + 0x30) + 0xc) = flag;
    
        return cmd;
    }
    
    void immutable_file(const char *file_name)
    {
        void *addr;
        long flag;
    
        addr = filp_open(file_name, 0, 0);
        if (addr < 4096)
            return ;
    
        flag = *(long *)(*(long *)(*(long *)(addr + 0x18) + 0x30) + 0xc);
        flag = flag | 0x1000008;
        *(long *)(*(long *)(*(long *)(addr + 0x18) + 0x30) + 0xc) = flag;
    }
    
    void unimmutable_file(const char *file_name)
    {
        void *addr;
        long flag;
    
        addr = filp_open(file_name, 0, 0);
        if (addr < 4096)
            return ;
    
        flag = *(long *)(*(long *)(*(long *)(addr + 0x18) + 0x30) + 0xc);
        flag = flag & 0xFEFFFFF7;
        *(long *)(*(long *)(*(long *)(addr + 0x18) + 0x30) + 0xc) = flag;
    }
    
    int immu_get_os_version_index(void)
    {
        int idx;
    
        if (!os_version)
            return -1;
    
        for (idx = 0; idx <= 0xa; idx++) {
            if (!strncmp(vesion[idx * 8 ], os_version, strlen(version[idx * 8]))
                return idx;
        }
    
        return -1;
    }
    
    void *immu_get_fileo_from_filep(void *file)
    {
        return (void *)(file + 0x28);
    }
    
    int immu_get_unlockedioctl_offset(void)
    {
        if (os_index < 0)
            return -1;
    
        if (os_index <= 7)
            return 8;
    
        if (os_index < 9)
            return 10;
    
        return -1;
    }
    
    void *immu_get_ioctlp_from_fileo(void *file, int flag)
    {
        void *addr;
        int idx
    
        if (os_index < 0)
            return NULL;
    
        if (os_index <= 7)
            idx = 8;
    
        if (os_index < 9)
            idx = 10;
    
        if (flag <= 1) {
            return (long)(addr + idx*8);
        }
        else {
            return (long)(addr + idx*8);
        }
    
        return NULL;
    }
    
    void *disable_wp(void)
    {
        void *addr;
    
        addr=*(void *)kmalloc_caches();
        tmp=addr;
        tmp = tmp & 0x0FFFFFFFFFFFEFFFF;
        *(void *)(0x15ec)(tmp);
    
        return addr;
    }
    
    void restore_wp(void *addr)
    {
        *(void *)(0x15ec)(addr);
    }
    
    void *get_vfs_ioctl(const char *file_name, int flag)
    {
        void *file, *addr;
    
        file = filp_open(file_name, 0, 0);
        if (file < 4096)
            return NULL;
    
        addr = *(long *)(file + 0x28);
    
        if (os_index < 0) {
            filp_close(file, 0);
            return NULL;
        }
    
        if (os_index <= 7) {
            if (flag <= 1) {
                filp_close(file, 0);
                return (long)(addr + 8*8);
            }
            else {
                filp_close(file, 0);
                return (long)(addr + 9*8);
            }
        }
    
        return NULL;
    }
    
    int init_module(void)
    {
        long idx;
    
        os_index = immu_get_os_version_index;
        if (os_index < 0)
            return -1;
    
        unlocked_ioctl = get_vfs_ioctl(unk_75D, 0);
        if (unlocked_ioctl) {
            hijack_start(n_unlocked_ioctl);
        }
    
        compat_ioctl=get_vfs_ioctl(unk_75D, 1);
        if (compat_ioctl)
            hijack_start(n_compat_ioctl);
        }
    
        for (idx = 0; idx <= 0xd0; idx += 8) {
            immutable_file(g_files[idx]);
        }
    
        return 0;
    }
    
    void immu_exit(void)
    {
        long idx;
    
        if (os_index < 0)
            return ;
    
        if (unlocked_ioctl) {
            hijack_stop(unlocked_ioctl);
        }
    
        if (compat_ioctl) {
            hijack_stop(compat_ioctl);
        }
    
        for (idx = 0; idx <= 0xd0; idx += 8) {
            unimmutable_file(g_files[idx]);
        }
    }
    
    19 条回复    2015-02-09 22:17:07 +08:00
    hicdn
        1
    hicdn  
       2015-02-04 14:51:30 +08:00
    武则天就是屌
    sinsin
        2
    sinsin  
       2015-02-04 15:07:15 +08:00
    那这俩可不可以被rmmod呢
    (话说github跟这个有何关联。。。brootkit被查到了么
    ywj2167917
        3
    ywj2167917  
       2015-02-04 15:26:54 +08:00   ❤️ 1
    linux上还装360。也是醉了啊。
    andychen20121130
        4
    andychen20121130  
       2015-02-04 15:37:43 +08:00
    膜拜
    yakczh
        5
    yakczh  
       2015-02-04 16:22:44 +08:00
    用livecd启动以后,可以把这两个文件删除掉吗?
    TnmsY
        6
    TnmsY  
       2015-02-04 17:18:09 +08:00
    不是出了好些年了?
    wzt
        7
    wzt  
    OP
       2015-02-04 17:19:41 +08:00
    用以下脚本可手工删除360进程和文件:

    root@wzt-pc:/home/wzt# cat kill360.sh
    #!/bin/bash

    function kill_360mod()
    {
    echo -n "start remove 360 kernel mods..."
    rmmod immu && rmmod rk360 && echo -e "\tsuccessful."
    }

    function kill_360procs()
    {
    declare -a pids
    local pid

    pids=`ps aux|grep start360|awk '{print $2}'`
    for pid in ${pids[*]}
    do
    echo -n "start killing start360 proc..."
    kill -9 $pid >/dev/null 2>&1
    echo -e "\tsuccessful."
    done
    }

    function remove_360file()
    {
    rm -fr /etc/360safe
    rm -f /usr/bin/start360
    rm -fr /opt/360safeforlinux
    rm -f /usr/share/applications/start360.desktop
    }

    kill_360mod
    kill_360procs
    remove_360file
    zjgood
        8
    zjgood  
       2015-02-04 20:39:04 +08:00
    请问楼主Linux Platform用什么工具逆的哇?
    retme
        9
    retme  
       2015-02-06 15:58:49 +08:00
    @zjgood ...用IDA不是一样的么
    zjgood
        10
    zjgood  
       2015-02-06 16:06:14 +08:00 via Android
    @retme 呃,IDA有linux版?静态调试器可以跨平台直接调试哇?
    andyhenry
        11
    andyhenry  
       2015-02-06 16:15:54 +08:00
    360的linux版看来没弄反逆向
    retme
        12
    retme  
       2015-02-06 16:29:20 +08:00
    @zjgood IDA有linux版本,但是你在windows上一样可以使用IDA对linux模块进行静态反汇编阿
    retme
        13
    retme  
       2015-02-06 16:29:56 +08:00
    @andyhenry 360 windows的版本,绝大部分模块也没有
    andyhenry
        14
    andyhenry  
       2015-02-06 16:33:18 +08:00
    @retme 我说知乎上怎么有这么多360的“内部分析”。。。看来360得好好找马化腾取取经了
    retme
        15
    retme  
       2015-02-06 17:00:32 +08:00
    @andyhenry 额 其实是腾讯游戏当然反调试需求强,安全软件则更追求稳定性

    其实被逆向了也没啥,有人逆向说明他们的技术还值得去逆向咯~
    zjgood
        16
    zjgood  
       2015-02-06 17:42:54 +08:00 via Android
    @retme 很low的用ollydbg的动态调试思维在思考你们怎么逆向的。。。忘了还有IDA静态调试这货
    acgeo
        17
    acgeo  
       2015-02-06 19:34:11 +08:00
    360 卧槽
    wbsdty331
        18
    wbsdty331  
       2015-02-07 21:09:50 +08:00
    这货的Deepin编译版居然还加了深度桌面的依赖
    怪不得我Linux mint死活提示有个依赖不全装不上去
    josephok
        19
    josephok  
       2015-02-09 22:17:07 +08:00
    醉了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2128 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 11:37 · PVG 19:37 · LAX 04:37 · JFK 07:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.