郁金香灬老师 游戏安全  驱动 逆向调试 C/C++编程  脚本 UE4/UE5

找回密码
立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
发新帖
课程大纲和价格
官方联系方式2024在线课大纲QQ咨询

34万

积分

131

好友

145

主题
发表于 2022-12-28 16:22:12 | 查看: 6302| 回复: 0
BytesToHexStr.h
BytesToHexStr.cpp
HexStrToBytes.h
HexStrToBytes.cpp
CFind_Offset.h
CFind_Offset.cpp
CFind_Offset_GetBaseOfffset.cpp
CFind_Offset_MatchSearch.cpp
//以下是调用例子
基址偏移.h
OFFSET_所有对象数组.cpp
定位所有基址偏移.cpp
//main.cpp是入口函数所在
main.cpp

//BytesToHexStr.h
  1. #pragma once
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <Windows.h>
  5. char* ByteToHexChar(unsigned char c);
  6. void BytesToHexStr(IN  char *pBytes,IN SIZE_T nSize,OUT  char*pOutBufHexStr,IN SIZE_T nBufSize);
复制代码

//BytesToHexStr.cpp
  1. #include <windows.h>
  2. #include "BytesToHexStr.h"

  3. char* ByteToHexChar(unsigned char c)
  4. {
  5.         static char szRet[3]={0}; //FF 0F 00 1A 11
  6.         unsigned char szhigh=c/16;
  7.         unsigned char szlow=c-szhigh*0x10;
  8.         if (szhigh>=0&&szhigh<=9)
  9.         {
  10.                 szRet[0]='0'+szhigh; //30+9//'9'
  11.         }else
  12.         {
  13.                 //10..15
  14.                 szRet[0]='A'+szhigh-10;
  15.         }

  16.         if (szlow>=0&&szlow<=9)
  17.         {
  18.                 szRet[1]='0'+szlow; //30+9//'9'
  19.         }else if (szlow>=10&&szlow<=15)
  20.         {

  21.                 //10..15
  22.                 szRet[1]='A'+szlow-10;
  23.         }
  24.         return (char*) szRet;
  25. }

  26. void BytesToHexStr(IN  char *pBytes,IN SIZE_T nSize,OUT  char*pOutBufHexStr,IN SIZE_T nBufSize)
  27. {
  28.         DWORD n=0;
  29.         if (nBufSize/3<nSize)
  30.         {
  31.                 n=nBufSize/3;
  32.         }else
  33.         {
  34.                 n=nSize;
  35.         }
  36.         pOutBufHexStr[0]='\0';
  37.         for (UINT32 i=0;i<n;i++)
  38.         {
  39.                 strcat_s(pOutBufHexStr,nBufSize, ByteToHexChar(pBytes[i]));
  40.                 strcat_s(pOutBufHexStr,nBufSize,","); //×Ö½Ú·Ö¸ô·û
  41.         }
  42.         strcat_s(pOutBufHexStr,nBufSize,"\0"); //½áÊø·û
  43.         return ;
  44. }
复制代码

//HexStrToBytes.h
  1. #pragma once
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <Windows.h>
  5. //1、szHexStr 为待转换字16进制字串
  6. //2、szBytesbuf 是存放转换后的数据
  7. //3、nBufSize是szBytesbuf缓冲区的大小
  8. //4、返回成功转换的字节数量

  9. SIZE_T HexStrToBytes(const char*szHexStr, OUT BYTE*szBytesbuf, SIZE_T nBufSize);
  10. //带分隔符
  11. SIZE_T HexStrToBytesNew(const char*szHexStr, OUT BYTE*szBytesbuf, SIZE_T nBufSize);
  12. SIZE_T HexStrToBytesEx(IN const char*szHexStr, OUT BYTE*szBytesbuf, SIZE_T nBufSize, OUT BYTE*szStar);



复制代码

