逆向分析 360 for linux 版本

2015-02-04 14:40:58 +08:00
 wzt

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]);
    }
}
8103 次点击
所在节点    Linux
19 条回复
hicdn
2015-02-04 14:51:30 +08:00
武则天就是屌
sinsin
2015-02-04 15:07:15 +08:00
那这俩可不可以被rmmod呢
(话说github跟这个有何关联。。。brootkit被查到了么
ywj2167917
2015-02-04 15:26:54 +08:00
linux上还装360。也是醉了啊。
andychen20121130
2015-02-04 15:37:43 +08:00
膜拜
yakczh
2015-02-04 16:22:44 +08:00
用livecd启动以后,可以把这两个文件删除掉吗?
TnmsY
2015-02-04 17:18:09 +08:00
不是出了好些年了?
wzt
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
2015-02-04 20:39:04 +08:00
请问楼主Linux Platform用什么工具逆的哇?
retme
2015-02-06 15:58:49 +08:00
@zjgood ...用IDA不是一样的么
zjgood
2015-02-06 16:06:14 +08:00
@retme 呃,IDA有linux版?静态调试器可以跨平台直接调试哇?
andyhenry
2015-02-06 16:15:54 +08:00
360的linux版看来没弄反逆向
retme
2015-02-06 16:29:20 +08:00
@zjgood IDA有linux版本,但是你在windows上一样可以使用IDA对linux模块进行静态反汇编阿
retme
2015-02-06 16:29:56 +08:00
@andyhenry 360 windows的版本,绝大部分模块也没有
andyhenry
2015-02-06 16:33:18 +08:00
@retme 我说知乎上怎么有这么多360的“内部分析”。。。看来360得好好找马化腾取取经了
retme
2015-02-06 17:00:32 +08:00
@andyhenry 额 其实是腾讯游戏当然反调试需求强,安全软件则更追求稳定性

其实被逆向了也没啥,有人逆向说明他们的技术还值得去逆向咯~
zjgood
2015-02-06 17:42:54 +08:00
@retme 很low的用ollydbg的动态调试思维在思考你们怎么逆向的。。。忘了还有IDA静态调试这货
acgeo
2015-02-06 19:34:11 +08:00
360 卧槽
wbsdty331
2015-02-07 21:09:50 +08:00
这货的Deepin编译版居然还加了深度桌面的依赖
怪不得我Linux mint死活提示有个依赖不全装不上去
josephok
2015-02-09 22:17:07 +08:00
醉了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/168194

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX