Save
Saving
  • Zero

    内核重载步奏:
    1、把ntkrnlpa.exe从磁盘中加载到内存
    2、内核基地址重定位
    3、SSDT重定位,还有一个动态获取已加载驱动ntkrnlpa.exe的首地址
    4、先自己调用一个SSDT函数 获得KiFastCallEntry 的函数地址,然后HOOK获取调用SSDT程序的进程名字判断是不是我们工具的名字是转入新内核不是走旧内核;

    #pragma once //只编译一次
    #ifdef __cplusplus
    extern"C"
    {
    #endif
    #include "ntddk.h"
    #include "ntimage.h"
    #ifdef __cplusplus
    }
    #endif //如果是c++代码用c的方式链接{它}
    #define _max(a,b)  a>b?a:b
    //这是一个SSDT表的结构类型先声明一下
    #pragma pack(1)
    typedef struct ServiceDescriptorEntry {
            unsigned int *ServiceTableBase;
            unsigned int *ServiceCounterTableBase;
            unsigned int NumberOfServices;
            unsigned char *ParamTableBase;
    } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
    #pragma pack()
    extern "C"{
            __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
    }
    //遍历驱动名用的一个结构
    typedef struct _LDR_DATA_TABLE_ENTRY {
            LIST_ENTRY InLoadOrderLinks;
            LIST_ENTRY InMemoryOrderLinks;
            LIST_ENTRY InInitializationOrderLinks;
            PVOID DllBase;
            PVOID EntryPoint;
            ULONG SizeOfImage;
            UNICODE_STRING FullDllName;
            UNICODE_STRING BaseDllName;
            ULONG Flags;
            USHORT LoadCount;
            USHORT TlsIndex;
            union {
                    LIST_ENTRY HashLinks;
                    struct {
                            PVOID SectionPointer;
                            ULONG CheckSum;
                    };
            };
            union {
                    struct {
                            ULONG TimeDateStamp;
                    };
                    struct {
                            PVOID LoadedImports;
                    };
            };
    } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
    //全局变量
    PVOID sizeof_image;    //映射到内存的地址指针
    ULONG  OrigImage;    //原来的内核基地址
    ServiceDescriptorTableEntry_t *  pNewSSDT;//新SSDT地址
    ULONG        g_ntcreatefile;         //保存原始的SSDT
    ULONG        g_fastcall_hookpointer; //保存要HOOK的地址
    ULONG        g_goto_origfunc;        //判断后要返回的地址
    //恢复内存保护 
    void PageProtectOn()
    {
            __asm
            {
                    mov  eax, cr0
                    or   eax, 10000h
                    mov  cr0, eax
                    sti
            }
    }
    //去掉内存保护
    void PageProtectOff()
    {
            __asm
            {
                    cli
                    mov  eax, cr0
                    and  eax, not 10000h
                    mov  cr0, eax
            }
    }
    //****************************************判断HOOK部分的******************************************
    //声明函数指针
    typedef NTSTATUS(*NTCREATEFILE) (
            __out PHANDLE FileHandle,
            __in ACCESS_MASK DesiredAccess,
            __in POBJECT_ATTRIBUTES ObjectAttributes,
            __out PIO_STATUS_BLOCK IoStatusBlock,
            __in_opt PLARGE_INTEGER AllocationSize,
            __in ULONG FileAttributes,
            __in ULONG ShareAccess,
            __in ULONG CreateDisposition,
            __in ULONG CreateOptions,
            __in_bcount_opt(EaLength) PVOID EaBuffer,
            __in ULONG EaLength
            );  //声明
    //特征码搜寻
    ULONG SearchHookPointer(ULONG StartAddress)
    {
            ULONG        u_index;
            UCHAR        *p = (UCHAR*)StartAddress;
            for (u_index = 0; u_index < 200; u_index++)
            {
                    if (
                            *p == 0x33 &&
                            *(p + 1) == 0xC9 &&
                            *(p + 2) == 0x8B &&
                            *(p + 3) == 0x57 &&
                            *(p + 4) == 0x0C)
                    {
                            return (ULONG)p;
                    }
                    p--;
            }
            return 0;
    }
    //进程判断
    ULONG   FilterKiFastCallEntry()
    {
    
            ULONG l_deviation;//偏移
            ULONG l_base_address;// 基地址
            ULONG l_current_address;//当前地址
            __asm
            {
                    mov     l_deviation, eax
                            mov     l_base_address, edi
                            mov     l_current_address, edx
            }
    
            //判断是不是要进入SSDT中的函数
            if (l_base_address == (ULONG)KeServiceDescriptorTable.ServiceTableBase)
            {
                    
                    if (strstr((char*)PsGetCurrentProcess() + 0x16c, "FishcOD.exe") || strstr((char*)PsGetCurrentProcess() + 0x16c, "cheatengine") != 0)
                    {
                            //返回新重载的SSDT里
                            return pNewSSDT->ServiceTableBase[l_deviation];
                    }
            }
            //返回原来的地址
            return l_current_address;
    }
    //判断是否是我们通行的进程
    __declspec(naked)
    void NewKiFastCallEntry()
    {
            __asm
            {
                    xor     ecx, ecx
                    mov     edx, dword ptr[edi + 0Ch]
                    mov     edi, dword ptr[edi]
                    mov     cl, byte ptr[eax + edx]
                    mov     edx, dword ptr[edi + eax * 4]
                    sub     esp, ecx
                    shr     ecx, 2
                    pushad
                    pushfd
                    call    FilterKiFastCallEntry
                    mov[esp + 0x18], eax //换的是栈里边的值
    
                    popfd
                    popad
                    jmp   g_goto_origfunc
            }
    }
    //还原HOOK   KiFastCallEntry
    void UnHookKiFastCallEntry()
    {
            UCHAR        str_origfuncode[5] = { 0x33, 0xC9, 0x8B, 0x57, 0x0C };
            if (g_fastcall_hookpointer == 0)
            {
                    return;
            }
            PageProtectOff();
            RtlCopyMemory((PVOID)g_fastcall_hookpointer, str_origfuncode, 5);
            PageProtectOn();
    }
    //替换转跳指令
    void HookKiFastCallEntry(ULONG HookPointer)
    {
            ULONG        u_temp;
            UCHAR        str_jmp_code[5];
            str_jmp_code[0] = 0xE9;
            u_temp = (ULONG)NewKiFastCallEntry - HookPointer - 5;
            *(ULONG*)&str_jmp_code[1] = u_temp;
            PageProtectOff();
            RtlCopyMemory((PVOID)HookPointer, str_jmp_code, 5);
            PageProtectOn();
    }
    //我们呢自己的NtCreateFile
    NTSTATUS NewNtCreateFile(
            __out PHANDLE FileHandle,
            __in ACCESS_MASK DesiredAccess,
            __in POBJECT_ATTRIBUTES ObjectAttributes,
            __out PIO_STATUS_BLOCK IoStatusBlock,
            __in_opt PLARGE_INTEGER AllocationSize,
            __in ULONG FileAttributes,
            __in ULONG ShareAccess,
            __in ULONG CreateDisposition,
            __in ULONG CreateOptions,
            __in_bcount_opt(EaLength) PVOID EaBuffer,
            __in ULONG EaLength
            )
    {
            
            ULONG        u_call_retaddr;
            __asm{
                    pushad
                    mov eax, [ebp + 0x4]
                    mov u_call_retaddr, eax
                    popad
            }
            g_fastcall_hookpointer = SearchHookPointer(u_call_retaddr);
            if (g_fastcall_hookpointer == 0)
            {
                    KdPrint(("search failed."));
            }
            else{
                    KdPrint(("search success."));
            }
            g_goto_origfunc = g_fastcall_hookpointer + 0x12;
            HookKiFastCallEntry(g_fastcall_hookpointer);
            //还原SSDT
            PageProtectOff();
            KeServiceDescriptorTable.ServiceTableBase[66] = (unsigned int)g_ntcreatefile;
            PageProtectOn();
            
            return ((NTCREATEFILE)g_ntcreatefile)(
                    FileHandle, \
                    DesiredAccess, \
                    ObjectAttributes, \
                    IoStatusBlock, \
                    AllocationSize, \
                    FileAttributes, \
                    ShareAccess, \
                    CreateDisposition, \
                    CreateOptions, \
                    EaBuffer, \
                    EaLength);
    }
    //HOOKNtCreateFile
    void SearchKiFastCallEntry()
    {
            
            HANDLE                                hFile;
            NTSTATUS                        Status;
            OBJECT_ATTRIBUTES        ObjAttr;
            UNICODE_STRING                usFileName;
            IO_STATUS_BLOCK                IoStatusBlock;
            RtlInitUnicodeString(&usFileName, L"\\??\\C:\\Windows\\System32\\ntkrnlpa.exe");
            InitializeObjectAttributes(\
                    &ObjAttr, \
                    &usFileName, \
                    OBJ_CASE_INSENSITIVE, \
                    NULL, \
                    NULL);
            g_ntcreatefile = KeServiceDescriptorTable.ServiceTableBase[66];
            PageProtectOff();
            KeServiceDescriptorTable.ServiceTableBase[66] = (unsigned int)NewNtCreateFile;
            PageProtectOn();
            Status = ZwCreateFile(\
                    &hFile, \
                    FILE_ALL_ACCESS, \
                    &ObjAttr, \
                    &IoStatusBlock, \
                    NULL, \
                    FILE_ATTRIBUTE_NORMAL, \
                    FILE_SHARE_READ, \
                    FILE_OPEN, \
                    FILE_NON_DIRECTORY_FILE, \
                    NULL, \
                    0);
            if (NT_SUCCESS(Status))
            {
                    ZwClose(hFile);
            }
    }
    //************************************重定位部分********************************************************************
    //SSDT重定位
    VOID RelocationSSDT(PVOID NewAddress, ULONG RawAddress)
    {                       
            
            ULONG RelativeOffset; //相对的偏移量
            RelativeOffset = (ULONG)NewAddress - RawAddress;//相对的偏移地址
            pNewSSDT = (ServiceDescriptorTableEntry_t*)((ULONG)&KeServiceDescriptorTable + RelativeOffset); //新SSDT地址
            if (!MmIsAddressValid(pNewSSDT))
            {
                    KdPrint(("pNewSsdt is Error"));
                    return;
            }
    
            pNewSSDT->NumberOfServices = KeServiceDescriptorTable.NumberOfServices; //拷贝SSDT函数数量
            ULONG uDeviation; //函数偏移
            uDeviation = (ULONG)KeServiceDescriptorTable.ServiceTableBase - RawAddress;//Relative Virtual Address 相对于基址
            pNewSSDT->ServiceTableBase = (unsigned int*)((ULONG)NewAddress + uDeviation); //新地址加相对偏移地址(旧SSDT-旧基址)
            if (!MmIsAddressValid(pNewSSDT->ServiceTableBase))
            {
                    KdPrint(("pNewSSDT->ServiceTableBase is Error"));
                    return;
            }
            //遍历修改SSDTServiceTableBase数组的值
            int i;
            for (i = 0; i<pNewSSDT->NumberOfServices; i++)
            {
                    pNewSSDT->ServiceTableBase[i] += RelativeOffset;
            }
    
            KdPrint(("success RelocationSSDT"));
    }
    //基地址重定位
    void BaseRelocation(PVOID pNewImage)
    {
            ULONG                                        i;                    //for循环变量
            ULONG                                        uRelocTableSize;      //存放数据块中的数据总个数
            ULONG                                        OriginalImageBase;    //内存文件的首装入地址
            ULONG                                        Type;                 //16位数据高4位
            ULONG                                         *uRelocAddress;       //指向需要修改内容的地址
            PIMAGE_DOS_HEADER                pImageDosHeader;      //DOS头
            PIMAGE_NT_HEADERS                pImageNtHeader;       //NT头
            IMAGE_DATA_DIRECTORY        ImageDataDirectory;   //数据表
            IMAGE_BASE_RELOCATION        *pImageBaseRelocation;//重定位表
    
            //将新内核地址作为一个PE文件头,依次向下,目的是寻找重定位表结构
            pImageDosHeader = (PIMAGE_DOS_HEADER)pNewImage;
            //定位到IMAGE_NT_HEADER
            pImageNtHeader = (PIMAGE_NT_HEADERS)((ULONG)pNewImage + pImageDosHeader->e_lfanew);
            //获取内核文件的imagebase,以便后面做偏移修改。
            OriginalImageBase = pImageNtHeader->OptionalHeader.ImageBase;
            //定位到数据目录
            ImageDataDirectory = pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
            //定位到重定位表结构
            pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)(ImageDataDirectory.VirtualAddress + (ULONG)pNewImage);
            if (pImageBaseRelocation == NULL)
            {
                    return;
            }
            //修改数据*************************
            while (pImageBaseRelocation->SizeOfBlock)
            {   //得到需要更改数据的个数
    
                    uRelocTableSize = (pImageBaseRelocation->SizeOfBlock - 8) / 2;
                    //循环遍历
                    for (i = 0; i<uRelocTableSize; i++)
                    {//判断高4位是否等于3
                            Type = pImageBaseRelocation->TypeOffset[i] >> 12;
                            if (Type == IMAGE_REL_BASED_HIGHLOW)
                            {
                                    //让指针指向要修改的数据
                                    uRelocAddress = (ULONG *)((ULONG)(pImageBaseRelocation->TypeOffset[i] & 0xfff) + pImageBaseRelocation->VirtualAddress + (ULONG)pNewImage);
                                    //修改重定位数据,原数据加上一个偏移
                                    *uRelocAddress = (*uRelocAddress + (OrigImage - OriginalImageBase));
    
                            }
                    }
                    //把指针移到下一个快,如果->SizeOfBlock为空了,表示没有块了退出循环
                    pImageBaseRelocation = (IMAGE_BASE_RELOCATION *)((ULONG)pImageBaseRelocation + pImageBaseRelocation->SizeOfBlock);
            }
            KdPrint(("基址重定位完毕"));
    }
    //重载内核
    VOID  ReloadKernel()  //重载内核
    {
    
            //创建文件*******
            HANDLE    hfile;     //接受句柄
            NTSTATUS  status;    //状态
            IO_STATUS_BLOCK      io_status_block;    //接受状态结构
            OBJECT_ATTRIBUTES    object_attributes;  //句柄属性
            UNICODE_STRING       path_name;
            RtlInitUnicodeString(&path_name, L"\\??\\C:\\Windows\\System32\\ntkrnlpa.exe");
            //初始化对象属性
            InitializeObjectAttributes(&object_attributes, //对象属性变量 POBJECT_ATTRIBUTES OUT  
                    &path_name,                                                                   //文件名   PUNICODE_STRING
                    OBJ_CASE_INSENSITIVE,                      //表示不区分大小写
                    NULL,                                      //NULL
                    NULL);                                     //NULL
            //创建文件
            status = ZwCreateFile(
                    &hfile,                  //返回的句柄  OUT PHANDLE
                    FILE_ALL_ACCESS,         //访问权限->所有权限
                    &object_attributes,      //POBJECT_ATTRIBUTES 该结构包含要打开的文件名
                    &io_status_block,        //PIO_STATUS_BLOCK 返回结果状态 OUT
                    0,                       //初始分配大小,0是动态分配
                    FILE_ATTRIBUTE_NORMAL,   //文件属性 一般为<-或者0;
                    FILE_SHARE_READ,         //指定共享方式一般<- 或者0;
                    FILE_OPEN,               //这个参数指定要对文件干嘛
                    FILE_NON_DIRECTORY_FILE, //指定控制打开操作和句柄使用的附加标志位
                    NULL,                    //指向可选的扩展属性区
                    0);                      //扩展属性区的长度
            if (!NT_SUCCESS(status))
            {
                    KdPrint(("ZwCreateFile Failed!"));
                    return;
            }
            //读取DOS头******
            IMAGE_DOS_HEADER        image_dos_header;//dos头结构
            LARGE_INTEGER       large_integer;//记录偏移
            large_integer.QuadPart = 0;
            status = ZwReadFile(hfile,       //ZwCreateFile成功后得到的句柄  
                    NULL,                        //一个事件  NULL
                    NULL,                        //回调例程。NULL
                    NULL,                        //NULL
                    &io_status_block,            //PIO_STATUS_BLOCK 返回结果状态 OUT ,同上
                    &image_dos_header,           //存放读取数据的缓冲区 OUT PVOID  
                    sizeof(IMAGE_DOS_HEADER),    //试图读取文件的长度
                    &large_integer,              //要读取数据相对文件的偏移量PLARGE_INTEGER
                    0);                          //NULL
            if (!NT_SUCCESS(status))
            {
                    KdPrint(("Read ImageDosHeader Failed!"));
                    ZwClose(hfile);
                    return;
            }
            //读取NT头*******
            IMAGE_NT_HEADERS   image_nt_header;//NT头
            large_integer.QuadPart = image_dos_header.e_lfanew; //PE头偏移
            status = ZwReadFile(hfile,       //ZwCreateFile成功后得到的句柄  
                    NULL,                        //一个事件  NULL
                    NULL,                        //回调例程。NULL
                    NULL,                        //NULL
                    &io_status_block,            //PIO_STATUS_BLOCK 返回结果状态 OUT ,同上
                    &image_nt_header,           //存放读取数据的缓冲区 OUT PVOID  
                    sizeof(IMAGE_NT_HEADERS),    //试图读取文件的长度
                    &large_integer,              //要读取数据相对文件的偏移量PLARGE_INTEGER
                    0);                          //NULL
            if (!NT_SUCCESS(status))
            {
                    KdPrint(("Read image_nt_header Failed!"));
                    ZwClose(hfile);
                    return;
            }
            //读取区块*****
            IMAGE_SECTION_HEADER * p_image_section_header;//指向多个区块结构
            //分配所有模块总大小
            p_image_section_header = (IMAGE_SECTION_HEADER*)ExAllocatePool(NonPagedPool,        //NonPagedPool  从非分页内存池中分配内存 
                    sizeof(IMAGE_SECTION_HEADER)*image_nt_header.FileHeader.NumberOfSections);
            //读
            large_integer.QuadPart += sizeof(IMAGE_NT_HEADERS); //区块偏移
            status = ZwReadFile(hfile,       //ZwCreateFile成功后得到的句柄  
                    NULL,                        //一个事件  NULL
                    NULL,                        //回调例程。NULL
                    NULL,                        //NULL
                    &io_status_block,            //PIO_STATUS_BLOCK 返回结果状态 OUT ,同上
                    p_image_section_header,           //存放读取数据的缓冲区 OUT PVOID  
                    sizeof(IMAGE_SECTION_HEADER)*image_nt_header.FileHeader.NumberOfSections,    //试图读取文件的长度
                    &large_integer,              //要读取数据相对文件的偏移量PLARGE_INTEGER
                    0);                          //NULL
            if (!NT_SUCCESS(status))
            {
                    KdPrint(("Read p_image_section_header Failed!"));
                    ExFreePool(p_image_section_header);
                    ZwClose(hfile);
                    return;
            }
            //复制数据**********
            //PVOID sizeof_image;//定义成全局变量  因为卸载的时候要释放掉内存
            sizeof_image = ExAllocatePool(NonPagedPool, image_nt_header.OptionalHeader.SizeOfImage);//NonPagedPool  从非分页内存池中分配内存 
            if (sizeof_image == 0)
            {
                    KdPrint(("sizeof_image ExAllocatePool Failed!"));
                    ExFreePool(sizeof_image);
                    ExFreePool(p_image_section_header);  //释放内存
                    ZwClose(hfile);
                    return;
            }
            //初始化下内存
            memset(sizeof_image, 0, image_nt_header.OptionalHeader.SizeOfImage);
            RtlCopyMemory(sizeof_image, &image_dos_header, sizeof(IMAGE_DOS_HEADER));        //dos头
            RtlCopyMemory((PVOID)((ULONG)sizeof_image + image_dos_header.e_lfanew),
                    &image_nt_header, sizeof(IMAGE_NT_HEADERS));                                 //nt头
            RtlCopyMemory((PVOID)((ULONG)sizeof_image + image_dos_header.e_lfanew + sizeof(IMAGE_NT_HEADERS)),       //区块
                    p_image_section_header, sizeof(IMAGE_SECTION_HEADER)*image_nt_header.FileHeader.NumberOfSections);//计算区块总大小
    
            
            ULONG sizeof_raw_data;
            for (ULONG i = 0; i<image_nt_header.FileHeader.NumberOfSections; i++)
            {   
                    sizeof_raw_data = _max(p_image_section_header[i].Misc.VirtualSize, p_image_section_header[i].SizeOfRawData);
                    large_integer.QuadPart = p_image_section_header[i].PointerToRawData;   
                    //读
                    status = ZwReadFile(hfile,        
                            NULL,                        
                            NULL,                        
                            NULL,                        
                            &io_status_block,            
                            (PVOID)((ULONG)sizeof_image + p_image_section_header[i].VirtualAddress),          
                            sizeof_raw_data,             
                            &large_integer,              
                            0);                          
                    if (!NT_SUCCESS(status))
                    {
                            KdPrint(("循环区块出错[%s]%x\n",
                                    p_image_section_header[i].Name,
                                    (ULONG)sizeof_image + p_image_section_header[i].VirtualAddress));
    
                            ExFreePool(sizeof_image);
                            ExFreePool(p_image_section_header);  //释放内存
                            ZwClose(hfile);
                            return;
                    }
            }
            BaseRelocation(sizeof_image);
            KdPrint(("重载内存成功"));
    
            ExFreePool(p_image_section_header);  
            ZwClose(hfile);
            return;
    }
    //动态获取基地址
    PVOID SearchDriver(PDRIVER_OBJECT pDriverObject, wchar_t *strDriverName)
    {   
    
    
            LDR_DATA_TABLE_ENTRY        *pDataTableEntry, *pTempDataTableEntry;
            PLIST_ENTRY                                pList;        //下一个节点
            UNICODE_STRING                        usModuleName; // 存放字符串
            
            RtlInitUnicodeString(&usModuleName, strDriverName);
            
            pDataTableEntry = (LDR_DATA_TABLE_ENTRY*)pDriverObject->DriverSection;
            if (!pDataTableEntry)
            {
                    return 0;
            }
    
            pList = pDataTableEntry->InLoadOrderLinks.Flink;
    
            
            while (pList != &pDataTableEntry->InLoadOrderLinks)
            {
                    
                    pTempDataTableEntry = (LDR_DATA_TABLE_ENTRY *)pList;
    
                    
                    if (0 == RtlCompareUnicodeString(&pTempDataTableEntry->BaseDllName, &usModuleName, FALSE))
                    {
                            return pTempDataTableEntry->DllBase;
    
                    }
                    
                    pList = pList->Flink;
            }
            KdPrint(("获取ntkrnlpa.exe基地址失败"));
            return 0;
    }
    //***************************************************************************
    //卸载函数
    VOID MyDriverUnload(IN PDRIVER_OBJECT pDriverObject)
    {
            KdPrint(("成功进入卸载函数"));
            if (sizeof_image != 0)
            {
                    KdPrint(("sizeof_image内存释放"));
                    ExFreePool(sizeof_image);//释放内存
            }
            UnHookKiFastCallEntry();
            KdPrint(("全部卸载完成"));
    }
    //驱动入口
    extern"C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
            IN PUNICODE_STRING pRegistryPath)
    {
            KdPrint(("加载驱动成功"));
            pDriverObject->DriverUnload = MyDriverUnload;//卸载函数
            //获取基地址
            OrigImage = (ULONG)SearchDriver(pDriverObject, L"ntoskrnl.exe");
            if (!OrigImage)
            {
                    KdPrint(("获取ntoskrnl.exe失败"));
                    return 0;
            }
            KdPrint(("ntoskrnl.exe驱动模块首地址=%x", OrigImage));
            //内核重载
            ReloadKernel();
            RelocationSSDT(sizeof_image, OrigImage);
            KdPrint(("加载内存模块首地址=%x", sizeof_image));
            //HOOK KiFastCallEntry;
            SearchKiFastCallEntry();
            return STATUS_SUCCESS;
    }
    

    posted in GuaiK重灾区 read more
  • Zero

    1、首先用指令:uname -r查看内核版本,可以看到我的版本号是3.14的


    2、然后去https://www.kernel.org下载相应版本的内核源代码,我选择下载3.14.7,点击后面的tar.xz即可下载(tar.xz是LINUX下的高压缩版本)


    3、将下载下来的压缩包复制到/usr/src目录下
    sudo cp -r -f -v linux-3.14.7.tar.xz /usr/src


    4、解压内核源代码

    sudo xz -d linux-3.14.7.tar.xz
    sudo tar xvf linux-3.14.7.tar
    

    5、切换到解压后的目录
    cd linux-3.14.7


    6、将系统中自带的.config文件复制到本次解压的目录中
    sudo cp -r -f -v /usr/src/kernels/3.14.6-200.fc20.x86_64/.config ./


    7、开始编译

    make                      (等待1小时,可以泡杯咖啡看看电视)
    make bzImage              (编译压缩形式的内核)
    make modules               (编译选择的模块) 
    make modules_install       (将编译后的模块转移到系统标准位置
    

    posted in GuaiK实验室 read more
  • Zero

    ;****************************************************
    ;DevName:进程导入表API_HOOK
    ;By:guluting
    ;****************************************************
                            .386
                            .model flat,stdcall
                            option casemap:none
    ;****************************************************
    include                        windows.inc
    include                        user32.inc
    includelib                user32.lib
    include                        kernel32.inc
    includelib                kernel32.lib
    include                        rsrc.inc
    include                        psapi.inc
    includelib                psapi.lib
     
    AFD_RECV        equ        12017h
    AFD_SEND        equ        1201fh
     
    AFD_WSABUF        struct
            len        dd        ?
            buf        dd        ?
    AFD_WSABUF ends        
    AFD_INFO        struct
            lpWsaBuf        dd        ?
            BufferCount        dd        ?
            AfdFlags        dd        ?
            TdiFlags        dd        ?
    AFD_INFO ends
    ;****************************************************
    .data?
    hHook                dd        ?
    hWinMain        dd        ?
    hWinSetting        dd        ?
    .data
    hInstance        dd        ?
    hCurProc        dd        ?
    lpNtDeviceIoControl        dd        ?        ;存放旧NtDeviceIoControl
    lpNewNtDeviceIoControl        dd        ?        ;存放新NtDeviceIoControl
    ImportNtDeviceIoControl        dd        ?        ;导入表中用于存放NtDeviceIoControl地址的内存
     
    .const
    szCaption        db        '提示!',0
    szMswsock        db        'mswsock.dll',0
    szNtDll                db        'ntdll.dll',0
    szNtDeviceIoControlFile        db        'NtDeviceIoControlFile',0
     
    .code
    ;------------------------------------------------------
    ;NtDeviceIoControlFile回调函数
    ;------------------------------------------------------
    NewNtDeviceIoControlFile        proc        FileHandle,Event,ApcRoutine,ApcContext,\
                                            IoStatusBlock,IoControlCode,InputBuffer,\
                                            InputBufferLength,OutputBuffer,OutputBufferLength
            LOCAL        @buf[1024]:byte
             
            mov eax,IoControlCode
            .if        eax == AFD_SEND
                    pushad
                    invoke RtlZeroMemory,addr @buf,sizeof @buf
                    mov edi,InputBuffer
                    assume edi:ptr AFD_INFO
                    mov edi,[edi].lpWsaBuf
                    assume edi:ptr AFD_WSABUF
                    invoke lstrlen,[edi].buf
                    .if        eax < 10
                            jmp @F
                    .endif
                    invoke RtlMoveMemory,addr @buf,[edi].buf,[edi].len
                    ;显示封包内容
                    invoke SendDlgItemMessage,hWinSetting,IDC_PACKET_LIST,LB_ADDSTRING,0,addr @buf
                    invoke SendDlgItemMessage,hWinSetting,IDC_PACKET_LIST,LB_GETCOUNT,0,0
                    dec eax
                    invoke SendDlgItemMessage,hWinSetting,IDC_PACKET_LIST,LB_SETCURSEL,eax,0
                    popad
                    assume edi:nothing
            .endif
    @@:
            ;调用原始NtDeviceIoControlFile
            push        OutputBufferLength
            push        OutputBuffer
            push        InputBufferLength
            push        InputBuffer
            push        IoControlCode
            push        IoStatusBlock
            push        ApcContext
            push        ApcRoutine
            push        Event
            push        FileHandle
            call lpNtDeviceIoControl
            ret
    NewNtDeviceIoControlFile        endp
    ;------------------------------------------------------
    ;还原函数
    ;------------------------------------------------------
    _UnHookDeviceIoControl        proc
            LOCAL        @btw
            invoke WriteProcessMemory,hCurProc,ImportNtDeviceIoControl,offset lpNtDeviceIoControl,sizeof dword,addr @btw
            ret
    _UnHookDeviceIoControl endp
    ;------------------------------------------------------
    ;拦截函数
    ;------------------------------------------------------
    _HookDeviceIoControl        proc
            LOCAL        @hMod
            LOCAL        @btw
            LOCAL        @import
            LOCAL        @count
            mov @count,0
            ;获取模块起始地址
            invoke GetModuleHandle,offset szMswsock
            .if        !eax
                    ret
            .endif
            mov @hMod,eax
            pushad
            mov esi,eax
            assume esi:ptr IMAGE_DOS_HEADER
            movzx eax,[esi].e_magic
            .if        (eax != IMAGE_DOS_SIGNATURE)
                    ret
            .endif
            add esi,[esi].e_lfanew
            assume esi:ptr IMAGE_NT_HEADERS
            mov eax,[esi].Signature
            .if        (eax != IMAGE_NT_SIGNATURE)
                    ret
            .endif
            mov esi,[esi].OptionalHeader.DataDirectory[8].VirtualAddress
            .if        !esi
                    ret
            .endif
            add esi,@hMod
            assume esi:ptr IMAGE_IMPORT_DESCRIPTOR        ;esi指向了第一个导入表
            ;循环处理每一个导入表
            .while [esi].OriginalFirstThunk || [esi].TimeDateStamp || \
                    [esi].ForwarderChain || [esi].Name1 || [esi].FirstThunk
                    mov edx,@hMod
                    add edx,[esi].Name1
                    invoke lstrcmp,edx,offset szNtDll
                    .if        eax == 0
                            mov @import,esi        ;导入表RVA
                            .break
                    .endif
                    add esi,sizeof IMAGE_IMPORT_DESCRIPTOR
            .endw
            ;当前为ntdll的导入表
            mov esi,[esi].OriginalFirstThunk        
            add esi,@hMod                                ;esi当前指向IMAGE_THUNK_DATA结构数组
            assume edx:ptr IMAGE_IMPORT_BY_NAME
            .while        esi
                    .if        esi & IMAGE_ORDINAL_FLAG32
                    .else
                            mov edx,@hMod
                            add edx,dword ptr [esi]
                            invoke lstrcmp,addr [edx].Name1,offset szNtDeviceIoControlFile
                            .if        eax == 0
                                    mov esi,@import
                                    mov esi,[esi].FirstThunk
                                    add esi,@hMod
                                    mov eax,sizeof IMAGE_THUNK_DATA
                                    mul @count
                                    add esi,eax
                                    mov eax,dword ptr [esi]
                                    mov lpNtDeviceIoControl,eax
                                    mov eax,offset NewNtDeviceIoControlFile
                                    mov lpNewNtDeviceIoControl,eax
                                    mov ImportNtDeviceIoControl,esi
                                    ;写入自己程序的地址进行跳转
                                    invoke WriteProcessMemory,hCurProc,esi,offset lpNewNtDeviceIoControl,sizeof dword,addr @btw
                                    .break
                            .endif
                    .endif
                    add esi,4
                    mov eax,@count
                    add eax,1
                    mov @count,eax
            .endw
            assume edx:nothing
            assume esi:nothing
            popad
            ret
     
    _HookDeviceIoControl endp
    ;------------------------------------------------------
    ;Hook回调函数
    ;-------------------------------------------------------
    _HookCallBack        proc        _dwCode,_wParam,lParam
     
            invoke CallNextHookEx,hHook,_dwCode,_wParam,lParam
            ret
                     
    _HookCallBack endp
    ;-------------------------------------------------------
    ;安装当前钩子函数
    ;-------------------------------------------------------
    _InstallUrlHook        proc _hWnd,_hWinSetting
            push        _hWnd
            pop        hWinMain
            push        _hWinSetting
            pop        hWinSetting
            invoke SetWindowsHookEx,WH_GETMESSAGE,offset _HookCallBack,hInstance,NULL
            mov hHook,eax
            ret
    _InstallUrlHook endp
    ;-------------------------------------------------------
    ;卸载当前钩子函数
    ;-------------------------------------------------------
    _UnInstallUrlHook        proc
            invoke UnhookWindowsHookEx,hHook
            ret
    _UnInstallUrlHook endp
    ;-------------------------------------------------------
    ;动态链接库入口
    ;-------------------------------------------------------
    DllEnter        proc        _hInstance,_dwReason,_dwReserved
            mov eax,_dwReason
            .if        eax == DLL_PROCESS_ATTACH
                    push _hInstance
                    pop hInstance
                    invoke GetCurrentProcess
                    mov hCurProc,eax
                    call _HookDeviceIoControl
            .elseif        eax == DLL_PROCESS_DETACH
                    call _UnHookDeviceIoControl
            .endif
            mov eax,TRUE
            ret
     
    DllEnter endp
    end DllEnter
    
    

    posted in GuaiK重灾区 read more
  • Zero

    @裸奔的de饺子 常用的消息协议有三种:AMQP, MQTT, STOMP,RabbitMQ消息队列默认支持的是AMQP协议,但是应该也可以让RabbitMQ使用MQTT协议。😑

    posted in GuaiK实验室 read more
  • Zero

    @裸奔的de饺子 我接触过最轻量的消息队列是ZeroMQ,不过作者好像去了另一个世界了,不知道现在还有没有人在维护了。ZeroMQ不需要部署任何服务,基本上消息队列支持的几种模式它都有。

    posted in GuaiK实验室 read more
  • Zero

    @裸奔的de饺子 我们现在在使用的微服务框架Nameko+RabbitMQ消息队列,目前测试下来使用比较轻便也稳定😀

    posted in GuaiK实验室 read more
  • Zero

    simhash是locality sensitive hash(局部敏感哈希)的一种,最早由Moses Charikar在《similarity estimation techniques from rounding algorithms》一文中提出。Google就是基于此算法实现网页文件查重的。
    simhash将一个文档转换成一个64位的字节的simhash值,然后判断重复只需要判断他们的simhash值的距离是不是<n,就可以判断两个文档是否相似。

    #-*- coding:UTF-8 -*-
    #
    # 文章内容查重模块
    
    import jieba
    from simhash import Simhash, SimhashIndex
    
    class CheckDup():
        def __init__(self):
            self.__index = None
    
        def add_index(self,key,value):
            s = Simhash([tag for tag in jieba.cut_for_search(value) if len(tag)>2])
            if self.__index == None:
                print "init check dup..."
                # k=16
                self.__index = SimhashIndex([(key,s)], k=16)
            else:
                # print "add index key:"+key
                self.__index.add(key,s)
    
        def del_index(self,key,value):
            s = Simhash([tag for tag in jieba.cut_for_search(value) if len(tag)>2])
            if self.__index:
                # print "del index key:"+key
                self.__index.delete(key,s)
    
        def update_index(self,key,old_v,new_v):
            os = Simhash([tag for tag in jieba.cut_for_search(old_v) if len(tag)>2])
            ns = Simhash([tag for tag in jieba.cut_for_search(new_v) if len(tag)>2])
            if self.__index:
                # print "update index key:"+key
                self.__index.delete(key,os)
                self.__index.add(key,ns)
    
        def find_near(self,value):
            if self.__index == None:
                return []
            s = Simhash([tag for tag in jieba.cut_for_search(value) if len(tag)>2])
            return self.__index.get_near_dups(s)
    
    

    posted in GuaiK实验室 read more
  • Zero

    #-*- coding:UTF-8 -*-
    from numpy import *
    def loadDataSet():
        postingList = [
            ["my","dog","has","flea","problems","help","please"],
            ["maybe","not","take","him","to","dog","park","stupid"],
            ["my","dalmation","is","so","cute","I","love","him"],
            ["stop","posting","stupid","worthless","garbage"],
            ["mr","licks","ate","my","steak","how","to","stop","him"],
            ["quit","buying","worthless","dog","food","stupid"]
        ]
        classVec = [0,1,0,1,0,1]    # 1代表侮辱性文字,0代表正常言论
        return postingList,classVec
    
    def createVocabList(dataSet):
        vocabSet = set([])
        for document in dataSet:
            vocabSet = vocabSet | set(document) # 计算所有文档并集
        return list(vocabSet)
    
    
    def setOfWords2Vec(vocabList,inputSet):
        returnVec = [0]*len(vocabList)
        for word in inputSet:
            if word in vocabList:
                returnVec[vocabList.index(word)] += 1
            else:
                print "the word:%s is not in my Vocabulary!" % word
        return returnVec
    
    
    def trainNBO(trainMatrix,trainCategory):
        numTrainDocs = len(trainMatrix)     # 计算出待训练的文档数
        numWords = len(trainMatrix[0])      # 计算出单词总数
        pAbusive = sum(trainCategory)/float(numTrainDocs) # 计算出侮辱性文档占总文档的比值
        p0Num = ones(numWords)
        p1Num = ones(numWords)
        p0Denom = 2.0
        p1Denom = 2.0
        for i in range(numTrainDocs):
            if trainCategory[i] == 1: # 侮辱性文档
                p1Num += trainMatrix[i]
                p1Denom += sum(trainMatrix[i])
            else:
                p0Num += trainMatrix[i]
                p0Denom += sum(trainMatrix[i])
        p1Vect = log(p1Num/p1Denom)
        p0Vect = log(p0Num/p0Denom)
        return p0Vect,p1Vect,pAbusive
    
    
    def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
        p1 = sum(vec2Classify * p1Vec) + log(pClass1)
        p0 = sum(vec2Classify * p0Vec) + log(1.0-pClass1)
        if p1 > p0:
            return 1
        else:
            return 0
    
    def testNB():
        listOPosts,listClasses = loadDataSet()
        myVocabList = createVocabList(listOPosts)
        trainMat = []
        for postinDoc in listOPosts:
            trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
        p0V,p1V,pAb = trainNBO(array(trainMat),array(listClasses))
        testEntry = ["quit","buying","worthless","dog","food","stupid"]
        thisDoc = array(setOfWords2Vec(myVocabList,testEntry))
        print testEntry,"classified as:",classifyNB(thisDoc,p0V,p1V,pAb)
    
    testNB()
    

    posted in GuaiK实验室 read more
  • Zero

    Python集合处理常见的有添加,删除,交集与并集操作。
    以下是集合操作的常见符号:

    数学符号 Python符号 含义
    - - 差集
    & 交集
    并集

    集合创建

    [输入]set("ghostds")
    [输出]set(['d', 'g', 'h', 'o', 's', 't'])
    

    交集

    [输入]a = set("abc")
    [输入]b = set("cdef")
    [输入]a & b
    [输出]set(['c'])
    

    并集

    [输入]a = set("abc")
    [输入]b = set("cdef")
    [输入]a | b
    [输出]set(['a', 'c', 'b', 'e', 'd', 'f'])
    

    差集

    [输入]a = set("abc")
    [输入]b = set("cdef")
    [输入]a - b
    [输出]set(['a', 'b'])
    

    posted in GuaiK实验室 read more