4,7周围玩家
![](https://images.cnblogs.com/cnblogs_com/xe2011/201205/201205260838351251.jpg)
开2个游戏账号,游戏用CE挂对进程,选中这个玩家,因为是自己双开,所以HPMIN数值非常清楚
用CE
![](https://images.cnblogs.com/cnblogs_com/xe2011/201205/201205260838354283.png)
![](https://images.cnblogs.com/cnblogs_com/xe2011/201205/201205260838353726.png)
![](https://images.cnblogs.com/cnblogs_com/xe2011/201205/201205260838358710.png)
![](https://images.cnblogs.com/cnblogs_com/xe2011/201205/201205260838351742.png)
![](https://images.cnblogs.com/cnblogs_com/xe2011/201205/201205260838364773.png)
![](https://images.cnblogs.com/cnblogs_com/xe2011/201205/201205260838367805.png)
![](https://images.cnblogs.com/cnblogs_com/xe2011/201205/201205260838367248.png)
![](https://images.cnblogs.com/cnblogs_com/xe2011/201205/20120526083836280.png)
ROMAN HPmin= [[[[[[[00924E0C]+1c]+08]+20]+18]+EDX*4]+04]+450
edx=12B1653C-12B162F8=244
名称
名称
遍历的时候要挂对进程
roman=[[[[[[[[924e0c]+8]+20]+18]+244]+4]+5CC]+0]
其他偏移MemView(结构化内存监视器)查找
//中的玩家的属性值 = [[[[[[[00924E0C]+1c]+08]+20]+18]+EDX*4]+04]+偏移值
玩家数组=[[[00924E0C]+1c]+08]+20
+14 周围玩家数量
+20 周围玩家最大数组
+18 ???
玩家数组列表=[[[[[00924E0C]+1c]+08]+20]+18]+EDX*4
玩家对象=[[[[[[00924E0C]+1c]+08]+20]+18]+EDX*4]+04
玩家属性=[玩家对象]+偏移
[+5cc]+0 名称
+448 等级
+43C ID号
+450 红最小值
+478 红最大值
+700 距离
+3C 坐标X
+44 坐标Y
+40 坐标Z
//
![](https://images.cnblogs.com/cnblogs_com/xe2011/201205/201205260838383986.png)
{此段代码需要hook的支持}
/// <summary>
/// {人物是在游戏当中还是小退}
/// </summary>
function InGame():Boolean;
var gameretn:DWORD;
begin
asm
mov eax,[$00924D48]
mov gameretn,eax
end;
if gameretn=0 then Result:=true{在游戏当中}
else if gameretn>=1 then Result:=False; {人物在角色选择界面}
end;
procedure TForm1.Button1Click(Sender: TObject);
/// <summary>
/// 周围玩家
/// </summary>
var
I :Integer;
pPlayer :PDWORD;
playerBase :DWORD;
player_name :PDWORD;
player_id :PDWORD;
player_amount :PDWORD;
player_hpMin :PDWORD;
player_hpMax :PDWORD;
player_level :PDWORD;
player_posx :pSingle;
player_posy :pSingle;
player_posz :pSingle;
player_distance :PSingle;
player_px :single;
player_py :single;
player_pz :single;
player_name1 :PWideChar;
player_name2 :string;
begin
{
//中的玩家的属性值 = [[[[[[[00924E0C]+1c]+08]+20]+18]+EDX*4]+04]+偏移值
玩家数组=[[[00924E0C]+1c]+08]+20
+14 周围玩家数量
+20 周围玩家最大数组
+18 ???
玩家数组列表=[[[[[00924E0C]+1c]+08]+20]+18]+EDX*4
玩家对象=[[[[[[00924E0C]+1c]+08]+20]+18]+EDX*4]+04
玩家属性=[玩家对象]+偏移
[+5cc]+0 名称
+448 等级
+43C ID号
+450 红最小值
+478 红最大值
+700 距离
+3C 坐标X
+44 坐标Y
+40 坐标Z
}
if InGame=False then Exit;
asm
mov eax,[$924E0C]
mov eax,[eax+$1c]
mov eax,[eax+$8]
mov eax,[eax+$20]
mov ecx,[eax+$14]
mov Player_amount,ecx
mov ecx,[eax+$18]
mov playerBase,ecx
end;
Memo1.Clear;
for I:=0 to 768 do
begin
pPlayer:=pointer(playerBase+I*4);
if pPlayer^>0 then //当对象数组列表不为0的时候才添加
begin
pPlayer :=Pointer(pPlayer^+$4); // 玩家对象指针=[玩家列表基址]+04
player_hpMin :=Pointer(pPlayer^+$450);
player_hpMax :=Pointer(pPlayer^+$478);
player_level :=Pointer(pPlayer^+$448);
player_id :=Pointer(pPlayer^+$43C);
player_name :=Pointer(pPlayer^+$5CC);//名称
player_name1 :=Pointer(player_name^+$0);
player_name2 :=WideCharTostring(player_name1);
player_distance:=Pointer(pPlayer^+$700); //距离
player_posx :=Pointer(pPlayer^+$3C);
player_posy :=Pointer(pPlayer^+$44);
player_posz :=Pointer(pPlayer^+$40);
player_px :=Trunc(player_posx^/10+400); //x坐=取整数部分(坐标/10)+400
player_py :=Trunc(player_posy^/10+550); //Y坐标=取整数部分(坐标/10)+550
player_pz :=Trunc(player_posz^/10); //z坐标=取整数部分(坐标/10)
memo1.lines.add(Format('ID %x hp %d/%d LV%d 坐标%.f,%.f,%.f ↑ 距离 %f %s',[player_id^,player_hpMin^,player_hpMax^,player_level^,player_px,player_py,player_pz,player_distance^,player_name2]));
end;
end;
Memo1.Hint:=Memo1.Text;
end;
/// <summary>
/// {人物是在游戏当中还是小退}
/// </summary>
function InGame():Boolean;
var gameretn:DWORD;
begin
asm
mov eax,[$00924D48]
mov gameretn,eax
end;
if gameretn=0 then Result:=true{在游戏当中}
else if gameretn>=1 then Result:=False; {人物在角色选择界面}
end;
procedure TForm1.Button1Click(Sender: TObject);
/// <summary>
/// 周围玩家
/// </summary>
var
I :Integer;
pPlayer :PDWORD;
playerBase :DWORD;
player_name :PDWORD;
player_id :PDWORD;
player_amount :PDWORD;
player_hpMin :PDWORD;
player_hpMax :PDWORD;
player_level :PDWORD;
player_posx :pSingle;
player_posy :pSingle;
player_posz :pSingle;
player_distance :PSingle;
player_px :single;
player_py :single;
player_pz :single;
player_name1 :PWideChar;
player_name2 :string;
begin
{
//中的玩家的属性值 = [[[[[[[00924E0C]+1c]+08]+20]+18]+EDX*4]+04]+偏移值
玩家数组=[[[00924E0C]+1c]+08]+20
+14 周围玩家数量
+20 周围玩家最大数组
+18 ???
玩家数组列表=[[[[[00924E0C]+1c]+08]+20]+18]+EDX*4
玩家对象=[[[[[[00924E0C]+1c]+08]+20]+18]+EDX*4]+04
玩家属性=[玩家对象]+偏移
[+5cc]+0 名称
+448 等级
+43C ID号
+450 红最小值
+478 红最大值
+700 距离
+3C 坐标X
+44 坐标Y
+40 坐标Z
}
if InGame=False then Exit;
asm
mov eax,[$924E0C]
mov eax,[eax+$1c]
mov eax,[eax+$8]
mov eax,[eax+$20]
mov ecx,[eax+$14]
mov Player_amount,ecx
mov ecx,[eax+$18]
mov playerBase,ecx
end;
Memo1.Clear;
for I:=0 to 768 do
begin
pPlayer:=pointer(playerBase+I*4);
if pPlayer^>0 then //当对象数组列表不为0的时候才添加
begin
pPlayer :=Pointer(pPlayer^+$4); // 玩家对象指针=[玩家列表基址]+04
player_hpMin :=Pointer(pPlayer^+$450);
player_hpMax :=Pointer(pPlayer^+$478);
player_level :=Pointer(pPlayer^+$448);
player_id :=Pointer(pPlayer^+$43C);
player_name :=Pointer(pPlayer^+$5CC);//名称
player_name1 :=Pointer(player_name^+$0);
player_name2 :=WideCharTostring(player_name1);
player_distance:=Pointer(pPlayer^+$700); //距离
player_posx :=Pointer(pPlayer^+$3C);
player_posy :=Pointer(pPlayer^+$44);
player_posz :=Pointer(pPlayer^+$40);
player_px :=Trunc(player_posx^/10+400); //x坐=取整数部分(坐标/10)+400
player_py :=Trunc(player_posy^/10+550); //Y坐标=取整数部分(坐标/10)+550
player_pz :=Trunc(player_posz^/10); //z坐标=取整数部分(坐标/10)
memo1.lines.add(Format('ID %x hp %d/%d LV%d 坐标%.f,%.f,%.f ↑ 距离 %f %s',[player_id^,player_hpMin^,player_hpMax^,player_level^,player_px,player_py,player_pz,player_distance^,player_name2]));
end;
end;
Memo1.Hint:=Memo1.Text;
end;
附件列表