如何知道已经编译成的 dll 文件里有什么函数声明???

时间:2021-11-11 17:41:04
如何知道已经编译成的 dll 文件里有什么函数声明??? up有分.

15 个解决方案

#1


up

#2


实际上dll以及大量的可执行文件都属于PE格式文件。
PE格式文件有专用的存储方法,只要知道它的存储方法,这件事就不难做到。
实际上,PE格式文件重要的是知道文件头和段结构。
如果你想仔细了解PE格式,你可以去微软的官方主页MSDN查找,有相当完整的资料。
通过了解PE格式文件,你可以知道dll有什么函数接口,甚至可以知道它用到了其他的什么DLL

以下是PE格式文件的读取方法
Public Function C_GetFilePE(FILE_PATH As String, C_List As ListBox) As Boolean
On Error GoTo ine
Dim i As Long
Dim j As Long
Dim C_Characteristics As String
Dim C_File As String
Dim C_Fr As Integer
Dim C_Sign As Byte
Dim C_SignOff As Long
Dim C_COFFOff As Long
Dim C_OPThead As Long
Dim C_Flag As Integer
Dim Temp_Str As String
Dim C_Base As Long
Dim C_DataTable As Long
Dim C_DataCount As Long
Dim C_DataName(1 To 8) As Byte
Dim C_DataNameT As String

C_Fr = FreeFile

Call C_GetFileInfo(FILE_PATH, C_List)

C_Characteristics = "文件特征: "
Open FILE_PATH For Binary Access Read As #C_Fr
'偏移&H3C + 1地址得到文件是否为PE格式文件
Get #C_Fr, &H3C + 1, C_Sign
Get #C_Fr, C_Sign + 1, C_SignOff
If Not C_SignOff = &H4550 Then
   Close C_Fr
   C_Characteristics = "此文件不是PE格式文件。"
   C_List.AddItem C_Characteristics
   C_GetFilePE = False
   GoTo inerr
Else
   C_Characteristics = "PE格式文件。"
   C_List.AddItem C_Characteristics
   C_GetFilePE = True
End If
'得到COFF文件头的偏移地址
C_COFFOff = CLng(C_Sign) + 4
'得到可选文件头的偏移地址
C_OPThead = C_COFFOff + 20

'得到文件属性
Get #C_Fr, C_COFFOff + 18 + 1, C_Flag
Temp_Str = "文件属性: "
C_List.AddItem Temp_Str
Call GetPEChar(C_Flag, C_List)

'得到文件基址
Get #C_Fr, C_OPThead + 29, C_Base
Temp_Str = "文件基址: " & "&H" & Hex(C_Base)
C_List.AddItem Temp_Str
Get #C_Fr, C_OPThead + 92 + 1, C_DataCount
C_DataTable = C_OPThead + 96 + C_DataCount * 8
If C_DataCount > 0 Then
   Temp_Str = "段名: "
   C_List.AddItem Temp_Str
   For i = 1 To C_DataCount
      '得到段名称
      For j = 1 To 8
         Get #C_Fr, C_DataTable + j + (i - 1) * 40, C_DataName(j)
      Next j
      C_DataNameT = StrConv(C_DataName, vbUnicode)
      C_DataNameT = Trim(Replace(C_DataNameT, Chr(0), " "))
      If C_DataNameT <> "" Then
         Temp_Str = "   " & C_DataNameT
         C_List.AddItem Temp_Str
      End If
   Next i
End If
Close C_Fr
GoTo inerr
ine:
   MsgBox Err.Description, , "错误信息"
inerr:
End Function

#3


得到文件相关的信息的封装方法
Public Function C_GetFileInfo(FILE_PATH As String, C_List As ListBox)
Dim C_FileSize As Long
Dim C_Lpdwhandle As Long
Dim C_Data() As Byte
Dim C_Lret As Long
Dim C_VerSion As String
Dim C_LpBuffer As Long
Dim C_LpSize As Long
Dim C_FF As VS_FIXEDFILEINFO
Dim C_Lup As Long
Dim C_Llow As Long
Dim C_FVersion As String
Dim C_PVersion As String
Dim C_FDataTime As String
Dim C_CCompany As String
Dim C_Lun As Long           '以下判断文件语言版本
Dim C_ILunID As Integer
Dim C_ICodePage As Integer
Dim C_SLunID As String
Dim C_SCodePage As String
Dim i As Long


