天龙八部的几个CALL写法【Delphi版】
//===============================CALL部份START=======================================
{自动走路}
procedure CallWalk(xy: PCoordinate); stdcall;
var
x,y: Single;
begin
x := xy^.x;
y := xy^.y;
asm
pushad
mov edx, x
mov eax, y
mov ecx, eax
push ecx
push edx
mov ecx, [BaseAddr]
mov ecx, [ecx + $64]
mov ecx, [ecx + $160]
mov eax, CallWalkAddr
call eax
popad
end;
end;
procedure Walk(x, y: Single);
var MyZuoBiao:TCoordinate;
begin
MyZuoBiao.x:=x;
MyZuoBiao.y:=y;
InjectFunc(hWulin,@CallWalk,@MyZuoBiao,SizeOf(TCoordinate));
end;
//使用技能
function UseSkill(p: PSkillParam):DWORD; Stdcall;
var
c1,c2,c3,c4,c5,c6 :DWORD;
begin
c1 :=p^.c1;
c2 :=p^.c2;
c3 :=p^.c3;
c4 :=p^.c4;
c5 :=p^.c5;
c6 :=p^.c6;
asm
pushad
push c6
push c5
push c4
push c3
push c2
push c1
mov ecx,DWORD PTR DS:[BaseAddr]
mov edx,DWORD PTR DS:[ecx+$64]
mov ecx,DWORD PTR DS:[edx+$160]
mov eax, CallUseSkillAddr
call eax
popad
end;
result:=0;
end;
//打坐 :c1=23 c2=FFFFFFFF c3=FFFFFFFF c4=BF800000 c5=BF800000 c6=BF800000
procedure DaZuo;
var
UsesJiNeng :TSkillParam;
begin
UsesJiNeng.c1 := $23;
UsesJiNeng.c2 := $FFFFFFFF;
UsesJiNeng.c3 := $FFFFFFFF;
UsesJiNeng.c4 := $BF800000;
UsesJiNeng.c5 := $BF800000;
UsesJiNeng.c6 := $BF800000;
InjectFunc(hWulin,@UseSkill,@UsesJiNeng,SizeOf(UsesJiNeng));
end;
//返回大理城:c1=16 c2=FFFFFFFF c3=FFFFFFFF c4=BF800000 c5=BF800000 c6=BF800000
procedure GoToDaLi;
var
UsesJiNeng :TSkillParam;
begin
UsesJiNeng.c1 := $16;
UsesJiNeng.c2 := $FFFFFFFF;
UsesJiNeng.c3 := $FFFFFFFF;
UsesJiNeng.c4 := $BF800000;
UsesJiNeng.c5 := $BF800000;
UsesJiNeng.c6 := $BF800000;
InjectFunc(hWulin,@UseSkill,@UsesJiNeng,SizeOf(UsesJiNeng));
end;
//打怪:c1=技能编号 c2=FFFFFFFF c3=怪ID c4=BF800000 c5=BF800000 c6=BF800000
procedure Attack(jiNengID,GuaiID: DWORD);
var
UsesJiNeng :TSkillParam;
begin
UsesJiNeng.c1 := jiNengID;
UsesJiNeng.c2 := $FFFFFFFF;
UsesJiNeng.c3 := GuaiID;
UsesJiNeng.c4 := $BF800000;
UsesJiNeng.c5 := $BF800000;
UsesJiNeng.c6 := $BF800000;
InjectFunc(hWulin,@UseSkill,@UsesJiNeng,SizeOf(UsesJiNeng));
end;
//捡物品_全捡 用包裹基址
procedure Select;Stdcall;
begin
asm
pushad
mov ecx,wpBaseAdr
mov ecx,[ecx]
mov eax,[ecx]
call dword ptr [eax+$d8]
popad
end;
end;
//打开捡物窗口 可走近捡物
procedure OpenSelect1(bagid:pparam);Stdcall;
var
eax1:Cardinal;
begin
eax1:=bagid^.id;
asm
pushad
push eax1
mov eax,dword ptr [OpenCall_ECX]
mov eax,[eax]
call dword ptr [eax+$7c]
popad
end;
end;
//捡物品窗口是否打开
function Openselecttrue:BOOL;stdcall;
var
base:Cardinal;
begin
base:= mem.ReadInt(OPenSelectBaseAdr+$10);
base:= mem.ReadInt(base);
base:= mem.ReadInt(base+$c);
base:= mem.ReadInt(base+$64);
if base=1 then Result:=True else Result:=False;
end;
//===============================CALL部份END=======================================
走路CALL调用方式是这样的。(0520版)
先 Push y
再 Push x
传递寄存器 ECX=[[[CharBaseAddr]+64]+160]
传递寄存器 EDX=[[[[CharBaseAddr]+64]+160]]
调用 CALL 004506F0
使用DELPHI的在传递参数时可能没什么问题。
使用VB的就有问题了。因为坐标参数是Single类型,而clsASM.Push参数是Long类型。两者在内存中存储的方式不一样。所以要使用一个API。
Call CopyMemory(Long类型的x,Single类型的x,4)
Call CopyMemory(Long类型的y,Single类型的y,4)
然后把Long类型的坐标传递给Push就可以了。
{自动走路}
procedure CallWalk(xy: PCoordinate); stdcall;
var
x,y: Single;
begin
x := xy^.x;
y := xy^.y;
asm
pushad
mov edx, x
mov eax, y
mov ecx, eax
push ecx
push edx
mov ecx, [BaseAddr]
mov ecx, [ecx + $64]
mov ecx, [ecx + $160]
mov eax, CallWalkAddr
call eax
popad
end;
end;
procedure Walk(x, y: Single);
var MyZuoBiao:TCoordinate;
begin
MyZuoBiao.x:=x;
MyZuoBiao.y:=y;
InjectFunc(hWulin,@CallWalk,@MyZuoBiao,SizeOf(TCoordinate));
end;
//使用技能
function UseSkill(p: PSkillParam):DWORD; Stdcall;
var
c1,c2,c3,c4,c5,c6 :DWORD;
begin
c1 :=p^.c1;
c2 :=p^.c2;
c3 :=p^.c3;
c4 :=p^.c4;
c5 :=p^.c5;
c6 :=p^.c6;
asm
pushad
push c6
push c5
push c4
push c3
push c2
push c1
mov ecx,DWORD PTR DS:[BaseAddr]
mov edx,DWORD PTR DS:[ecx+$64]
mov ecx,DWORD PTR DS:[edx+$160]
mov eax, CallUseSkillAddr
call eax
popad
end;
result:=0;
end;
//打坐 :c1=23 c2=FFFFFFFF c3=FFFFFFFF c4=BF800000 c5=BF800000 c6=BF800000
procedure DaZuo;
var
UsesJiNeng :TSkillParam;
begin
UsesJiNeng.c1 := $23;
UsesJiNeng.c2 := $FFFFFFFF;
UsesJiNeng.c3 := $FFFFFFFF;
UsesJiNeng.c4 := $BF800000;
UsesJiNeng.c5 := $BF800000;
UsesJiNeng.c6 := $BF800000;
InjectFunc(hWulin,@UseSkill,@UsesJiNeng,SizeOf(UsesJiNeng));
end;
//返回大理城:c1=16 c2=FFFFFFFF c3=FFFFFFFF c4=BF800000 c5=BF800000 c6=BF800000
procedure GoToDaLi;
var
UsesJiNeng :TSkillParam;
begin
UsesJiNeng.c1 := $16;
UsesJiNeng.c2 := $FFFFFFFF;
UsesJiNeng.c3 := $FFFFFFFF;
UsesJiNeng.c4 := $BF800000;
UsesJiNeng.c5 := $BF800000;
UsesJiNeng.c6 := $BF800000;
InjectFunc(hWulin,@UseSkill,@UsesJiNeng,SizeOf(UsesJiNeng));
end;
//打怪:c1=技能编号 c2=FFFFFFFF c3=怪ID c4=BF800000 c5=BF800000 c6=BF800000
procedure Attack(jiNengID,GuaiID: DWORD);
var
UsesJiNeng :TSkillParam;
begin
UsesJiNeng.c1 := jiNengID;
UsesJiNeng.c2 := $FFFFFFFF;
UsesJiNeng.c3 := GuaiID;
UsesJiNeng.c4 := $BF800000;
UsesJiNeng.c5 := $BF800000;
UsesJiNeng.c6 := $BF800000;
InjectFunc(hWulin,@UseSkill,@UsesJiNeng,SizeOf(UsesJiNeng));
end;
//捡物品_全捡 用包裹基址
procedure Select;Stdcall;
begin
asm
pushad
mov ecx,wpBaseAdr
mov ecx,[ecx]
mov eax,[ecx]
call dword ptr [eax+$d8]
popad
end;
end;
//打开捡物窗口 可走近捡物
procedure OpenSelect1(bagid:pparam);Stdcall;
var
eax1:Cardinal;
begin
eax1:=bagid^.id;
asm
pushad
push eax1
mov eax,dword ptr [OpenCall_ECX]
mov eax,[eax]
call dword ptr [eax+$7c]
popad
end;
end;
//捡物品窗口是否打开
function Openselecttrue:BOOL;stdcall;
var
base:Cardinal;
begin
base:= mem.ReadInt(OPenSelectBaseAdr+$10);
base:= mem.ReadInt(base);
base:= mem.ReadInt(base+$c);
base:= mem.ReadInt(base+$64);
if base=1 then Result:=True else Result:=False;
end;
//===============================CALL部份END=======================================
走路CALL调用方式是这样的。(0520版)
先 Push y
再 Push x
传递寄存器 ECX=[[[CharBaseAddr]+64]+160]
传递寄存器 EDX=[[[[CharBaseAddr]+64]+160]]
调用 CALL 004506F0
使用DELPHI的在传递参数时可能没什么问题。
使用VB的就有问题了。因为坐标参数是Single类型,而clsASM.Push参数是Long类型。两者在内存中存储的方式不一样。所以要使用一个API。
Call CopyMemory(Long类型的x,Single类型的x,4)
Call CopyMemory(Long类型的y,Single类型的y,4)
然后把Long类型的坐标传递给Push就可以了。