关于delphi内嵌汇编的问题

时间:2022-02-17 04:06:51
我在function使用内嵌汇编(已经通过DLL,注入到某个游戏中去了)
function  UseItem(var  Bag_itemId;  Bmun:  DWORD):single;
    asm
    pushad
    push    1                                // Arg4 = 00000001
    push    Bag_itemId                             // Arg3 物品ID
    push    Bmun                             // Arg2 物品在包裹内的格子数
    push    0                                // Arg1 = 00000000
    mov esi,$008D6498
    mov esi,[esi+$20]
    mov eax,$0056A670
    call eax                         // \elementc.0056A670
    popad
    end;
end;

然后调用UseItem(1727,1);
但是却汇编出错??(可以编译过去)

但是直接在Button6Click中使用却不会出错,我觉得可能是传递参数出了错误,请问怎么解决

22 个解决方案

#1


最新研究又发现
asm
    pushad
    push    1                                // Arg4 = 00000001
    push    Bag_itemId                             // Arg3 物品ID
    push    Bmun                             // Arg2 物品在包裹内的格子数
    push    0                                // Arg1 = 00000000
    mov esi,$008D6498
    mov esi,[esi+$20]
    mov eax,$0056A670
    call eax                         // \elementc.0056A670
    popad
    end;
把里面的参数(Bag_itemId,Bmun)改成实际值还是通不过,这样可能不是参数传递的问题了,难道是???

#2


没有深入研究过delphi支持的asm,帮不上忙,顶一下

#3


偶原来也发现过,直接写在控件事件里没有问题,
自己搞个函数或过程就不行!等楼下高人解答……

#4


因为你用的变参,
所以
push Bag_itemId // Arg3 物品ID
push Bmun // Arg2 物品在包裹内的格子数
应该不行。
你是说改成
push 立即数
也不行吗?

#5


回楼上的,改成实际数值也不行,所以应该不是参数的问题(即使不调用参数,直接用实际数值带入也不行)

#6


顶,100分寻高手

#7


你把那个var去掉试试, 带var的话,实际传递的是地址值

#8


我说的不一定正确. 

再是, 你把贴子转移到技术区, 会有更多人愿意出手. 非技术分, 很少有人在意的.
况且本来就是技术问题,不应该放在非技术区.

#9


回楼上的,应该跟参数没关系,我把参数去掉也不行

#10


可以保证传递到变址寄存器ESI里的立即数$008D6498是正确有效的吗?

#11


是的,在Button6Click中使用不会出错

#12


Button6Click和function UseItem 这两个过程中的段地址应该是不同的吧.... 我没经验, 帮顶了.

#13


up

#14


有几点这里说一下:
1、不同版本的delphi编译器,对于函数汇编出来的代码是不一样的,我曾经就碰到
过在delphi7能正常运行的ASM代码在delphi6下出错。建议你,认真核对函数对于参数
的调用规则;
2、TObject及类的调用与一般函数参数的调用又是不一样,对于TObject的代码还有虚拟
及动态装载的问题。
3、建议先使用delphi写的代码,再反汇编成汇编进行优化。

由于代码不全,无法给出更多的建议

#15


你声明是这样
function  UseItem(var  Bag_itemId;  Bmun:  DWORD):single;
asm
  ...
end;
还是:
function  UseItem(var  Bag_itemId;  Bmun:  DWORD):single;
begin
asm
  ...
end;
end;

#16


回楼上的,我用D7和D2007都编译过了,不行的,至于你说的2,3点,由于我刚学D不久,还不能明白,下面是源代码


procedure  UseItem(var  Bag_itemId;  Bmun:  Integer);//Bag_itemId:物品ID;Bmun物品在包裹内的格子数(从0开始)
var
Bag_itemId_,Bmun_:Integer;
begin
Bag_itemId_:=Bag_itemId;
Bmun_:=Bmun;
    asm
    pushad
    push    1                                // Arg4 = 00000001
    push    Bag_itemId_                              // Arg3 物品ID
    push    Bmun_                              // Arg2 物品在包裹内的格子数(从0开始)
    push    0                                // Arg1 = 00000000
    mov esi,lpmain
    mov esi,[esi+$20]
    mov eax,Address_useitem
    call eax                         // \elementc.0056A670
    popad
    end;
end;
再用这个调用
procedure TFrm_Pop.ListBox1DblClick(Sender: TObject);
var
  ItemId,ItemMum,Bag_main,Bag_max:Integer;
