欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]调戏:简易的飘动线程

[原创]调戏:简易的飘动线程

上次在
【原创】调戏:纯应用层的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
欢迎有兴趣研究各类游戏安全相关技术的人员加入。

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功