Coff format continues to the structure of theLIB file

zhaozj2021-02-11  198

Previous article introduces the structure of the COFF target file. If you try to be a connection to a connection, you will find that there is not enough to operate. When we connect programs, we must not only use target files, and library files are essential.

What is the structure of the library file?

In fact, the structure of the library file is also very simple. It is a collection of "a bunch" target file. After making the target file into the library, we will automatically find the corresponding target file in the library file when using the functions implemented in the target file, and use it. This greatly reduces our management of the target documents, reducing the burden on code reuse.

Festival in the lib file

The concept of "section" used in the COFF format appears in the lib format. However, the section of the lib file is much simpler. Let's take a look at its overall structure:

As shown in the right: The lib format has only four types of sections, namely First Sec, Second Sec, LongName Sec, and Obj Sec; where Second Sec, longname sec is optional, many lib files are not available. The starting Singature is just a logo, which is equivalent to the magic number in the COFF target file. It is a string of length 8, the value is "! / n". First Sec, as the name suggests, the first section. It contains all the symbols in the library and the location of the target files in the library (absolute offset) in the library. Second sec is the second section. Its content is the same as FIRST SEC. Different, Second Second Seconds are a sequence table that looks out that the symbols in the library look for a lot faster than through First Sec.

SignatureFirst Secsecond SeclongName Secobj Sec1Obj Sec2 ......

LongName Sec is a long name. This section is a string table. It contains all long target file names. If there is no corresponding target file name in the later OBJ SEC, we have to find it in this section.

Obj SEC is the target file section. The original data of different target files is stored in these sections.

In the library file, there are two parts in each section. One part is the head, and the other part is the data of the section; the data is followed behind the head. The header describes the type, length, etc. of the data. The format of these headers is the same. Its structure is described as follows:

Typedef struct {

Char name [16]; // Name

Char Time [12]; // Time

Char userid [6]; // User ID

Char groupid [6]; // Group ID

Char mode [8]; // mode

CHAR SIZE [10]; // Length

Char endofheader [2]; // end

SectionHeader;

It can be seen that the data in the head is all string. The advantage of using a string is to improve the compatibility of the format because the arrangement of data is different on different machines. Some machines are working in Little-Endian, and some work in a Big-endian method, they are not compatible with each other (the difference between these two ways !? Please look at my "Coff format", where there are Description). There will be this problem with a string (later we will encounter). But it is also inconvenient, it is necessary to convert a string into a value, more steps.

In this structure, three members of Name, Size, and Endofheader are most common. Name is the name of the section! SIZE is also very well understood, the length of the data. What should I pay attention to now is this Endofheader member! This member marks the end of the head, its content is "` / n "(note that there is no wrong, two characters" `" and "/ n"). how about it? Is it a bit strange? Why have this ending? The length of each section must be determined, and the data length in each section also knows. Don't you read down in order? The answer is: no! Because there is a gap between each section! Usually a byte or zero-byte. If it is a zero-byte, it is OK to read down according to the order. But if it is not zero, I have to be misplaced. You must know that the misplaced is not, you have to locate it with an end. If the end is not right at the read head, you will find a byte by one byte until you find the end character, you can be aligned. Remember! Remember! Of course, this problem does not exist by the offset given in First Second SEC. Will not happen, rest assured to read!

Let us now look at what data in each section looks like.

First Sec

In the first section, it is usually every section in the lib. Its name is "/". The structure of its data part is as follows:

Typedef struct {

Unsigned long symbolnum; // The number of symbols in the library

Unsigned long symboloffset [n]; // The offset of the target section of the symbol

Char strtable [m]; // Symbol name string table

FigSTsec;

The first member Symbolnum is the number of symbols. note! It is stored in Big-endian mode (the data on the X86 platform is stored in Little-Endian mode. Here you should pay attention to the conversion. The CONVERT function later can be mutually mutually mutually Conversion).

The second member Symboloffset is an array, and its length n is the number of symbols, that is, Symbolnum. This array stores the offset of the target section where each symbol is located. We can easily find the target file where the symbol is located. note! It is also stored in Big-endian format.

The third member strable is a string table, and its length m is the value of sectionHeader.size (Symbolnum 1) * 4. Its structure is simple, that is, a bunch of strings ending with '/ 0' (the same as the string table structure in the COFF file). In some systems, it may also be a collection of strings ending with two characters of "// n".

A simple structure, but there are two lengths of the length of the two members. How can I easily read these data from the lib, leave it to everyone, think it is! Below I only give a function that performs Little-Endian and BIG-Endian interactions.

Inline Void Convert (Void * p // Pointer to convert data

, size_t size = 4 // data length, long is 4, Short is 2

) {

Char * buf = (char *) P;

CHAR TEMP;

For (SIZE_T I = 0; I

Temp = BUF [I];

BUF [I] = BUF [Size-I-1];

BUF [SIZE-I-1] = TEMP;

}

}

SECOND Second now looks at the second section.

This section is very similar to the first quarter! It is usually the second section of the lib file. Its name is also "/" (Note: The first section called "/" in the file is the first section, the second is the second section). However, its structure is different from the first quarter, as follows:

Typedef struct {

Number of unsigned long objnum; // Obj sec

Unsigned long objoffset [x]; // Each OBJ SEC offset

Unsigned long symbolnum; // The number of symbols in the library

Unsigned short symbolidx [n]; / / Symbol in the index in the Objoffset table

Char strtable [m]; // Symbol name string table

Secondsec;

The first member Objnum is the number of OBJ SEC in the library.

The second member Objoffset is an offset table that records the offset of all OBJ SEC in the library. The number of records in this table is Objnum.

The third member Symbolnum is the same as the Symbolnum meaning in First Sec.

The fourth member Symbolidx has become an index that records the corresponding name string in the Objoffset table, we have to find the OBJ SEC position we want to symbol through two indexes. The number of projects is Symbolnum. However, please note that this index is a unsigned short type, no longer a unsigned long.

The fifth member of the STRTABLE structure is the same as in First Sec. However, its length m is reduced by the value of sectionheader.size ((ObjNum 1) * 4 (Symbolnum 2) * 2).

It is worth noting that all the data here is Little-Endian format. Don't make a mistake!

LongName Sec

This section is a string table, its name is "//", its structure with firstsec.strtable. Not much here.

Obj Sec

The data in this section is the original data of the COFF file, and read it out of the file, is a COFF file. For its format, please refer to the article "COFF format".

It is to point out that its naming method is somewhat special. If the name of the OBJ file is less than 16 characters, it will be saved in the Name member of SectionHeader, ending with '/' characters. If you cannot save in the Name member, the first character of the Name member is '/', followed by following this name in longname sec.

E.g:

/ N

......

Longname Sec:

THIS_IS_LONG_NAME0001 / 0

THIS_IS_LONG_NAME0002 / 0

......

Obj Sec1:

Name [16]: "ShortName /"

......

Obj Sec2:

Name [16]: "/ 0" // This uses the first long file name this_is_long_name0001

......

Obj Sec3:

Name [16]: "/ 22" // Use the second long file name this_is_long_name0002

......

OK! It has now introduced the structure of the lib file. Everyone's connector can add new features. However, here only give the most basic lib file structure, the export library of the dynamic connection library (DLL) is a bit special, I will introduce in the PE file format.

转载请注明原文地址:https://www.9cbs.com/read-5679.html

New Post(0)