从周围玩家的HPmin开始
开2个游戏账号,游戏用CE挂对进程,选中这个玩家,因为是自己双开,所以HPMIN数值非常清楚
用CE
ESI=155FE830
EDX=
18E5D898
EAX=12B162F8,EDX=
18E5D898
ECX=044B3238
EAX=00F06F38
EDI=04533768
ESI=00925468
EAX=00924E0C
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
//
{此段代码需要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 ;
附件列表