mm0000 发表于 2011-8-7 13:21:59

情人节大奉献_名将三国驱动保护的分析

【详细过程】
传闻写智辅很赚钱.于是我搞了搞.之前没有灰色产业链的商业积累.身边的朋友也越来越少.基本上智辅这块由于牵扯到钞票
的关系,所以很少有人讨论.
其实我一开始的主要目的是像赚钱.也没打算发出来.但是觉得自己现在的编程技术和水平想吃这个票子确实来的有点太累了
所以痛下决心,再花半年打基础.至少怎完vmp.然后把写脚本,写插件那些能力再提高一翻翻.再来吃这个票子.
首先向在背后默默鼓励我的商务朋友表示歉意.东西我还是会慢慢完成.就当作练习.只是觉得,忙活了半天没让你们赚到钱实
在有点不好意思.
谈技术了:
1.hs保护:
我打log分析出了第九城wof的hs只需要调其hs的7号函数
    HMODULE hEhsvc = NULL;
    hEhsvc = (HMODULE)GetModuleHandleA("EHSvc.dll");
    if (hEhsvc == INVALID_HANDLE_VALUE)
    {
      printf("<<<<<<<<<<<<<<<get EHSvc.dll handle error<<<<<<<<<<<\r\n");
    }
    else
    {
      UnStallAntiDebugUnStall = NULL;
      UnStall = (UnStallAntiDebug)GetProcAddress( hEhsvc,"7");
      if (UnStall == NULL)
      {
      printf("<<<<<<<<<<<<<<<get EHSvc.dll get fun 7 Error<<<<<<<<<<<\r\n");
      MessageBoxA(NULL,"abc","abc",MB_OK);
      }
      else
      {
      UnStall();
      }
      
    }
流程如上代码.

执行后就卸载掉保护了.
2.还原封包
2.1
   非动作封包还原.
   因为动作封包在包上有个index所以我把这个游戏的封包分成非动作封包和动作封包.具体哪个index的意义,我还没有
分析.
   打开商店的封包明文
   BYTE   OpenShop[] = {0x1b,0x00,0x00,0x00,0x08,0x00,0x01,0x12,0x00,0x00,0x00,0x00};--这个包完整的说,不因
该算打开的全明文.世纪其头部有个经过另外一个函数算出来的效验值.
   打开商店的全代码:
       RtlZeroMemory(&g_packCmd,sizeof(PACK_CMD));
    BYTE   OpenShop[] = {0x1b,0x00,0x00,0x00,0x08,0x00,0x01,0x12,0x00,0x00,0x00,0x00};
    g_packCmd.dwCmdAddr = (DWORD)OpenShop;
    g_packCmd.dwCmdLen = 0x0c;
    g_packCmd.dwEncodeTableLen = 0x10;
    if (dwEncodeTable!=0)
    {
      g_packCmd.dwEncodeTable = dwEncodeTable;
    }
    else
    {
      MessageBoxA(NULL,"Dot get table","Dot get table",MB_OK);
      return;
    }
    __asm
    {
         
      mov    eax,g_packCmd.dwEncodeTableLen
      pusheax
      mov    eax,g_packCmd.dwEncodeTable
      sub   eax,0x10
      push    eax
      mov   esi,eax
      mov   eax,edi
      mov   eax,g_packCmd.dwCmdLen
      push    eax
      mov    eax,g_packCmd.dwCmdAddr
      push    eax
      mov   eax,Package_Data
      calleax
      add    esp,0x10
      xor    eax,eax
      mov   edi,esi
table_change:
      add byte ptr ,al
      add eax,1
      cmp eax,0x10
      jltable_change
    }
    BYTESendEncodeTable = {0};
    DWORD *pdwpointer = (DWORD*)SendEncodeTable;
    *pdwpointer = (DWORD)dwHead+0x10;
    memcpy((SendEncodeTable+4),(void*)g_packCmd.dwCmdAddr,0x0c);
    send(g_send,(char*)SendEncodeTable,0x10,0);

这个代码中起重函数Package_Data是风暴的加密函数.加密方式我就不多说了.是垃圾.
给出封包加密函数的汇编代码
          _Package_Data   proc    near
          mov    eax,dword ptr
          xor   ecx, ecx
          xor   edx, edx
          test    eax, eax
          jbe   short FLA_1
          push    ebx
          push    ebp
          mov   ebp, dword ptr
          push    esi
          mov   esi, dword ptr
          push    edi
          mov   edi, dword ptr
          lea   esp, dword ptr
FLA_3:      
          mov   bl, byte ptr
          xor   byte ptr , bl
          add   ecx, 1
          cmp   ecx, edi
          jb      short FLA_2
          xor   ecx, ecx
FLA_2:
          add   edx, 1
          cmp   edx, eax
          jb      short FLA_3
          pop   edi
          pop   esi
          pop   ebp
          pop   ebx
