2016-11-15 2 views
1

Я пытаюсь перепроектировать некоторые сборки, и я добрался до этой точки:GAS x86: Чтение таблица прыжка/интерпретация переключателя заявления

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 

я могу видеть, что то, что я ищу здесь есть оператор switch, где случай по умолчанию - когда -0x4 (% rbp)> 5, но я путаюсь в нескольких инструкциях:

Является ли 40074b просто точкой на скачкообразном переходе и нажатием этой команды в rax, чтобы после этого мы могли перейти в правильное место в корпусе коммутатора (это линия 400753)?

В этом случае я не знаю, как интерпретировать наши разные случаи. Если я правильно понимаю таблицу переходов начинается по адресу 400928, туда я вижу:

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) 

На данный момент у меня есть смутное представление о том, что я смотрю на. Предположительно с линией 400753 мы прыгаем где-то в этой таблице, но что тогда? Или мое понимание полностью отключено?

+0

0x400928 in .rodata? Если это только в разделе .text, смешанном с кодом, это странно. Обычно вы группируете данные и код отдельно по соображениям производительности, потому что у процессоров есть разделенные кэши (и отдельные dTLB/iTLB). –

+0

он находится в .rodata – nichow

+0

Итак, вам нужно использовать '-D' или что-то, чтобы разобрать этот некод. Теперь вы знаете, почему ваши инструменты не хотели его разбирать: P –

ответ

3

Таблица прыжка представляет собой массив указателей, а не код. Дисассемблер не знает этого, поэтому он декодирует байты в качестве инструкций. Вы должны игнорировать это и просто посмотреть на байтах:

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) 

Первые 8 байт 55 07 40 00 00 00 00 00, указатель на инструкцию на 0x400755. Здесь вы найдете case 0.

+0

Как мы узнаем, что это' case 0', а не любой другой номер? – nichow

+1

@nichow: потому что он использует операнд 'switch()' в качестве индекса массива напрямую, без добавления/sub для его смещения или чего-то еще. Если это не произошло ранее в коде, вы не показывали. –

Смежные вопросы