nichow
nichow

Reputation: 49

GAS x86: Reading a jump table / interpreting a switch statement

I'm trying to reverse engineer some assembly, and I've gotten to this point:

40073f: 89 45 fc                mov    %eax,-0x4(%rbp)
  400742:   83 7d fc 05             cmpl   $0x5,-0x4(%rbp)
  400746:   77 37                   ja     40077f <f51+0x85>
  400748:   8b 45 fc                mov    -0x4(%rbp),%eax
  40074b:   48 8b 04 c5 28 09 40    mov    0x400928(,%rax,8),%rax
  400752:   00 
  400753:   ff e0                   jmpq   *%rax
  400755:   b8 11 00 00 00          mov    $0x11,%eax
  40075a:   eb 28                   jmp    400784 <f51+0x8a>
  40075c:   b8 12 00 00 00          mov    $0x12,%eax
  400761:   eb 21                   jmp    400784 <f51+0x8a>
  400763:   b8 13 00 00 00          mov    $0x13,%eax
  400768:   eb 1a                   jmp    400784 <f51+0x8a>
  40076a:   b8 14 00 00 00          mov    $0x14,%eax
  40076f:   eb 13                   jmp    400784 <f51+0x8a>
  400771:   b8 15 00 00 00          mov    $0x15,%eax
  400776:   eb 0c                   jmp    400784 <f51+0x8a>
  400778:   b8 16 00 00 00          mov    $0x16,%eax
  40077d:   eb 05                   jmp    400784 <f51+0x8a>
  40077f:   b8 0a 00 00 00          mov    $0xa,%eax
  400784:   5d                      pop    %rbp
  400785:   c3                      retq 

I can see that what I'm looking at here is a switch statement where the default case is when -0x4(%rbp) > 5, but I'm confused about a few instructions:

Is 40074b just going to a spot on the jump table and pushing that instruction into rax so we can jump to the proper spot in the switch case after that (which is line 400753)?

In which case I have no idea how to interpret our different cases. If my understanding is correct the jump table starts at address 400928, going there I see:

  400928:   55                      push   %rbp
  400929:   07                      (bad)  
  40092a:   40 00 00                add    %al,(%rax)
  40092d:   00 00                   add    %al,(%rax)
  40092f:   00 5c 07 40             add    %bl,0x40(%rdi,%rax,1)
  400933:   00 00                   add    %al,(%rax)
  400935:   00 00                   add    %al,(%rax)
  400937:   00 63 07                add    %ah,0x7(%rbx)
  40093a:   40 00 00                add    %al,(%rax)
  40093d:   00 00                   add    %al,(%rax)
  40093f:   00 6a 07                add    %ch,0x7(%rdx)
  400942:   40 00 00                add    %al,(%rax)
  400945:   00 00                   add    %al,(%rax)
  400947:   00 71 07                add    %dh,0x7(%rcx)
  40094a:   40 00 00                add    %al,(%rax)
  40094d:   00 00                   add    %al,(%rax)
  40094f:   00 78 07                add    %bh,0x7(%rax)
  400952:   40 00 00                add    %al,(%rax)
  400955:   00 00                   add    %al,(%rax)

At this point I have little idea of what I'm looking at. Presumably with line 400753 we jump to somewhere in this table, but then what? Or is my understanding completely off?

Upvotes: 1

Views: 1426

Answers (1)

user2404501
user2404501

Reputation:

The jump table is an array of pointers, not code. The disassembler doesn't know that, so it decodes the bytes as instructions. You have to ignore that and just look at the bytes:

400928:   55                      push   %rbp
400929:   07                      (bad)  
40092a:   40 00 00                add    %al,(%rax)
40092d:   00 00                   add    %al,(%rax)
40092f:   00 5c 07 40             add    %bl,0x40(%rdi,%rax,1)

The first 8 bytes are 55 07 40 00 00 00 00 00, a pointer to the instruction at 0x400755. That's where you find case 0.

Upvotes: 3

Related Questions