C_FileSize = GetFileVersionInfoSize(FILE_PATH, C_Lpdwhandle)
If C_FileSize <= 0 Then        '如果得不到文件长度或文件长度为0
   Get_API_ERROR Err.LastDllError
   GoTo inerr
End If
ReDim C_Data(1 To C_FileSize)  '重定义文件字符数组,用于将文件内容考出

'得到文件相关信息
C_Lret = GetFileVersionInfo(FILE_PATH, C_Lpdwhandle, C_FileSize, C_Data(1))
If C_Lret = 0 Then
   Get_API_ERROR Err.LastDllError
   GoTo inerr
End If
C_VerSion = "\"                '返回根块
C_Lret = VerQueryValue(C_Data(1), C_VerSion, C_LpBuffer, C_LpSize)
If C_Lret = 0 Then
   GoTo inerr
End If
'将指针C_LpBuffer的内容拷贝导C_FF结构中
CopyMemory ByVal VarPtr(C_FF), ByVal C_LpBuffer, C_LpSize

'得到文件版本信息
C_Lup = CLng(C_FF.dwFileVersionMS / &H10000)
C_Llow = CLng(C_FF.dwFileVersionMS / &HFFFF&)
C_FVersion = CStr(C_Lup) & "." & CStr(C_Llow)

C_Lup = CLng(C_FF.dwFileVersionLS / &H10000)
C_Llow = CLng(C_FF.dwFileVersionLS / &HFFFF&)
C_FVersion = C_FVersion & "." & CStr(C_Lup) & "." & CStr(C_Llow)
C_FVersion = "文件版本: " & C_FVersion

'得到产品版本信息
C_Lup = CLng(C_FF.dwProductVersionMS / &H10000)
C_Llow = CLng(C_FF.dwProductVersionMS / &HFFFF&)
C_PVersion = CStr(C_Lup) & "." & CStr(C_Llow)

C_Lup = CLng(C_FF.dwProductVersionLS / &H10000)
C_Llow = CLng(C_FF.dwProductVersionLS / &HFFFF&)
C_PVersion = C_PVersion & "." & CStr(C_Lup) & "." & CStr(C_Llow)
C_PVersion = "产品版本: " & C_PVersion

'得到文件创建时间
C_FDataTime = "文件创建时间:" & FileDateTime(FILE_PATH)

'得到文件语言版本
C_VerSion = "\VarFileInfo\Translation"
C_Lret = VerQueryValue(C_Data(1), C_VerSion, C_LpBuffer, C_LpSize)
If C_Lret <> 0 Then
   C_Lun = C_LpSize / 4
   For i = 0 To C_Lun - 1
       VBGetTarget C_ILunID, C_LpBuffer + 4 * i, 2
       VBGetTarget C_ICodePage, C_LpBuffer + 4 * i + 2, 2
       If C_ILunID = LANG_ENGLISH Then Exit For
   Next i
Else
   C_ILunID = &H409
   C_ICodePage = &H4B0
End If

C_SLunID = Hex(C_ILunID)
Do While Len(C_SLunID) < 4
   C_SLunID = "0" & C_SLunID
Loop
C_SCodePage = Hex(C_ICodePage)
Do While Len(C_SCodePage) < 4
   C_SCodePage = "0" & C_SCodePage
Loop
C_VerSion = "\StringFileInfo\" & C_SLunID & C_SCodePage & "\CompanyName"
C_Lret = VerQueryValue(C_Data(1), C_VerSion, C_LpBuffer, C_LpSize)
If C_Lret = 0 Then
   GoTo inerr
End If
C_CCompany = ""
For i = 1 To C_LpSize
   C_CCompany = C_CCompany & Chr(C_Data(C_LpBuffer - VarPtr(C_Data(1)) + i))
Next
C_CCompany = "公司名称: " & C_CCompany

'显示结果
C_List.Clear
C_List.AddItem C_FVersion
C_List.AddItem C_PVersion
C_List.AddItem C_FDataTime
C_List.AddItem C_CCompany
inerr:
End Function

