看流星社区

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

分享下C++ 特征码扫描

[复制链接]

该用户从未签到

发表于 2013-8-9 20:42:50 | 显示全部楼层 |阅读模式
int main(int argc, char* argv[])

{

    //查找游戏窗口

    HWND hGame = ::FindWindow("DxFirst", NULL);

    if(hGame == NULL) return FALSE;

     

    DWORD processId;

    HANDLE process;

    ::GetWindowThreadProcessId(hGame, &processId);

    process = ::OpenProcess(PROCESS_ALL_ACCESS, false, processId);

    //83C404C3CCCCA1              1           人物基址往下搜索

    //C3CCCCCCCCCCCCCCCCCCCC8B442404A3ECA72001      0       人物基址往上搜索

    //5557535152C6400801E8            1        打怪call

      

     //基址在特征码下面

     DWORD addr = ScanAddress(process, "83C404C3CCCCA1");

     printf("人物基址:%X\n",addr);

      

     //基址在特征码上面

     DWORD addr = ScanAddress(process, "C3CCCCCCCCCCCCCCCCCCCC8B442404A3ECA72001", 3, 0);

     printf("人物基址:%X\n",addr);


    DWORD call = ScanCall(process, "5557535152C6400801E8");

    printf("call基址:%X\n",call);

    ::CloseHandle(process);

    return 0;

}

//下面是ScanAddress的实现
  1. //需要引入的头文件:

  2. #include <stdio.h>

  3. #include <stdlib.h>

  4. #include <windows.h>

  5. union Base   

  6. {

  7.     DWORD   address;

  8.     BYTE    data[4];

  9. };

  10. /************************************************************************/

  11. /* 函数说明:根据特征码扫描基址

  12. /* 参数一:process 要查找的进程

  13. /* 参数二:markCode 特征码字符串,不能有空格

  14. /* 参数三:特征码离基址的距离,默认距离:1

  15. /* 参数四:findMode 扫描方式,找到特征码后,默认为:1

  16. /*                  0:往上找基址(特征码在基址下面)

  17. /*                  1:往下找基址(特征码在基址上面)

  18. /* 参数五:offset 保存基址距离进程的偏移,默认为:不保存

  19. /************************************************************************/

  20. DWORD ScanAddress(HANDLE process, char *markCode,  

  21.                   DWORD distinct = 1, DWORD findMode = 1,  

  22.                   LPDWORD offset = NULL)

  23. {

  24.     //起始地址

  25.     const DWORD beginAddr = 0x00400000;

  26.     //结束地址

  27.     const DWORD endAddr = 0x7FFFFFFF;

  28.     //每次读取游戏内存数目的大小

  29.     const DWORD pageSize = 4096;


  30.     ////////////////////////处理特征码/////////////////////

  31.     //特征码长度不能为单数

  32.     if (strlen(markCode) % 2 != 0) return 0;

  33.     //特征码长度

  34.     int len = strlen(markCode) / 2;

  35.     //将特征码转换成byte型

  36.     BYTE *m_code = new BYTE[len];

  37.     for (int i = 0; i < len; i++){

  38.         char c[] = {markCode[i*2], markCode[i*2+1], '\0'};

  39.         m_code<i> = (BYTE)::strtol(c, NULL, 16);

  40. </i>    }


  41.     /////////////////////////查找特征码/////////////////////

  42.     BOOL _break = FALSE;

  43.     //用来保存在第几页中的第几个找到的特征码

  44.     int curPage = 0;

  45.     int curIndex = 0;

  46.     Base base;

  47.     //每页读取4096个字节

  48.     BYTE page[pageSize];

  49.     DWORD tmpAddr = beginAddr;

  50.     while (tmpAddr <= endAddr - len){

  51.         ::ReadProcessMemory(process, (LPCVOID)tmpAddr, &page, pageSize, 0);

  52.         //在该页中查找特征码

  53.         for (int i = 0; i < pageSize; i++){

  54.             for (int j = 0; j < len; j++){

  55.                 //只要有一个与特征码对应不上则退出循环

  56.                 if (m_code[j] != page[i + j])break;

  57.                 //找到退出所有循环

  58.                 if (j == len - 1){

  59.                     _break = TRUE;

  60.                     if (!findMode){

  61.                         curIndex = i;

  62.                         base.data[0] = page[curIndex-distinct-4];

  63.                         base.data[1] = page[curIndex-distinct-3];

  64.                         base.data[2] = page[curIndex-distinct-2];

  65.                         base.data[3] = page[curIndex-distinct-1];

  66.                     }else{

  67.                         curIndex = i + j;

  68.                         base.data[0] = page[curIndex+distinct+1];

  69.                         base.data[1] = page[curIndex+distinct+2];

  70.                         base.data[2] = page[curIndex+distinct+3];

  71.                         base.data[3] = page[curIndex+distinct+4];

  72.                     }

  73.                     break;

  74.                 }

  75.             }

  76.             if (_break) break;

  77.         }

  78.         if (_break) break;

  79.         curPage++;

  80.         tmpAddr += pageSize;

  81.     }

  82.     if(offset != NULL){

  83.         *offset = curPage * pageSize + curIndex + beginAddr;

  84.     }

  85.     return base.address;

  86. }


  87. /************************************************************************/

  88. /* 函数说明:根据特征码扫描call地址

  89. /* 参数一:process 要查找的进程

  90. /* 参数二:markCode 特征码字符串,不能有空格

  91. /* 参数三:特征码离基址的距离,默认距离:1

  92. /* 参数四:findMode 扫描方式,找到特征码后,默认为:1

  93. /*                  0:往上找基址

  94. /*                  1:往下找基址

  95. /************************************************************************/

  96. DWORD ScanCall(HANDLE process, char *markCode,  

  97.                DWORD distinct = 1, DWORD findMode = 1)

  98. {

  99.     DWORD offset;

  100.     DWORD call = ScanAddress(process, markCode, distinct, findMode, &offset);

  101.     call += offset;

  102.     if(findMode) call = call + 5 + distinct;

  103.     else call = call - distinct;

  104.     return call;

  105. }
复制代码
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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

GMT+8, 2024-5-16 00:48

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

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