查看文章
 
WINNT.H内的_IMAGE_IMPORT_BY_NAME 变长数组示例
2010-08-26 16:29

【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;
}


类别:10暑假学习笔记| |分享到i贴吧|浏览(369)|评论 (0)
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
     

   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu