看流星社区

 找回密码
 注册账号
查看: 2457|回复: 0

Ring3反作弊篇(基于EBP遍历调用栈及模块名)

[复制链接]

该用户从未签到

发表于 2018-3-6 22:27:00 | 显示全部楼层 |阅读模式
之前自己做的一款老游戏的基于R3入门级的反作弊代码中的片段,仅供学习参考~~

通杀Win XP/7/8,哪位兄弟装了WIN10麻烦测试一下谢谢!

源码如下:


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

  2. #include "stdafx.h"
  3. #include <Windows.h>
  4. #include <stdio.h>

  5. #include "EasyDetour.h"

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

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

  10. fnMessageBoxA    pMessageBoxA = NULL;

  11. DWORD Functiion(DWORD x, DWORD y);


  12. //
  13. // 提取函数
  14. //
  15. BOOL TiQuan()
  16. {
  17.     HANDLE    hToken;
  18.     BOOL    fOk = FALSE;

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

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

  28.         fOk = (GetLastError() == ERROR_SUCCESS);
  29.         CloseHandle(hToken);
  30.     }

  31.     return fOk;
  32. }

  33. //
  34. // 获取PE文件大小
  35. //
  36. DWORD GetPEImageSize(HMODULE hModule)
  37. {
  38.     PBYTE pInfo = (PBYTE)hModule;
  39.     PIMAGE_DOS_HEADER pImgDos = (PIMAGE_DOS_HEADER)pInfo;
  40.     PIMAGE_NT_HEADERS pImgNt;
  41.     if(pImgDos->e_magic==IMAGE_DOS_SIGNATURE)
  42.     {
  43.         pImgNt = (PIMAGE_NT_HEADERS)&pInfo[pImgDos->e_lfanew];
  44.         if(pImgNt)
  45.         {
  46.             if(pImgNt->Signature==IMAGE_NT_SIGNATURE)
  47.             {
  48.                 return pImgNt->OptionalHeader.SizeOfImage;
  49.             }
  50.         }
  51.     }
  52.     return NULL;
  53. }

  54. //
  55. // Hook MessageBox for test
  56. //
  57. BOOL WINAPI GetCheatModuleByEBP(DWORD nEBP,char *pszPath,int nLen)
  58. {
  59.     TiQuan();
  60.     if(nEBP == 0)
  61.         return FALSE;

  62.     DWORD    nPEB = nEBP;
  63.     BOOL    bFound = FALSE;
  64.     HMODULE hMods[1024] = {0};
  65.     DWORD    cbNeeded = 0;
  66.     char    szModName[MAX_PATH];

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

  70.     nPEB = nEBP;
  71.     for (UINT i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
  72.     {
  73.         GetModuleFileNameExA(hProcess, hMods[i], szModName, _countof(szModName));
  74.         if(hMods[i])
  75.         {
  76.             if(nPEB >= (DWORD)hMods[i] && (nPEB <= ((DWORD)hMods[i] + GetPEImageSize(hMods[i]))))
  77.             {
  78.                 memset(pszPath,0x00,nLen);
  79.                 wsprintfA(pszPath,"%s",szModName);
  80.                 bFound = TRUE;
  81.                 break;
  82.             }
  83.         }
  84.     }

  85.     CloseHandle(hProcess);
  86.     return bFound;
  87. }

  88. //
  89. // Hook MessageBox for test
  90. //
  91. int WINAPI newMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType)
  92. {
  93.     Functiion(0,0);
  94.     return pMessageBoxA(hWnd,lpText,lpCaption,uType);
  95. }

  96. //
  97. // 回调函数
  98. //
  99. DWORD BackCall(DWORD Address)
  100. {
  101.     char    szDllPath[MAX_PATH] = {0x00};
  102.     if(GetCheatModuleByEBP(Address,szDllPath,MAX_PATH))
  103.         printf("检测地址:0x%08x  %s\n", Address, szDllPath);
  104.     else
  105.         printf("检测地址:0x%08x  未知模块\n", Address, szDllPath);

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

  109.     return 0;
  110. }

  111. //
  112. // 检测呼叫者调用连
  113. //
  114. BOOL __declspec(naked)  Check(void)
  115. {
  116.     __asm push ebp;
  117.     __asm mov ebp, esp;
  118.     __asm sub esp, 0x8;

  119.     __asm push edi;
  120.     __asm push ecx;

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

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

  127. __Loop:

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

  131.     //
  132.     // 调用匹配规则函数
  133.     __asm push eax;
  134.     __asm call dword ptr[ebp + 0xc];
  135.     __asm add esp, 0x4;
  136.      
  137.     //
  138.     // 获取上一个堆栈的指针
  139.     __asm mov edi, dword ptr[edi];

  140.     __asm cmp eax, 0x1;
  141.     __asm je __Out;

  142.     //
  143.     // 如果已经为空了 则直接退出
  144.      
  145.     __asm cmp edi, 0x0;
  146.     __asm je __Out;

  147.     __asm loop __Loop;

  148. __Out:

  149.     __asm pop ecx;
  150.     __asm pop edi;
  151.     __asm add esp, 0x8;
  152.     __asm pop ebp;
  153.     __asm ret;
  154. }



  155. //
  156. // 测试函数
  157. //
  158. DWORD Functiion(DWORD x, DWORD y)
  159. {

  160.     //
  161.     // 设置回调函数
  162.     __asm mov edx, dword ptr[BackCall];
  163.     __asm push edx;

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

  169.     return x + y;
  170. }

  171. // 这里是测试函数
  172. DWORD Function(DWORD x,DWORD y)
  173. {
  174.     //x += y;
  175.     __asm mov edx,dword ptr[x];
  176.     __asm add edx,0x10;                // 深度检测10个
  177.     __asm mov dword ptr[x],edx;
  178.     return x;
  179. }

  180. int MsgBox()
  181. {
  182.     return MessageBoxA(NULL,"Hello World by Koma !","Test",MB_OK);
  183. }

  184. int _tmain(int argc, _TCHAR* argv[])
  185. {
  186.     pMessageBoxA = MessageBoxA;
  187.     DetourHook((void**)&pMessageBoxA,newMessageBoxA);
  188.     MsgBox();
  189.     while(getchar() != 'a')
  190.         Sleep(0);
  191.     DetourUnHook((void**)&pMessageBoxA,newMessageBoxA);
  192.     return 0;
  193. }