//HexStrToBytes.cpp
  1. #include <windows.h>
  2. #include "HexStrToBytes.h"
  3. #include <stdio.h>
  4. #include <string>
  5. using namespace std;
  6.                                                          
  7. unsigned char charToByte(char c)
  8. {
  9. //0..9
  10. //a..f
  11. //A..F
  12.         unsigned char cret=0;
  13.         if (c>='0'&&c<='9')
  14.         {
  15.                 cret=c-'0';//'1'
  16.         }else         if (c>='a'&&c<='f')
  17.         {
  18.                 cret=c-'a'+10;//'1'
  19.         }else   if (c>='A'&&c<='F')
  20.         {
  21.                 cret=c-'A'+10;//'1'
  22.         }

  23.         return cret;
  24. }

  25. //1、szHexStr 为待转换字16进制字串
  26. //2、szBytesbuf 是存放转换后的数据
  27. //3、nBufSize是szBytesbuf缓冲区的大小


  28. SIZE_T HexStrToBytes(const char*szHexStr,OUT BYTE*szBytesbuf,SIZE_T nBufSize)
  29. {
  30.         int dwHexLen=(int)strlen(szHexStr);
  31.         unsigned char OneByte=0;
  32.         int j=0;
  33.         int nBytes=0;
  34.         for (int i=0;i<=dwHexLen;i++)
  35.         {
  36.                
  37.                  //判断,分隔符
  38.                  if (i&&i%2==0)
  39.                  {
  40.                          nBytes++;
  41.                          szBytesbuf[j++]=OneByte;
  42.                          //检测缓冲是否溢出
  43.                          if (j>=nBufSize)
  44.                          {
  45.                                  //溢出了 返回
  46.                                  break;
  47.                          }
  48.                          OneByte=0;//初始化 以备下一字节的转换
  49.                  }
  50.                  {
  51.                           OneByte=OneByte*16+charToByte(szHexStr[i]);
  52.                  }
  53.         }

  54.         if(nBytes>68) {MessageBoxA(0,"特征码过长","警示",1);};
  55.         return nBytes;
  56. };

  57. //带分隔符
  58. SIZE_T HexStrToBytesNew(const char*szHexStr,OUT BYTE*szBytesbuf,SIZE_T nBufSize)
  59. {
  60.         int dwHexLen=(int)strlen(szHexStr);
  61.         unsigned char OneByte=0;
  62.         int j=0;
  63.         int nBytes=0;
  64.         for (int i=0;i<=dwHexLen;i++)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
  65.         {
  66.                
  67.                  //判断,分隔符
  68.                  if (szHexStr[i]==','||szHexStr[i]=='\0')
  69.                  {
  70.                          nBytes++;
  71.                          szBytesbuf[j++]=OneByte;
  72.                          //检测缓冲是否溢出
  73.                          if (j>=nBufSize)
  74.                          {
  75.                                  //溢出了 返回
  76.                                  break;
  77.                          }
  78.                          OneByte=0;//初始化 以备下一字节的转换
  79.                  }else
  80.                  {
  81.                           OneByte=OneByte*16+charToByte(szHexStr[i]);
  82.                  }
  83.         }
  84.         return nBytes;
  85. };

  86. bool 是通配符(BYTE c)
  87. {        //自己定义通配符 可以是所有的非数字符号
  88.         bool flag = false;
  89.         if (c == '*'||c == '?')
  90.         {
  91.                 flag = true;
  92.         }
  93.         else if (c == '?')  //全角状态的问号
  94.         {
  95.                 flag = true;
  96.         }
  97.         return flag;
  98. }

  99. bool 是数字(IN BYTE c,OUT BYTE &num)
  100. {
  101. bool  flag = false;
  102. //0..9
  103. //a..f
  104. //A..F
  105.         //unsigned char cret = 0;
  106.         if (c >= '0'&&c <= '9')
  107.         {
  108.                 num = c - '0';//'1'
  109.                 flag = true;
  110.         }
  111.         else         if (c >= 'a'&&c <= 'f')
  112.         {
  113.                 num = c - 'a' + 10;//'1'
  114.                 flag = true;
  115.         }
  116.         else   if (c >= 'A'&&c <= 'F')
  117.         {
  118.                 num = c - 'A' + 10;//'1'
  119.                 flag = true;
  120.         }
  121.         return flag;
  122. }

  123. bool 是分隔符(BYTE c)
  124. {
  125.         bool flag = false;
  126.         if (c == ',' || c == ' ')
  127.         {
  128.                 flag = true;
  129.         }
  130.         else if (c == ';')   
  131.         {
  132.                 flag = true;
  133.         }
  134.         return flag;
  135.          
  136. }

  137. //str是待处理的字符串
  138. //to_replaced 是被替换的字符串
  139. //newchars是新的字符串
  140. string& replace_str(string& str, const string& to_replaced, const string& newchars)     
  141.   {
  142.       for(string::size_type pos(0); pos != string::npos; pos += newchars.length())   
  143.       {
  144.           pos = str.find(to_replaced,pos);
  145.           if(pos!=string::npos)     
  146.              str.replace(pos,to_replaced.length(),newchars);     
  147.           else  
  148.               break;  
  149.       }     
  150.       return   str;     
  151.   }

  152. //带分隔符,通配符处理
  153. SIZE_T HexStrToBytesEx(IN const char*szHexStr, OUT BYTE*szBytesbuf, SIZE_T nBufSize,OUT BYTE*szStar)
  154. {
  155.         char tmpstr[256] = { 0 };
  156.         strcpy_s(tmpstr, szHexStr );
  157.         //printf("szHexStr=%s\r\n", szHexStr);
  158.         int dwHexLen = (int)strlen(szHexStr);
  159.         {
  160. //替换所有0x前缀0X
  161. //替换所有分隔符
  162. //不是数字的全当通配符

  163.                 //所有小写字母转大写
  164.                 for (int i = 0; i <= dwHexLen; i++)
  165.                 {
  166.                         if (tmpstr[i] >= 'a'&&tmpstr[i] <= 'z')
  167.                         {
  168.                                 //转大写
  169.                                 tmpstr[i] = tmpstr[i] + 'A' - 'a'; //'a'>'A'                   'A' - 'a'=-32
  170.                         }
  171.                 }
  172.                 std::string newHexStr = tmpstr;//这里不直接赋值为szHexStr,是为防止缓冲区重叠
  173.                 //替换所有0x前缀0X
  174.                 replace_str(newHexStr, "0X", "");//小写的0x已经在上边被转换
  175.                 //替换所有分隔符
  176.                 replace_str(newHexStr, ",", "");//中文逗号
  177.                 replace_str(newHexStr, ",", "");//英文逗号
  178.                 replace_str(newHexStr, " ", "");//英文逗号
  179.                 replace_str(newHexStr, "\t", "");//英文逗号
  180.                 strcpy_s(tmpstr, newHexStr.c_str());
  181.         }

  182.         unsigned char OneByte = 0;
  183.         int j = 0;
  184.         int nBytes = 0;
  185.         BYTE num=0;
  186.         dwHexLen =(int) strlen(tmpstr);
  187.         for (int i = 0; i <= dwHexLen; i++)
  188.         {

  189.         //  2个字符一组处理
  190.         //        if (是数字(tmpstr[i],num))         
  191.                 if (i&&i % 2 == 0)
  192.                 {        //i=2,4,6,8,10 偶数才会走到这里
  193.                 //        printf("[%03d]=%02X <%03d>\r\n",j, OneByte, OneByte);
  194.                         nBytes++;
  195.                         szBytesbuf[j++] = OneByte;
  196.                        
  197.                         //检测缓冲是否溢出
  198.                         if (j >= nBufSize|| tmpstr[i]=='\0')
  199.                         {
  200.                                 //遇到字符口中结束 或者 溢出了返回
  201.                                 break;
  202.                         }
  203.                         OneByte = 0;//初始化 以备下一字节的转换
  204.                 }

  205.                 {          //i=0,1,2,3,4,5,6
  206.                         bool flag=是数字(tmpstr[i], num);         // 1A,3F
  207.                         if (flag)
  208.                         {
  209.                                 OneByte = OneByte * 16 + num;// charToByte(tmpstr[i]);
  210.                         }else
  211.                         {
  212.                                 //不是数字 全当通配符处理了 ** ?? ??
  213.                                 //通配符 也必须是成对出现 否则格式就是错误的
  214.                                 if (tmpstr[i] != tmpstr[i + 1])
  215.                                 {
  216.                                         char buf[512];
  217.                                         sprintf_s(buf, "szHexStr=%s,tmpstr=%s通配符未成对出现", szHexStr, tmpstr);
  218.                                         MessageBoxA(0, buf, "ERROR HexStrToBytesEx", 0);
  219.                                 }
  220.                                 //printf("[%03d]=<%c,%c>\r\n", j, tmpstr[i], tmpstr[i+1]);
  221.                                  
  222.                                 szStar[j+0] = 1;           //保存通配符位置

  223.                                 i = i + 1; //一次性跳过一对通配符 需要的是i=i+2 这里加1是因为for循环那里还有个i++

  224.                         }
  225.                        
  226.                 }

  227.         }
  228.         //printf("\r\n");
  229.         return nBytes;
  230. };
复制代码

