床上躺了这么长时间~写点东西充实一下自己好了~By Anskya
OMF,COFF的LIB函数的声明头部简单的说一下好了
By Anskya
OMF是Intel发布的obj格式,COFF据说是M$从UNIX上学来的这个具体内部信息也不太了解
1.连接库函数的声明:
记事本打开各种LIB自然就可以发现一些不同的地方
COFF格式下:LIB函数声明为__imp__XXXX@X
_imp__XXX为函数的声明头部,前面的那个_为C语言调用方式附加的_
@X=X为传递参数的数量*4
也就是说比如说MessageBoxA函数需要传递入4个参数..
那他的声明为__imp__MessageBoxA@12
相同道理其他的也差不多.MASM系列的COFF编译器默认就是把函数都以以上形式编译,
你打开VC调试一下程序既可以发现call [_imp__MessageBox@12]
许多教你C语言和ASM共享LIB和函数头部的书或者文章都有以上说明
具体参考《Intel汇编语言程序设计(第四版)》
OMF格式就很容易发现了.他没有__imp__头部直接就是一个函数的声明后面也没有标号
这里我也没有作其他调查和过多的捣鼓..简单的看了一下BCB的连接库还有NASM的
OMF现对于COFF格式来说就相对简单一些.具体代码可以参考<Alink的源代码>
下载地址:alink.sourceforge.net
看一下NASM-Alink的连接库和声明头部既可以发现[extern _MessageBoxA@16]
他没有前面的_imp__虽然不能代表什么(我也不知道为什么coff为什么要以这个打头)
COFF与OMF在函数声明上最大的区别就在于此了~记下这点以后下面在创建连接库的时候有用的
Alink自带的Win32.lib格式也是按照__imp__XXX打头的但是仔细看一下他没有后面的标号?
其实MASM也可以做到,只是平时我们使用的MASM的时候没有注意到这里.
好了总结一下上面的知识点:其实就三句话就可以总结了
OMF_OBJ格式:正常的函数声明_XXXXX
OMF_LIB格式:有__imp__
COFF_LIB格式:__imp__XXXX@X
有了以上的资料和知识就可以来打造自己的LIB了?
有什么作用?不知道大家发现没有MASM的编译器总喜欢把许多垃圾编译到OBJ或者LIB里面
导致在最终生成的PE也会有许多这种东西..但是不可否认M$的连接器的确是不错.
当然你也可以使用polink来连接(效果是一样的~虽然参数没有M$link多但是也足够用了)
新版的MASM编译器也支持编译OMF格式的OBJ了,个人感觉没太大用处(Delphi和BCB都不能直接拿来用
还是需要自己转换一些东西~这里推荐一下EliCZ叔叔的OMF2D这个工具..去EliCZ主页看看好了)
2.自己编译自定义函数声明的连接库
首先说说一般情况下的连接库的创建好了
一般我们创建自己的连接库的时候总是一个参数就够了"link -LIB /NOLOGO XXX_lib.obj"
MASM:link -LIB /NOLOGO XXX_lib.obj
TASM:TLIB /C XXX_lib.lib + XXX_lib.obj
现在来说说用M$创建没有标号的连接库
我们需要导出表的头部.
M$link有个连接参数可以帮我们做到这点
/MACHINE:{ALPHA|ARM|IX86|MIPS|MIPS16|MIPSR41XX|PPC|SH3|SH4}
以上是连接库的标准类型我们需要的是IX86
然后再自己整理一下函数表头和函数头部模版
代码:
NAME KERNEL32.dll
EXPORTS
AddAtomA
AddAtomW
AddConsoleAliasA
AddConsoleAliasW
AllocConsole
AllocateUserPhysicalPages
.
.
.
网上可以寻找到现成的工具..当然你也可以自己写
(很容易写个遍历导出表的工具相信以大家的智商怎么可能实现不了呢)
建议使用Broland的impdef来生成:impdef -h -def:xxx.def -
下面可以执行命令打造了"LINK -LIB -MACHINE:IX86 -DEF:user32.Def -OUT:user32.lib"
然后用记事本打开看看是不是没有@X的标号了?
好了现在完成标准的OMF_LIB创建了COFF的我就不多说了--看一下MASM32包中的批处理就知道了
创建Broland的BCB用的LIB最好使用BCB 5.5里面的工具这里我也不多说了
3.编译代码+连接:
上面我们连接好了需要的连接库下面我们来写代码然后连接
上面已经说明了我们连接出来的连接库是__imp__XXX这样的
没有序号..所以编写代码的时候我们需要将__imp__加再函数头部修改一下可以成为
extern __imp__WIn32API
然后调用的时候直接call __imp__WIn32API
就OK了~
写两个宏
代码:
TASM:(C声明结构编译器会自动再函数前面增加一个_)
callw macro WinAPI
extern C _imp__&WinAPI:DWORD
call _imp__&WinAPI
endm
NASM:
%macro callw 1
extern __imp__%1
call [__imp__%1]
%endmacro
下面可以编写代码了
代码:
callw macro WinAPI
extern C _imp__&WinAPI:DWORD
call _imp__&WinAPI
endm
.586
.model flat
locals @@
public C Start
.data
msg Byte "[*] Hello World Coder! (C) Anskya.",0dh,0ah,0
cap Byte "MsgBox By Anskya",0
.code
Start:
pushad
push 0
push offset cap
push offset msg
push 0
callw MessageBoxA
;invoke MessageBoxA,0,<offset msg>,<offset cap>,0
popad
ret
end Start
然后老方法用TASM编译.MASM连接就可以了
代码:
\D.N.ASM\bin\tasm32 /mx /m4 /z HelloW.asm
\D.N.ASM\bin\link /subsystem:windows \D.N.ASM\lib\KERNEL32.lib \D.N.ASM\lib\user32.lib /ignore:4033,4078 /nologo /entry:Start /FILEALIGN:0x200 /MERGE:.data=.text /MERGE:.rdata=.text /SECTION:.text,RWX HelloW.OBJ
pause
转载请保留版权[原文出处看雪论坛] 谢谢。。By Anskya
下面就编译出了我们需要的程序..运行一下完全OK