Save
Saving
  • guluting

    重点讲解:
    装饰器(@)是Python中非常重要的『东西』,你在微博中艾特谁,她还是她,你改变不了她。但是在python中你艾特了某个函数,你将对它拥有控制权,哪怕把它改的面目全非也是可以的。
    装饰器是什么意思呢?
    装饰器就是一个接受函数对象的函数,好吧,有点绕口,请看代码:

    class Girl():
        def __init__(self):
            self.msg = "Girl:I dislike you!"
        def output(self):
            return self.msg
    
    def Change(obj):
        # 洗脑模式
        obj.msg = "Girl:I like you!"
        return obj
    
    print Change(Girl()).output()
    # 输出结果:Girl:I like you!
    

    那么显然写成Change(Girl()).output()不是很直观,我们来换一种更Pythoner的:
    直接通过装饰器去改写输出函数output,在函数输出前修改msg数据

    def ChangeOutput(msg):
        def change_output(func):
            def new_output(s):
                s.msg = "Girl:I like you!"
                return func(s)
            return new_output
        return change_output
    
    class Girl():
        instance = None
        def __init__(self):
            self.msg = "Girl:I dislike you!"
    
        @ChangeOutput("Girl:I link you!")
        def output(self):
            return self.msg
    
    print Girl().output()
    

    下面就是用装饰器来模拟Flask的原理了。

    # -*- coding: utf-8 -*-
    class GuaikNet():
        def __init__(self):
            # URI与处理函数的映射
            self._func_map = {}
    
        def route(self, uri):       # 装饰器,用来接受参数
            def _new_func(func):    # 新的函数对象,用来替代被装饰的函数,参数为被装饰的函数对象
                self._func_map[uri] = func
                return func
            return _new_func
    
        def server(self, uri):
            func = self._func_map[uri]
            if func:
                return func()
            else:
                raise ValueError('Route "{}" has not been registered'.format(uri))
    
    app = GuaikNet()
    @app.route("/")
    def hello():
        return "Hello GuaikNet"
    
    print app.server("/")
    

    posted in GuaiK实验室 read more
  • guluting

    VSCode是微软出品的一款比较轻量的文本编辑工具,和Github出品的Atom类似,而且都提供了很强大的插件功能。
    CMake是一款跨平台的编译工具,它能够生成各种项目文件或makefile文件。
    决定使用VSCode+CMake编译驱动的主要原因是感觉Visual Studio太过于臃肿了吧,自从写驱动程序以来都经历过了使用文本编辑器或者VC++6.0开发,微软的产品功能越来越全面的同时也会让产品变得太臃肿了。开发驱动程序脚本编辑器足矣。


    下面需要准备的工具(自行安装):

    下载WDK

    https://docs.microsoft.com/zh-cn/windows-hardware/drivers/download-the-wdk

    下载VSCode

    https://code.visualstudio.com/

    下载CMake

    https://cmake.org/download/

    下载FindWDK项目(用来搜索WDK相关路径)

    https://github.com/SergiusTheBest/FindWDK.git


    建立工程目录:

    NetFilter(主目录)
    |--cmake
        |--FindWdk.cmake     # 在FindWDK中复制过来
    |--network               # FWPM网络过滤模块
        |--main.c
        |--CMakeLists.txt
    |--CMakeLists.txt        # CMake配置文件
    |--build.bat             # 自动编译脚本
    

    相关代码

    network->main.c

    #pragma once
    #pragma warning(push)
    #pragma warning(disable : 4201)
    #pragma warning(disable : 4324)
    #define NDIS_SUPPORT_NDIS6 1
    #include <ntifs.h>
    #include <ntddk.h>
    #include <ndis.h>
    #include <fwpsk.h>
    #include <fwpmk.h>
    #include <wdm.h>
    #pragma warning(pop)
    #define INITGUID
    #include <guiddef.h>
    
    #define DEVICE_NAME L"\\Device\\GhostNet"
    #define DEVICE_DOSNAME L"\\DosDevices\\GhostNet"
    #define kmalloc(_s) ExAllocatePoolWithTag(NonPagedPool, _s, 'GSYS')
    #define kfree(_p) ExFreePool(_p)
    
    DEFINE_GUID
        (
            GUID_ALE_AUTH_CONNECT_CALLOUT_V4,
            0x6812fc83,
            0x7d3e,
            0x499a,
            0xb8, 0x59,
            0x55, 0xe0, 0xd8, 0x5f, 0x34, 0x8b);
    
    
    
    PDEVICE_OBJECT gDevObj;
    HANDLE gEngineHandle = 0;
    HANDLE gInjectHandle = 0;
    
    UINT32 gAleConnectCalloutId = 0;
    UINT64 gAleConnectFilterId = 0;
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING regPath);
    VOID DriverUnload(PDRIVER_OBJECT driver);
    
    //协议代码转为名称
    char *ProtocolIdToName(UINT16 id)
    {
        char *ProtocolName = (char *)kmalloc(16);
        switch (id)
        {
        case 1:
            strcpy_s(ProtocolName, 4 + 1, "ICMP");
            break;
        case 2:
            strcpy_s(ProtocolName, 4 + 1, "IGMP");
            break;
        case 6:
            strcpy_s(ProtocolName, 3 + 1, "TCP");
            break;
        case 17:
            strcpy_s(ProtocolName, 3 + 1, "UDP");
            break;
        case 27:
            strcpy_s(ProtocolName, 3 + 1, "RDP");
            break;
        default:
            strcpy_s(ProtocolName, 7 + 1, "UNKNOWN");
            break;
        }
        return ProtocolName;
    }
    
    NTSTATUS NTAPI WallNotifyFn(
        IN FWPS_CALLOUT_NOTIFY_TYPE notifyType,
        IN const GUID *filterKey,
        IN const FWPS_FILTER *filter)
    {
        return STATUS_SUCCESS;
    }
    
    VOID NTAPI WallFlowDeleteFn(
        IN UINT16 layerId,
        IN UINT32 calloutId,
        IN UINT64 flowContext)
    {
        return;
    }
    
    
    
    // 连接过滤
    void NTAPI ALEConnectClassify(
        IN const FWPS_INCOMING_VALUES0 *inFixedValues,
        IN const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues,
        IN OUT void *layerData,
        IN const void *classifyContext,
        IN const FWPS_FILTER *filter,
        IN UINT64 flowContext,
        OUT FWPS_CLASSIFY_OUT *classifyOut)
    {
        char *ProtocolName = NULL;
        DWORD LocalIp, RemoteIP;
        LocalIp = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_ADDRESS].value.uint32;
        RemoteIP = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_ADDRESS].value.uint32;
        ProtocolName = ProtocolIdToName(inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_PROTOCOL].value.uint16);
        DbgPrint("[WFP]IRQL=%d;PID=%ld;Path=%S;Local=%u.%u.%u.%u:%d;Remote=%u.%u.%u.%u:%d;Protocol=%s\n",
                 (USHORT)KeGetCurrentIrql(),
                 (DWORD)(inMetaValues->processId),
                 (PWCHAR)inMetaValues->processPath->data, //NULL,//
                 (LocalIp >> 24) & 0xFF, (LocalIp >> 16) & 0xFF, (LocalIp >> 8) & 0xFF, LocalIp & 0xFF,
                 inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_PORT].value.uint16,
                 (RemoteIP >> 24) & 0xFF, (RemoteIP >> 16) & 0xFF, (RemoteIP >> 8) & 0xFF, RemoteIP & 0xFF,
                 inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_PORT].value.uint16,
                 ProtocolName);
        
        kfree(ProtocolName);
        classifyOut->actionType = FWP_ACTION_PERMIT; //允许连接
    
        //禁止IE联网(设置“行动类型”为FWP_ACTION_BLOCK)
        // if(wcsstr((PWCHAR)inMetaValues->processPath->data,L"iexplore.exe"))
        // {
        // classifyOut->actionType = FWP_ACTION_BLOCK;
        // classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
        // classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
        // }
        return;
    }
    
    
    /*
    * 注册过滤层回调函数
    */
    NTSTATUS RegisterCalloutForLayer(
        IN const GUID *layerKey,
        IN const GUID *calloutKey,
        IN FWPS_CALLOUT_CLASSIFY_FN classifyFn,
        IN FWPS_CALLOUT_NOTIFY_FN notifyFn,
        IN FWPS_CALLOUT_FLOW_DELETE_NOTIFY_FN flowDeleteNotifyFn,
        OUT UINT32 *calloutId,
        OUT UINT64 *filterId)
    {
        NTSTATUS status = STATUS_SUCCESS;
        FWPS_CALLOUT sCallout = {0};
        FWPM_FILTER mFilter = {0};
        FWPM_FILTER_CONDITION mFilter_condition[1] = {0};
        FWPM_CALLOUT mCallout = {0};
        FWPM_DISPLAY_DATA mDispData = {0};
        BOOLEAN bCalloutRegistered = FALSE;
        sCallout.calloutKey = *calloutKey;
        sCallout.classifyFn = classifyFn;
        sCallout.flowDeleteFn = flowDeleteNotifyFn;
        sCallout.notifyFn = notifyFn;
        status = FwpsCalloutRegister(gDevObj, &sCallout, calloutId);
        if (!NT_SUCCESS(status))
        {
            DbgPrint("FwpsCalloutRegister failed.");
            goto exit;
        }
        bCalloutRegistered = TRUE;
        mDispData.name = L"WFP TEST";
        mDispData.description = L"TESLA.ANGELA's WFP TEST";
        mCallout.applicableLayer = *layerKey;
        mCallout.calloutKey = *calloutKey;
        mCallout.displayData = mDispData;
        status = FwpmCalloutAdd(gEngineHandle, &mCallout, NULL, NULL);
        if (!NT_SUCCESS(status))
        {
            DbgPrint("FwpmCalloutAdd falied");
            goto exit;
        }
        mFilter.action.calloutKey = *calloutKey;
        mFilter.action.type = FWP_ACTION_CALLOUT_TERMINATING;
        mFilter.displayData.name = L"WFP TEST";
        mFilter.displayData.description = L"TESLA.ANGELA's WFP TEST";
        mFilter.layerKey = *layerKey;
        mFilter.numFilterConditions = 0;
        mFilter.filterCondition = mFilter_condition;
        mFilter.subLayerKey = FWPM_SUBLAYER_UNIVERSAL;
        mFilter.weight.type = FWP_EMPTY;
        status = FwpmFilterAdd(gEngineHandle, &mFilter, NULL, filterId);
        if (!NT_SUCCESS(status))
        {
            DbgPrint("FwpmFilterAdd failed");
            goto exit;
        }
    exit:
        if (!NT_SUCCESS(status))
        {
            if (bCalloutRegistered)
            {
                FwpsCalloutUnregisterById(*calloutId);
            }
        }
        return status;
    }
    
    NTSTATUS WallRegisterCallouts()
    {
        NTSTATUS status = STATUS_SUCCESS;
        BOOLEAN bInTransaction = FALSE;
        BOOLEAN bEngineOpened = FALSE;
        FWPM_SESSION session = {0};
        session.flags = FWPM_SESSION_FLAG_DYNAMIC;
        status = FwpmEngineOpen(NULL,
                                RPC_C_AUTHN_WINNT,
                                NULL,
                                &session,
                                &gEngineHandle);
        if (!NT_SUCCESS(status))
            goto exit;
        bEngineOpened = TRUE;
        status = FwpmTransactionBegin(gEngineHandle, 0);
        if (!NT_SUCCESS(status))
            goto exit;
        bInTransaction = TRUE;
        // 注册Connect
        status = RegisterCalloutForLayer(
            &FWPM_LAYER_ALE_AUTH_CONNECT_V4,
            &GUID_ALE_AUTH_CONNECT_CALLOUT_V4,
            ALEConnectClassify,
            WallNotifyFn,
            WallFlowDeleteFn,
            &gAleConnectCalloutId,
            &gAleConnectFilterId);
        if (!NT_SUCCESS(status))
        {
            DbgPrint("RegisterCalloutForLayer-FWPM_LAYER_ALE_AUTH_CONNECT_V4 failed!\n");
            goto exit;
        }
    
        status = FwpmTransactionCommit(gEngineHandle);
        if (!NT_SUCCESS(status))
            goto exit;
        bInTransaction = FALSE;
    exit:
        if (!NT_SUCCESS(status))
        {
            if (bInTransaction)
            {
                FwpmTransactionAbort(gEngineHandle);
            }
            if (bEngineOpened)
            {
                FwpmEngineClose(gEngineHandle);
                gEngineHandle = 0;
            }
        }
        return status;
    }
    
    NTSTATUS WallUnRegisterCallouts()
    {
        if (gEngineHandle != 0)
        {
            // 删除FilterId
            FwpmFilterDeleteById(gEngineHandle, gAleConnectFilterId);
            // 删除CalloutId
            FwpmCalloutDeleteById(gEngineHandle, gAleConnectCalloutId);
            // 清空FilterId
            gAleConnectFilterId = 0;
            // 反注册CalloutId
            FwpsCalloutUnregisterById(gAleConnectCalloutId);
            // 清空CalloutId
            gAleConnectCalloutId = 0;
            // 关闭引擎
            FwpmEngineClose(gEngineHandle);
            gEngineHandle = 0;
        }
        return STATUS_SUCCESS;
    }
    
    // #pragma alloc_text(PAGE, DriverUnload)
    VOID DriverUnload(PDRIVER_OBJECT driver)
    {
        UNICODE_STRING DeviceDosName;
        WallUnRegisterCallouts();
        RtlInitUnicodeString(&DeviceDosName,DEVICE_DOSNAME);
        IoDeleteSymbolicLink(&DeviceDosName);
        IoDeleteDevice(driver->DeviceObject);
    }
    
    NTSTATUS DefIRPHandler(IN PDEVICE_OBJECT devobj, IN PIRP Irp){
        Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_SUCCESS;
    }
    
    NTSTATUS CreateIRPHandler(IN PDEVICE_OBJECT devobj, IN PIRP Irp){
        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_SUCCESS;
    }
    
    NTSTATUS CloseIRPHandler(IN PDEVICE_OBJECT devobj, IN PIRP Irp){
        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_SUCCESS;
    }
    
    // #pragma alloc_text(INIT, DriverEntry)
    NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING regPath)
    {
        // PAGED_CODE();
        NTSTATUS status;
        UNICODE_STRING DeviceName,DeviceDosName;
        RtlInitUnicodeString(&DeviceName,DEVICE_NAME);
        RtlInitUnicodeString(&DeviceDosName,DEVICE_DOSNAME);
        // 设置默认IRP派遣处理函数
        for(UINT i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++){
            driver->MajorFunction[i] = DefIRPHandler;
        }
        //  IRP 打开关闭处理函数
        driver->MajorFunction[IRP_MJ_CREATE] = CreateIRPHandler;
        driver->MajorFunction[IRP_MJ_CLOSE] = CloseIRPHandler;
        driver->DriverUnload = DriverUnload;
        status = IoCreateDevice(driver,
                                0,
                                NULL,
                                FILE_DEVICE_UNKNOWN,
                                0, TRUE,
                                &gDevObj);
        if (!NT_SUCCESS(status))
            return status;
        if (!gDevObj)
            return STATUS_UNEXPECTED_IO_ERROR;
        status = WallRegisterCallouts();
        if (!NT_SUCCESS(status))
            return status;
        
    
        // 设置设备读写方式
        gDevObj->Flags |= DO_DIRECT_IO;
        // 创建符号链接
        status = IoCreateSymbolicLink(&DeviceDosName, &DeviceName);
        gDevObj->Flags &= ~ DO_DEVICE_INITIALIZING;
        return STATUS_SUCCESS;
    }
    

    network->CMakeLists.txt

    SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/./build)
    wdk_add_driver(network main.c)
    target_link_libraries(network ntoskrnl ndis fwpkclnt uuid)
    

    NetFilter->CMakeLists.txt
    其中需要自己设置一下WDK Library链接的路径

    cmake_minimum_required(VERSION 3.0)
    
    project(NetFilter)
    
    set_property(GLOBAL PROPERTY USE_FOLDERS ON)
    
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0 /WX")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W0 /WX")
    
    list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/./cmake")
    find_package(WDK REQUIRED)
    
    # 设置WDK Library路径
    link_directories("C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.17134.0\\km\\x86")
    add_subdirectory(comport)
    add_subdirectory(network)
    

    NetFilter->build.bat
    如果需要编译Release版本的请替换脚本中的Debug字符串

    cmake .
    devenv ./NetFilter.sln /Build "Debug"
    

    祝你成功编译出sys文件 😈
    0_1540261742778_WX20181023-102839@2x.png

    posted in GuaiK重灾区 read more
  • guluting

    收费的,不过价格不贵。短信验证的签名不需要审核,你在brand中填什么它就给你显示什么,及时性还不错。

    posted in GuaiK实验室 read more
  • guluting

    NEXMO官网

    https://www.nexmo.com/

    短信验证码发送与验证实例


    api_key和api_secret替换成你自己的。


    import logging
    import requests
    
    api_key = "your_api_key"
    api_secret = "your_api_secret"
    brand = "Guaik"
    
    def sendVerifyCode(self,number):
        # param  : number 接收验证码的手机号
        # retval : 返回请求id,在验证的时候会用到
        request_id = None
        try:
            data = {"api_key":api_key,"api_secret":api_secret,"number":number,"brand":brand}
            headers = {'Content-Type': 'application/json'}
            r = requests.post("https://api.nexmo.com/verify/json",headers = headers, data = json.dumps(data))
            data = json.loads(r.text)
            if data["status"] == "0":
                request_id = data["request_id"]
        except Exception as e: logging.error(e)
        return request_id
    
    
    def checkCode(self,request_id,code):
        # param request_id : 请求id,在发送验证码成功时返回
        # param code       : 手机接收到的验证码
        # retval           : 验证成功返回True
        result = False
        try:
            data = {"api_key":api_key,"api_secret":api_secret,"request_id":request_id,"code":code}
            headers = {'Content-Type': 'application/json'}
            r = requests.post("https://api.nexmo.com/verify/check/json",headers = headers, data = json.dumps(data))
            data = json.loads(r.text)
            if data["status"] == "0":
                result = True
        except Exception as e: logging.error(e)
        return result
    
    

    posted in GuaiK实验室 read more
  • guluting

    《怪客实验室》的观念


    精神:我们会乐而不疲的去创造轮子,总有些人不明白创造轮子的乐趣。

    价值:如果不会饿死,折腾技术是否能盈利已经没那么重要了。(希望靠未来技术赚钱,而不是搬砖)


    《怪客实验室》的目的


    为有想法的开发人员,设计师提供一个交流互动的平台。一起创造新事物,互助解决难题。


    《怪客实验室》的观方向


    机器学习,游戏引擎,信息安全,图像算法,音效算法,虚拟现实(AR)


    《怪客实验室》的最优成员


    • 擅长软件开发,软件调试,算法
    • 有自己长期的研究方向

    关注我们的公众号:
    qrcode_for_gh_bcb1ef62b874_430.jpg

    posted in GuaiK新闻 read more
  • guluting

    特地的将prepareGeometryChange()拿出来说是因为它是一个很容易让人忽视掉的一个函数。
    用过QGraphicsItem类去绘图的应该都知道每个图元都是有一个矩形的轮廓的,通过在下列函数中设置

    QRectF QGraphicsItem::boundingRect() const{
        return QRectF(l, t, w, h);
    }
    

    我们再实际使用中的时候会经常去的改变图元的位置,因为你创建的图元不可能永远都是静态的(你可以直接贴个图片得了)
    我们会通过函数去绘制我们的图元:

    int g_left;    // 左边距参数
    void QGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
        Q_UNUSED(option);
        Q_UNUSED(widget);
        QColor color = QColor(0x00,0x00,0x00);
        color.setAlpha(50);
        painter->setPen(QPen(color,1));
        painter->setBrush(QColor(0xff,0xff,0xff));
        painter->setOpacity(1);
        painter->drawRect(g_left,t,w,h); 
    }
    

    我们可能会通过鼠标的位置去改变左边距的参数

    void CursorItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        if (event->buttons() == Qt::LeftButton) {
            g_left = event->pos().x();
            prepareGeometryChange();      # 请看这一句 这是重点
            QGraphicsScene::update();     # 伪代码,通知场景刷新图元
        }
    }
    

    prepareGeometryChange()的目的在于通知场景即将发生的变化,这样场景会去刷新图元的位置坐标,否则,场景将不会察觉到item的变化,结果也未知。为了避免一些未知异常的产生,每次在修改图片坐标或形状时,按照以下步骤进行:

    • 修改boundingRect中用到的参数数据(坐标)本例中的g_left。

    • 列表然后调用prepareGeometryChange()去通知scene即将发生变化。

    • 列表QGraphicsScene::update();强制让场景层刷新图元数据。

    posted in GuaiK实验室 read more
  • guluting

    备份

    # -h:主机地址    -d:数据库名称
    # 该指令会在当前目录生成dump目录,数据库备份目录就在其中
    mongodump -h localhost:27017 -d [db_name]
    

    恢复

    # -h 主机地址    -d:数据库名称    最后跟上之前备份的数据库路径
    mongorestore -h localhost:27017 -d [db_name]  ./dump/[db_name]
    

    posted in GuaiK机房 read more
  • guluting

    @joy 很赞,有种生化危机的风格☣

    posted in GuaiK设计师 read more
  • guluting

    安装

    yum install python-setuptools && easy_install pip
    pip install shadowsocks
    

    启动

    # -p:端口 -k:密码 -m:加密协议
    sudo ssserver -p 40000 -k [passwd] -m rc4-md5 --user nobody -d start
    # 防火墙添加端口号
    yum remove iptables
    yum install firewalld
    systemctl enable firewalld
    systemctl start firewalld
    firewall-cmd --zone=public --add-port=40000/tcp --permanent
    firewall-cmd --reload
    

    停止

    sudo ssserver -d stop
    

    posted in GuaiK机房 read more
  • guluting

    Mac安装MTR:
    brew install mtr

    MTR检测路由状态:
    sudo mtr -w [host]

    0_1539839470557_WX20181018-131059@2x.png

    posted in GuaiK机房 read more