C# 以编程方式读取可调用的dll函数
我的项目需要检查.c和.dll文件。它结合这些信息来确定它应该调用什么,然后调用它 我需要检查dll以找到哪个dll具有哪个功能。我已经将dll映射到内存而不初始化它。现在我需要将标题映射到某个地方,这样我就可以读出包含可调用名称的部分 我该怎么做?这是迄今为止的代码:C# 以编程方式读取可调用的dll函数,c#,dllimport,kernel32,C#,Dllimport,Kernel32,我的项目需要检查.c和.dll文件。它结合这些信息来确定它应该调用什么,然后调用它 我需要检查dll以找到哪个dll具有哪个功能。我已经将dll映射到内存而不初始化它。现在我需要将标题映射到某个地方,这样我就可以读出包含可调用名称的部分 我该怎么做?这是迄今为止的代码: [DllImport("kernel32.dll")] static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, Lo
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);
public static string[] GetFKTNames(string dll)
{
IntPtr lib = LoadLibraryEx(dll, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES);
//INDICATES WHAT I WANT TO DO, BUT DOES NOT WORk
//Header header = GetHeader(lib);
//Unload(lib);
//return header.Names;
}
编辑#2:
我取得了一点进步,今天就放弃了。。。在德国有4天的空闲时间
我不完全确定这种编组是否正确——我没有办法测试它。我很想读一本关于这个主题的书,所以如果你知道一本解释headerstuff如何工作以及有哪些不同标题的好书,请发表评论
private static List<string> ListDLLFunctions(string sADllName)
{
List<string> names = new List<string>();
IntPtr LoadedImage = LoadLibraryEx(sADllName, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES);
IMAGE_NT_HEADERS header = (IMAGE_NT_HEADERS) Marshal.PtrToStructure(libPtr, typeof(IMAGE_NT_HEADERS));
// ImageExportDirectory = (_IMAGE_EXPORT_DIRECTORY*)
// ImageDirectoryEntryToData(LoadedImage.MappedAddress,
// false, IMAGE_DIRECTORY_ENTRY_EXPORT, &cDirSize);
// if (ImageExportDirectory != NULL)
// {
// dNameRVAs = (DWORD *)ImageRvaToVa(LoadedImage.FileHeader,
// LoadedImage.MappedAddress,
// ImageExportDirectory->AddressOfNames, NULL);
// for(size_t i = 0; i < ImageExportDirectory->NumberOfNames; i++)
// {
// sName = (char *)ImageRvaToVa(LoadedImage.FileHeader,
// LoadedImage.MappedAddress,
// dNameRVAs[i], NULL);
// slListOfDllFunctions.push_back(sName);
// }
// }
FreeLibrary(LoadedImage);
return names;
}
static void Main(string[] args)
{
List<string> names = ListDLLFunctions("KERNEL32.DLL");
}
私有静态列表ListDLLFunctions(字符串SADLName)
{
列表名称=新列表();
IntPtr LoadedImage=LoadLibraryEx(sADllName,IntPtr.Zero,LoadLibraryFlags.DONT\u RESOLVE\u DLL\u REFERENCES);
IMAGE_NT_HEADERS header=(IMAGE_NT_HEADERS)Marshal.PtrToStructure(libPtr,typeof(IMAGE_NT_HEADERS));
//ImageExportDirectory=(\u图像\u导出\u目录*)
//ImageDirectoryEntryToData(LoadeImage.MappeAddress,
//错误,图像\目录\条目\导出(&cDirSize);
//if(ImageExportDirectory!=NULL)
// {
//dNameRVAs=(DWORD*)ImageRvaToVa(LoadeImage.FileHeader,
//LoadeImage.MappeAddress,
//ImageExportDirectory->AddressOfNames,空);
//对于(大小i=0;iNumberOfNames;i++)
// {
//sName=(char*)ImageRvaToVa(LoadeImage.FileHeader,
//LoadeImage.MappeAddress,
//dNameRVAs[i],空);
//slListOfDllFunctions.push_-back(sName);
// }
// }
免费图书馆(LoadeImage);
返回姓名;
}
静态void Main(字符串[]参数)
{
List name=ListDLLFunctions(“KERNEL32.DLL”);
}
非源于代码,而是源于我通常使用的控制台
用于查看Dll导出的实用程序
我认为您可以将该工具与Process.Start(…)
一起使用,并解析其输出,以获得所需的信息
希望这有帮助。非源于代码,而是源于我通常使用的控制台 用于查看Dll导出的实用程序 我认为您可以将该工具与
Process.Start(…)
一起使用,并解析其输出,以获得所需的信息
希望这有帮助。没有“一次调用”功能可以为您完成这项工作。
您必须加载dll并在导出表中查找名称
-也许您可以尝试将其移植到c#没有“一次调用”功能可以为您实现。
您必须加载dll并在导出表中查找名称
-也许您可以尝试将其移植到c#我解决了我的用例的问题: 我将lib加载到momory中,将其复制到bytearray中,然后使用PE信息对其进行调查 关于这个话题,有几个有用的资源对我帮助很大:
public class DLLHelper
{
private byte[] dllInMemory;
private UInt32 PESizeOfImage;
private UInt32 VA_PE;
[DllImport("kernel32.dll")]
static public extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);
[DllImport("kernel32.dll")]
static public extern bool FreeLibrary(IntPtr hModule);
public enum LoadLibraryFlags : uint
{
DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008
}
public DLLHelper(string dllpath)
{
PESizeOfImage = GetDllSizeInMemory(dllpath);
dllInMemory = GetDLLCopy(dllpath, PESizeOfImage);
UInt32 VA_p_PE = 0x3C;
VA_PE = Get4ByteFromLocation(VA_p_PE, dllInMemory);
}
private byte[] GetDLLCopy(string dllpath, uint PESizeOfImage)
{
IntPtr libPtr = LoadLibraryEx(dllpath, IntPtr.Zero, LoadLibraryFlags.DONT_RESOLVE_DLL_REFERENCES);
byte[] dllInMemory = new byte[PESizeOfImage];
Marshal.Copy(libPtr, dllInMemory, 0, (int)PESizeOfImage);
FreeLibrary(libPtr);
return dllInMemory;
}
private UInt32 GetDllSizeInMemory(string dllpath)
{
byte[] dllpreload = File.ReadAllBytes(dllpath);
UInt32 pp_PE = 0x3C;
UInt32 p_PE = Get4ByteFromLocation(pp_PE, dllpreload);
UInt32 p_PEOPTIONALHEADER = p_PE + 0x18;
UInt32 p_PESizeOfImage = p_PEOPTIONALHEADER + 0x38;
return Get4ByteFromLocation(p_PESizeOfImage, dllpreload);
}
public void DumpToFile(String filename)
{
File.WriteAllBytes(filename, dllInMemory);
}
public string GetDLLName()
{
UInt32 VAExport = GetVAExport(VA_PE, dllInMemory);
UInt32 VAName = GetVAName(VAExport, dllInMemory);
String Name = GetString(VAName, dllInMemory);
return Name;
}
public List<String> GetFunctionNames()
{
List<String> fkts = new List<String>();
UInt32 VAExport = GetVAExport(VA_PE, dllInMemory);
UInt32 VA_p_firstFKT = GetVA_p_firstFKT(VAExport, dllInMemory);
UInt32 VA_p_lastFKT = GetVA_p_lastFKT(VAExport, dllInMemory);
for (UInt32 VA_p_fkt = VA_p_firstFKT; VA_p_fkt <= VA_p_lastFKT; VA_p_fkt += sizeof(UInt32))
{
UInt32 VA_fkt = Get4ByteFromLocation(VA_p_fkt, dllInMemory);
fkts.Add(GetString(VA_fkt, dllInMemory));
}
return fkts;
}
private UInt32 GetVA_p_lastFKT(UInt32 VAExport, byte[] dllInMemory)
{
UInt32 first = GetVA_p_firstFKT(VAExport, dllInMemory);
UInt32 count = GetfktCount(VAExport, dllInMemory);
UInt32 last = first + (count - 1) * sizeof(UInt32);
return last;
}
private UInt32 GetfktCount(UInt32 VAExport, byte[] dllInMemory)
{
UInt32 RVA_Count = 0x14;
UInt32 VA_Count = VAExport + RVA_Count;
return Get4ByteFromLocation(VA_Count, dllInMemory);
}
private UInt32 GetVA_p_firstFKT(UInt32 VAExport, byte[] dllInMemory)
{
UInt32 RVA_p_FIRST = 0x20;
UInt32 VA_p_FIRST = VAExport + RVA_p_FIRST;
return Get4ByteFromLocation(VA_p_FIRST, dllInMemory);
}
private UInt32 GetVAName(UInt32 VAExport, byte[] dllInMemory)
{
UInt32 RVA_p_NAME = 0x0C;
UInt32 VA_p_NAME = VAExport + RVA_p_NAME;
return Get4ByteFromLocation(VA_p_NAME, dllInMemory);
}
private UInt32 GetVAExport(UInt32 VAPE, byte[] dllInMemory)
{
UInt32 RVA_p_EXPORT = 0x78;
UInt32 VA_p_EXPORT = VAPE + RVA_p_EXPORT;
return Get4ByteFromLocation(VA_p_EXPORT, dllInMemory);
}
string GetString(UInt32 location, byte[] dll)
{
int length = 0;
while (dll[location + length] != 0x00)
{
length++;
}
if (location > int.MaxValue) throw new Exception("uncastable");
return Encoding.UTF8.GetString(dll, (int)location, length);
}
private UInt32 Get4ByteFromLocation(UInt32 location, byte[] dll)
{
if (!(BitConverter.IsLittleEndian))
{
byte[] partial = GetByteSubset(4, location, dll);
Array.Reverse(partial);
return BitConverter.ToUInt32(partial, 0);
}
return BitConverter.ToUInt32(dll, (int)location);
}
private byte[] GetByteSubset(int size, UInt32 location, byte[] dll)
{
byte[] val = new byte[size];
for (int i = 0; i < size; i++)
{
val[i] = dll[location + i];
}
return val;
}
}
公共类DLLHelper
{
专用字节[]dllInMemory;
私人UInt32 PESizeOfImage;
私人单位32个;
[DllImport(“kernel32.dll”)]
静态公共外部IntPtr LoadLibraryEx(字符串lpFileName、IntPtr hReservedNull、LoadLibraryFlags dwFlags);
[DllImport(“kernel32.dll”)]
静态公共外部布尔自由库(IntPtr hModule);
公共枚举加载库标志:uint
{
不解析DLL引用=0x00000001,
加载\忽略\代码\验证\级别=0x00000010,
将库加载为数据文件=0x00000002,
将库作为数据文件加载\u EXCLUSIVE=0x00000040,
将库作为图像资源加载=0x00000020,
加载带有\u更改的\u搜索\u路径的\u=0x00000008
}
公共DLLHelper(字符串dllpath)
{
PESizeOfImage=GetDllSizeInMemory(dllpath);
dllInMemory=GetDLLCopy(dllpath,PESizeOfImage);
UInt32 VA_p_PE=0x3C;
VA_PE=Get4ByteFromLocation(VA_p_PE,dllInMemory);
}
专用字节[]GetDLLCopy(字符串dllpath,uint PESizeOfImage)
{
IntPtr libPtr=LoadLibraryEx(dllpath,IntPtr.Zero,LoadLibraryFlags.DONT\u RESOLVE\u DLL\u REFERENCES);
字节[]dllInMemory=新字节[PESizeOfImage];
封送处理副本(libPtr,dllInMemory,0,(int)PESizeOfImage);
免费图书馆;
返回dllInMemory;
}
专用UInt32 GetDllSizeInMemory(字符串dllpath)
{
字节[]dllpreload=File.ReadAllBytes(dllpath);
UInt32 pp_PE=0x3C;
UInt32 p_PE=Get4ByteFromLocation(pp_PE,dllpreload);
UInt32 p_peopoptionalHeader=p_PE+0x18;
UInt32 p_PESizeOfImage=p_peopoptionalheader+0x38;
返回Get4ByteFromLocation(p_PESizeOfImage,dllpreload);
}
公共无效转储文件(字符串文件名)
{
writealBytes(文件名,dllInMemory);
}
公共字符串GetDLLName()
{
UInt32 VAExport=获取VAExport(虚拟磁盘,dllInMemory);
UInt32 VAName=GetVAName(VAExport,dllInMemory);
String Name=GetString(VAName,dllInMemory);
返回名称;
}
公共列表GetFunctionNames()
{
List fkts=新列表();
UInt32 VAExport=获取VAExport(虚拟磁盘,dllInMemory);
UInt32 VA_p_firstFKT=GetVA_p_firstFKT(VAExport,dllInMemory);
UInt32 VA_p_lastFKT=GetVA_p_lastFKT(VAExport,dllInMemory)