//位置结构。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