begin
    Bag_main:=DuMem(base+$85c);
    Bag_max:=DuMem(Bag_main+$10);
    ItemMum:=ListBox1.ItemIndex;
    ItemId:=DuMem(DuMem(DuMem(Bag_main+$C)+4*ListBox1.ItemIndex)+$8);
    UseItem(ItemId,ItemMum);
end;
则出错

定义procedure  UseItem(var  Bag_itemId;  Bmun:  Integer);
  const lpmain=$008D6498 ;                  //基地址8D64B4-1C
  const Address_useitem=$0056A670;


而在这里则不会出错
procedure TFrm_Pop.ListBox1DblClick(Sender: TObject);
var
  Address:Pointer;
  ItemId,ItemMum,Bag_main:Integer;
begin
    Address:=Pointer($0056A670);
    Bag_main:=DuMem(base+$85c);
    ItemMum:=ListBox1.ItemIndex;
    ItemId:=DuMem(DuMem(DuMem(Bag_main+$C)+4*ListBox1.ItemIndex)+$8);
asm
pushad
push    1                                // Arg4 = 00000001
push    ItemId                              // Arg3 物品ID
push    ItemMum                              // Arg2 物品在包裹内的格子数(从0开始)
push    0                                // Arg1 = 00000000
mov esi,lpmain
mov esi,[esi+$20]
lea ecx,[esi+$D4]
call    Address                        // \elementc.0056A670
popad
end;
end;

#17


谢谢jiju(UNCC)的提示,去掉begin end就不会汇编出错了,但无法传递参数,只能用实际数值代替
Bag_itemId和Bmun才可以

function  UseItem(var  Bag_itemId;  Bmun:  Integer): Single;//Bag_itemId:物品ID;Bmun物品在包裹内的格子数(从0开始)
    asm
    pushad
    push    1                                // Arg4 = 00000001
    push    Bag_itemId                             // Arg3 物品ID
    push    Bmun                              // Arg2 物品在包裹内的格子数(从0开始)
    push    0                                // Arg1 = 00000000
    mov esi,lpmain
    mov esi,[esi+$20]
    lea ecx,[esi+$D4]
    mov eax,$0056A670
    call eax                         // \elementc.0056A670
    popad
    end;

#18


这就是那个var的问题了,var传递的是变量的地址

#19


你应该:
push [Bag_itemId] // Arg3 物品ID
push Bmun // Arg2 物品在包裹内的格子数(从0开始)

#20


偶也来学习一下。

#21


call eax;

eax 你都没赋值

#22


解决了,谢谢大家,给分了

#1


最新研究又发现
asm
    pushad
    push    1                                // Arg4 = 00000001
    push    Bag_itemId                             // Arg3 物品ID
    push    Bmun                             // Arg2 物品在包裹内的格子数
    push    0                                // Arg1 = 00000000
    mov esi,$008D6498
    mov esi,[esi+$20]
    mov eax,$0056A670
    call eax                         // \elementc.0056A670
    popad
    end;
把里面的参数(Bag_itemId,Bmun)改成实际值还是通不过,这样可能不是参数传递的问题了,难道是???

#2


没有深入研究过delphi支持的asm,帮不上忙,顶一下

#3


偶原来也发现过,直接写在控件事件里没有问题,
自己搞个函数或过程就不行!等楼下高人解答……

#4


因为你用的变参,
所以
push Bag_itemId // Arg3 物品ID
push Bmun // Arg2 物品在包裹内的格子数
应该不行。
你是说改成
push 立即数
也不行吗?

#5


回楼上的,改成实际数值也不行,所以应该不是参数的问题(即使不调用参数,直接用实际数值带入也不行)

#6


顶,100分寻高手

#7


你把那个var去掉试试, 带var的话,实际传递的是地址值

#8


我说的不一定正确. 

再是, 你把贴子转移到技术区, 会有更多人愿意出手. 非技术分, 很少有人在意的.
况且本来就是技术问题,不应该放在非技术区.

#9


回楼上的,应该跟参数没关系,我把参数去掉也不行

#10


可以保证传递到变址寄存器ESI里的立即数$008D6498是正确有效的吗?

#11


是的,在Button6Click中使用不会出错

#12


Button6Click和function UseItem 这两个过程中的段地址应该是不同的吧.... 我没经验, 帮顶了.

#13