FLA_1:
          retn   
_Package_Dataendp
   具体数据结构,请自己分析分析.

算封包效验的函数代码
_Package_Headproc    near
         movzx   edx,word ptr
         xor   eax,eax
         test    dx,dx
         jbe   short FLA_1
         movzx   edx, dx
         push    esi
         mov   edi, edi
FLA_2:         
         movzx   esi, byte ptr
         add   eax, esi
         add   ecx, 1
         sub   edx, 1
         jnz   short FLA_2
         pop   esi
FLA_1:         
         retn
_Package_Head endp
具体我也不说了.这个在有index的风暴就要自己去算下效验.比如说攻击.
下边我贴出一个攻击的发包代码

    BYTE   AttackPack[] = {0xaf,0x05,0x00,0x00,0x10,0x00,0x17,0x08,0x0a,0xa1,0x34,0x00,0x00,0x21,0x24,0x60,0xff,0xff,0xff,0xff};
    g_packCmd.dwCmdAddr = (DWORD)AttackPack;
    g_packCmd.dwCmdLen = 0x14;
    g_packCmd.dwEncodeTableLen = 0x10;
   
   
    if (g_packIndex == 0)
    {
      MessageBoxA(NULL,"packIndex error","packIndex error",MB_OK);
      return;
    }
    if (dwEncodeTable!=0)
    {
      g_packCmd.dwEncodeTable = dwEncodeTable;
    }
    else
    {
      MessageBoxA(NULL,"Dot get table","Dot get table",MB_OK);
      return;
    }
    __asm
    {
      leaecx,AttackPack
      moveax,g_packIndex
      moveax,dword ptr
      movdword ptr ,eax
      addecx,4
      moveax,Package_Head
      call eax
      leaecx,AttackPack
      movdword ptr ,eax
    }
    __asm
    {
      mov    eax,g_packCmd.dwEncodeTableLen
      pusheax
      mov    eax,g_packCmd.dwEncodeTable
      push    eax
      mov   esi,eax
      mov   edi,eax
      mov   eax,0x14
      push    eax
      mov   eax,g_packCmd.dwCmdAddr
      push    eax
      mov    eax,Package_Data
      calleax
      add    esp,0x10
      xor   eax,eax
      mov   edi,esi
      change_table:
      add byte ptr ,al
      add eax,1
      cmp eax,0x10
      jlchange_table
    }

    BYTE attackPakc = {0};
    DWORD* dwordPointer = (DWORD*)attackPakc;
    *dwordPointer = (DWORD)dwHead+0x18;
    memcpy((attackPakc+0x04),(void*)g_packCmd.dwCmdAddr,0x14);
    send(g_send,(char*)attackPakc,0x18,0);


    //index+14
    __asm
    {
      mov eax,g_packIndex
      mov ebx,dword ptr
      add ebx,0x14
      mov dword ptr ,ebx
    }
    return;
   
具体过程就是.
1.取index
2.算效验
3.加密.
4.加个包长度头
5.发包.

到这里,有心的人可以作脱机挂了.只是还由很多的过程要分析.只能说还原了封包.重要的还是分析后边的协议.不过分析
协议不复杂.



下边谈内挂.

我一开是想做变态的全屏秒杀挂.难免要找一些数据结构.
具体我分析到如下结果了.

其主程序很多时候使用一片内存作为参数传递,那我们就适时的在一些特定的点动态的修改其内存.实现修改攻击等数据.
我找到了攻击坐标.
实现了全屏打.但是一旦攻击一下.其就会切换验证模式.然后就失效了.总的来说,就是可以在单人模式下.攻击一次.

我的修改和我的修改的地方的特征地址大概如下代码.具体游戏版本可能有更新.不过按照我的思路,修改那片内存,一样可
以实现很多功能.不过一定要在适当的时候修改.
代码如下.特征码在注释片断.**** Hidden Message *****

zhdmzjy 发表于 2011-11-20 17:44:56

很赚钱吗?我不觉得

cbh352933721 发表于 2011-11-22 20:50:43

顶楼主。。。。。。。

超人rocky 发表于 2011-11-29 19:19:24

体我分析到如下结果了

cooby 发表于 2013-9-28 09:18:48

羡慕楼主的确是很羡慕,顶一下。

swyx 发表于 2013-11-1 14:42:03

真的可以么,我记得这破游戏麻烦。。。

seny11 发表于 2014-1-10 13:09:25

1111111111111

qq412158094 发表于 2019-3-28 16:13:10

支持楼主,支持看流星社区,以后我会经常来!

q350684803 发表于 2020-9-15 16:39:16

过名将三国驱动保护(XP sp2系统下通过)
页: [1]
查看完整版本: 情人节大奉献_名将三国驱动保护的分析