7.ida-creating a struct body

Source: Internet
Author: User
Tags arithmetic data structures manual numeric require
classification of structural bodies

A notable feature of structs is that data fields in structs are accessed by name rather than indexed as arrays. The bad thing is that the field name is converted to a numeric offset by the compiler. As a result, the way the struct fields are accessed in the Disassembly code list looks very similar to the way you access array elements using a constant index.

Note that there is a memory alignment rule in the struct, so do not assume that the compiler will use the minimum space required to allocate the struct. By default, the compiler will try to align the struct field with the memory address to most efficiently read and write these fields 1. Globally allocated structure

As with the globally allocated array, the compiler learns the address of the globally allocated struct at compile time. This allows the compiler to calculate the address of each member in the struct at compile time without having to perform any calculations at run time.

The following code:

struct sttest
{
	int    F1;
	Short  F2;
	Char   f3;
	int    f4;
	Double f5;
};
Sttest G_st;
void Fun ()
{
	g_st.f1 = ten;
	G_ST.F2 =;
	G_ST.F3 = +;
	G_ST.F4 = +;
	G_st.f5 = 50.0;
}

The corresponding assembly is: it can be seen that in this disassembly code list, access to struct members does not require any arithmetic calculations, if there is no source code, you simply cannot conclude that the program uses the structure.

Push    EBP
mov     EBP, esp
mov     dword_403018, ten; int f1 = ten
mov     eax,
mov     word_ 40301C, Ax; Word F2 = "
mov     byte_40301e", "byte" = "F3" = "
mov     dword_403020", "int f4 =     " FLD Ds:dbl _4020e0   ; f5 = dbl_403028 = 50.0
fstp    dbl_403028
pop     ebp
retn

2. Stack allocation structure

Similarly, it is also difficult to identify the structure of a stack allocation based solely on the stack layout.

void Fun ()
{
	sttest l_st;
	L_ST.F1 = ten;
	L_ST.F2 =;
	L_ST.F3 = +;
	L_ST.F4 = +;
	L_st.f5 = 50.0;
}

The corresponding assembly is: Similarly, accessing a field in a struct does not require any arithmetic calculations, because at compile time, the compiler is able to determine the relative offset of each field within the stack frame