//CFind_Offset.h
  1. #pragma once

  2. #include <stdio.h>
  3. #include <windows.h>
  4. #include <psapi.h>
  5. #include <tchar.h>
  6. char* GetBjTime(IN OUT char*buf, size_t nBufSize);
  7. typedef class _CFind_Offset
  8. {
  9. public:

  10. static         HWND  GetHwnd();//获取目标窗口句柄
  11. static        DWORD GetPID(); //获取目标PID
  12. static        HANDLE GetProcessHandle();//获取目标进程句柄
  13. static  UINT_PTR GetExeBase();//获取目标进程主模块基址
  14. static  BOOL  GetExeData(OUT PBYTE &pbuf,OUT size_t &nReadSize);
  15. static  BOOL  FindOffset(IN BYTE* buf, IN size_t bufSize, IN BYTE* 特征码, IN BYTE 特征码长度, OUT DWORD &nOffset);
  16. static  INT_PTR  GetBaseOfffset(IN INT_PTR 指令地址,IN INT_PTR 指令长度,IN INT_PTR 指令前缀长度);

  17. static  INT_PTR  GetBaseOfffset(const char*特征码, INT_PTR 特征码偏移, BYTE 指令长度, BYTE 指令前缀长度);
  18. static  INT_PTR  GetBaseOfffsetEx(IN const char*特征码, IN  INT_PTR 特征码偏移, IN  BYTE 指令长度, IN  BYTE 指令前缀长度);
  19. static  INT_PTR  MatchSearch(IN const char*特征码带通配符, IN  INT_PTR 特征码偏移, IN  BYTE 指令长度, IN  BYTE 指令前缀长度);         //

  20. static  INT_PTR  MatchSearch(IN const char *变量名,
  21.         IN const char*特征码带通配符,
  22.         IN  INT_PTR 特征码偏移,
  23.         IN  BYTE 指令长度,
  24.         IN  BYTE 指令前缀长度);         // CFind_Offset
  25. static  void printfCmdAndFile(const char*buf);

  26. }CFind_Offset;

复制代码

//CFind_Offset.cpp

  1. #include "CFind_Offset.h"

  2. //buf 是目标进程的代码数据
  3. //bufSize 代码段数据的大小
  4. //特征码
  5. //特征码长度
  6. //nOffset返回找到的偏移         =目标进程特征地址-目标进程主模块地址
  7. static  char tmpbuf[0x6247000] = { 0 };//根据文件大小设置本地的缓冲区 100MB

  8. BOOL  CFind_Offset::FindOffset(IN BYTE* buf, IN size_t bufSize,IN BYTE* 特征码,IN BYTE 特征码长度,OUT DWORD &nOffset)
  9. {
  10.                    for (size_t i=0;i<bufSize- 特征码长度;i++)
  11.                    {
  12.                            if (memcmp(buf + i, 特征码, 特征码长度) == 0)        //内存比较
  13.                            {
  14.                                    nOffset =(DWORD)i;
  15.                                    return TRUE;
  16.                                    break;
  17.                            }
  18.                    }
  19.                    return FALSE;
  20. };

  21. INT_PTR  CFind_Offset::GetBaseOfffset(IN INT_PTR 指令地址, IN INT_PTR 指令长度, IN INT_PTR 指令前缀长度)
  22. {
  23.         INT_PTR p1 = 指令地址/*Mir4G.exe*/ + 指令前缀长度;
  24.         if ((p1+4) > sizeof(tmpbuf))
  25.         {
  26.                 MessageBoxA(NULL, "错误的参数", "ERROR", 0);
  27.                 return 0;
  28.         }
  29.         else
  30.         {
  31.                 //000000013F59223D     | 48 8B 0D EC D8 9A 05     | mov rcx,qword ptr ds:[144F3FB30]  | Mir4G.exe+5E0FB30  //13F130000+        5E0FB30
  32.                 //$-2C         | 48 8B 0D EC D8 9A 05     | mov rcx,qword ptr ds:[145D7FB30]  | Mir4G.exe+5E0FB30                  mov rcx qword ptr[????]           EC D8 9A 05 //059AD8EC

  33.                 INT_PTR 偏移 = *(DWORD*)(tmpbuf+p1);
  34.                 //目标地址=指令地址+指令长度+偏移          
  35.                 //144F3FB30=000000013F59223D+7+059AD8EC                  
  36.                 //13F130000+        5E0FB30        = 13F130000+46223D+7+059AD8EC                  //EXE基址=13F130000
  37.                 // exe基址+        5E0FB30        = exe基址+46223D+7+059AD8EC
  38.                 // exe基址+        5E0FB30        = exe基址+指令地址+7+059AD8EC
  39.                 // exe基址+        5E0FB30        = exe基址+指令地址+指令长度+偏移

  40.                 // 5E0FB30= 指令地址+指令长度+偏移

  41.                 INT_PTR 目标地址 = 指令地址 + 指令长度 + 偏移;
  42.                  
  43.                 return 目标地址;  
  44.         }
  45.        
  46. };
  47. //只读取一次
  48. BOOL  CFind_Offset::GetExeData(OUT PBYTE &pbuf, OUT size_t &nReadSize)
  49. {
  50.        
  51.         static  size_t nsize = 0;         //用于保存实际读取的字节大小

  52.         if (nsize)
  53.         {
  54.                 nReadSize = nsize;
  55.                 pbuf = (PBYTE)tmpbuf;
  56.                 return TRUE;
  57.         }
  58.         //顺利的情况下 以下代码只会执行一次
  59.         HANDLE hp = GetProcessHandle();          //获取目标进程句柄权限
  60.         UINT_PTR exebase = GetExeBase(); //获取目标进程的 主模块基址
  61.         BOOL br=ReadProcessMemory(hp, (PVOID)exebase, tmpbuf, sizeof(tmpbuf), &nsize);
  62.         if (br == FALSE)
  63.         {
  64.                 printf("hp=%p Error  GetLastError()=%d line=%d\r\n", hp, GetLastError(),__LINE__);
  65.                 getchar();
  66.         }
  67.         else
  68.         {
  69.                 nReadSize = nsize;
  70.                 pbuf =(BYTE*) tmpbuf;
  71.                
  72.         }

  73.         return br;
  74. };

  75. HWND  CFind_Offset::GetHwnd()
  76. {
  77.         HWND h = FindWindowA("UnrealWindow", NULL); //"UnrealWindow"  // "Mir4G[1]" "Mir4G[2]"
  78.         if (h)
  79.         {
  80.                 return h;
  81.         }
  82.         else
  83.         {
  84.                 printf("Error line=%d FindWindowA ret NULL 游戏未打开 \r\n", __LINE__);
  85.                 getchar();
  86.         }
  87.         return 0;
  88. };
  89. DWORD CFind_Offset::GetPID()
  90. {
  91.         HWND h = GetHwnd();
  92.         DWORD pid = 0;
  93.         GetWindowThreadProcessId(h, &pid);

  94.         return pid;
  95. };

  96. HANDLE CFind_Offset::GetProcessHandle()
  97. {
  98.         DWORD pid = GetPID();
  99.         static HANDLE hp = OpenProcess(PROCESS_ALL_ACCESS, false, pid);//如失败,返回值为空,可调用GetLastError获得错误代码。
  100.         if (hp==NULL )
  101.         {
  102.                 printf("Error line=%d OpenProcess ret NULL GetLastError()=%d \r\n", __LINE__, GetLastError());
  103.                 getchar();
  104.         }
  105.         return hp;
  106. };

  107. UINT_PTR CFind_Offset::GetExeBase()
  108. {
  109.         //return(UINT_PTR) GetModuleHandleA(NULL);//代码已经注入到目标进程空间
  110.         static        UINT_PTR exeBase64 = NULL;
  111.         HMODULE hMods[1024]; //20*sizeof(HMODULE ) //160
  112.         DWORD cbNeeded;
  113.         unsigned int i;
  114.         HANDLE 进程句柄 = GetProcessHandle();
  115.         if (exeBase64) return exeBase64;
  116.         // Get a list of all the modules in this process.
  117.         BOOL br = EnumProcessModules(进程句柄, hMods, sizeof(hMods), &cbNeeded);
  118.         if (br)
  119.         {
  120.                 UINT32 模块数量 = cbNeeded / sizeof(HMODULE);
  121.                 for (i = 0; i < 模块数量; i++)
  122.                 {
  123.                         TCHAR szModName[MAX_PATH] = { 0 };
  124.                     DWORD iret=        GetModuleFileNameEx(进程句柄, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR));
  125.                        
  126.                         // Get the full path to the module's file.
  127.                         //printf("i=[%d],szModName=%s hMods[%d]=%p>>>\r\n",i, szModName,i,hMods[i]);
  128.                         if (iret)
  129.                         {
  130.                                 //如果是 .exe模块 直接返回基址
  131.                                 if (strstr(szModName, ".exe")) //*.bin *.dat //Mir4G.exe
  132.                                 {
  133.                                         exeBase64 = (UINT_PTR)hMods[i]; //hMods[0]
  134.                                         printf("//主模块Mir4G.exe地址=%llX  i=%d\r\n", exeBase64, i);
  135.                                 }
  136.          
  137.                         }
  138.                 }
  139.         }
  140.         else
  141.         {
  142.                 /*
  143.         〖0〗-操作成功完成。
  144.   〖1〗-功能错误。
  145.   〖2〗-系统找不到指定的文件。
  146.   〖3〗-系统找不到指定的路径。
  147.   〖4〗-系统无法打开文件。
  148.   〖5〗-拒绝访问。
  149.   〖6〗-句柄无效。
  150.                 */
  151.                 printf("Error EnumProcessModules line=%d  GetLastError=%d 进程句柄=%p", __LINE__,GetLastError(), 进程句柄);
  152.                 getchar();
  153.         }

  154.         // Release the handle to the process.

  155.         //CloseHandle(进程句柄);

  156.         return exeBase64;
  157. }