#4


用vs6.0Tools里面的DEPENDS.EXE

#5


得到所有的PE格式文件导出函数列表
Public Function C_GetPEExport(FILE_PATH As String, C_List As ListBox)
Dim i As Integer
Dim C_Lret As Long
Dim C_BaseAddr As String
Dim C_PRavExportDir As Long
Dim C_PavExportDir As Long
Dim Temp_Str As String
Dim C_ExportNamePointerTableVA As Long
Dim C_NextAddress As Long
Dim C_StartAddress As Long
Dim C_LoadImage As LOADED_IMAGE
Dim C_PEFileHeader As IMAGE_PE_FILE_HEADER
Dim C_ExportDir As IMAGE_EXPORT_DIRECTORY_TABLE   '段表结构目录
C_List.Clear
'获得函数输出表
C_List.AddItem "【导出表】"

C_Lret = MapAndLoad(FILE_PATH, "", C_LoadImage, True, True)
If C_Lret = 0 Then
   Get_API_ERROR Err.LastDllError
   GoTo inerr
End If
'得到文件映射的基址
C_BaseAddr = "基址为: " & "&H" & Hex(C_LoadImage.MappedAddress)
C_List.AddItem C_BaseAddr

CopyMemory ByVal VarPtr(C_PEFileHeader), ByVal C_LoadImage.pFileHeader, 256
'得到映射文件的输出表相对虚拟地址
C_PRavExportDir = C_PEFileHeader.OptionalHeader.DataDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT).RVA
'转换成虚拟地址
C_PavExportDir = ImageRvaToVa(C_LoadImage.pFileHeader, C_LoadImage.MappedAddress, C_PRavExportDir, 0&)
If C_PavExportDir = 0 Then
   'MsgBox "读取输出表相对虚拟地址错误。", , "错误信息"
   GoTo inerr
End If
CopyMemory ByVal VarPtr(C_ExportDir), ByVal C_PavExportDir, Len(C_ExportDir)
Temp_Str = "输出函数数量: " & C_ExportDir.NumberOfNames & "个"
C_List.AddItem Temp_Str

C_ExportNamePointerTableVA = ImageRvaToVa(C_LoadImage.pFileHeader, C_LoadImage.MappedAddress, C_ExportDir.ExportNamePointerTableRVA, 0&)
C_StartAddress = C_ExportNamePointerTableVA
'得到下一个函数的地址
VBGetTarget C_NextAddress, C_ExportNamePointerTableVA, 4
'循环得到函数名称
For i = 0 To C_ExportDir.NumberOfNames - 1
    C_NextAddress = ImageRvaToVa(C_LoadImage.pFileHeader, C_LoadImage.MappedAddress, C_NextAddress, 0&)
    Temp_Str = LPSTRtoBSTR(C_NextAddress)
    C_List.AddItem "    " & Temp_Str
    C_StartAddress = C_StartAddress + 4
    VBGetTarget C_NextAddress, C_StartAddress, 4
Next i

C_Lret = UnMapAndLoad(C_LoadImage)
If C_Lret = 0 Then
   MsgBox "卸载函数失败。", , "错误信息"
End If
inerr:
   Call C_GetPEImput(FILE_PATH, C_List)
End Function

#6


以前的Win9x的快速查看具有这个功能。
以前还有dlldump.exe文件,现在好像没有了。

dll函数外部入口可以隐藏,这样就不能访问对外函数名。我以前用“快速查看”看过几个DLL,比较旧的W32Dll能看到所有函数,有些就不能。

#7


帮你  up

#8


函数名很容易看到
可参数就没有那么容易了
只能反汇编,看汇编代码

#9


基本上只能看到有哪些函数名,如果没说明文档的话是无法使用的!得不到参数列表......

#10


帮你  up

#11


看这里,兄弟,有你要的,不过,可都是汇编吖  

 http://www.csdn.net/develop/Read_Article.asp?Id=13362

#12


用 Depends 能得到函数名和序号。
要得到参数的话:
1. 如果 DLL 的函数名被装饰过,用 depends 可以得到装饰前的参数表和返回值。
2. 如果 DLL 的函数名没有被装饰过,只能反汇编了。(Windows 的系统 API 函数好难看懂啊!)

#13


学习

#14


up!
学习!

#15


up up up

#1


up

#2


实际上dll以及大量的可执行文件都属于PE格式文件。
PE格式文件有专用的存储方法,只要知道它的存储方法,这件事就不难做到。
实际上,PE格式文件重要的是知道文件头和段结构。
如果你想仔细了解PE格式,你可以去微软的官方主页MSDN查找,有相当完整的资料。
通过了解PE格式文件,你可以知道dll有什么函数接口,甚至可以知道它用到了其他的什么DLL

以下是PE格式文件的读取方法
Public Function C_GetFilePE(FILE_PATH As String, C_List As ListBox) As Boolean
On Error GoTo ine
Dim i As Long
Dim j As Long
Dim C_Characteristics As String
Dim C_File As String
Dim C_Fr As Integer
Dim C_Sign As Byte
Dim C_SignOff As Long
Dim C_COFFOff As Long
Dim C_OPThead As Long
Dim C_Flag As Integer
Dim Temp_Str As String
Dim C_Base As Long
Dim C_DataTable As Long
Dim C_DataCount As Long
Dim C_DataName(1 To 8) As Byte
Dim C_DataNameT As String

C_Fr = FreeFile

Call C_GetFileInfo(FILE_PATH, C_List)

C_Characteristics = "文件特征: "
Open FILE_PATH For Binary Access Read As #C_Fr
'偏移&H3C + 1地址得到文件是否为PE格式文件
Get #C_Fr, &H3C + 1, C_Sign
Get #C_Fr, C_Sign + 1, C_SignOff
If Not C_SignOff = &H4550 Then
   Close C_Fr
   C_Characteristics = "此文件不是PE格式文件。"
   C_List.AddItem C_Characteristics
   C_GetFilePE = False
   GoTo inerr
Else
   C_Characteristics = "PE格式文件。"
   C_List.AddItem C_Characteristics
   C_GetFilePE = True
End If
'得到COFF文件头的偏移地址
C_COFFOff = CLng(C_Sign) + 4
'得到可选文件头的偏移地址
C_OPThead = C_COFFOff + 20

'得到文件属性
Get #C_Fr, C_COFFOff + 18 + 1, C_Flag
Temp_Str = "文件属性: "
C_List.AddItem Temp_Str
Call GetPEChar(C_Flag, C_List)

'得到文件基址
Get #C_Fr, C_OPThead + 29, C_Base
Temp_Str = "文件基址: " & "&H" & Hex(C_Base)
C_List.AddItem Temp_Str
Get #C_Fr, C_OPThead + 92 + 1, C_DataCount
C_DataTable = C_OPThead + 96 + C_DataCount * 8
If C_DataCount > 0 Then
   Temp_Str = "段名: "
   C_List.AddItem Temp_Str
   For i = 1 To C_DataCount
      '得到段名称
      For j = 1 To 8
         Get #C_Fr, C_DataTable + j + (i - 1) * 40, C_DataName(j)
      Next j
      C_DataNameT = StrConv(C_DataName, vbUnicode)
      C_DataNameT = Trim(Replace(C_DataNameT, Chr(0), " "))
      If C_DataNameT <> "" Then
         Temp_Str = "   " & C_DataNameT
         C_List.AddItem Temp_Str
      End If
   Next i
End If
Close C_Fr
GoTo inerr
ine:
   MsgBox Err.Description, , "错误信息"
inerr:
End Function

#3


得到文件相关的信息的封装方法
Public Function C_GetFileInfo(FILE_PATH As String, C_List As ListBox)
Dim C_FileSize As Long
Dim C_Lpdwhandle As Long
Dim C_Data() As Byte
Dim C_Lret As Long
Dim C_VerSion As String
Dim C_LpBuffer As Long
Dim C_LpSize As Long
Dim C_FF As VS_FIXEDFILEINFO
Dim C_Lup As Long
Dim C_Llow As Long
Dim C_FVersion As String
Dim C_PVersion As String
Dim C_FDataTime As String
Dim C_CCompany As String
Dim C_Lun As Long           '以下判断文件语言版本
Dim C_ILunID As Integer
Dim C_ICodePage As Integer
Dim C_SLunID As String
Dim C_SCodePage As String
Dim i As Long


C_FileSize = GetFileVersionInfoSize(FILE_PATH, C_Lpdwhandle)
If C_FileSize <= 0 Then        '如果得不到文件长度或文件长度为0
   Get_API_ERROR Err.LastDllError
   GoTo inerr
End If
ReDim C_Data(1 To C_FileSize)  '重定义文件字符数组,用于将文件内容考出

'得到文件相关信息
C_Lret = GetFileVersionInfo(FILE_PATH, C_Lpdwhandle, C_FileSize, C_Data(1))
If C_Lret = 0 Then
   Get_API_ERROR Err.LastDllError
   GoTo inerr
End If
C_VerSion = "\"                '返回根块
C_Lret = VerQueryValue(C_Data(1), C_VerSion, C_LpBuffer, C_LpSize)
If C_Lret = 0 Then
   GoTo inerr
End If
'将指针C_LpBuffer的内容拷贝导C_FF结构中
CopyMemory ByVal VarPtr(C_FF), ByVal C_LpBuffer, C_LpSize

'得到文件版本信息
C_Lup = CLng(C_FF.dwFileVersionMS / &H10000)
C_Llow = CLng(C_FF.dwFileVersionMS / &HFFFF&)
C_FVersion = CStr(C_Lup) & "." & CStr(C_Llow)

C_Lup = CLng(C_FF.dwFileVersionLS / &H10000)
C_Llow = CLng(C_FF.dwFileVersionLS / &HFFFF&)
C_FVersion = C_FVersion & "." & CStr(C_Lup) & "." & CStr(C_Llow)
C_FVersion = "文件版本: " & C_FVersion

'得到产品版本信息
C_Lup = CLng(C_FF.dwProductVersionMS / &H10000)
C_Llow = CLng(C_FF.dwProductVersionMS / &HFFFF&)
C_PVersion = CStr(C_Lup) & "." & CStr(C_Llow)

C_Lup = CLng(C_FF.dwProductVersionLS / &H10000)
C_Llow = CLng(C_FF.dwProductVersionLS / &HFFFF&)
C_PVersion = C_PVersion & "." & CStr(C_Lup) & "." & CStr(C_Llow)
C_PVersion = "产品版本: " & C_PVersion

'得到文件创建时间
C_FDataTime = "文件创建时间:" & FileDateTime(FILE_PATH)

'得到文件语言版本
C_VerSion = "\VarFileInfo\Translation"
C_Lret = VerQueryValue(C_Data(1), C_VerSion, C_LpBuffer, C_LpSize)
If C_Lret <> 0 Then
   C_Lun = C_LpSize / 4
   For i = 0 To C_Lun - 1
       VBGetTarget C_ILunID, C_LpBuffer + 4 * i, 2
       VBGetTarget C_ICodePage, C_LpBuffer + 4 * i + 2, 2
       If C_ILunID = LANG_ENGLISH Then Exit For
   Next i
Else
   C_ILunID = &H409
   C_ICodePage = &H4B0
End If

C_SLunID = Hex(C_ILunID)
Do While Len(C_SLunID) < 4
   C_SLunID = "0" & C_SLunID
Loop
C_SCodePage = Hex(C_ICodePage)
Do While Len(C_SCodePage) < 4
   C_SCodePage = "0" & C_SCodePage
Loop
C_VerSion = "\StringFileInfo\" & C_SLunID & C_SCodePage & "\CompanyName"
C_Lret = VerQueryValue(C_Data(1), C_VerSion, C_LpBuffer, C_LpSize)
If C_Lret = 0 Then
   GoTo inerr
End If
C_CCompany = ""
For i = 1 To C_LpSize
   C_CCompany = C_CCompany & Chr(C_Data(C_LpBuffer - VarPtr(C_Data(1)) + i))
Next
C_CCompany = "公司名称: " & C_CCompany

'显示结果
C_List.Clear
C_List.AddItem C_FVersion
C_List.AddItem C_PVersion
C_List.AddItem C_FDataTime
C_List.AddItem C_CCompany
inerr:
End Function

#4


用vs6.0Tools里面的DEPENDS.EXE

#5


得到所有的PE格式文件导出函数列表
Public Function C_GetPEExport(FILE_PATH As String, C_List As ListBox)
Dim i As Integer
Dim C_Lret As Long
Dim C_BaseAddr As String
Dim C_PRavExportDir As Long
Dim C_PavExportDir As Long
Dim Temp_Str As String
Dim C_ExportNamePointerTableVA As Long
Dim C_NextAddress As Long
Dim C_StartAddress As Long
Dim C_LoadImage As LOADED_IMAGE
Dim C_PEFileHeader As IMAGE_PE_FILE_HEADER
Dim C_ExportDir As IMAGE_EXPORT_DIRECTORY_TABLE   '段表结构目录
C_List.Clear
'获得函数输出表
C_List.AddItem "【导出表】"

C_Lret = MapAndLoad(FILE_PATH, "", C_LoadImage, True, True)
If C_Lret = 0 Then
   Get_API_ERROR Err.LastDllError
   GoTo inerr
End If
'得到文件映射的基址
C_BaseAddr = "基址为: " & "&H" & Hex(C_LoadImage.MappedAddress)
C_List.AddItem C_BaseAddr

CopyMemory ByVal VarPtr(C_PEFileHeader), ByVal C_LoadImage.pFileHeader, 256
'得到映射文件的输出表相对虚拟地址
C_PRavExportDir = C_PEFileHeader.OptionalHeader.DataDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT).RVA
'转换成虚拟地址
C_PavExportDir = ImageRvaToVa(C_LoadImage.pFileHeader, C_LoadImage.MappedAddress, C_PRavExportDir, 0&)
If C_PavExportDir = 0 Then
   'MsgBox "读取输出表相对虚拟地址错误。", , "错误信息"
   GoTo inerr
End If
CopyMemory ByVal VarPtr(C_ExportDir), ByVal C_PavExportDir, Len(C_ExportDir)
Temp_Str = "输出函数数量: " & C_ExportDir.NumberOfNames & "个"
C_List.AddItem Temp_Str

C_ExportNamePointerTableVA = ImageRvaToVa(C_LoadImage.pFileHeader, C_LoadImage.MappedAddress, C_ExportDir.ExportNamePointerTableRVA, 0&)
C_StartAddress = C_ExportNamePointerTableVA
'得到下一个函数的地址
VBGetTarget C_NextAddress, C_ExportNamePointerTableVA, 4
'循环得到函数名称
For i = 0 To C_ExportDir.NumberOfNames - 1
    C_NextAddress = ImageRvaToVa(C_LoadImage.pFileHeader, C_LoadImage.MappedAddress, C_NextAddress, 0&)
    Temp_Str = LPSTRtoBSTR(C_NextAddress)
    C_List.AddItem "    " & Temp_Str
    C_StartAddress = C_StartAddress + 4
    VBGetTarget C_NextAddress, C_StartAddress, 4
Next i

C_Lret = UnMapAndLoad(C_LoadImage)
If C_Lret = 0 Then
   MsgBox "卸载函数失败。", , "错误信息"
End If
inerr:
   Call C_GetPEImput(FILE_PATH, C_List)
End Function

#6


以前的Win9x的快速查看具有这个功能。
以前还有dlldump.exe文件,现在好像没有了。

dll函数外部入口可以隐藏,这样就不能访问对外函数名。我以前用“快速查看”看过几个DLL,比较旧的W32Dll能看到所有函数,有些就不能。

#7


帮你  up

#8


函数名很容易看到
可参数就没有那么容易了
只能反汇编,看汇编代码

#9


基本上只能看到有哪些函数名,如果没说明文档的话是无法使用的!得不到参数列表......

#10


帮你  up

#11


看这里,兄弟,有你要的,不过,可都是汇编吖  

 http://www.csdn.net/develop/Read_Article.asp?Id=13362

#12


用 Depends 能得到函数名和序号。
要得到参数的话:
1. 如果 DLL 的函数名被装饰过,用 depends 可以得到装饰前的参数表和返回值。
2. 如果 DLL 的函数名没有被装饰过,只能反汇编了。(Windows 的系统 API 函数好难看懂啊!)

#13


学习

#14


up!
学习!

#15


up up up