Quantcast
Channel: 看雪安全论坛
Viewing all articles
Browse latest Browse all 9556

技术专题 【原创】调戏:简易的飘动线程

$
0
0
上次在
【原创】调戏:纯应用层的Anti本地调试器(1)
里简单做了一些AntiOD的事情,不过其中忘记玩一下CRC检测软件断点。
现在补上CRC检测的代码,为了防止CRC代码特征定位流,直接使用ntdll里的CRC计算函数完成工作(这个还是有点小问题的)。

这里的重点是检测的线程使用了代码飘动化,呵呵,其实非常简单的方式,直接把线程的代码抠出来放在其他位置运行就好了,如果需要用到什么函数,直接通过线程参数传递就好了(这是简单的飘动,复杂的飘动,由于本人比较懒,所以 原谅我,等下次吧)。

另外还有一些关于判断PE节属性区别code和非code能力的节表的...基础知识请使用baidu和pediy的各种pe格式精华文脑补。
代码:

#include "stdafx.h"
#pragma warning(disable:4005)
#include <stdio.h>
#include <windows.h>
#include <winternl.h>
#include <ntstatus.h>
#include <string.h>
#include <tlhelp32.h>
#pragma comment(lib,"ntdll.lib")


typedef VOID (__stdcall *_CheckCRCCallBack)();
typedef VOID (__stdcall *_Sleep)(DWORD dwMilliseconds);
typedef unsigned int (__stdcall *_RtlComputeCrc32)(int dwInitial, void* pData, int iLen);
typedef struct _THREAD_CONTEXT_
{
        _RtlComputeCrc32 funcRtlComputeCrc32;
        _Sleep funcSleep;
        _CheckCRCCallBack funcCallBack;
        PVOID CheckAddress;
        int CheckSize;
}THREAD_CONTEXT,*PTHREAD_CONTEXT;

DWORD GetModuleImageSize(PVOID lphModule)
{
        DWORD dwResult = 0;
        PIMAGE_DOS_HEADER lpDosHeaders;
        PIMAGE_NT_HEADERS lpNtHeaders;

        //        验证模块是否是PE文件
        if (lphModule == NULL) return dwResult;

        lpDosHeaders = (PIMAGE_DOS_HEADER)lphModule;
        if (lpDosHeaders->e_magic == IMAGE_DOS_SIGNATURE)
        {
                lpNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)lphModule + lpDosHeaders->e_lfanew);
                if (lpNtHeaders->Signature == IMAGE_NT_SIGNATURE)
                {
                        dwResult = lpNtHeaders->OptionalHeader.SizeOfImage;
                }
        }
        return dwResult;
}

int GetShellCodeLen(BYTE *lpShell)
{
        DWORD dwStart=(DWORD)lpShell;
        int len=0;
        while(*(DWORD *)dwStart!=0xAAAAAAAA)
        {
                dwStart++;
                len++;
        }
        return len;
}

DWORD WINAPI CheckCRC(LPVOID ThreadContext)
{
        unsigned int Crc32=0;
        PTHREAD_CONTEXT ctx = (PTHREAD_CONTEXT)ThreadContext;
        Crc32 = ctx->funcRtlComputeCrc32(0,ctx->CheckAddress,ctx->CheckSize);
        while(1)
        {
                unsigned int crc32_new = ctx->funcRtlComputeCrc32(0,ctx->CheckAddress,ctx->CheckSize);
                if (crc32_new!=Crc32)
                {
                        ctx->funcCallBack();
                }
                ctx->funcSleep(3000);
        }
        __asm
        {
                        _emit 0xAA
                        _emit 0xAA
                        _emit 0xAA
                        _emit 0xAA
        }
        return 0;

}

VOID __stdcall DefCallBack()
{
        AfxMessageBox(TEXT("进程代码被修改"));
        TerminateProcess(GetCurrentProcess(),-1);
}
VOID CreateAntiBpThread(PVOID Address,int nSize)
{
        PTHREAD_CONTEXT thctx;
        HMODULE NtdllMod = LoadLibraryW(L"ntdll.dll");
        thctx = (PTHREAD_CONTEXT)VirtualAllocEx(GetCurrentProcess(),NULL,sizeof(THREAD_CONTEXT),MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);

        thctx->funcRtlComputeCrc32 = (_RtlComputeCrc32)GetProcAddress(NtdllMod,"RtlComputeCrc32");
        thctx->funcSleep = (_Sleep)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),"Sleep");
        thctx->CheckAddress = Address;
        thctx->CheckSize = nSize;
        thctx->funcCallBack = DefCallBack;
        PVOID ThreadCode =NULL;
        DWORD ThreadSize =0;
        ThreadSize = GetShellCodeLen((BYTE *)CheckCRC);
        ThreadCode = (PVOID)VirtualAllocEx(GetCurrentProcess(),NULL,ThreadSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
        RtlCopyMemory(ThreadCode,(PVOID)CheckCRC,ThreadSize);

        CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadCode,(LPVOID)thctx,0,NULL);
}
VOID SetAntiBp(PVOID ImageBase)
{
        UINT nSectionNumber=0;
        UINT i=0;

        PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)ImageBase;
        PIMAGE_NT_HEADERS NtHeader =NULL;
        PIMAGE_FILE_HEADER FileHeader = NULL;
        PIMAGE_SECTION_HEADER FirstSection = NULL;

        NtHeader = (PIMAGE_NT_HEADERS)((DWORD)DosHeader + DosHeader->e_lfanew);

        FileHeader = (PIMAGE_FILE_HEADER)&NtHeader->FileHeader;

        FirstSection =(PIMAGE_SECTION_HEADER)(DosHeader->e_lfanew + FileHeader->SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + sizeof(UINT32));

        nSectionNumber = FileHeader->NumberOfSections;


        for (i=0;i<nSectionNumber;i++)
        {
                PIMAGE_SECTION_HEADER SectionHeader = (PIMAGE_SECTION_HEADER)((ULONG_PTR)DosHeader + (ULONG_PTR)FirstSection + (i * sizeof(IMAGE_SECTION_HEADER)));

                BOOL IsMonitored =
                        (SectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE)
                        &&
                        (SectionHeader->Characteristics &IMAGE_SCN_MEM_READ)
                        &&
                        (SectionHeader->Characteristics & IMAGE_SCN_CNT_CODE)
                        &&
                        !(SectionHeader->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
                        ;
                if (IsMonitored)//根据段属性来,只有code是需要crc的~~~
                {

                        OutputDebugStringA("create code check\r\n");
                        CreateAntiBpThread((VOID *)((ULONG_PTR)DosHeader + SectionHeader->VirtualAddress), SectionHeader->Misc.VirtualSize);
                }
        }
}

VOID InitAntiBp()
{
        SetAntiBp(GetModuleHandle(NULL));
        SetAntiBp(GetModuleHandle(TEXT("kernel32.dll"));//可以设置模块哦!
}

IGS游戏安全技术培训
QQ群:48715131
欢迎有兴趣研究各类游戏安全相关技术的人员加入。

Viewing all articles
Browse latest Browse all 9556

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>