精华内容
下载资源
问答
  • 反光检测

    2021-01-13 20:55:50
    Automatic segmentation and inpainting of specular highlights for endoscopic imaging 论文反光检测部分pythonn实现 代码写的很乱,可直接运行,后期有时间在整理整理,写写注释 import cv2 import numpy as np ...

    Automatic segmentation and inpainting of specular highlights for endoscopic imaging 论文反光检测部分pythonn实现

    代码写的很乱,可直接运行,后期有时间在整理整理,写写注释

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    import scipy
    
    from skimage import measure, filters, data
    
    img = cv2.imread('../data/fazhi/95.jpg')
    w = img.shape[0]
    h = img.shape[1]
    
    # model1
    cR = img[:, :, 0]
    cG = img[:, :, 1]
    cB = img[:, :, 2]
    
    cE = 0.2989 * cR + 0.5870 * cG + 0.1140 * cB
    
    
    def calc_module1_specular_mask(cE, cG, cB, T1):
        p95_cG = cG * 0.95
        p95_cE = cE * 0.95
        p95_cB = cB * 0.95
        # p95_cG = prctile(cG(:), 95)
        # p95_cB = prctile(cB(:), 95)
        # p95_cE = prctile(cE(:), 95)
        rGE = p95_cG / p95_cE
        rBE = p95_cB / p95_cE
        img_new = np.zeros((w, h, 1))
        for i in range(0, w):
            for j in range(0, h):
    
                if all([(cG[i][j] > rGE[i][j] * T1), (cB[i][j] > rBE[i][j] * T1), (cE[i][j] > T1)]):
                    img_new[i][j] = 255
                else:
                    img_new[i][j] = 0
    
        return img_new
    
    
    module1_specular_mask = calc_module1_specular_mask(cE, cG, cB, T1=240)
    cv2.imwrite('../data/New/95-model1.jpg',module1_specular_mask)
    
    
    # cv2.imshow('s',img)
    
    
    def calc_centroid_color_info(specular_mask_T2_abs, img):
        kernel = np.ones((2, 2), np.uint8)
        dilated_mask_1 = cv2.erode(specular_mask_T2_abs, kernel, iterations=1)
        kernel = np.ones((4, 4), np.uint8)
        dilated_mask_2 = cv2.erode(specular_mask_T2_abs, kernel, iterations=1)
        centroid_color_area = dilated_mask_2 - dilated_mask_1
        labeled_area = measure.label(centroid_color_area)  # 连通区域标记
        num_region = max(labeled_area.reshape(labeled_area.shape[0] * labeled_area.shape[1]))
        centroid_color_info = []
        for i in range(1, num_region):
            dict = {}
            [row_index, col_index] = np.where(labeled_area == i)
            num_possible_specular_points = len(row_index)
            dict['centroid_row'] = np.mean(row_index)
            dict['centroid_col'] = np.mean(col_index)
            dict['centroid_color'] = np.mean(img[row_index, col_index, :])  ## 不明确
            centroid_color_info.append(dict)
    
        return centroid_color_info
    
    
    def calc_distance(x, y, x1, y1):
        distance_to_centroid = np.sqrt((x - x1) ** 2 + (y - y1) ** 2)
        return distance_to_centroid
    
    
    def find_the_nearest_region(centroid_color_info, pixel_row, pixel_col):
        num_region = len(centroid_color_info)
        nearset_region_index = 0
        nearset_distance = 1e6
        for j in range(1, num_region):
            distance_to_centroid = calc_distance(pixel_row, pixel_col, centroid_color_info[j]['centroid_row'],
                                                 centroid_color_info[j]['centroid_col'])
            if distance_to_centroid < nearset_distance:
                nearset_distance = distance_to_centroid
                nearset_region_index = j
    
        nearest_region = centroid_color_info[nearset_region_index]
        return nearest_region
    
    
    def filling_image_using_centroid_color(specular_mask_T2_abs, img):
        # filling possible specular highlights by the centroid color
        centroid_color_info = calc_centroid_color_info(specular_mask_T2_abs, img)
        specular_mask_T2_abss = specular_mask_T2_abs.reshape(specular_mask_T2_abs.shape[0], specular_mask_T2_abs.shape[1])
        [row_index, col_index] = np.where(specular_mask_T2_abss == 255)
        num_possible_specular_points = len(row_index)
        filled_img = img
        for i in range(1, num_possible_specular_points):
            # looking for the nearst centroid color for every specular point
            # and fill it
            nearest_region = find_the_nearest_region(centroid_color_info, row_index[i], col_index[i])
            filled_img[row_index[i], col_index[i], :] = nearest_region['centroid_color']
        return filled_img
    
    
    def contrast_coeffcient(c):
        mean_c = np.mean(c);
        std_c = np.std(c);
        t = 1 / ((mean_c + std_c) / mean_c)
        return t
    
    
    def calc_modul2_specular_mask(filled_img, T2_rel, cR, cG, cB):
        R = filled_img[:, :, 0]
        fR = cv2.medianBlur(R, 31)
        fG = cv2.medianBlur(filled_img[:, :, 1], 31)
        fB = cv2.medianBlur(filled_img[:, :, 2], 31)
        filtered_img = np.stack((fR, fG, fB), axis=2)
    
        for i in range(filled_img.shape[0]):
            for j in range(filled_img.shape[1]):
                if (fR[i][j] < 2.2204e-16):
                    fR[i][j] = 1e7
                if (fG[i][j] < 2.2204e-16):
                    fG[i][j] = 1e7
                if (fB[i][j] < 2.2204e-16):
                    fB[i][j] = 1e7
        tR = contrast_coeffcient(cR)
        tG = contrast_coeffcient(cG)
        tB = contrast_coeffcient(cB)
    
        max_img = np.stack(((tR * cR / fR), (tG * cG / fG), (tB * cB / fB)), axis=2)
        e_max = np.amax(max_img, 2)
        module2_specular_mask = e_max > T2_rel
        return module2_specular_mask
    
        # fR(fR <  2.2204e-16) = 1e7
        # fG(fG <  2.2204e-16) = 1e7
        # fB(fB <  2.2204e-16) = 1e7
    
    
    # model2
    specular_mask_T2_abs = calc_module1_specular_mask(cE, cG, cB, T1=190)
    
    filled_img = filling_image_using_centroid_color(specular_mask_T2_abs, img)
    plt.imshow(filled_img)
    plt.show()
    module2_specular_mask = calc_modul2_specular_mask(filled_img, T2_rel=1.2, cR=cR, cG=cG, cB=cB)
    # module2_specular_mask = np.array(module2_specular_mask)
    
    final_mask = np.zeros((w, h, 1))
    for i in range(0, w):
        for j in range(0, h):
            if module2_specular_mask[i][j] == True or module1_specular_mask[i][j] == 255:
                final_mask[i][j][0] = 255
            else:
                final_mask[i][j][0] = 0
    
    N_min = 5000
    T3 = 5
    
    
    def postprocessing(final_mask, cE, N_min, T3):
        kernel = np.ones((3, 3), np.uint8)
        final_mask = cv2.erode(final_mask, kernel, iterations=1)
        labeled_area = measure.label(final_mask)
        num_region = np.max(labeled_area[:])
        post_specular_mask = final_mask
        for i in range(1, num_region):
            index = np.where(labeled_area == i)
            if (len(index) >= N_min):
                post_specular_mask[index] = 0
    
        return post_specular_mask
    
    
    mask = postprocessing(final_mask, cE, N_min=3000, T3=5)
    
    mg_gray = cv2.imread('../data/fazhi/95.jpg', cv2.IMREAD_GRAYSCALE)
    # 利用图像中要提取的目标区域与其背景在灰度特性上的差异,把图像看作具有不同灰度级的两类区域(目标区域和背景区域)的组合,选取一个比较合理的阈值
    thresh = filters.threshold_otsu(mg_gray)
    
    # ret,thresh = cv2.threshold(img,cv2.THRESH_BINARY)
    # 根据阈值分割
    TTTT = np.zeros((w, h))
    dst = (mg_gray >= thresh) * 255.0
    
    for i in range(0, w):
        for j in range(0, h):
            if mask[i][j] > 0 and dst[i][j] > 0:
                TTTT[i][j] = 255
    
    image2 = np.concatenate([TTTT, mask, dst], axis=1)
    #cv2.imwrite(r"D:\code dp\YXTX\data\New\TTTT2.jpg", TTTT)
    plt.set_cmap("binary")
    # plt.imshow(TTTT)
    # plt.imshow(mask)
    # plt.imshow(dst)
    plt.imshow(image2)
    
    plt.show()
    cv2.imwrite('../data/New/95_mask.jpg',TTTT)
    cv2.imwrite('../data/New/95_mask-image2.jpg',image2)
    
    # cv2.imshow('d', module2_specular_mask)
    # cv2.waitKey()
    # module2_specular_mask = module2_specular_mask*255
    # cv2.imshow('6',filled_img)
    # plt.imshow(module2_specular_mask)
    # #plt.set_camp('binary')
    # plt.show()
    
    
    ### inpainting
    
    decay_win_size = 10
    decay_cof = 20
    
    
    def InpainttingArnold2010(mask, img, decay_win_size, decay_cof):
        filled_img = filling_image_using_centroid_color(mask, img)
        cv2.imwrite('../data/New/95filled.jpg', filled_img)
        # plt.set_cmap("binary")
        # plt.imshow(filled_img)
        # plt.show()
        sig = 8
        gaussian_filtered_img = cv2.GaussianBlur(filled_img, (3, 3), sig, sig)
        cv2.imshow('s',gaussian_filtered_img)
    
        #mx = imfilter(double(specular_mask), ones(decay_win_size)/decay_cof)
        mx = scipy.ndimage.filters.convolve(mask, np.ones((decay_win_size,decay_win_size))/decay_cof, mode='nearest')
        cv2.imshow('mx',mx)
        cv2.waitKey()
        mx = mx + mask
        mx = (mx > 1) *1
        mx = np.array([mx])
        mx = mx.reshape(w,h,1)
        inpainted_img = mx * (gaussian_filtered_img) + (1 - mx) * img
        return inpainted_img
    
    
    inpainted_img = InpainttingArnold2010(TTTT, img, decay_win_size, decay_cof)
    #plt.imshow(inpainted_img)
    cv2.imwrite('../data/New/95inpaint.jpg',inpainted_img)
    plt.show()
    
    

    自己添加一个固定阈值后做并集

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    import scipy
    
    from skimage import measure, filters, data
    
    img = cv2.imread('../data/fazhi/8.jpg')
    w = img.shape[0]
    h = img.shape[1]
    
    # model1
    cR = img[:, :, 0]
    cG = img[:, :, 1]
    cB = img[:, :, 2]
    
    cE = 0.2989 * cR + 0.5870 * cG + 0.1140 * cB
    
    
    def calc_module1_specular_mask(cE, cG, cB, T1):
        p95_cG = cG * 0.95
        p95_cE = cE * 0.95
        p95_cB = cB * 0.95
        # p95_cG = prctile(cG(:), 95)
        # p95_cB = prctile(cB(:), 95)
        # p95_cE = prctile(cE(:), 95)
        rGE = p95_cG / p95_cE
        rBE = p95_cB / p95_cE
        img_new = np.zeros((w, h, 1))
        for i in range(0, w):
            for j in range(0, h):
    
                if all([(cG[i][j] > rGE[i][j] * T1), (cB[i][j] > rBE[i][j] * T1), (cE[i][j] > T1)]):
                    img_new[i][j] = 255
                else:
                    img_new[i][j] = 0
    
        return img_new
    
    
    module1_specular_mask = calc_module1_specular_mask(cE, cG, cB, T1=240)
    cv2.imwrite('../data/New/8-model1.jpg',module1_specular_mask)
    
    
    # cv2.imshow('s',img)
    
    
    def calc_centroid_color_info(specular_mask_T2_abs, img):
        kernel = np.ones((4, 4), np.uint8)
        dilated_mask_1 = cv2.erode(specular_mask_T2_abs, kernel, iterations=1)
        kernel = np.ones((6, 6), np.uint8)
        dilated_mask_2 = cv2.erode(specular_mask_T2_abs, kernel, iterations=1)
        centroid_color_area = dilated_mask_2 - dilated_mask_1
        labeled_area = measure.label(centroid_color_area)  # 连通区域标记
        num_region = np.max(labeled_area.reshape(labeled_area.shape[0] * labeled_area.shape[1]))
        centroid_color_info = []
        for i in range(1, num_region):
            dict = {}
            [row_index, col_index] = np.where(labeled_area == i)
            num_possible_specular_points = len(row_index)
            dict['centroid_row'] = np.mean(row_index)
            dict['centroid_col'] = np.mean(col_index)
            ii = img[row_index, col_index, :]
            dict['centroid_color'] = np.mean(ii,axis=0)  ## 不明确
            centroid_color_info.append(dict)
    
        return centroid_color_info
    
    
    def calc_distance(x, y, x1, y1):
        distance_to_centroid = np.sqrt((x - x1) ** 2 + (y - y1) ** 2)
        return distance_to_centroid
    
    
    def find_the_nearest_region(centroid_color_info, pixel_row, pixel_col):
        num_region = len(centroid_color_info)
        nearset_region_index = 0
        nearset_distance = 1e6
        for j in range(1, num_region):
            distance_to_centroid = calc_distance(pixel_row, pixel_col, centroid_color_info[j]['centroid_row'],
                                                 centroid_color_info[j]['centroid_col'])
            if distance_to_centroid < nearset_distance:
                nearset_distance = distance_to_centroid
                nearset_region_index = j
    
        nearest_region = centroid_color_info[nearset_region_index]
        return nearest_region
    
    
    def filling_image_using_centroid_color(specular_mask_T2_abs, img):
        # filling possible specular highlights by the centroid color
        centroid_color_info = calc_centroid_color_info(specular_mask_T2_abs, img)
        specular_mask_T2_abss = specular_mask_T2_abs.reshape(specular_mask_T2_abs.shape[0], specular_mask_T2_abs.shape[1])
        [row_index, col_index] = np.where(specular_mask_T2_abss > 0)
        num_possible_specular_points = len(row_index)
        filled_img = img
        for i in range(1, num_possible_specular_points):
            # looking for the nearst centroid color for every specular point
            # and fill it
            nearest_region = find_the_nearest_region(centroid_color_info, row_index[i], col_index[i])
            filled_img[row_index[i], col_index[i], :] = nearest_region['centroid_color']
        return filled_img
    
    
    def contrast_coeffcient(c):
        mean_c = np.mean(c);
        std_c = np.std(c);
        t = 1 / ((mean_c + std_c) / mean_c)
        return t
    
    
    def calc_modul2_specular_mask(filled_img, T2_rel, cR, cG, cB):
        R = filled_img[:, :, 0]
        fR = cv2.medianBlur(R, 31)
        fG = cv2.medianBlur(filled_img[:, :, 1], 31)
        fB = cv2.medianBlur(filled_img[:, :, 2], 31)
        filtered_img = np.stack((fR, fG, fB), axis=2)
    
        for i in range(filled_img.shape[0]):
            for j in range(filled_img.shape[1]):
                if (fR[i][j] < 2.2204e-16):
                    fR[i][j] = 1e7
                if (fG[i][j] < 2.2204e-16):
                    fG[i][j] = 1e7
                if (fB[i][j] < 2.2204e-16):
                    fB[i][j] = 1e7
        tR = contrast_coeffcient(cR)
        tG = contrast_coeffcient(cG)
        tB = contrast_coeffcient(cB)
    
        max_img = np.stack(((tR * cR / fR), (tG * cG / fG), (tB * cB / fB)), axis=2)
        e_max = np.amax(max_img, 2)
        module2_specular_mask = e_max > T2_rel
        return module2_specular_mask
    
        # fR(fR <  2.2204e-16) = 1e7
        # fG(fG <  2.2204e-16) = 1e7
        # fB(fB <  2.2204e-16) = 1e7
    
    
    # model2
    specular_mask_T2_abs = calc_module1_specular_mask(cE, cG, cB, T1=190)
    
    filled_img = filling_image_using_centroid_color(specular_mask_T2_abs, img)
    #plt.imshow(filled_img)
    plt.show()
    module2_specular_mask = calc_modul2_specular_mask(filled_img, T2_rel=1.2, cR=cR, cG=cG, cB=cB)
    # module2_specular_mask = np.array(module2_specular_mask)
    
    final_mask = np.zeros((w, h, 1))
    for i in range(0, w):
        for j in range(0, h):
            if module2_specular_mask[i][j] == True or module1_specular_mask[i][j] == 255:
                final_mask[i][j][0] = 255
            else:
                final_mask[i][j][0] = 0
    
    N_min = 5000
    T3 = 5
    
    
    def postprocessing(final_mask, cE, N_min, T3):
        kernel = np.ones((3, 3), np.uint8)
        final_mask = cv2.erode(final_mask, kernel, iterations=1)
        labeled_area = measure.label(final_mask)
        num_region = np.max(labeled_area[:])
        post_specular_mask = final_mask
        for i in range(1, num_region):
            index = np.where(labeled_area == i)
            if (len(index) >= N_min):
                post_specular_mask[index] = 0
    
        return post_specular_mask
    
    
    mask = postprocessing(final_mask, cE, N_min=3000, T3=5)
    
    mg_gray = cv2.imread('../data/fazhi/8.jpg', cv2.IMREAD_GRAYSCALE)
    # 利用图像中要提取的目标区域与其背景在灰度特性上的差异,把图像看作具有不同灰度级的两类区域(目标区域和背景区域)的组合,选取一个比较合理的阈值
    thresh = filters.threshold_otsu(mg_gray)
    
    # ret,thresh = cv2.threshold(img,cv2.THRESH_BINARY)
    # 根据阈值分割
    TTTT = np.zeros((w, h))
    dst = (mg_gray >= thresh) * 255.0
    
    for i in range(0, w):
        for j in range(0, h):
            if mask[i][j] > 0 and dst[i][j] > 0:
                TTTT[i][j] = 255
    
    
    ## 固定阈值
    
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    blurred = cv2.GaussianBlur(gray, (11, 11), 0)
    
    # threshold the image to reveal light regions in the
    # blurred image
    
    #y = blurred[:,:,2]/(blurred[:,:,1] + blurred[:,:,2] + blurred[:,:,3])
    
    th = cv2.threshold(blurred, 200, 255, cv2.THRESH_BINARY)[1]
    
    
    for i in range(0, w):
        for j in range(0, h):
            if TTTT[i][j]>0 or th[i][j]>0:
                TTTT[i][j]=255
    
    
    
    
    image2 = np.concatenate([TTTT, mask, dst], axis=1)
    #cv2.imwrite(r"D:\code dp\YXTX\data\New\TTTT2.jpg", TTTT)
    plt.set_cmap("binary")
    # plt.imshow(TTTT)
    # plt.imshow(mask)
    # plt.imshow(dst)
    #plt.imshow(image2)
    
    plt.show()
    cv2.imwrite('../data/New/8_mask+uzhi.jpg',TTTT)
    
    展开全文
  • 虚拟机检测与反检测相关

    千次阅读 2011-10-03 15:58:03
    虚拟机软件的漏洞和虚拟机执行环境的检测与反检测(一) 虚拟机软件的漏洞和虚拟机执行环境的检测与反检测(二) vmware的检测与反检测 检测虚拟机汇编代码 漏洞法检测虚拟机 虚拟机检测技术剖析 检测...

    虚拟机软件的漏洞和虚拟机执行环境的检测与反检测(一)

    虚拟机软件的漏洞和虚拟机执行环境的检测与反检测(二)

    vmware的检测与反检测

    检测虚拟机汇编代码

    漏洞法检测虚拟机

    虚拟机检测技术剖析

    检测源码:

    #include <windows.h>
    #include <stdio.h>
    
    BOOL gInVMWARE, gInVirtualPC;
    
    BOOL VMWareTest()
    {
    BYTE PortValue1,PortValue2;
    __try
    {
        __asm
        {
          pushad 
          pushfd
          xor ebx,ebx
          mov ecx,0xa 
          mov eax, 'VMXh'        ; EAX=magic    //564D5868
          mov dx, 'VX'            ; DX=magic
          in eax, dx            ; specially processed io cmd
          cmp ebx, 'VMXh'        ; also eax/ecx modified (maybe vmw/os ver?)
          sete al;
        movzx eax, al
          mov gInVMWARE, eax;
          popfd
          popad
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        gInVMWARE=FALSE;
    }
    return gInVMWARE;
    }
    
    BOOL VirtualPCTest()
    {
    __try
    {
        __asm
        {
          pushad      
          mov ebx, 0 // Flag
          mov eax, 1 // VPC function number
          __emit 0Fh
          __emit 3Fh
          __emit 07h
          __emit 0Bh
          test ebx, ebx
        sete al
        movzx eax, al
          mov gInVirtualPC , eax;
          popad
        }
    
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        gInVirtualPC=FALSE;
    }
    return gInVirtualPC;
    }
    
    BOOL VMTest()
    {
        ULONG xdt = 0 ;
        ULONG InVM = 0;
        __asm
        {
            push edx
                sidt [esp-2]
                pop edx
                nop
                mov xdt , edx
        }
        printf("idt = %08x\n" , xdt);
        if (xdt > 0xd0000000)
        {
            //printf("IDT Test :running in vm!\n");
            InVM = 1;
        }
        else
        {
            InVM = 0;
        }
        __asm
        {
            push edx
                sgdt [esp-2]
                pop edx
                nop
                mov xdt , edx
        }
        
        printf("gdt = %08x\n" , xdt);
        
        if (xdt > 0xd0000000)
        {
            InVM += 1;
        }
        else
        {
            InVM += 0;
        }
        return InVM;
    }
    
    int main()
    {
        if (VMWareTest())
        {
            printf("In Vmware !!!");
        }
        else if (VirtualPCTest())
        {
            printf("In VirtualPC!!!!");
        }
        else if (VMTest())
        {
            printf("In VM !");
        }
        else
        {
            printf("In Host!");
        }
        
        getchar ();
        return 1;
    }


    过虚拟机中Themida检测方法:
    两步可以通吃很多Anti-vmware的方法

    第一步是在虚拟机系统的配置文件添加 

    monitor_control.restrict_backdoor = "true"

    关闭后门

    第二步建议开起虚拟机,然后虚拟机 - 设置 - Hardware - Processors - 禁止加速二进制翻译勾起

    或添加

    disable_acceleration = "TRUE"



    其它参考:

    http://forum.eviloctal.com/thread-31834-1-1.html

    展开全文
  • 游戏外挂检测和反检测

    万次阅读 2010-04-24 22:56:00
    关于游戏外挂检测和反检测(真正的防封技术)在网上找到篇关于游戏外挂检测和反检测的文章拿来跟断点的朋友分享。详细文章见附件,这里写些简介。 一:内存探测法 服务器发送个Paket检测游戏内存,然后返回服务器...

    关于游戏外挂检测和反检测(真正的防封技术)
    在网上找到篇关于游戏外挂检测和反检测的文章拿来跟断点的朋友分享。详细文章见附件,这里写些简介。
        一:内存探测法
            服务器发送个Paket检测游戏内存,然后返回服务器。这对游戏公开的挂威胁大。
            反侦测基本思想是拦截Peket,返回伪装Peket。
        二:DLL扫描
            游戏反外挂系统(Module32First/Module32Next)扫描游戏中的DLL,返回。
            反侦测思想是DLL隐藏。
        三:进程扫描
            游戏反外挂系统(Process32First/Process32Next)扫描用户进程,返回。
            反侦测思想也是进程隐藏(如将外挂进程注入到游戏进程)
        四:窗口扫描
            游戏反外挂系统(EnumWindows)扫描进程窗口,返回。这主要针对有GUI界面的外挂(外挂都有)
            反侦测思想是随机产生窗口类名和窗口名。(现在很多外挂都能做到这点)

    暴雪和黑客的战争(游戏外挂与反外挂)BZ加亮
    [    sell=5][/sell][    post]如前一篇文章所说,D2X中hacks的发展大约可以分为三个阶段,即前1.10的发展成熟期,1.10的过渡期以及1.11的衰落期。
    一直到1.09d(1.10前的最后一个版本)为止,D2X中几乎没有作弊检测机制,这一时期是hacker们最幸福的时期。说没有是因为它没有专门的检测代码,而说几乎没有是因为它有些机制还是可以用来做作弊检测用途的。
    一处是它的自动升级机制。在战网上玩过的玩家都知道,每次连到战网的时候,会有一个对话框提示正在检查游戏版本,如果用户本机和服务器端额版本不一致的话,自动进行升级。Diablo的自动升级功能在游戏业界可能是首创,这大大降低了游戏的上手难度。我接触过不少外国玩家,跟国内玩家不同的是,他们中很多人都是一些15岁不到的小孩,让他们自己从网上下载补丁包升级几乎是不可能的事。自动升级的过程如下:
    1,玩家连到战网;
    2,服务器端发送一个专门用于版本检查的DLL到客户端;
    3,客户端在本机保存该DLL;
    4,客户端调用LoadLibrary加载DLL
    5,客户端调用该DLL导出的一个函数。该函数通过计算几个重要的客户端游戏文件的校验判断版本是否匹配,不匹配则做自动升级。
    6,客户端版本检测完毕,调用FreeLibrary卸载DLL并删除文件。

    在这个过程中,由于版本检查DLL保存在服务器端,因此显然它可能会被随时修改,增加一些其他功能,如作弊检测。从版本检测相关代码(见文末)调用的Win32 API,LoadLibraryA/GetProcAddress/FreeLibrary/DeleteFileA,可以大致看出这一过程。


    另外一处不为人知的机制是,在玩家连上战网后,服务器端有时(不是一定会发,而且发送时机也不确定)会发送一个DLL (Extrawork.dll)到客户端运行,然后把结果返回给服务器端,其工作原理和版本检测机制的工作原理非常类似。显然这个机制也可以用于作弊检测。不过根据很多hacker观测的结果,extrawork.dll一般用于收集玩家的系统配置信息,包括CPU主频、内存容量、操作系统版本等。

    虽然这两点机制都可能用于作弊检测,但在1.10以前的时间里,没有迹象表明暴雪利用了这点,因此在这一时期出现的hacks也都没有相应的反检测措施。

    版本检测的相关代码:

    XXXX45A3                 lea     ecx, [esp+124h]
    XXXX45AA                 push    ecx             ; IX86ver0.dll
    XXXX45AB                 call    ds:LoadLibraryA
    XXXX45B1                 mov     ebp, eax
    XXXX45B3                 test    ebp, ebp
    XXXX45B5                 jz      loc_6FF046F1
    XXXX45BB                 push    offset aCheckrevision ; "CheckRevision"
    XXXX45C0                 push    ebp             ; hModule
    XXXX45C1                 call    ds:GetProcAddress
    XXXX45C7                 mov     esi, eax
    XXXX45C9                 test    esi, esi
    XXXX45CB                 jnz     short loc_6FF045DF
    XXXX45CD                 push    offset aErrorFailedT_0 ; "<ERROR: Failed to execute Versioning DL"...
    XXXX45D2                 call    nullsub_1
    XXXX45D7                 add     esp, 4
    XXXX45DA                 jmp     loc_6FF046EA
    XXXX45DF loc_XXXX45DF:
    ;......
    XXXX46E6                 call    esi             ; CheckRevision
    XXXX46E8                 mov     ebx, eax
    XXXX46EA
    XXXX46EA loc_XXXX46EA:                           ; CODE XREF: DownloadAndRunVersioningDLL+15A j
    XXXX46EA                 push    ebp             ; hLibModule
    XXXX46EB                 call    ds:FreeLibrary
    XXXX46F1
    XXXX46F1 loc_XXXX46F1:                           ; CODE XREF: DownloadAndRunVersioningDLL+F3 j
    XXXX46F1                                         ; DownloadAndRunVersioningDLL+11E j ...
    XXXX46F1                 mov     eax, [esp+430h+hArchive]
    XXXX46F5                 pop     ebp
    XXXX46F6                 test    eax, eax
    XXXX46F8                 jz      short loc_XXXX4700
    XXXX46FA                 push    eax             ; hArchive
    XXXX46FB                 call    Storm_252_SFileCloseArchive
    XXXX4700
    XXXX4700 loc_XXXX4700:                           ; CODE XREF: DownloadAndRunVersioningDLL+278 j
    XXXX4700                 push    32h             ; dwMilliseconds
    XXXX4702                 call    ds:Sleep
    XXXX4708                 mov     esi, ds:DeleteFileA
    XXXX470E                 push    offset g_szVersionDLLName ; lpFileName
    XXXX4713                 call    esi ; DeleteFileA
    XXXX4715                 mov     al, [esp+42Ch+FileName]
    XXXX471C                 test    al, al
    XXXX471E                 jz      short loc_XXXX472A
    XXXX4720                 lea     eax, [esp+42Ch+FileName]
    XXXX4727                 push    eax             ; lpFileName
    XXXX4728                 call    esi ; DeleteFileA


    暴雪在WOW开发的后期,终于能够腾出人手来升级持续了2年之久的D2X 1.09d。由于1.09d时期hacks泛滥,暴雪觉得有必要打击一下这种嚣张的气焰,于是加入了hacks检测机制,这就是在1.10时期经常提起的packet 64/65检测。

    何谓packet?packet即网络数据包,D2中服务器端和客户端之间的交互是通过互相发送packet进行的。D2中的packet又分为out-of-game(进入游戏前)packet和in-game(游戏内)packet两种,这里提到的都是in-game packet。in-game packet的第一个字节为packet ID,指示该packet的含义,接着的是相应的(可变长)参数。比如ID 01代表walk命令,长度为5字节,ID后面跟两个16位参数,指示walk的目的坐标,因此它的格式为:01 [WORD x] [WORD y]。需要注意的是D2中不同patch版本的packet ID含义是不一样的,不能通用。1.10中的一个比较完整的in-game packet列表可以在这里找到:http://www.edgeofnowhere.cc/viewtopic.php?t=303771

    跟hacks检测有关的是packet 64和65。packet 64长度是9字节,格式为:64 [DWORD address 1] [DWORD address 2],后面的两个DWORD是服务器端想检测的两个内存地址;packet 65长度为1字节(没有参数),检查4个最有可能被patch的地址。packet 64/65的检查结果经过简单的混淆处理(增加sniffer抓包分析的难度)后发送回服务器端,如果被检测地址里的指令或数据被改过,检测结果自然就和原先的不符,因此暴雪就知道你在用hack。这种检测方法就是所谓的memory probe,即内存探测法。那暴雪怎么知道应该检测哪些地址呢?hack的detour patch(旁路点)是固定的,像maphack和d2jsp这种著名的公开发行的hack,暴雪当然会拿来研究因此也会知道它们patch了哪些地方。至于那些自己开发自娱自乐的,暴雪是没法知道的,因此相对安全点儿。但是如果你的patch点正好和maphack、d2jsp这些相同,那还是有可能不幸中标。

    以下为packet 64检测中的相关代码片断,其中eax和ecx分别为两个待检测的内存地址,检测结果分别存入局部变量var_result1和var_result2中随后发送回服务器端:

    .text:XXXXF362 $CHECK_RESULT1: ; CODE XREF: CheckDetectionResult+87 j
    .text:XXXXF362 cmp eax, esi ; not zero
    .text:XXXXF364 jz short $CLEAR_RESULT1 ; Jump if Zero (ZF=1)
    .text:XXXXF366 mov [ebp+arg1], esi
    .text:XXXXF369 mov eax, [eax]
    .text:XXXXF36B mov [ebp+var_result1], eax
    .text:XXXXF36E mov [ebp+arg1], -1
    .text:XXXXF375 jmp short $CHECK_RESULT2 ; Jump

    .text:XXXXF39B $CHECK_RESULT2: ; CODE XREF: CheckDetectionResult+A5 j
    .text:XXXXF39B ; CheckDetectionResult+C4 j
    .text:XXXXF39B cmp ecx, esi ; Compare Two Operands
    .text:XXXXF39D jz short $CLEAR_RESULT2 ; Jump if Zero (ZF=1)
    .text:XXXXF39F mov [ebp+arg1], 1
    .text:XXXXF3A6 mov ecx, [ecx]
    .text:XXXXF3A8 mov [ebp+var_result2], ecx
    .text:XXXXF3AB mov [ebp+arg1], -1
    .text:XXXXF3B2 jmp short $SEND_DETECT_RESULT ; Jump

    packet 65的检测代码和packet 64类似,除了它检测的是几个固定地址。

    packet 64/65的memory probe机制,结合前一篇介绍过的已有的version-checking.dll和extrawork.dll,就构成了暴雪在Diablo II 1.10 patch中采用的hacks检测机制。

    下图显示了d2jsp 1.2.0中使用的部分旁路点(d2jsp 1.2.0用于Diablo II 1.11b,但意思是一样的)。

    暴雪在1.10补丁中加入hack检测机制,在某种程度上直接导致了原本和谐的D2X游戏黑客社群的分裂。一部分出于对检测机制的顾虑,停止更 新自己的作品,如d2hackit;另一部分则把他们的hack具有的反检测功能当成卖点开始收费,如d2maphack和d2jsp;还有一部分黑客出 于不满开始制作这些收费hacks的替代品,如d2hackmap,C3PO,d2bs等;甚至有些黑客出来破解这些收费hacks。

    如前一篇文章所说,暴雪在1.10中加入packet 64/65检测。最早公布packet 64被用作hack检测的是jhj。当然Mousepad在jhj之前就已知道这一点,但是他当时正打算对maphack收费,反检测是一大卖点,因此一 直没有公布。在jhj公布了他的发现后,我检查了相关代码,又发现了packet 65也被用作hack检测。

    如前文的分析,packet 64/65检测用的都是memory probe方法,那么memory probe该怎么对付呢?一种简单的想法是在客户端截获packet 64/65检测,不让它返回检测结果。截获packet 64/65检测思路是对的,但不返回检测结果其实也是一种信息,暴雪完全可能根据这点判断你在使用hacks,最不济也会把你踢下线,显然不是好的做法。 对付memory probe,更好的做法是伪造检测结果。这需要截获packet 64/65检测,然后根据要检测的内存地址返回该地址被修改前的数据(如果已经被修改了的话),这样无论检测哪个地址,检测结果都和没有使用hacks时 的一样。

    具体到实现方法,大约又有三种。

    一种是hack在安装旁路点时,先保存原先的数据,这样在遇到检测时就能知道patch前的数据。使用这种方法的有d2maphack、d2jsp等。这种方法最简单,实现起来也容易,占用额外内存也不大。缺点只能保护自己,不能保护其他hacks。

    第二种方法由jhj实现,其原理是在加载任何hack之前,先对游戏中用到的重要的dll做备份,这样就获得了这些dll干净的副本。然后截获 packet 64/65检测入口,根据检测地址,从干净的副本中返回相应的数据。这就是jhj在 1.10时期发布的antidetection.dll。这种方法最大的优点是通用,可以保护其它hacks-其他hack不需要有任何反检测措施就能避 开检测。但是这种实现也有不小的缺陷。其一是它必须抢在其他所有hack之前加载,否则无法获得干净副本-如果无法获得干净副本这种方法就完全失去意义- 这在有些情况下是不容易做到的,比如无人职守的BOT。其二是所有重要的dll都要备份,这会额外消耗不少内存,对机器配置差或者多开BOT的玩家有很大 影响。其三是antidection.dll只备份了它认为重要的dll,而不是所有dll,这样如果有的hack修改的dll不在它的保护范围,还是有 可能被抓到。

    第三种方法由我实现,称之为模块重建法(module re-construction),首先在d2hackmap中实现,后来ABin升级d2hackit时请我帮忙实现anti-detection模 块,因此我又把它集成进了d2hackit 2.00版本中。这种方法的思路是截获packet 64/65检测入口(显然所有反检测方法都需要这一步),根据检测地址判断出目标模块名称和其在硬盘文件路径,然后从该模块的硬盘文件开始重建一份干净的 副本,最后从干净的副本中返回相应的数据。这种方法在没有检测活动时(其实1.10时期packet 64/65检测很少出现)不会消耗额外内存,可保护所有dll,也无需抢先加载。我个人觉得是一种比较理想的方法。当然,模块重建法的难点在于如何从一个 dll文件重建一份和已加载模块被修改前完全一样的副本(其实是代码段和只读数据段完全一样,读写数据段无所谓),这在以后的文章中应该有机会介绍到。

    另外,除了packet 64/65检测,别忘了1.10以前一直就有的version-checking.dll和extrawork.dll机制。虽然它们在前1.10时期从 未被用作hack检测,但是显然暴雪在1.10时期开始重视打击hacks,因此也不得不防。回想一下这两处机制,由于这两个dll都存放在服务器端,必 要时发送到客户端运行并返回结果。不让它们运行显然是不行的。并且显然它们的检测手段也是无限、未知的,伪造检测结果也不可行。那该怎么办呢?

    对付这种手段的一种比较有效的方法是,截取并保存尽可能多的从服务器端传过来的dll,逐一分析,标出安全的和不安全的,并对每个dll建立签名 (signature)。这样在每次客户端接收到dll时,先计算出其签名然后和已事先分析过的所有dll签名比较,这样就可知道该dll安不安全(即能 否检测出我的hack),如果安全则让它执行,如果不安全则hack会自己卸载,然后再让该dll执行。这样就不会被它抓到。另外对于未知模块(即该 dll的签名不在列表里),应该把它保存下来以供事后分析,同时为保安全hack自己卸载,在以后分析后再把它标识为安全或不安全。当然对于不安全的模块 还应进一步研究反检测方法然后把它标为安全模块。d2maphack、d2jsp采取的都是这种策略。d2hackmap由于我后来没有太多精力人工分析 这些模块,因此只在配置文件里设置开关变量,指示d2hackmap遇到这些模块时如何处理(有忽略、卸载自身、保存模块文件并卸载自身三种选择)。至于 jhj的AntiDetection.dll是没有这方面的反检测保护的。事实证明这种策略是比较有效的。一个可能的原因是由于设计所限,这种发送dll 检测机制尚不具备快速变形、频繁运行的能力。

    展开全文
  • Xposed 反检测

    千次阅读 2019-07-14 22:03:00
    下面我们聊聊 xposed 的检测机制。 市面上 xposed 的检测手段一般包含如下几种方法 XposedInstaller 检测; Java 层检测是否安装 xposed 组件; 堆栈信息检测 xposed 相关信息; 检测关键方法是否是 native ...

    前段时候微信封禁了一大批使用 xposed 的微信账号,对一些运营微信的企业造成的巨大损失。下面我们聊聊 xposed 的检测机制。

    市面上 xposed 的检测手段一般包含如下几种方法

    1. XposedInstaller 检测;
    2. Java 层检测是否安装 xposed 组件;
    3. 堆栈信息检测 xposed 相关信息;
    4. 检测关键方法是否是 native 方法;(只能检测出是否 hook, 但是不能检测 hook 手段)
    5. 直接调用 /system/framework/XpsedBridge.jar 内部的方法来验证;
    6. 查看 /system/bin/ 、/system/lib/、/system/lib64/、内部是否存在 xposed 相关文件;
    7. 查看 app 内部加载库列表是否存在不正常的 so 库;(验证文件 /proc/self/maps 内容);
    8. 检测关键方法的特征码;
    9. 其他未知的方法

    针对以上的检测方法,可以针对性的隐藏掉 xposed 的关键特征:

    1. 替换 XposedInstall 包名;
    2. 隐藏 XposedBridge.jar(替换包名和自身名字);
    3. 隐藏包含 xposed 名字特征的文件;
    4. 隐藏掉 lib_xposed_art.so 、lib_xposed_dalvik.so 等 xposed 特征;
    5. 隐藏掉 xposed.prop 文件

    以上内容仅提供一种思路,不代表全部方法,有感兴趣的朋友可以加我微信私聊

    微信号:hunter-688

    展开全文
  • 虚拟机的检测与反检测学习报告 成果: 1、实现了通过特权指令in,检测虚拟机。 参考资料:https://bbs.pediy.com/thread-119969.htm 2、实现了绕过上述检测。通过修改虚拟机配置文件,关闭特权指令。 参考资料...
  • x64dbg反检测插件2017年1月21日版本
  • 一、反调试技术 反调试技术是一种常见的反检测技术,因为恶意软件总是企图监视自己的代码以检测是否自己正在被调试。为做到这一点,恶意软件可以检查自己代码是否被设置了断点,或者直接通过系统调用来检测调试器。...
  • Root检测与反检测

    千次阅读 2018-12-25 23:54:59
    Root检测手段 检查已安装的包: SuperSU应用程序 生根应用程序:利用权限升级漏洞来启动设备的应用程序(例如One Click Root,iRoot) Root Apps:需要root权限才能使用其功能的应用程序。例如busybox,SetCPU,...
  • 外挂技术之-检测和反检测

    千次阅读 2011-07-29 09:52:32
    关于游戏外挂检测和反检测(真正的防封技术)在网上找到篇关于游戏外挂检测和反检测的文章拿来跟断点的朋友分享。详细文章见附件,这里写些简介。 一:内存探测法 服务器发送个Paket检测游戏内存,然后返回服务器...
  • 按照上游进行自动修补,并为Android构建反检测版本的frida-server。 跟随FRIDA上游自动修补程序,并为Android构建反检测版本的frida-server。 提示:不要分叉该存储库 补丁 模块 姓名 frida-core 0001-string_frida...
  • 谷歌的无头浏览器和反检测 无头浏览:是在使用selenium是的无可视化,在后台自动运行而不显示出来 反检测:有些网站会检测访问的selenium是否是机器,判断是的话会不给请求 from selenium import webdriver from ...
  • 安卓的检测与反检测

    2020-07-18 17:06:38
    先来看一段检通过包管理器PackageManager测代码包名检测: PackageManager packageManager=getApplicationContext().getPackageManager(); List<ApplicationInfo> appliacationInfoList=packageManager.get...
  • 眼镜反光检测

    千次阅读 2019-08-07 15:40:29
    参考文章:... 首先我们可以手机一批数据使用数据训练一哥网络模型, 测试代码(.h5模型在CSDN里可以下载) import tensorflow as tf import os import glob from skimage import io import matp...
  • 《安卓的检测与反检测 》通过检测扫描包名来获取需要的信息,这篇阐述一下方法的扫描改包名容易改方法费事要多点。方法的扫描要用到反射。有什么意义呢,只要源代码不调整顺序枚举方法名和顺序组,合运算出来哈希值...
  • 反调试技术是一种常见的反检测技术,因为恶意软件总是企图监视自己的代码以检测是否自己正在被调试。为做到这一点,恶意软件可以检查自己代码是否被设置了断点,或者直接通过系统调用来检测调试器。 1.断点 ...
  • 所谓的反检测是为了让网站服务器检测不出我们使用了selenium,否则某些门户网站通过使用反爬手段导致我们无法爬取成功。 这些代码不用去死记硬背,只需要在需要使用的时候拿过来用就可以了。 from selenium import ...
  • 它更加健壮并具有其他功能,并且重点关注反调试和反检测。 特征 反调试 避免取消隐藏,lsof,ps,ldd检测 隐藏文件和目录 隐藏远程连接 隐藏流程 隐藏登录名 PCAP挂钩可避免局部嗅探 两个接受后门。 加密的accept...
  • python selenium 反检测

    千次阅读 2019-12-17 19:34:20
    现在有大量的反爬机制,通常我们爬虫有re,bs4,selenium,这里重点说...在这里我们通过js代码发现他有个检测机制 #通过查看window.navigator.webdriver信息可以看到这里是为true window.navigator.webdrive...
  •  一、反调试技术 反调试技术是一种常见的反检测技术,因为恶意软件总是企图监视自己的代码以检测是否自己正在被调试。为做到这一点,恶意软件可以检查自己代码是否被设置了断点,或者直接通过系统调用来检测调试器...
  • vmware的检测与反检测

    千次阅读 2013-09-29 10:34:19
    先说3种方法 代码: ...由于某些原因,上面的模拟漏洞我只贴了MJ0011的代码,还有几个漏洞(暂时不公开写出来,当然无法对付VMWare的)可以对付其他几款虚拟机,比如VBox(开了VT也被检测)。
  • 恶意软件是一种招人恨的代码,因为它们专干坏事,如泄漏个人隐私、造成数据丢失,等等。...而反检测技术,就是在恶意软件的分析阶段设置障碍,让分析人员无法或难以对恶意代码进行分析,这主要包括两类技术,一种
  • 实现无可视化界面的操作 """ chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') """ 实现规避检测 """ option = ChromeOptions() option.add_...
  • 国外xposed过检测工具是一款能隐藏xposed框架的辅助工具,它能绕过apk的签名验证,绕过手机系统的某些限制,成功修改apk的框架服务,也可以多模拟位置,root系统进行隐藏,提供伪造信息,对你的手机进行很多个性化...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,609
精华内容 1,843
关键字:

反检测