$ push    EBP
004 mov     EBP, esp
004 Sub     ESP, 18h
01C mov     [ebp+var_18],
01C mov     eax, 14h
01C mov     [ebp+var_14], ax
01C mov     [Ebp+var_12],
01C mov     [ebp+var_
01C fld     ds:dbl_4020e0
01C fstp    [ebp+var_8]
01C mov     ESP, EBP
004 Pop     EBP
RETN
3. Structure of the heap allocation

Because the address of the struct is not known at compile time, the compiler has no choice but to generate code to calculate the correct offset for each field in the struct.

If a struct is allocated in the heap, the only clue to the compiler that references the struct is a pointer to the start address of the struct.

void Fun ()
{
	sttest* PST = new Sttest;
	PST->F1 = ten;
	PST->F2 =;
	PST->F3 = +;
	Pst->f4 = +;
	Pst->f5 = 50.0;
}

The corresponding assembly is:

Push    EBP
mov     EBP, esp
Sub     ESP, 8
push    ,              unsigned int call    ?? 2@yapaxi@z    ; operator new (UINT)
add     ESP, 4
mov     [ebp+var_8], eax; EAX as PST pointer, Var_8 is also
mov     eax, [ebp+var_8]
mov     [ebp+var_4], eax
mov     ecx, [ebp+var_4]; ecx = PST
mov     DWORD ptr [ECX], 10; (int*) PST = ten
mov     edx, a
mov     eax, [ebp+var_4]; eax = PST
mov     [eax+4], DX     ; (word*) (pst+4) =
a mov     ecx, [ebp+var_4]; ecx = PST
mov     byte ptr [ecx+6], 30; (byte*) (pst+6) = 30, verified that the second is word byte
mov     edx, [ebp+var_4]; edx = PST
mov     dword ptr [edx+8], 40; (int*) (pst+8) =
EAX mov     , [ebp+var_4]; eax = PST
fld ds:dbl_4020f0     fstp    qword ptr [eax+10h]; (DQ) (pst+16) =50.0
mov     ESP, ebp
pop     ebp
retn
4. Structure Array
void Fun ()
{
	sttest* PST = new sttest[2];
	PST[1].F1 = ten;
	PST[1].F2 =;
	PST[1].F3 = +;
	PST[1].F4 = +;
	Pst[1].f5 = 50.0;
}

Disassembly is no different: compared with the above, each item adds 24

Push    EBP
mov     EBP, esp
Sub     ESP, 8
push              ; 48/2 = Call    ?? 2@yapaxi@z    ; operator new (UINT)
add     ESP, 4
mov     [ebp+var_8], eax
mov     eax, [ebp+ Var_8]
mov     [ebp+var_4], eax
mov     ecx, [ebp+var_4]
mov     dword ptr [ecx+24], ten; pst+24, note +24
mov     edx,
eax mov     , [ebp+var_4]
mov     [eax+1ch], DX
mov     ecx, [ebp+var_4 ]
mov     byte ptr [ecx+30], pst+24+6
mov     edx, [ebp+var_4]
mov     dword ptr [edx+32], Max; PS T+24+8
mov     eax, [ebp+var_4]
fld     ds:dbl_4020f0
fstp    qword ptr [eax+40]; pst+14+16
mov     ESP, ebp
pop     ebp
retn

Create a struct body

Ida's inability to identify structures in the analysis phase can be attributed to two reasons. First, although Ida understands the layout of a struct, it does not have enough information to judge that the program actually uses the struct. Second, the structure of the program may be a non-standard structure that Ida knows nothing about. In both cases, the problem can be resolved, starting with the Structures window 1. Add struct

The first 4 lines of text in the Structures window are used to alert the user to possible actions in that window.

Use hotkey INSERT to start

When you specify the name of the struct and click the OK button, Ida creates an empty struct definition in the structures window

2. Edit struct Members

(1) To add a new field to the struct, place the cursor on the last line defined by the struct (the row containing the ends) and press the D key. The size of the new field depends on the first size you select on the data carousel

(2) If you need to modify the size of the field, first place the cursor on the name of the new field, and then press the D key repeatedly to start the data type on the data carousel Loop, so that the correct data size is selected for the new field. Alternatively, you can use Options▶setup data types to specify a size that does not exist on the data carousel. If the new field is an array, right-click its name and select array from the context menu

(3) To change the name of a struct field, click the field name and press the N key, or right-click the name and select Rename in the context menu and enter a name in the input box.

Here are the help instructions:

• The byte offset of a field is displayed on the left side of the structures window.

• The new size of the structure is updated in a timely manner on the first line of the structure definition.

• You can add comments to a struct field just as you would add a comment to any disassembly line.

• Use the U key to delete a field only if it is the last field in the struct. For other fields, pressing the U key just becomes undefined and can be restored by the D key

Ida does not differentiate between compressed and uncompressed structures. To align the fields appropriately, if you need to fill in the bytes, then you have to be responsible for adding those bytes. The padding byte is best added as a dummy field of the appropriate size. After you add additional fields, you can choose to cancel or retain the definitions for those fields.

• The bytes assigned to the middle of the struct can delete the undefined byte only after the definition of the associated field is canceled (the state of the struct), and the Edit▶shrink struct type (which shrinks the structure).

• You can also add a new byte in the middle of the struct: Select a field after the new byte, and then insert a certain number of bytes in front of the selected field using the Edit▶expand struct type, which expands the struct types.

• If you know the size of a struct without knowing its layout, you need to create two fields. The first field is an array whose size subtracts 1 bytes (size-1) from the size of the structure, and the second field should be 1 bytes. After you create the second field, the definition of the first (array) field is canceled. In this way, the size of the struct is preserved, and then, after you have a closer look at the structure's layout, you can go back and define its field and its size.

After creation is complete as follows:

3. Collapse Open Structure

You can select any field in the structure and press the minus key in the numeric keypad to collapse the definition of the structure into a single line of summaries, or you can double-click the struct name to open the definition. (or ctrl+/ctrl-)

working with structural body templates

1. Right-click, you can see the structure offset option on the context menu: it is clearly stated that it can be sttest.f5+24 (pst[1].f5 = 50.0;)

2. Another way, you can format stacks and global variables into the entire structure, double-click the variable, open the detailed stack frame view, and then use the Edit▶struct Var (alt+q) command to display a set of known structures

After the assembly of the above structure becomes: After reformatting, Ida realizes that any memory reference to the 24-byte block allocated to Var_8 must refer to a field in that struct. If Ida finds such a reference, it makes every effort to associate the memory reference with a defined field in the struct variable

var_8= sttest ptr-8

push    ebp
mov     EBP, esp
Sub     ESP, 8
push    ,              unsigned int
Call    ?? 2@yapaxi@z    ; operator new (UINT)
add     ESP, 4
mov     [ebp+var_8.f1], eax
mov     eax, [EBP +VAR_8.F1]
mov     dword ptr [EBP+VAR_8.F2], eax
mov     ecx, DWORD ptr [EBP+VAR_8.F2]
mov     DWORD ptr [ecx+ (size sttest)], ten
mov     edx,
mov     eax, DWORD ptr [EBP+VAR_8.F2]
mov     [eax +1CH], DX
mov     ecx, DWORD ptr [EBP+VAR_8.F2]
mov     byte ptr [ecx+30], the
mov     edx, DWORD ptr [ EBP+VAR_8.F2]
mov     [edx+ (sttest.f4+18h)], +
mov     eax, DWORD ptr [EBP+VAR_8.F2]
fld     ds :d bl_4020f0
FSTP    [eax+ (sttest.f5+18h)]
mov     ESP, ebp
pop     ebp
retn

The process of formatting a global variable into a struct is almost identical to the process used to format the stack variable to import a new struct

Ida does offer some shortcuts in creating new structures. Ida is able to parse C (rather than C + +) data declarations, as well as the entire C header file, and automatically create the corresponding Ida struct for the struct defined in those declarations or header files. If you happen to have the source code of the binary file you are reversing, or at least a header file, you can save a lot of time by allowing Ida to extract the relevant struct directly from the source code.

Using the View▶open subviews▶local Types (see ▶ Open Subwindow ▶ Local type) command, you can open the local Types subwindow, which lists all the types resolved to the current database.

Resolve by using the Insert option in the Insert key or the context menu:

------------->

parsing C header file

To parse the header file, you can use File▶load file▶parse C headerfile (▶ Load File ▶ Parse C header file) to select the header file you want to parse. If everything is OK, Ida will notify you compilation successful (compile complete). If the parser encounters any problems, IDA will display an error message in the Output window

Ida adds all successfully parsed structures to the list of standard structures in the current database (specifically, at the end of the list). If the name of the new struct is the same as the name of an existing struct, Ida overrides the original structure definition with the new struct layout. Unless you explicitly choose to add a new struct, the new struct will not appear in the Structures window

• By default, the parser creates a 4-byte aligned struct, and of course you can change it using pack

• The parser can only understand the C standard data type. However, the parser can also understand preprocessor define directives and C typedef statements. Therefore, if the parser has encountered the appropriate typedef before, it will be able to correctly parse types such as unit32_t.

• If you do not have source code, then you will find that using a text editor to quickly define a struct layout in C notation and parse the resulting header file or paste the declaration into a new local type is more convenient than using IDA's cumbersome manual structure definition tool.

The simplest way to add data types to the local Types window is not immediately in structures (struct), right-click on the type and select Synchronize to IDB. use of standard structural bodies

Ida is able to identify a large number of data structures related to various libraries and API functions. When Ida manipulates a struct in the Disassembly code list, it adds the corresponding struct definition in the structures window. Therefore, the structures window displays a subset of the known structures that are applied to the current binary. In addition to creating a custom structure, you can also extract other standard structures from the list of known struct bodies in Ida and add them to the structures window.

First, press the In-sert key in the Structures window. In the Create Structure/union dialog box, there is an Add standard structure (add normal structure) button. By clicking this button, IDA will display the structure master list associated with the current compiler (detected in the analysis phase) and the file format. The structure master list also contains structures that are added to the database by parsing the C header file.

Example: (Parsing file header)

By default, the file header is not immediately loaded into the database after it is created. However, if you select the manual load (manual load) option when you initially create the database, you can load the file header into the database. Loading a file header ensures that only the data types associated with these headers appear in the database. In most cases, file headers are not formatted in any way, because the program does not normally refer to their own header directly. Therefore, it is not necessary for the parser to apply a struct template to the file header.

After a study of a PE binary file, you will find that the first part of the PE file is an MS-DOS header structure named Image_dos_header. In addition, the data in the Image_dos_header points to the location of a im-age_ne_header struct.

The first step is to add a standard image_dos_header struct (you can add the struct at the same time you open the Image_nt_header structure).

The second step is to use Edit▶struct Var (alt+q) to convert bytes starting from _image-base to a image_dos_header struct



 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.