复制代码

//CFind_Offset_GetBaseOfffset.cpp
  1. #include "CFind_Offset.h"
  2. #include "HexStrToBytes.h"
  3. //buf 是目标进程的代码数据
  4. //bufSize 代码段数据的大小
  5. //特征码
  6. //特征码长度
  7. //nOffset返回找到的偏移         =目标进程特征地址-目标进程主模块地址
  8. //static  char tmpbuf[0x6247000] = { 0 };//根据文件大小设置本地的缓冲区 100MB

  9. INT_PTR  CFind_Offset::GetBaseOfffsetEx(IN const char*特征码, IN  INT_PTR 特征码偏移, IN  BYTE 指令长度, IN  BYTE 指令前缀长度)
  10. {
  11.         OUT INT_PTR           nOffset = 0;
  12.         BYTE   字节集[256] = { 0 };
  13.         BYTE   通配符[256] = { 0 };//备用
  14.         size_t 特征码长度 = strlen(特征码);
  15.         if (特征码长度 > 128)
  16.         {
  17.                 MessageBoxA(0, "最大支持128字节特征码长度", "ERROR", 0);
  18.                 return 0;
  19.         }

  20.         //16进制字符串转 字节集数组
  21.         特征码长度 = HexStrToBytes(IN 特征码, OUT 字节集, IN 特征码长度);
  22.         BYTE* exebuf = 0;
  23.         size_t exebufsize = 0;
  24.         GetExeData(exebuf, exebufsize);
  25.         if (exebuf == NULL)
  26.         {
  27.                 MessageBoxA(0, "未成功获取目标进程代码段", "ERROR", 0);
  28.         }
  29.         BYTE*pexebuf = (BYTE*)exebuf;
  30.         for (size_t i = 0; i < exebufsize; i++)
  31.         {
  32.                 if (memcmp(pexebuf + i, 字节集, 特征码长度) == 0)
  33.                 {
  34.                         nOffset = i;
  35.                         break;
  36.                 }
  37.         }
  38.         //找到了特征码位置
  39.         if (nOffset)
  40.         {
  41.                 INT_PTR 指令地址 = nOffset + 特征码偏移;
  42.                 DWORD *偏移 = (DWORD*)(pexebuf + 指令地址 + 指令前缀长度);

  43.                 nOffset = 指令地址 + 指令长度 + 偏移[0];
  44.                 printf("指令地址=%llX nOffset=%llX\r\n", 指令地址, nOffset);
  45.         }
  46.         return nOffset;
  47. }

  48. INT_PTR  CFind_Offset::GetBaseOfffset(const char*特征码, INT_PTR 特征码偏移, BYTE 指令长度, BYTE 指令前缀长度)
  49. {
  50.         OUT INT_PTR           nOffset = 0;
  51.         BYTE   字节集[256] = { 0 };
  52.         //BYTE   通配符[256] = { 0 };//备用
  53.         size_t 特征码长度 = strlen(特征码);
  54.         if (特征码长度 > 128)
  55.         {
  56.                 MessageBoxA(0, "最大支持128字节特征码长度", "ERROR", 0);
  57.                 return 0;
  58.         }

  59.         //16进制字符串转 字节集数组
  60.         特征码长度=HexStrToBytes(IN 特征码, OUT 字节集, IN 特征码长度);
  61.         BYTE* exebuf = 0;
  62.         size_t exebufsize = 0;
  63.         GetExeData(exebuf, exebufsize);
  64.         if (exebuf==NULL)
  65.         {
  66.                 MessageBoxA(0, "未成功获取目标进程代码段", "ERROR", 0);
  67.         }
  68.         BYTE*pexebuf = (BYTE*)exebuf;
  69.     for (size_t i=0;i< exebufsize;i++)
  70.     {
  71.                 if (memcmp(pexebuf + i, 字节集, 特征码长度) == 0)
  72.                 {
  73.                         nOffset = i;
  74.                         break;
  75.                  }
  76.     }
  77.         //找到了特征码位置
  78.         if (nOffset)
  79.         {
  80.                 INT_PTR 指令地址 = nOffset + 特征码偏移;
  81.                 DWORD *偏移 = (DWORD*) (pexebuf+指令地址 + 指令前缀长度);

  82.                 nOffset = 指令地址 + 指令长度 + 偏移[0];
  83.                 printf("指令地址=%llX nOffset=%llX\r\n", 指令地址, nOffset);
  84.         }
  85.         return nOffset;
  86. };
