SimTower要做的第一件事就是从
WAVEMIXINIT
运行WAVMIX16.DLL
。据我所知,如果返回值为0
,它将显示一个对话框并禁用声音。我现在的计划是简单地创建一个人造wavmix16将会(暂时)始终从该函数返回0的dll。这应该可以让我获得一个入口点来运行我自己的代码,并开始游戏。 ,并且可以看到该调用即将传入我的函数中,因为如果我取消注释while循环,该程序将被卡在其中。转到我的返回语句。
(Windows XP)
这是被调用的DDL函数的程序集。我有点不确定为什么除了
wavmix16.dll
和mov
(例如retf
吗?)之外还有更多的东西,但是我对此很陌生,所以也许这很正常。 /> 这是原始DLL函数的汇编:
非常感谢任何帮助,谢谢!
#1 楼
您的伪函数未将堆栈固定在该函数的结尾处。根据调用约定,它的末尾应该具有pop ds
pop bp
dec bp
。
假设函数中的堆栈指针具有1000h的值(在
CS:IP
已被压入堆栈以进行远端调用之后)。然后,您将拥有原始函数; sp = 1000h
mox ax, ds
...
push bp ; sp = 0ffeh
mov bp, sp ; bp = 0ffeh
...
lea sp, [bp-2] ; sp = 0ffch
pop ds ; sp = 0ffeh
pop bp ; sp = 1000h
retf
要使问题中使用的编译器,Digital Mars编译器dmc.exe,在生成以下指令时从far函数返回时,传递标志
-Wm
,该标志将“生成INC BP / DEC BP标记远堆栈帧”。评论
关于inc bp / dec bp:blogs.msdn.microsoft.com/oldnewthing/20110316-00/?p = 11203
–伊戈尔·斯科钦斯基♦
17年11月8日12:44
谢谢!我在函数中添加了xor ax,ax,pop ds,pop bp,dec bp,retf作为内联汇编,它解决了!
– LinusUnnebäck
17年11月8日在16:55
话虽如此,如果有人可以指出正确的方向,让DigitalMars编译器dmc.exe输出正确的指令,我将非常高兴:)
– LinusUnnebäck
17年11月8日在17:03
我找到了!标志-Wm将使dmc“ Generate INC BP / DEC BP标记远堆栈帧”。将此添加到答案中以确保完整性。最好在其他编译器中添加如何执行此操作:)
– LinusUnnebäck
17年11月8日在19:56
评论
您是否检查了是否使用了正确的参数和调用约定?这似乎是清理错误。据我所知。查看wavemix库的头文件,我可以看到该函数定义为HANDLE WINAPI WaveMixInit(void);。 HANDLE被定义为我在代码中以相同方式定义的空指针。 WINAPI,如果我理解本文的正确之处与我的__far __pascal相同...我将添加原始DLL中的反编译函数,看看是否可以发现任何差异...
对我来说,似乎我的函数在返回之前将2个值压入堆栈,而原始DLL在返回之前将6个值压入并弹出4个值(再次保留2个),这对我来说意味着调用约定应该相同。 ..
WINAPI应该解析为__stdcall(在现代系统上)。在另一个节点上,您的函数不会还原原始的bp和sp。真的很奇怪的约定
因此,由于没有发现任何输出16位代码的现代系统,因此我正在使用古老的编译器来编译16位DLL :)我正在遵循DigitalMars的本指南并使用其编译器