You can use IDA to interactively define and manipulate structures in the disassembly.
Sample program
Consider this simple sample C program:
Copy #include <stdio.h>
struct client {
char code;
long id;
char name[32];
client *next;
};
void print_clients(client *ptr) {
while ( ptr != NULL ) {
printf("ID: %4ld Name: %-32s\n",ptr->id,ptr->name);
ptr = ptr->next;
}
}
Standard disassembly
Here is the disassembly with no structures defined, as IDA automatically generates it:
Copy .text:0000000180011690 ; void __fastcall print_clients(client *ptr)
.text:0000000180011690 ?print_clients@@YAXPEAUclient@@@Z proc near
.text:0000000180011690 ; CODE XREF: print_clients(client *)↑j
.text:0000000180011690 ; DATA XREF: .pdata:000000018001E800↓o
.text:0000000180011690
.text:0000000180011690 ptr = qword ptr 10h
.text:0000000180011690
.text:0000000180011690 mov [rsp-8+ptr], rcx
.text:0000000180011695 push rbp
.text:0000000180011696 push rdi
.text:0000000180011697 sub rsp, 0E8h
.text:000000018001169E lea rbp, [rsp+20h]
.text:00000001800116A3 lea rcx, __57CB66E6_entry@cpp ; JMC_flag
.text:00000001800116AA call j___CheckForDebuggerJustMyCode
.text:00000001800116AA
.text:00000001800116AF
.text:00000001800116AF loc_1800116AF: ; CODE XREF: print_clients(client *)+5F↓j
.text:00000001800116AF cmp [rbp+0D0h+ptr], 0
.text:00000001800116B7 jz short loc_1800116F1
.text:00000001800116B7
.text:00000001800116B9 mov rax, [rbp+0D0h+ptr]
.text:00000001800116C0 add rax, 8
.text:00000001800116C4 mov r8, rax
.text:00000001800116C7 mov rax, [rbp+0D0h+ptr]
.text:00000001800116CE mov edx, [rax+4]
.text:00000001800116D1 lea rcx, _Format ; "ID: %4ld Name: %-32s\n"
.text:00000001800116D8 call j_printf
.text:00000001800116D8
.text:00000001800116DD mov rax, [rbp+0D0h+ptr]
.text:00000001800116E4 mov rax, [rax+28h]
.text:00000001800116E8 mov [rbp+0D0h+ptr], rax
.text:00000001800116EF jmp short loc_1800116AF
.text:00000001800116EF
.text:00000001800116F1 ; ---------------------------------------------------------------------------
.text:00000001800116F1
.text:00000001800116F1 loc_1800116F1: ; CODE XREF: print_clients(client *)+27↑j
.text:00000001800116F1 lea rsp, [rbp+0C8h]
.text:00000001800116F8 pop rdi
.text:00000001800116F9 pop rbp
.text:00000001800116FA retn
.text:00000001800116FA
.text:00000001800116FA ?print_clients@@YAXPEAUclient@@@Z endp
Defining structures
In order to use meaningful names instead of numbers, we open the local types window and press insert to define a new structure type. Structure members can be added with the D key for data and the A key for ASCII strings or by editing the structure (Alt-E) and adding members using the "C syntax" of the "Edit type" dialog box. When the first method is used, when we add new structure members, IDA automatically names them. You can change any member’s name by pressing N.
Copy struct client
{
char code;
int id;
char name[32];
client *next;
};
Improved disassembly
Finally, the defined structure type can be used to specify the type of an instruction operand. (menu Edit|Operand types|Struct offset).
Copy .text:0000000180011690 ; void __fastcall print_clients(client *ptr)
.text:0000000180011690 ?print_clients@@YAXPEAUclient@@@Z proc near
.text:0000000180011690 ; CODE XREF: print_clients(client *)↑j
.text:0000000180011690 ; DATA XREF: .pdata:000000018001E800↓o
.text:0000000180011690
.text:0000000180011690 ptr = qword ptr 10h
.text:0000000180011690
.text:0000000180011690 mov [rsp-8+ptr], rcx
.text:0000000180011695 push rbp
.text:0000000180011696 push rdi
.text:0000000180011697 sub rsp, 0E8h
.text:000000018001169E lea rbp, [rsp+20h]
.text:00000001800116A3 lea rcx, __57CB66E6_entry@cpp ; JMC_flag
.text:00000001800116AA call j___CheckForDebuggerJustMyCode
.text:00000001800116AA
.text:00000001800116AF
.text:00000001800116AF loc_1800116AF: ; CODE XREF: print_clients(client *)+5F↓j
.text:00000001800116AF cmp [rbp+0D0h+ptr], 0
.text:00000001800116B7 jz short loc_1800116F1
.text:00000001800116B7
.text:00000001800116B9 mov rax, [rbp+0D0h+ptr]
.text:00000001800116C0 add rax, 8
.text:00000001800116C4 mov r8, rax
.text:00000001800116C7 mov rax, [rbp+0D0h+ptr]
.text:00000001800116CE mov edx, [rax+client.id]
.text:00000001800116D1 lea rcx, _Format ; "ID: %4ld Name: %-32s\n"
.text:00000001800116D8 call j_printf
.text:00000001800116D8
.text:00000001800116DD mov rax, [rbp+0D0h+ptr]
.text:00000001800116E4 mov rax, [rax+client.next]
.text:00000001800116E8 mov [rbp+0D0h+ptr], rax
.text:00000001800116EF jmp short loc_1800116AF
.text:00000001800116EF
.text:00000001800116F1 ; ---------------------------------------------------------------------------
.text:00000001800116F1
.text:00000001800116F1 loc_1800116F1: ; CODE XREF: print_clients(client *)+27↑j
.text:00000001800116F1 lea rsp, [rbp+0C8h]
.text:00000001800116F8 pop rdi
.text:00000001800116F9 pop rbp
.text:00000001800116FA retn
.text:00000001800116FA
.text:00000001800116FA ?print_clients@@YAXPEAUclient@@@Z endp