繁体   English   中英

从汇编代码调用ac库函数时出现运行错误

[英]running error when calling a c library function from assmbly code

我试图对链接器及其工作原理有更好的了解,因此我尝试从c库(MSVCRTD.lib)中调用简单函数(printf),但使用MASM上的汇编代码。

我从“ MSVCRTD.lib”库中剖析了外部符号,该库具有许多printf的功能,例如:

__imp__printf
_printf
___imp___printf_l
;and more ...

我遇到了2个挑战(链接/构建)和(运行)。

至于将我的汇编代码链接到库的第一个挑战根本不是问题,我可以将我的汇编代码与对库的任何外部函数的任何调用链接起来,我只需要模仿装饰的(混用的)名称即可。功能,以便链接器可以识别它。 我首先尝试了第二个“ _printf”,它锁定得更短,更好,并且在分解它的代码后,我知道它在堆栈上带有2个参数,并且是cdecl调用约定,所以我编写了它需要的代码,它是:

.386
.model flat,stdcall
.stack 4096
option casemap :none
Extern printf :PROC    ; MASM will decorate it to be "_printf"

.data
message byte "Hello C library, this is MASM calling"

.code
main proc
push 0
push offset message
call printf
add esp,8 ; clean the stack
retn
main endp
end

开枪! 每件事都很顺利。

在此处输入图片说明

但是当我尝试使用“ _imp__printf”做同样的事情时, 问题就开始了。

BTY:这个函数是c编译器在编写著名的hello世界时调用的函数! c应用

链接器成功构建了程序,但是当我运行程序时,它崩溃了!

我阅读了链接器输出消息,除了显示以下内容的行外,所有内容看起来都很正常:“从MSVCRTD.lib(MSVCR100D.dll)丢弃_printf”。

我使用OllyDBG调试了程序,然后发现应该落在函数上的调用指令实际上落在了被识别为DATA的区域上! 在.rdata部分中

在此处输入图片说明

为什么“ _printf 功能成功,而“ __imp__printf”没有:(,有什么成见?

感谢Jester先生和Raymond Chen先生,他们在评论中提供了解决该问题的方法。

这是__imp__printf的声明。 像工作示例_printf一样被声明为PROC,但是有DATA这样声明。

Extern _imp__printf :DWORD

将使其像printf

非常感谢你们

编辑:这不是解决方案,但我将其留作以后参考。 下一个答案中的解决方案。

我想我快要弄清楚为什么由于跳转指令中的问题而导致调用_imp__printf外部函数失败,这就是我所做的。

我试图建立一个世界! C程序,以查看_imp__printf函数在符号表中的外观,如果该文件被编译为C程序而不是汇编程序,那么我将转储从两个调用程序(MASM /和c)编译的OBJ文件,然后结果非常有趣,这是从C文件编译的OBJ中的_imp__printf

在此处输入图片说明

这是从MASM文件编译的OBJ中的_imp__printf

在此处输入图片说明

有趣! 并且在参考COFF文档之后,似乎重定位类型REL32将迫使链接器无法正确处理导入地址表,因此跳转指令将像以前一样落下。

现在我的问题是“如何告诉MASM用_imp__printf符号类型“ DIR32”汇编文件?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM