分享
 
 
 

windows下一些Structure定义(pe、IMAGE_IMPORT_DESCRIPTOR

王朝system·作者佚名  2006-04-28
窄屏简体版  字體: |||超大  

=================================

Structure of Import Symbols table

=================================

A portable executable (PE) file contains

IMAGE_NT_HEADERS

This struct's members are:

DWORD Signature

IMAGE_FILE_HEADER FileHeader

IMAGE_OPTIONAL_HEADER OptionalHeader// not really optional, fyi

Then the IMAGE_OPTIONAL_HEADER struct contains:

//

// Standard fields.

//

WORD Magic;

BYTE MajorLinkerVersion;

BYTE MinorLinkerVersion;

DWORD SizeOfCode;

DWORD SizeOfInitializedData;

DWORD SizeOfUninitializedData;

DWORD AddressOfEntryPoint;

DWORD BaseOfCode;

DWORD BaseOfData;

//

// NT additional fields.

//

DWORD ImageBase;

DWORD SectionAlignment;

DWORD FileAlignment;

WORD MajorOperatingSystemVersion;

WORD MinorOperatingSystemVersion;

WORD MajorImageVersion;

WORD MinorImageVersion;

WORD MajorSubsystemVersion;

WORD MinorSubsystemVersion;

DWORD Reserved1;

DWORD SizeOfImage;

DWORD SizeOfHeaders;

DWORD CheckSum;

WORD Subsystem;

WORD DllCharacteristics;

DWORD SizeOfStackReserve;

DWORD SizeOfStackCommit;

DWORD SizeOfHeapReserve;

DWORD SizeOfHeapCommit;

DWORD LoaderFlags;

DWORD NumberOfRvaAndSizes;

IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

Then the DataDirectory array :

0'th member:Export Symbols

1'st member:Import Symbols

2'nd member:Resources

...

11'th member:Bound Import

12'th member:Import Address Table

...

The IMAGE_DATA_DIRECTORY struct consists of two fields:

DWORD VirtualAddress;// the RVA of the data structure

DWORD Size;// the size of the data structure

Then if we have a PE that imports two modules, we'll have:

(1) one IMAGE_DATA_DIRECTORY structure for Import Symbols

(2) let's say that struct's VirtualAddress is 0xc7d8 -- recall this is an RVA

(3) then 0xc7d8 is where the first IMAGE_IMPORT_DESCRIPTOR lives

(4) since we are importing two modules, there will be 3 IMAGE_IMPORT_DESCRIPTOR

structs in our array (which starts at 0xc7d8, recall)

--> the 3rd IMAGE_IMPORT_DESCRIPTOR is all zeroes

(5) then the Size field above (for this IMAGE_DATA_DIRECTORY) will be 3 *

sizeof( IMAGE_IMPORT_DESCRIPTOR )

The IMAGE_IMPORT_DESCRIPTOR struct consists of five fields :

Union {

DWORD Characteristics;

PIMAGE_THUNK_DATA OriginalFirstThunk;

};

DWORD TimeDateStamp;

DWORD ForwarderChain;

DWORD Name;

PIMAGE_THUNK_DATA FirstThunk;

--> Each of these fields is 4 bytes long so sizeof( IMAGE_IMPORT_DESCRIPTOR ) is

20 bytes == 0x1C

--> So the Size field will be 60 bytes == 0x3C

Now let's examine the contents of the Import Symbols table; recall that this table

is -- in this case -- an array of 3 IMAGE_IMPORT_DESCRIPTOR structs.

Now here are some potential values for the fields:

-------------------------------------

// 3rd IMAGE_IMPORT_DESCRIPTOR struct

-------------------------------------

0xc810FirstThunk:0

0xc80cName:0

0xc808ForwarderChain:0

0xc804TimeDateStamp:0

0xc800OriginalFirstThunk:0

-------------------------------------

// 2nd IMAGE_IMPORT_DESCRIPTOR struct

-------------------------------------

0xc7fcFirstThunk:0x8000

0xc7f8Name:0xc398 (the RVA of the name of this module)

0xc7f4ForwarderChain:0

0xc7f0TimeDateStamp:0

0xc7ecOriginalFirstThunk:0xc084

-------------------------------------

// 1st IMAGE_IMPORT_DESCRIPTOR struct

-------------------------------------

0xc7e8FirstThunk:0xc178

0xc7e4Name:0xc2c0 (the RVA of the name of this module)

0xc7e0ForwarderChain:0

0xc7dcTimeDateStamp:0

0xc7d8OriginalFirstThunk:0xc030

All addresses are RVAs.

------------------------------

Now at locations (from above):

------------------------------

0xc2c0contains"MSVCR80.DLL"

0xc398contains"KERNEL32.DLL"

Now OriginalFirstThunk points to the Import Name Table for the module and

FirstThunk points to the Import Address Table for the module.

Each of these two tables (Import Name and Import Address) consist of an

array of IMAGE_THUNK_DATA structs. An IMAGE_THUNK_DATA struct consists of:

Union {

PBYTE ForwarderString;

PDWORD Function;

DWORD Ordinal;

PIMAGE_IMPORT_BY_NAME AddressOfData;

};

In our case the Union member "AddressOfData" will be the member used for

each struct in these two tables. This value (AddressOfData) contains the

RVA for an IMAGE_IMPORT_BY_NAME struct. The contents of an IMAGE_IMPORT_NAME

struct are :

WORD Hint;// recall that WORDs are two bytes each

BYTE Name[1]; // this is NOT really 1 byte long; This is a variable-sized field

For the PE -- before it's loaded -- the Import Name Table and the Import Address

Table are merely two copies of the same table. For example let's say we're

importing twenty or so symbols from MSVCR80.dll then our Import Name Table starts

at 0xc030 (OriginalFirstThunk address above) and our Import Address Table starts

at 0xc178 (FirstThunk address above).

-------------------------------------

So we might have something like this:

-------------------------------------

------------------------------------

// Import Name Table for MSVCR80.dll

------------------------------------

0xc080AddressOfData:0// null terminate table

...

0xc044AddressOfData:0xc300

0xc040AddressOfData:0xc2f8

0xc03cAddressOfData:0xc2ea

0xc038AddressOfData:0xc2e0

0xc034AddressOfData:0xc2d8

0xc030AddressOfData:0xc2cc

---------------------------------------

// Import Address Table for MSVCR80.dll

---------------------------------------

0xc1c8AddressOfData:0// null terminate table

...

0xc18cAddressOfData:0xc300

0xc188AddressOfData:0xc2f8

0xc184AddressOfData:0xc2ea

0xc180AddressOfData:0xc2e0

0xc17cAddressOfData:0xc2d8

0xc178AddressOfData:0xc2cc

Note that the AddressOfData values don't increase by a fixed amount; that's

because the data contained at those addresses is variable length. So what

is the data contained at those addresses?

Starting at 0xc2cc is an array of IMAGE_IMPORT_BY_NAME structs. Each such

struct contains the name of a function (imported by this module which in

this case is MSVCR80.DLL) as well as a "Hint" for this function.

---------------------------------------------------------------------

Continuing the above example, we have the following values in memory:

---------------------------------------------------------------------

...

0xc3122-byte hint for mbstowcs

0xc308"mbstowcs"// null-terminated is 9 bytes long

0xc3062-byte hint for fopen

0xc300"fopen"// null-terminated is 6 bytes long

0xc2fe2-byte hint for atoi

0xc2f8"atoi"// null-terminated is 5 bytes long

0xc2f62-byte hint for _vsnprintf

0xc2ea"_vsnprintf"// null-terminated is 11 bytes long

0xc2e82-byte hint for _strdup

0xc2e0"_strdup"// null-terminated is 8 bytes long

0xc2de2-byte hint for _open

0xc2d8"_open"// null-terminated is 6 bytes long

0xc2d62-byte hint for _memccpy

0xc2cc"_memccpy"// null-terminated is 9 bytes long

0xc2c0"MSVCR80.DLL"// null-terminated is 12 bytes long

So now you see what the AddressOfData values -- contained in the Import Name

Table and the Import Address Table -- refer to. One small detail, when the

null-terminated name of a function is an odd number, then an extra byte must

be added to the name so that the WORD hint field starts on a WORD-aligned

boundary. This is why, for example, the size of the IMAGE_IMPORT_BY_NAME

struct for _memccpy is 12 bytes even though null-terminated "_memccpy" is

9 bytes and the WORD hint adds 2 bytes (total of 11 bytes); that extra byte

is to align the hint on a WORD boundary.

===============================================

So why do we have two copies of the same table?

===============================================

Perceptive question, Watson!

These two tables are used by the PE loader to map the function names to

addresses when loading the PE. Since we don't know at compile time WHERE

the various functions will exist in the address space (since these functions

are part of DLLs), the loader does that resolution for us. In particular

the loader will replace each entry in the Import Address Table (IAT) with

the actual address of the function.

For example, the first entry in the MSVCR80.DLL IAT is 0xc2cc and that

corresponds to "_memccpy". Usually MSVCR80.DLL loads at address 0x00360000,

i.e. that's the base address for this DLL. Moreover the RVA for _memccpy

is 0x49F10. Therefore if MSVCR80.dll is loaded in its usual spot then

the value stored at 0xc178 (which is originally 0xc2cc) will be changed

to ( 0x00360000 + 0x49F10 ) == 0x003a9f10 since that's the address where

the _memccpy code lives in memory at the time this PE is loaded.

Note that because we have *two* copies of this same initial table, after

we replace 0xc2cc in the IAT with the address for _memccpy (as above),

if for any reason we need to go in the other direction (i.e. to know

which function that address corresponds to) we can consult the Import

Name Table at 0xc030 which still contains the RVA 0xc2cc and see that

"_memccpy" is the function for this resolved address.

===========================

From : C:/lcc/include/win.h

===========================

//

// there's one IMAGE_IMPORT_DESCRIPTOR for every DLL that the PE uses

//

typedef struct _IMAGE_IMPORT_DESCRIPTOR {

union {

DWORD Characteristics;

// points to Import Name Table (INT)

// contains RVA of an array of IMAGE_THUNK_DATA structs

PIMAGE_THUNK_DATA OriginalFirstThunk;

} ;

DWORD TimeDateStamp;

DWORD ForwarderChain;

DWORD Name;// e.g. "USER32.dll"

PIMAGE_THUNK_DATA FirstThunk;// points to IAT

} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;

//

// the IAT is an array of IMAGE_THUNK_DATA structs

//

typedef struct _IMAGE_THUNK_DATA {

union {// is one of the following 4 things

PBYTE ForwarderString;// 4 bytes

PDWORD Function;// 4 bytes

DWORD Ordinal;// 4 bytes

// ------------- is usually this ------------- \PIMAGE_IMPORT_BY_NAME AddressOfData; // 4 bytes

} ;

} IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA;

//

// as above, usually we interpret an IMAGE_THUNK_DATA struct as a POINTER to an :

// "IMAGE_IMPORT_BY_NAME" struct

//

typedef struct _IMAGE_IMPORT_BY_NAME {

WORD Hint;// 2 bytes

// contaisn index into the export table of the DLL

// from which we get (import) this function

BYTE Name[1];// 1 byte; contains name of the import function

// is an ASCIIZ string

} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有