【qduwg原创2010-8-26】
研究WINNT.H里面的导入名表结构体_IMAGE_IMPORT_BY_NAME 时,发现一个问题,结构体成员Name数组竟然是1,但是实际上反汇编看到是一个不同长度的字符串。怎么实现的呢?很多人在网上提到如下说法,但没有深入分析为什么。这里就给出一个参考例子。说明怎么搭建那个名字表的。当然这个名字表都是由
typedef struct _IMAGE_THUNK_DATA32 {
union { PBYTE ForwarderString;
PDWORD Function;
DWORD Ordinal;
PIMAGE_IMPORT_BY_NAME AddressOfData;
} u1;
} IMAGE_THUNK_DATA32;
结构指向的。IMAGE_THUNK_DATA32则由struct _IMAGE_IMPORT_DESCRIPTOR
中的OriginalFirstThunk;指向。
typedef struct _IMAGE_IMPORT_BY_NAME {
WORD Hint;
BYTE Name[1];
} IMAGE_IMPORT_BY_NAME;
【网上的很多说法】其中Hint字段的内容是可选的,如果它不是0,则它也表示函数的序号,我们编程是不必考虑它。虽然上面的定义中Name数组只包含一个元素,但其实它是一个变长数组,保存的是一个以NULL结尾的字符串,也就是函数名。
该程序演示了创造变长数组的办法。必须用动态开辟内存办法实现。
必要声明成指针,然后在malloc的时候,根据iNum数目进行申请,譬如iNum为5个int,
这可以这样 p = (test *)malloc(sizeof(test) + (iNum - 1) * sizeof(int));
这样,后面的内容可以通过p->data[i]访问了.
#include<iostream>
using namespace std;
//#pragma pack(1)如果是设置了按字节填充,则后面int len1=sizeof(impname)+ strlen(s1)即可。
//否则需要减一。可以在各个元素之间用0隔开。
typedef struct IMPNAME
{
short int hint;//模拟函数序号
char name[1];//模拟函数名
} impname;
int main()
{
impname *p,*s[2];
char s1[ ]="add";
char s2[ ]="substruct";
char *q;
int len1=sizeof(impname)+ strlen(s1)-1;
int len2=sizeof(impname)+ strlen(s2)-1;
int l=len1+len2;
p=(impname*) malloc(l);
p->hint=0;
strcpy(p->name,s1);
cout<<p->hint<<endl;
cout<<p->name<<endl;
s[0]=p;
q=(char*)p; //指针类型变换,强制为单个字节的指针类型。可以按字节增加步长,否则按4的倍数增加,如p+x,实际上是p+4*x;
q=q+len1;
p=(impname*)q; //类型转换为原来的类型指向结构体的。
p->hint=1;
strcpy(p->name,s2);
cout<<p->hint<<endl;
cout<<p->name<<endl;
s[1]=p;
cout<<"------------------------------"<<endl;
cout<<"order="<<s[0]->hint<<endl;
cout<<"function name="<<s[0]->name<<endl;
cout<<"order="<<s[1]->hint<<endl;
cout<<"function name="<<s[1]->name<<endl;
return 0;
}