复制代码

//CFind_Offset_MatchSearch.cpp


  1. #include "CFind_Offset.h"
  2. #include "HexStrToBytes.h"

  3. //相等时返回0
  4. int MatchCmp(const BYTE* s1, const BYTE*s2,  const BYTE* star1, size_t len)
  5. {
  6. #ifdef _DEBUG
  7.         if (!s1 || !s2 || !star1)
  8.         {
  9.                 MessageBoxA(0,"Error指针参数为NULL","MatchCmp", 0);
  10.         }
  11. #endif

  12.         size_t i = 0;
  13.         for (i = 0; i < len; i++)
  14.         {
  15.            if (star1[i] || (s1[i] == s2[i])) //是通配符                 memcmp
  16.            {   
  17.                  //  printf("star1[%d]=%02X s1,s2<02X,%02X>\r\n", star1[i], s1[i], s2[i]);
  18.                    continue;  

  19.            }else
  20.            {
  21.                    break;
  22.            }
  23.         }

  24.         //printf("i=%zd len=%zd\r\n",i,len);
  25.     if (i==len)
  26.     {
  27.                 return 0;        //相等
  28.         }
  29.         else
  30.         {
  31.                 return(int)i+1; //不等
  32.         }
  33.          
  34. }
  35. INT_PTR  CFind_Offset::MatchSearch(IN const char*特征码带通配符, IN  INT_PTR 特征码偏移, IN  BYTE 指令长度, IN  BYTE 指令前缀长度)
  36. {
  37.         UINT_PTR base = GetExeBase();
  38.         PBYTE pexebuf = 0;
  39.         size_t nSizeExe = 0;
  40.         GetExeData(pexebuf, nSizeExe);

  41.         // // CFind_Offset_MatchSearch
  42.         INT_PTR nOffset = 0;
  43.         {
  44.                 //char 特征码带通配符[] = "48 8B 15ZZ**??**FF 90 48080000 48 83 BF C8040000 00";          //11223355667788AAXX88                  
  45.                 BYTE features[256];                          
  46.                 BYTE star1[256] = { 0 };                           
  47.                 size_t nsize1 = HexStrToBytesEx(特征码带通配符,OUT features, sizeof(features), OUT star1);
  48.                  

  49.                 if (nSizeExe&&nsize1)
  50.                 {
  51.                         for (size_t i = 0; i < nSizeExe- nsize1; i++)
  52.                         {           //int MatchCmp(const BYTE* s1, const BYTE*s2,  const BYTE* star1, size_t len)
  53.                                 int iret = MatchCmp(pexebuf + i, features, star1, nsize1);
  54.                                 if (iret == 0)
  55.                                 {
  56.                                         nOffset = i;
  57.                                         break;
  58.                                 }
  59.                         }
  60.                 }


  61.         }



  62.         //找到了特征码位置
  63.         if (nOffset)
  64.         {
  65.                 INT_PTR 指令地址 = nOffset + 特征码偏移;
  66.                 DWORD *偏移 = (DWORD*)(pexebuf + 指令地址 + 指令前缀长度);

  67.                 //printf("//nOffset=%zX 特征码偏移=%zX <%zX,%d,%X>=%zX\r\n", nOffset, 特征码偏移, 指令地址,指令长度 , 偏移[0]
  68.                 //, 指令地址 + 指令长度 + 偏移[0]);

  69.                 nOffset = (DWORD)(指令地址 + 指令长度 + 偏移[0]);        //会存在溢出的情况
  70. //#ifdef _DEBUG
  71. //                printf("//%s> 搜索结果<%zX,%zX>\r\n", 特征码带通配符, base + nOffset, nOffset);
  72. //                printf("//指令地址=<%zX,%zX> nOffset=<%zX,%zX>\r\n", base + 指令地址, 指令地址, base + nOffset, nOffset);
  73. //#endif // _DEBUG
  74.         }



  75.         return nOffset;
  76. }

  77. int  WriteToFile(const char* szLine)
  78. {
  79.         const char* sFilePath = "基址偏移.h";
  80.         //printf("sFilePath=%s line=%d \n", sFilePath,__LINE__);
  81.         //FileRename(sFilePath);

  82.         FILE* fp = 0;
  83.         fopen_s(&fp,sFilePath, "ab+"); //w+ 清新后写 a+ 在文件尾追加写
  84.         if (fp == NULL)
  85.         {
  86.                 return -1;
  87.         }
  88.         fwrite(szLine, strlen(szLine), 1, fp);
  89.         fclose(fp);
  90.         return 0;
  91. }

  92. void CFind_Offset::printfCmdAndFile(const char*buf)
  93. {
  94.         printf(buf);
  95.         WriteToFile(buf);
  96. };

  97. INT_PTR  CFind_Offset::MatchSearch(
  98.         IN const char *变量名,
  99.         IN const char*特征码带通配符,
  100.         IN  INT_PTR 特征码偏移,
  101.         IN  BYTE 指令长度,
  102.         IN  BYTE 指令前缀长度)
  103. {
  104.          char buf[512];
  105.          UINT_PTR exeBase=GetExeBase();
  106.          INT_PTR nOffset = MatchSearch(特征码带通配符, 特征码偏移, 指令长度, 指令前缀长度);
  107.          sprintf_s(buf,"const UINT_PTR %s =0x%zX; // %zX >%s<%zd,%d,%d>\r\n",
  108.                  变量名,
  109.                  nOffset,
  110.                  exeBase+nOffset,特征码带通配符 ,特征码偏移, 指令长度, 指令前缀长度);
  111.          //写文件
  112.          printf(buf);
  113.          WriteToFile(buf);
  114.          return nOffset;
  115. }
复制代码

