Dll 导入地址表中的Thunk表?

Dll 导入地址表中的Thunk表?,dll,portable-executable,thunk,Dll,Portable Executable,Thunk,与EXE文件中用于导入外部DLL中使用的函数的导入地址表相关的thunk表是什么 这个thunk表只是一个包含其他函数“thunk”的表吗?thunk是导入表的一部分(IMAGE\u DIRECTORY\u ENTRY\u Import)和延迟导入表(IMAGE\u DIRECTORY\u ENTRY\u Delay\u Import)。对它们进行了描述 我将查看我的旧源代码,稍后将发布一个工作代码,该代码将转储这两个包含绑定信息的表 更新: 这是我在一个旧程序中喜欢的代码。它只支持32位PE,

与EXE文件中用于导入外部DLL中使用的函数的导入地址表相关的thunk表是什么


这个thunk表只是一个包含其他函数“thunk”的表吗?

thunk是导入表的一部分(
IMAGE\u DIRECTORY\u ENTRY\u Import
)和延迟导入表(
IMAGE\u DIRECTORY\u ENTRY\u Delay\u Import
)。对它们进行了描述

我将查看我的旧源代码,稍后将发布一个工作代码,该代码将转储这两个包含绑定信息的表

更新:

这是我在一个旧程序中喜欢的代码。它只支持32位PE,但可以轻松修改为64位。顺便说一句,您可以看到,它还转储绑定信息。要测试此绑定,请绑定要针对bind.exe转储的PE(例如,使用
bind.exe-u-v test.dll

代码由大约1000行组成,所以我不能在这里发布。我收到一条错误消息

哎呀!无法提交您的编辑,因为:

  • 正文不超过30000个字符;你输入了55095
所以我把它放在这里:。我希望这段代码能帮助你更好地进行详细描述

更新2:我发现我的旧答案不适合搜索引擎。因此,我将
PEInfo.c
的代码部分(函数
DumpImports
DumpExports
)包括在下面:

void MakeIdent(UINT nOffset)
{
对于(;不偏移;不偏移--)
printf(“”;//4个空格
}
无效转储DWORD(UINT nOffset,LPCSTR pszPrefix,DWORD dw)
{
MakeIdent(无偏移);
如果(dw<100)
printf(“%s:%d\n”,pszPrefix,dw);
否则如果(dw%(256*256)==0)
printf(“%s:0x%X\n”,pszPrefix,dw);
其他的
printf(“%s:%d(0x%X)\n”),pszPrefix,dw,dw);
}
无效DumpTimeDateStamp(UINT nOffset、LPCSTR PSZTimeDateStampRefix、DWORD dwTimeDateStamp)
{
//struct tm tmTime;/=本地时间((time)和dwTimeDateStamp);
//errno_t err=localtime_s(&tmTime,((time_t*)&dwTimeDateStamp));
struct tm*ptmTime=\u localtime32((\u time32\u t*)和dwTimeDateStamp);
系统时间stSystemTime;
静态字符串[128];
stSystemTime.wYear=(WORD)(1900+ptmTime->tm_年);
stSystemTime.wMonth=(WORD)(ptmTime->tm_mon+1);
stSystemTime.wDay=(WORD)ptmTime->tmmday;
stSystemTime.wDayOfWeek=(WORD)(ptmTime->tm_wday+1);
stSystemTime.wHour=(WORD)ptmTime->tm\u小时;
stSystemTime.wMinute=(WORD)ptmTime->tm\u min;
stSystemTime.wssecond=(WORD)ptmTime->tm_sec;
stSystemTime.wmillseconds=0;
MakeIdent(无偏移);
printf(“%s:0x%8X”(,pszTimeDateStamprefix,dwTimeDateStamp);
if(GetDateFormatA)(语言环境\用户\默认值,0,&stSystemTime,NULL,
szString,sizeof(szString)/sizeof(TCHAR))!=0){
printf(szString);
}
if(GetTimeFormatA)(语言环境\用户\默认值,0,&stSystemTime,NULL,
szString,sizeof(szString)/sizeof(TCHAR))!=0){
如果(szString[0]!=0)
printf(“”);
printf(szString);
}
printf(“)\n”);
}
无效转储导入(UINT nOffset、图像\u可选\u头32*pOptionalHeader、PBYTE pbyFile、,
IMAGE\u SECTION\u HEADER*pssectionheader,IMAGE\u NT\u HEADERS32*pNtHeader)//包含导出节的节的头
{
图像导入描述符*pImportDescriptor=(图像导入描述符*)((PBYTE)pbyFile+pSectionHeader->PointerToRawData+
PoputionHeader->DataDirectory[图像\目录\条目\导入].VirtualAddress-pSectionHeader->VirtualAddress);
DWORD DWBONDIMPORTVA=pOptionalHeader->DATADORY[IMAGE\u DIRECTORY\u ENTRY\u BOUND\u IMPORT].VirtualAddress;
图像绑定导入描述符*pFirstBoundImportDescriptor=NULL,*pBoundImportDescriptor;
//DumpDword(不偏移,文本(“特征”),pImportDescriptor->Characteristics);
if(DWA){
UINT i;
IMAGE_SECTION_HEADER*pFirstSectionHeader=(IMAGE_SECTION_HEADER*)((PBYTE)pOptionalHeader+//sizeof(IMAGE_可选_HEADER32));
pNtHeader->FileHeader.SizeOfOptionalHeader);
对于(i=0;iFileHeader.NumberOfSections;i++){
if(pFirstSectionHeader[i].VirtualAddress=pNtHeader->FileHeader.NumberOfSections)
pFirstBoundImportDescriptor=(图像绑定导入描述符*)((PBYTE)pbyFile+dwBoundImportVA);
}
对于(;pImportDescriptor->Characteristics;pImportDescriptor++){
IMAGE\u THUNK\u DATA*pOriginalFirstThunk=(IMAGE\u THUNK\u DATA*)((PBYTE)pbyFile+pSectionHeader->指针或数据+
pImportDescriptor->OriginalFirstThunk-pSectionHeader->VirtualAddress);
IMAGE\u THUNK\u DATA*pFirstThunk=(IMAGE\u THUNK\u DATA*)((PBYTE)pbyFile+pSectionHeader->指针到数据+
pImportDescriptor->FirstThunk-pSectionHeader->VirtualAddress);
图像数据*pOriginalThunk,*pThunk;
MakeIdent(无偏移);
printf(“%s”,pbyFile+pSectionHeader->PointerToRawData+pImportDescriptor->Name-pSectionHeader->VirtualAddress);
//DumpDword(nOffset,TEXT(“序号基”),pExportDirectory->Base);
如果(pImportDescriptor->TimeDateStamp==0){
//MakeIdent(无偏移);
printf(“(DLL未绑定)\n”);
}
else if(pImportDescriptor->TimeDateStamp==-1){
//如果绑定,则为实时日期\时间戳
////在图像\目录\条目\绑定\导入(新绑定)
//MakeIdent(无偏移);
printf(“(与新绑定绑定的DLL)\n”);
}
否则{
//MakeIdent(无偏移);
printf(“(与旧绑定绑定的DLL)”;
DumpTimeDateStamp(无偏移,“TimeDateStamp”,pImportDescriptor->TimeDateStamp);
}
MakeIdent(无偏移+1);
if(pImportDescriptor->TimeDateStamp)