[ring3反作弊篇] 基于EBP遍历调用栈及模块名

[ring3反作弊篇] VC++基于EBP遍历调用栈及模块名


入门级反作弊代码仅供参考~~




//
// CallStackList.cpp : 定义控制台应用程序的入口点。
//
// thanks for NV.
//

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>

#include "EasyDetour.h"

#include <TlHelp32.h>
#include <Psapi.h>
#pragma comment(lib,"psapi.lib")

typedef int (WINAPI *fnMessageBoxA)(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType);

fnMessageBoxA	pMessageBoxA = NULL;

DWORD Functiion(DWORD x, DWORD y);


//
// 提取函数
//
BOOL TiQuan()
{
	HANDLE	hToken;
	BOOL	fOk = FALSE;

	if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken))
	{
		TOKEN_PRIVILEGES tp;
		tp.PrivilegeCount=1;
		if(!LookupPrivilegeValueA(NULL,"SeDebugPrivilege",&tp.Privileges[0].Luid))
			Sleep(1);

		tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
		if(!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL))
			Sleep(1);

		fOk = (GetLastError() == ERROR_SUCCESS);
		CloseHandle(hToken);
	}

	return fOk;
}

//
// 获取PE文件大小
//
DWORD GetPEImageSize(HMODULE hModule)
{
	PBYTE pInfo = (PBYTE)hModule;
	PIMAGE_DOS_HEADER pImgDos = (PIMAGE_DOS_HEADER)pInfo;
	PIMAGE_NT_HEADERS pImgNt;
	if(pImgDos->e_magic==IMAGE_DOS_SIGNATURE)
	{
		pImgNt = (PIMAGE_NT_HEADERS)&pInfo[pImgDos->e_lfanew];
		if(pImgNt)
		{
			if(pImgNt->Signature==IMAGE_NT_SIGNATURE)
			{
				return pImgNt->OptionalHeader.SizeOfImage;
			}
		}
	}
	return NULL;
}

//
// Hook MessageBox for test
//
BOOL WINAPI GetCheatModuleByEBP(DWORD nEBP,char *pszPath,int nLen)
{
	TiQuan();
	if(nEBP == 0)
		return FALSE;

	DWORD	nPEB = nEBP;
	BOOL	bFound = FALSE;
	HMODULE hMods[1024] = {0};
	DWORD	cbNeeded = 0;
	char	szModName[MAX_PATH];

	HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_QUERY_LIMITED_INFORMATION, FALSE, GetCurrentProcessId());
	//IsWow64Process(hProcess, &Wow64Process); //判断是32位还是64位进程
	EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded);

	nPEB = nEBP;
	for (UINT i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
	{
		GetModuleFileNameExA(hProcess, hMods[i], szModName, _countof(szModName));
		if(hMods[i])
		{
			if(nPEB >= (DWORD)hMods[i] && (nPEB <= ((DWORD)hMods[i] + GetPEImageSize(hMods[i]))))
			{
				memset(pszPath,0x00,nLen);
				wsprintfA(pszPath,"%s",szModName);
				bFound = TRUE;
				break;
			}
		}
	}

	CloseHandle(hProcess);
	return bFound;
}

//
// Hook MessageBox for test
//
int WINAPI newMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType)
{
	Functiion(0,0);
	return pMessageBoxA(hWnd,lpText,lpCaption,uType);
}

//
// 回调函数
//
DWORD BackCall(DWORD Address)
{
	char	szDllPath[MAX_PATH] = {0x00};
	if(GetCheatModuleByEBP(Address,szDllPath,MAX_PATH))
		printf("检测地址:0x%08x  %s\n", Address, szDllPath);
	else
		printf("检测地址:0x%08x  未知模块\n", Address, szDllPath);

	//
	// 在这里添加白名单 黑名单匹配的代码 (黑名单返回1 白名单返回0)
	//

	return 0;
}

//
// 检测呼叫者调用连
//
BOOL __declspec(naked)  Check(void)
{
	__asm push ebp;
	__asm mov ebp, esp;
	__asm sub esp, 0x8;

	__asm push edi;
	__asm push ecx;

	//
	// 查询次数
	__asm mov ecx, dword ptr[ebp + 0x8];

	//
	// 设置堆栈指针
	__asm mov edi, dword ptr[ebp];

__Loop:

	//
	// 保存当前堆栈的返回地址 也就是呼叫这个函数的上一层函数的内存空间
	__asm mov eax, dword ptr[edi + 0x4];

	//
	// 调用匹配规则函数
	__asm push eax;
	__asm call dword ptr[ebp + 0xc];
	__asm add esp, 0x4;
	
	//
	// 获取上一个堆栈的指针
	__asm mov edi, dword ptr[edi];

	__asm cmp eax, 0x1;
	__asm je __Out;

	//
	// 如果已经为空了 则直接退出
	
	__asm cmp edi, 0x0;
	__asm je __Out;

	__asm loop __Loop;

__Out:

	__asm pop ecx;
	__asm pop edi;
	__asm add esp, 0x8;
	__asm pop ebp;
	__asm ret;
}



//
// 测试函数
//
DWORD Functiion(DWORD x, DWORD y)
{

	//
	// 设置回调函数
	__asm mov edx, dword ptr[BackCall];
	__asm push edx;

	//
	// 设置最大检测深度
	__asm push 0x50;
	__asm call dword ptr[Check];
	__asm add esp, 0x8;

	return x + y;
}

// 这里是测试函数
DWORD Function(DWORD x,DWORD y)
{
	//x += y;
	__asm mov edx,dword ptr[x];
	__asm add edx,0x10;				// 深度检测10个
	__asm mov dword ptr[x],edx;
	return x;
}

int MsgBox()
{
	return MessageBoxA(NULL,"Hello World by Koma !","Test",MB_OK);
}

int _tmain(int argc, _TCHAR* argv[])
{
	pMessageBoxA = MessageBoxA;
	DetourHook((void**)&pMessageBoxA,newMessageBoxA);
	MsgBox();
	while(getchar() != 'a')
		Sleep(0);
	DetourUnHook((void**)&pMessageBoxA,newMessageBoxA);
	return 0;
}



vs2010源码工程下载:

http://www.rayfile.com/zh-cn/files/a1dcbf4c-d15e-11e4-ac13-0015c55db73d/




vs2010源码工程下载


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪宁宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值