//基址偏移.h

  1. //#pragma once
  2. const UINT_PTR CALL02_OFFSET_取任务对象 =F431D0; // 1401431D0 >488D8FE0020000488B01FF5030<31,5,1>
  3. const UINT_PTR CALL01_RCX_OFFSET_取任务对象 =12072E0; // 1404072E0 >488D8FE0020000488B01FF5030<18,5,1>
  4. const UINT_PTR CALL_OFFSET_明文包 =12FE530; // 1404FE530 >41B888130000488D542430488B4808<15,5,1>
  5. const UINT_PTR CALL_RCX_OFFSET_明文包 =5D29FE8; // 144F29FE8 >41B888130000488D542430488B4808<-7,7,3>
  6. const UINT_PTR CALL_OFFSET_背包物品使用 =1178980; // 140378980 >440FB68710030000488B93B0000000488BCBE8<18,5,1>
  7. const UINT_PTR CALL_OFFSET_使用背包物品01 =9C7010; // 13FBC7010 >488BC8450FB6CD41B801000000488BD3E8<16,5,1>
  8. const UINT_PTR CALL_RCX_OFFSET_使用背包物品01 =6E4400; // 13F8E4400 >488BC8450FB6CD41B801000000488BD3E8<-5,5,1>
  9. const UINT_PTR CALL_OFFSET_选怪CALL01 =8FDA40; // 13FAFDA40 >0F28B424F0000000488B8338030000<-5,5,1>
  10. const UINT_PTR CALL_OFFSET_选怪CALL02 =8E7BC0; // 13FAE7BC0 >0F28B424F0000000488B8338030000<-16,5,1>
  11. const UINT_PTR CALL_OFFSET_取控件对象 =1D67F00; // 140F67F00 >4C8B4310488BD7488BC8488B5C24304883C4205F49FFE0<-5,5,1>
  12. const UINT_PTR CALL_OFFSET_寻路 =A06A60; // 13FC06A60 >C6442428028944242CF20F10833C060000<60,5,1>
  13. const UINT_PTR CALL_OFFSET_按键 =1DA30E0; // 140FA30E0 >33C04889BEF00100004889BEF8010000898611010000<48,7,3>
  14. const UINT_PTR CALL_OFFSET01_采集 =6E4400; // 13F8E4400 >4488642428C7442420000000004533C941B001<-8,5,1>
  15. const UINT_PTR CALL_OFFSET02_采集 =9AE9D0; // 13FBAE9D0 >4488642428C7442420000000004533C941B001<22,5,1>
  16. const UINT_PTR OFFSET_怪物人物采集物对象ID数组 =5D2AF30; // 144F2AF30 >32C04D85C07408410FB68080060000<-7,7,3>
  17. const UINT_PTR OFFSET_所有对象数组 =5E0FB30; // 14500FB30 >33C08B4008C1E81DA8010F85<-23,7,3>
  18. const UINT_PTR OFFSET_人物属性对象A =5D29B18; // 144F29B18 >488B01FF50283D5E240000<17,7,3>
  19. const UINT_PTR OFFSET_人物角色坐标基址 =5D2A540; // 144F2A540 > 48 8B 05 ********48 85 C0  74 **80 B8 88 03 00 00 0D  <0,7,3>
  20. const UINT_PTR OFFSET_NPC_ID_LIST =55A2CB0; // 1447A2CB0 >488D3CD04885FF0F84A5<-7,7,3>

  21. //#pragma once
  22. const UINT_PTR CALL02_OFFSET_取任务对象 =F431D0; // 1400431D0 >488D8FE0020000488B01FF5030<31,5,1>
  23. const UINT_PTR CALL01_RCX_OFFSET_取任务对象 =12072E0; // 1403072E0 >488D8FE0020000488B01FF5030<18,5,1>
  24. const UINT_PTR CALL_OFFSET_明文包 =12FE530; // 1403FE530 >41B888130000488D542430488B4808<15,5,1>
  25. const UINT_PTR CALL_RCX_OFFSET_明文包 =5D29FE8; // 144E29FE8 >41B888130000488D542430488B4808<-7,7,3>
  26. const UINT_PTR CALL_OFFSET_背包物品使用 =1178980; // 140278980 >440FB68710030000488B93B0000000488BCBE8<18,5,1>
  27. const UINT_PTR CALL_OFFSET_使用背包物品01 =9C7010; // 13FAC7010 >488BC8450FB6CD41B801000000488BD3E8<16,5,1>
  28. const UINT_PTR CALL_RCX_OFFSET_使用背包物品01 =6E4400; // 13F7E4400 >488BC8450FB6CD41B801000000488BD3E8<-5,5,1>
  29. const UINT_PTR CALL_OFFSET_选怪CALL01 =8FDA40; // 13F9FDA40 >0F28B424F0000000488B8338030000<-5,5,1>
  30. const UINT_PTR CALL_OFFSET_选怪CALL02 =8E7BC0; // 13F9E7BC0 >0F28B424F0000000488B8338030000<-16,5,1>
  31. const UINT_PTR CALL_OFFSET_取控件对象 =1D67F00; // 140E67F00 >4C8B4310488BD7488BC8488B5C24304883C4205F49FFE0<-5,5,1>
  32. const UINT_PTR CALL_OFFSET_寻路 =A06A60; // 13FB06A60 >C6442428028944242CF20F10833C060000<60,5,1>
  33. const UINT_PTR CALL_OFFSET_按键 =1DA30E0; // 140EA30E0 >33C04889BEF00100004889BEF8010000898611010000<48,7,3>
  34. const UINT_PTR CALL_OFFSET01_采集 =6E4400; // 13F7E4400 >4488642428C7442420000000004533C941B001<-8,5,1>
  35. const UINT_PTR CALL_OFFSET02_采集 =9AE9D0; // 13FAAE9D0 >4488642428C7442420000000004533C941B001<22,5,1>
  36. const UINT_PTR OFFSET_怪物人物采集物对象ID数组 =5D2AF30; // 144E2AF30 >32C04D85C07408410FB68080060000<-7,7,3>
  37. const UINT_PTR OFFSET_所有对象数组 =5E0FB30; // 144F0FB30 >33C08B4008C1E81DA8010F85<-23,7,3>
  38. const UINT_PTR OFFSET_人物属性对象A =5D29B18; // 144E29B18 >488B01FF50283D5E240000<17,7,3>
  39. const UINT_PTR OFFSET_人物角色坐标基址 =5D2A540; // 144E2A540 > 48 8B 05 ********48 85 C0  74 **80 B8 88 03 00 00 0D  <0,7,3>
  40. const UINT_PTR OFFSET_NPC_ID_LIST =55A2CB0; // 1446A2CB0 >488D3CD04885FF0F84A5<-7,7,3>
  41. //>>完成所有遍历

复制代码