up

#14


有几点这里说一下:
1、不同版本的delphi编译器,对于函数汇编出来的代码是不一样的,我曾经就碰到
过在delphi7能正常运行的ASM代码在delphi6下出错。建议你,认真核对函数对于参数
的调用规则;
2、TObject及类的调用与一般函数参数的调用又是不一样,对于TObject的代码还有虚拟
及动态装载的问题。
3、建议先使用delphi写的代码,再反汇编成汇编进行优化。

由于代码不全,无法给出更多的建议

#15


你声明是这样
function  UseItem(var  Bag_itemId;  Bmun:  DWORD):single;
asm
  ...
end;
还是:
function  UseItem(var  Bag_itemId;  Bmun:  DWORD):single;
begin
asm
  ...
end;
end;

#16


回楼上的,我用D7和D2007都编译过了,不行的,至于你说的2,3点,由于我刚学D不久,还不能明白,下面是源代码


procedure  UseItem(var  Bag_itemId;  Bmun:  Integer);//Bag_itemId:物品ID;Bmun物品在包裹内的格子数(从0开始)
var
Bag_itemId_,Bmun_:Integer;
begin
Bag_itemId_:=Bag_itemId;
Bmun_:=Bmun;
    asm
    pushad
    push    1                                // Arg4 = 00000001
    push    Bag_itemId_                              // Arg3 物品ID
    push    Bmun_                              // Arg2 物品在包裹内的格子数(从0开始)
    push    0                                // Arg1 = 00000000
    mov esi,lpmain
    mov esi,[esi+$20]
    mov eax,Address_useitem
    call eax                         // \elementc.0056A670
    popad
    end;
end;
再用这个调用
procedure TFrm_Pop.ListBox1DblClick(Sender: TObject);
var
  ItemId,ItemMum,Bag_main,Bag_max:Integer;
begin
    Bag_main:=DuMem(base+$85c);
    Bag_max:=DuMem(Bag_main+$10);
    ItemMum:=ListBox1.ItemIndex;
    ItemId:=DuMem(DuMem(DuMem(Bag_main+$C)+4*ListBox1.ItemIndex)+$8);
    UseItem(ItemId,ItemMum);
end;
则出错

定义procedure  UseItem(var  Bag_itemId;  Bmun:  Integer);
  const lpmain=$008D6498 ;                  //基地址8D64B4-1C
  const Address_useitem=$0056A670;


而在这里则不会出错
procedure TFrm_Pop.ListBox1DblClick(Sender: TObject);
var
  Address:Pointer;
  ItemId,ItemMum,Bag_main:Integer;
begin
    Address:=Pointer($0056A670);
    Bag_main:=DuMem(base+$85c);
    ItemMum:=ListBox1.ItemIndex;
    ItemId:=DuMem(DuMem(DuMem(Bag_main+$C)+4*ListBox1.ItemIndex)+$8);
asm
pushad
push    1                                // Arg4 = 00000001
push    ItemId                              // Arg3 物品ID
push    ItemMum                              // Arg2 物品在包裹内的格子数(从0开始)
push    0                                // Arg1 = 00000000
mov esi,lpmain
mov esi,[esi+$20]
lea ecx,[esi+$D4]
call    Address                        // \elementc.0056A670
popad
end;
end;

#17


谢谢jiju(UNCC)的提示,去掉begin end就不会汇编出错了,但无法传递参数,只能用实际数值代替
Bag_itemId和Bmun才可以

function  UseItem(var  Bag_itemId;  Bmun:  Integer): Single;//Bag_itemId:物品ID;Bmun物品在包裹内的格子数(从0开始)
    asm
    pushad
    push    1                                // Arg4 = 00000001
    push    Bag_itemId                             // Arg3 物品ID
    push    Bmun                              // Arg2 物品在包裹内的格子数(从0开始)
    push    0                                // Arg1 = 00000000
    mov esi,lpmain
    mov esi,[esi+$20]
    lea ecx,[esi+$D4]
    mov eax,$0056A670
    call eax                         // \elementc.0056A670
    popad
    end;

#18


这就是那个var的问题了,var传递的是变量的地址

#19


你应该:
push [Bag_itemId] // Arg3 物品ID
push Bmun // Arg2 物品在包裹内的格子数(从0开始)

#20


偶也来学习一下。

#21


call eax;

eax 你都没赋值

#22


解决了,谢谢大家,给分了