war3 Game
阅读原文时间:2023年07月08日阅读:2

转载请注明来源:https://www.cnblogs.com/hookjc/

//位置结构。x,y不多说,unknown是3F800000。浮点数1.0??
struct Pos
{
  DWORD x,y,unknow;
};

//由于但是是写成shellcode的,所以封装了函数

//storm.dll的地址
DWORD _declspec(noinline) GetStromAddr()
{
  return 0x15000000;
}
//game.dll的地址
DWORD _declspec(noinline)GetGameAddr()
{
  return 0x6f000000;
}

//只要在某些地方HOOK,调用这个函数就可以小地图上画出英雄单位
void AllDraw()
{
  DWORD HeroPoint,HeroNext;
  HeroPoint=GetHeroAddrPFunc();//获取英雄单位链表。(我称他为链表~~:p:)
  if (HeroPoint==0)
  {
    return ;
  }
  HeroNext=*(DWORD*)HeroPoint;//取出第一个单位的地址
  while (HeroNext!=0)
  {

    BYTE Dead=0;
    Dead=*(BYTE*)(HeroNext+0x20);//死了自然不用画
    if(Dead==0x46)
    {
                        //没死就画
      MainDraw(HeroNext);
    }

    HeroPoint+=0x18;//链表自增
    HeroNext=*(DWORD*)HeroPoint;//取出下一个单位地址。直到为0表示没有了
  }
}

//大地图坐标转小地图坐标的call 本来是有参数的。这里naked就不写了
void  _declspec(naked) FloatCall()
{
  _asm
  {
    push ebp
    mov ebp,esp
    pushad
      pushfd
      mov edx,[ebp+0xc]
    mov ecx,[ebp+0x10]
    push DWORD PTR SS:[ebp+8]
    push eax
    PUSH ESI
    MOV ESI,DWORD PTR SS:[ESP+0x8]
    FLD DWORD PTR DS:[ESI+0xC]
    MOV EAX,ECX
    FMUL DWORD PTR DS:[EDX+4]
    FLD DWORD PTR DS:[EDX]
    FMUL DWORD PTR DS:[ESI]
    FADDP ST(1),ST
    FLD DWORD PTR DS:[ESI+0x18]
    FMUL DWORD PTR DS:[EDX+0x8]
    FADDP ST(1),ST
    FSTP DWORD PTR DS:[EAX]
    FLD DWORD PTR DS:[ESI+0x4]
    FMUL DWORD PTR DS:[EDX]
    FLD DWORD PTR DS:[ESI+0x10]
    FMUL DWORD PTR DS:[EDX+4]
    FADDP ST(1),ST
    FLD DWORD PTR DS:[ESI+0x1C]
    FMUL DWORD PTR DS:[EDX+8]
    FADDP ST(1),ST
    FSTP DWORD PTR DS:[EAX+4]
    FLD DWORD PTR DS:[ESI+8]
    FMUL DWORD PTR DS:[EDX]
    FLD DWORD PTR DS:[ESI+0x14]
    FMUL DWORD PTR DS:[EDX+4]
    FADDP ST(1),ST
    FLD DWORD PTR DS:[ESI+0x20]
    POP ESI
    FMUL DWORD PTR DS:[EDX+8]
    FADDP ST(1),ST
    FSTP DWORD PTR DS:[EAX+8]
    pop eax
    add esp,4
    popfd
    popad
    mov esp,ebp
    pop ebp
    retn
  }
};

//这个确实不记得了
DWORD  GetHeroLC(DWORD HeroAddr)
{
  return *(DWORD*)(HeroAddr+0x58);
}

//获取坐标地址。填充需要的结构
void  GetHeroLocData(DWORD HeroAddr,Pos * p)
{

  p->x=*(DWORD*)(HeroAddr+0x284);
  p->y=*(DWORD*)(HeroAddr+0x288);
  p->unknow=0x3f800000;//浮点1.0
}

void  MainDraw(DWORD HeroAddr)
{
  Pos pReal;
  Pos pChange;
  DWORD lc=GetHeroLC(HeroAddr);

      //获取大地图坐标
  GetHeroLocData(HeroAddr,&pReal);

    DWORD Gaddr=GetGameAddr();

//把大地图 转到 小地图结构
  DWORD MiniVal=*(DWORD*)(Gaddr+0xACD06C);
  LPVOID p1=&pChange;
  LPVOID p2=&pReal;
  DWORD p3=MiniVal+0x750;
  _asm mov esp,esp
  _asm
  {
    pushad
    push p1
    push p2
    push p3
    call FloatCall
    add esp,0xc
    popad
  }

/*这里记得了,上面的GetHeroLC是用于计算玩家楼层。有一个标记。
所有的英雄单位还有一个数组,1表示要画图,0表示不要画图。*/

//想起来了,LC=楼层。

  //FloatCall(MiniVal+0x750,&pReal,&pChange);
  DWORD StartAddr=*(DWORD*)(MiniVal+0x2e4);

//StartAddr就是这个数组的地址

  DWORD TempCount=*(DWORD*)(StartAddr+lc*4);
  if (TempCount!=0)//如果数组里面显示要画了,那我们没必要多此一举
  {
    return ;
  }

  DWORD Judge=*(DWORD*)(MiniVal+0x2f0);
  Judge=*(DWORD*)(lc*4+Judge);
  if (Judge==0)//这里还有个判断,不记得是干嘛的了。
  {
    return ;
  }

//把数组里面的值标记为1,表示要画出来
  *(DWORD*)(StartAddr+lc*4)=TempCount+1;

//把这个结构放到一个位置,让魔兽画出来。
  lc=lc<<4;   DWORD CopyAddr=*(DWORD*)(lc+MiniVal+0x2fc);   DWORD Offset=TempCount*3;   CopyAddr+=Offset*4;   ((Pos*)CopyAddr)->x=pChange.x;
  ((Pos*)CopyAddr)->y=pChange.y;
  ((Pos*)CopyAddr)->unknow=pChange.unknow;
}

//获取英雄表头
DWORD  GetHeroAddrPFunc()
{
  DWORD HeroAddrPoint=0;
  DWORD Addr=0x55514+GetStromAddr();
  memcpy(&HeroAddrPoint,(LPCVOID)(Addr),4);

  if(*(DWORD*)(HeroAddrPoint+0x88)!=0x18)
    return 0;

  HeroAddrPoint=HeroAddrPoint+0x98;
  //特别注意,这里返回值可能为0;
  return HeroAddrPoint;
}

暂存:

原地址:http://www.ipahoo.com/2014/software_0807/1487.html

来源:python脚本自动迁移