//OFFSET_所有对象数组.cpp
  1. #include <windows.h>

  2. /*
  3. //#define OFFSET_所有对象数组   0x5DE7C70   // 49 8B C6 81 60 08 FF FF FF BF  //向上找第一个地址
  4. $-2E         | 7D 2C                    | jge mir4g.1403D2269               |
  5. $-2C         | 48 8B 0D EC D8 9A 05     | mov rcx,qword ptr ds:[145D7FB30]  | Mir4G.exe+5E0FB30                  mov rcx qword ptr[????]           EC D8 9A 05 //059AD8EC
  6. $-25         | 99                       | cdq                               |
  7. $-24         | 0F B7 D2                 | movzx edx,dx                      |
  8. $-21         | 03 C2                    | add eax,edx                       |
  9. $-1F         | 44 8B C0                 | mov r8d,eax                       |
  10. $-1C         | 0F B7 C0                 | movzx eax,ax                      |
  11. $-19         | 2B C2                    | sub eax,edx                       |
  12. $-17         | 41 C1 F8 10              | sar r8d,10                        |
  13. $-13         | 48 98                    | cdqe                              |
  14. $-11         | 49 63 D0                 | movsxd rdx,r8d                    |
  15. $-E          | 4C 8B 04 D1              | mov r8,qword ptr ds:[rcx+rdx*8]   |
  16. $-A          | 48 8D 0C 40              | lea rcx,qword ptr ds:[rax+rax*2]  |
  17. $-6          | 49 8D 04 C8              | lea rax,qword ptr ds:[r8+rcx*8]   |
  18. $-2          | EB 03                    | jmp mir4g.1403D226C               |
  19. $ ==>        | 49 8B C6                 | mov rax,r14                       |  0x49,0x8B,0xC6,0x81,0x60,0x08,0xFF,0xFF,0xFF,0xBF
  20. $+3          | 81 60 08 FF FF FF BF     | and dword ptr ds:[rax+8],BFFFFFFF |
  21. $+A          | 48 8D 15 E6 59 94 03     | lea rdx,qword ptr ds:[143D17C60]  | 143D17C60:L"ExtendedFacebook"

  22. */

  23. #include <windows.h>
  24. #include "CFind_Offset.h"
  25. const INT_PTR 特征码偏移 = -0x2C;
  26. const DWORD 指令长度 = 7;
  27. const DWORD 指令前缀长度 = 3;

  28. void  OFFSET_所有对象数组()
  29. {

  30.         INT_PTR exeBase = CFind_Offset::GetExeBase();
  31.         BYTE* buf = NULL;
  32.         size_t nSize = 0;
  33.         CFind_Offset::GetExeData(buf, nSize);
  34.         printf("ExeDataBuf=%p nSize=%zx \r\n", buf, nSize);
  35.         //char 特征码2[] = { 0x49,0x8B,0xC6,0x81,0x60,0x08,0xFF,0xFF,0xFF,0xBF };
  36.         BYTE 特征码[] = { 0x49,0x8B,0xC6,0x81,0x60,0x08,0xFF,0xFF,0xFF,0xBF };

  37.         DWORD 特征码地址偏移 = 0;
  38.         BOOL 是否找到 = CFind_Offset::FindOffset((BYTE*)buf, nSize, 特征码, sizeof(特征码), OUT 特征码地址偏移);
  39.         if (是否找到)
  40.         {
  41.                 printf("特征码长度=%zd  找到的偏移=0x%X 游戏特征地址=0x%llX\r\n", sizeof(特征码), 特征码地址偏移, exeBase + 特征码地址偏移);
  42.                 {
  43.                         INT_PTR 指令地址 = 特征码地址偏移 + 特征码偏移;
  44.                         //指令地址 指令长度 指令前缀长度
  45.                         INT_PTR 最终偏移=        CFind_Offset::GetBaseOfffset(指令地址, 指令长度, 指令前缀长度);
  46.                         printf("OFFSET_所有对象数组->(最终偏移=%zx 真实地址=%zx)\r\n", 最终偏移, exeBase+ 最终偏移);
  47.                 }
  48.         }
  49.         else
  50.         {
  51.                 printf("Error 相应特征码 未定位到 是否找到=%d\r\n", 是否找到);
  52.                 getchar();
  53.         }

  54. }

  55. // "498BC6816008FFFFFFBF"                  //0x49,0x8B,0xC6,0x81,0x60,0x08,0xFF,0xFF,0xFF,0xBF
  56. //INT_PTR  CFind_Offset::GetBaseOfffset(const char*特征码, INT_PTR 特征码偏移, BYTE 指令长度, BYTE 指令前缀长度)       
  57. void  OFFSET_所有对象数组02()
  58. {        //498BC6816008????FFBF
  59.         INT_PTR exeBase = CFind_Offset::GetExeBase();
  60.         INT_PTR 最终偏移 = CFind_Offset::GetBaseOfffset("498BC6816008FFFFFFBF", -0x2C, 7,3);
  61.         printf("OFFSET_所有对象数组02->(最终偏移=%zx 真实地址=%zx)\r\n", 最终偏移, exeBase + 最终偏移);
  62. }
复制代码

