从汇编代码

时间:2015-05-09 15:44:50

标签: c++ c debugging assembly linker

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

我从" MSVCRTD.lib"解析了外部符号。具有许多printf函数的库,如:

__imp__printf
_printf
___imp___printf_l
;and more ...

我有2个挑战(链接/建设)和(正在运行)。

至于将我的汇编代码链接到库的第一个挑战根本不是问题,我可以将我的汇编代码链接到对库的任何外部函数的任何调用,我只需要模仿装饰(Mangled)函数的名称,以便链接器可以识别它。我第一次尝试了第二个" _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

射击!每件事都很顺利。

enter image description here

但是当我用" _imp__printf" 尝试同样的事情时,问题开始。

BTY:这个函数是你编写着名的hello世界时c编译器调用的函数! c申请

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

我读取了链接器输出消息,除了表示:"从MSVCRTD.lib(MSVCR100D.dll)中删除_printf"。

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

enter image description here

为什么" _printf" 功能成功且" __ imp__printf" 没有:(,任何idias?

2 个答案:

答案 0 :(得分:1)

感谢Jester先生和Raymond Chen先生 他们在评论中为问题提供了解决方案。

这是__imp__printf的声明。它被声明为PROC,就像工作示例_printf一样,但有数据如此声明。

Extern _imp__printf :DWORD

将使其成为printf

非常感谢你们两位

答案 1 :(得分:0)

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

我想我已经接近弄清楚为什么因为跳转指令中的问题而调用_imp__printf外部函数失败,这就是我所做的..

我试图打造你好世界! C程序看看_imp__printf函数在符号表中的样子如果文件编译为C程序而不是程序集,我然后转储从两个调用程序编译的OBJ文件(MASM /和c),结果非常有趣,这里是从 C文件

编译的OBJ中的_imp__printf

enter image description here

以下是从 MASM文件

编译的OBJ中的_imp__printf

enter image description here

有趣!并且在引用COFF文档后似乎重定位类型REL32将强制链接器不能正确处理导入地址表,因此跳转指令将像以前一样掉落。

现在我的问题是"我怎么能告诉MASM用_imp__printf符号类型组装文件" DIR32"吗