复制代码



  1. // 暴力搜索R3断链隐藏模块
  2. BOOL WINAPI GetCheatModuleByEBP(const DWORD nEBP,const char *pszPath,const int nLen,DWORD & nCRC,DWORD & nFileSize);
  3. {
  4. DWORD ModuleBase = 0;
  5. DWORD ModuleSize = 0;
  6. WCHAR szModuleName[MAX_PATH] = {0};
  7. WCHAR szPathName[MAX_PATH] = {0};
  8. HANDLE hProcess = INVALID_HANDLE_VALUE;
  9.   
  10. memset(pszPath,0x00,nLen);
  11. nCRC = nFileSize = 0;
  12. if(nProcessID == 0)
  13.   return FALSE;
  14.   hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId());
  15. if(!hProcess)
  16.   return FALSE;
  17.   for(int i=-1, BaseAddress=0; BaseAddress<0x80000000; BaseAddress+=0x1000)
  18. {
  19.   MEMORY_BASIC_INFORMATION mbi;
  20.   if(NT_SUCCESS(ZwQueryVirtualMemory(hProcess, (PVOID)BaseAddress, MemoryBasicInformation, &mbi, sizeof(mbi), 0)))
  21.   {
  22.    if(ModuleBase && ModuleBase != (DWORD)mbi.AllocationBase && ModuleSize)
  23.     ModuleBase = ModuleSize = 0;
  24.     if(mbi.Type != MEM_IMAGE)
  25.     continue;
  26.     ModuleBase = (DWORD)mbi.AllocationBase;
  27.    if(ModuleBase && mbi.BaseAddress == (PVOID)BaseAddress)
  28.     ModuleSize = (DWORD)mbi.BaseAddress + mbi.RegionSize - (DWORD)mbi.AllocationBase;
  29.     if(mbi.AllocationBase != (PVOID)BaseAddress)
  30.     continue;
  31.    
  32.    if(ModuleBase == 0 || ModuleSize == 0)
  33.     continue;
  34.     if((ModuleBase <= nEBP) && (ModuleBase + ModuleSize) >= nEBP)
  35.    {
  36.     ULONG  NameSize = 0x100;
  37.     LPVOID  pBuffer = malloc(NameSize);
  38.     if(!pBuffer)
  39.     {
  40.      ASSERT(FALSE);
  41.      continue;
  42.     }
  43.      
  44.     NTSTATUS status = ZwQueryVirtualMemory(hProcess, (PVOID)mbi.AllocationBase, MemorySectionName, pBuffer, NameSize, &NameSize);
  45.     if(status == STATUS_INFO_LENGTH_MISMATCH || status == STATUS_BUFFER_OVERFLOW)
  46.     {
  47.      free(pBuffer);
  48.      pBuffer = malloc(NameSize);
  49.      status = ZwQueryVirtualMemory(hProcess, (PVOID)mbi.AllocationBase, MemorySectionName, pBuffer, NameSize, 0);
  50.     }
  51.      
  52.     if(!pBuffer) continue;
  53.      if(!NT_SUCCESS(status))
  54.     {
  55.      free(pBuffer);
  56.      continue;
  57.     }
  58.      POBJECT_NAME_INFORMATION SectionName = (POBJECT_NAME_INFORMATION)pBuffer;
  59.     ANSI_STRING  tmpAS;
  60.      PUNICODE_STRING usSectionName;
  61.     char   *pTemp = NULL;
  62.      usSectionName = (PUNICODE_STRING)pBuffer;
  63.     _wcsnicmp(szModuleName, usSectionName->Buffer, usSectionName->Length / sizeof(WCHAR));
  64.     wcsncpy(szModuleName, usSectionName->Buffer, usSectionName->Length / sizeof(WCHAR) );
  65.     szModuleName[usSectionName->Length / sizeof(WCHAR)] = UNICODE_NULL;
  66.     DeviceName2PathName(szPathName, szModuleName);
  67.     pTemp = (char *)malloc(sizeof(char)*(2*wcslen(szPathName)+1));
  68.     memset(pTemp , 0 , 2 * wcslen(szPathName)+1);
  69.     W2C(pTemp,szPathName,2 * wcslen(szPathName)+1) ;
  70.      memcpy(pszPath,pTemp,strlen(pTemp));
  71.     delete [] pTemp;
  72.     pTemp = NULL;
  73.      nFileSize = mbi.RegionSize;
  74.     nCRC   = GetFileCRC(pszPath);
  75.      free(pBuffer);
  76.     pBuffer = NULL;
  77.     CloseHandle(hProcess);
  78.     return TRUE;
  79.    }
  80.   } else if(ModuleBase && ModuleSize)
  81.   {
  82.    ModuleBase = ModuleSize = 0;
  83.   }
  84. }
  85.   CloseHandle(hProcess);
  86. return FALSE;
  87. }
复制代码
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-18 18:59

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表