//定位所有基址偏移.cpp
  1. #include "CFind_Offset.h"
  2. #include <time.h>

  3. int  WriteToFile(const char* szLine);

  4. char* GetBjTime(IN OUT char*buf,size_t nBufSize)
  5. {
  6.         //GetSystemTime(&sysTm); //获取格林威治标准时间,与北京时间相差8小时  
  7.         time_t t = time(NULL);
  8.         tm tp;
  9.         localtime_s(&tp, &t);   // 北京时间
  10.         sprintf_s(buf, nBufSize,"%d/%d/%d->", tp.tm_year + 1900, tp.tm_mon + 1, tp.tm_mday);
  11.         sprintf_s(buf, nBufSize,"%s%d:%d:%d\n",buf,tp.tm_hour, tp.tm_min, tp.tm_sec);

  12.         return buf;
  13. }
  14. int  定位所有基址并输入到文件()
  15. {
  16.         {        const char strline0[] = "\r\n#pragma once\r\n";
  17.         printf(strline0);
  18.         WriteToFile(strline0);
  19.         }
  20.         {
  21.         char sz特征码[] = "488D8FE0020000488B01FF5030"; //+0x1F
  22.         CFind_Offset::MatchSearch("CALL02_OFFSET_取任务对象", sz特征码, 0x1F, 5, 1);
  23.         CFind_Offset::MatchSearch("CALL01_RCX_OFFSET_取任务对象", sz特征码, 0x12, 5, 1);
  24.         }
  25.         //return 1;
  26.         {
  27.                 char sz特征码[] = "41B888130000488D542430488B4808";
  28.                 {

  29.                         char sz变量名[] = "CALL_OFFSET_明文包";
  30.                         CFind_Offset::MatchSearch(sz变量名, sz特征码, 0x0F, 5, 1);

  31.                 }
  32.                 {

  33.                         char sz变量名[] = "CALL_RCX_OFFSET_明文包";
  34.                         CFind_Offset::MatchSearch(sz变量名, sz特征码, -0x7, 7, 3);

  35.                 }

  36.         }
  37.         //CALL_OFFSET_背包物品使用
  38.         {
  39.                 char sz特征码[] = "440FB68710030000488B93B0000000488BCBE8"; // +0x12
  40.                 char sz变量名[] = "CALL_OFFSET_背包物品使用";
  41.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, 0x12, 5, 1);
  42.         }
  43.         {
  44.                 char sz特征码[] = "488BC8450FB6CD41B801000000488BD3E8"; // +0x10
  45.                 char sz变量名[] = "CALL_OFFSET_使用背包物品01";
  46.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, 0x10, 5, 1);
  47.         }
  48.         {
  49.                 char sz特征码[] = "488BC8450FB6CD41B801000000488BD3E8"; // -0x05
  50.                 char sz变量名[] = "CALL_RCX_OFFSET_使用背包物品01";
  51.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, -0x05, 5, 1);
  52.         }
  53.         //CALL_OFFSET_选怪
  54.         {
  55.                 char sz特征码[] = "0F28B424F0000000488B8338030000"; //-5
  56.                 char sz变量名[] = "CALL_OFFSET_选怪CALL01";
  57.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, -0x05, 5, 1);
  58.         }
  59.         {
  60.                 char sz特征码[] = "0F28B424F0000000488B8338030000"; //-0x10
  61.                 char sz变量名[] = "CALL_OFFSET_选怪CALL02";
  62.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, -0x10, 5, 1);
  63.         }
  64.         //CALL_OFFSET_取控件对象
  65.         {
  66.                 char sz特征码[] = "4C8B4310488BD7488BC8488B5C24304883C4205F49FFE0"; //-0x05
  67.                 char sz变量名[] = "CALL_OFFSET_取控件对象";
  68.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, -0x05, 5, 1);
  69.         }
  70.         //CALL_OFFSET_寻路
  71.         {
  72.                 char sz特征码[] = "C6442428028944242CF20F10833C060000"; //+0x3C
  73.                 char sz变量名[] = "CALL_OFFSET_寻路";
  74.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, 0x3C, 5, 1);
  75.         }
  76.         //CALL_OFFSET_按键
  77.         {
  78.                 char sz特征码[] = "33C04889BEF00100004889BEF8010000898611010000";
  79.                 char sz变量名[] = "CALL_OFFSET_按键";
  80.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, 0x30, 7, 3);
  81.         }
  82.         //CALL_OFFSET_采集
  83.         {
  84.                 char sz特征码[] = "4488642428C7442420000000004533C941B001"; //-8
  85.                 char sz变量名[] = "CALL_OFFSET01_采集";
  86.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, -8, 5, 1);
  87.         } {
  88.                 char sz特征码[] = "4488642428C7442420000000004533C941B001"; //+0x16
  89.                 char sz变量名[] = "CALL_OFFSET02_采集";
  90.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, 0x16, 5, 1);
  91.         }
  92.         //OFFSET_怪物人物采集物对象ID数组
  93.         {
  94.                 char sz特征码[] = "32C04D85C07408410FB68080060000"; // -0x07
  95.                 char sz变量名[] = "OFFSET_怪物人物采集物对象ID数组";
  96.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, -7, 7, 3);
  97.         }
  98.         //OFFSET_所有对象数组
  99.         {
  100.                 char sz特征码[] = "33C08B4008C1E81DA8010F85"; // -0x17
  101.                 char sz变量名[] = "OFFSET_所有对象数组";
  102.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, -0x17, 7, 3);
  103.         }
  104.         //OFFSET_人物属性对象A
  105.         {
  106.                 char sz特征码[] = "488B01FF50283D5E240000"; //+11
  107.                 char sz变量名[] = "OFFSET_人物属性对象A";
  108.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, 0x11, 7, 3);
  109.         }
  110.         //OFFSET_人物角色坐标基址
  111.         {
  112.                 char sz特征码[] = " 48 8B 05 ********48 85 C0  74 **80 B8 88 03 00 00 0D  "; //+9
  113.                 char sz变量名[] = "OFFSET_人物角色坐标基址";
  114.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, 0, 7, 3);
  115.         }

  116.         {
  117.                 char sz特征码[] = "488D3CD04885FF0F84A5"; //-07
  118.                 char sz变量名[] = "OFFSET_NPC_ID_LIST";
  119.                 CFind_Offset::MatchSearch(sz变量名, sz特征码, -7, 7, 3);
  120.         }
  121.          
  122.         {
  123.                 const char strline0[] = "//>>完成所有遍历-->>OK %t\r\n";
  124.                 printf(strline0);
  125.                 WriteToFile(strline0);

  126.                 char buf[256];
  127.                 GetBjTime(buf, sizeof(buf));

  128.                 CFind_Offset::printfCmdAndFile(buf);

  129.         }


  130.         return 1;
  131. }


复制代码

//main.cpp
  1. // FindBaseOffset.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. //
  3. #include <time.h>
  4. #include <iostream>
  5. #include "CFind_Offset.h"
  6. #include "HexStrToBytes.h"

  7. char* GetBjTime(IN OUT char*buf, size_t nBufSize);

  8. void 测试带通配符的特征转换()
  9. {
  10.         {
  11.                 char s1[] = "0x11,0x22,0x33,0x44,0x55,0xFF,0x1A,0x1b,0x1c,0x330x66";          //11223355667788AAXX88
  12.                 char s2[] = "ABCD112233**55??66";
  13.                 BYTE b1[256];
  14.                 BYTE b2[256];
  15.                 BYTE star1[256] = { 0 };
  16.                 BYTE star2[256] = { 0 };
  17.                 size_t nsize1 = HexStrToBytesEx(s1, b1, sizeof(b1), star1);
  18.                 size_t nsize2 = HexStrToBytesEx(s2, b2, sizeof(b2), star2);
  19.                 printf("nsize1=%zd,nsize2=%zd\r\n", nsize1, nsize2);
  20.                 getchar();
  21.         }
  22.         {
  23.                 char s1[] = "48 8B 15ZZ**??**FF 90 48080000 48 83 BF C8040000 00";          //11223355667788AAXX88
  24.                 char s2[] = "48 89 05**??****BE 3F000000  80 78 08 000F84";
  25.                 BYTE b1[256];
  26.                 BYTE b2[256];
  27.                 BYTE star1[256] = { 0 };
  28.                 BYTE star2[256] = { 0 };
  29.                 size_t nsize1 = HexStrToBytesEx(s1, b1, sizeof(b1), star1);
  30.                 size_t nsize2 = HexStrToBytesEx(s2, b2, sizeof(b2), star2);
  31.                 printf("nsize1=%zd,nsize2=%zd\r\n", nsize1, nsize2);
  32.                 getchar();

  33.         }

  34. }
  35. void  OFFSET_所有对象数组();
  36. void  OFFSET_所有对象数组02();
  37. int  定位所有基址并输入到文件();
  38. int main()
  39. {

  40.          定位所有基址并输入到文件();


  41.         getchar();
  42. }
复制代码


游戏安全课程 学员办理咨询联系QQ150330575 手机 139 9636 2600  免费课程 在 www.bilibili.com 搜 郁金香灬老师
您需要登录后才可以回帖 登录 | 立即注册

QQ咨询

QQ|Archiver|手机版|小黑屋|郁金香游戏技术

GMT+8, 2024-11-23 10:44 , Processed in 0.088324 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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