2015-03-02 7 views
0

Мне был предоставлен исполняемый файл, написанный первоначально на C, который играет в игру угадывания. Я, как игрок, должен угадать 5 чисел, и если я сделаю это правильно, бомба не исчезнет. Однако, как только я пропустил один, я проиграю, и бомба взрывается. До сих пор мой подход к этой проблеме состоял в том, чтобы разобрать исполняемый файл и попытаться прочитать решение оттуда. Я знаю, что в какой-то момент вызывается функция strcmp, то есть моя догадка против значения ключа будет храниться где-то до этого в регистре. То, что я потерял, это то, где его найти, и как получить доступ к правильной строке символов, хранящей это число.Понимание синтаксиса x86 относительно C 'bomb'

Вот ассемблер код, который я получил, чтобы:

0804856a <main>: 
804856a: 55      push %ebp 
804856b: 89 e5     mov %esp,%ebp 
804856d: 83 e4 f0    and $0xfffffff0,%esp 
8048570: 57      push %edi 
8048571: 56      push %esi 
8048572: 53      push %ebx 
8048573: 81 ec 14 02 00 00  sub $0x214,%esp //prologue code ends 
8048579: 8b 35 fc 98 04 08  mov 0x80498fc,%esi 
804857f: 83 7d 08 02    cmpl $0x2,0x8(%ebp) 
8048583: 75 18     jne 804859d <main+0x33> 
8048585: c7 44 24 04 fb 86 04 movl $0x80486fb,0x4(%esp) 
804858c: 08 
804858d: 8b 45 0c    mov 0xc(%ebp),%eax 
8048590: 8b 40 04    mov 0x4(%eax),%eax 
8048593: 89 04 24    mov %eax,(%esp) 
8048596: e8 65 fe ff ff   call 8048400 <[email protected]> 
804859b: 89 c6     mov %eax,%esi 
804859d: bb 01 00 00 00   mov $0x1,%ebx 
80485a2: bf e4 98 04 08   mov $0x80498e4,%edi 
80485a7: 3b 35 fc 98 04 08  cmp 0x80498fc,%esi 
80485ad: 75 10     jne 80485bf <main+0x55> 
80485af: 89 5c 24 04    mov %ebx,0x4(%esp) 
80485b3: c7 04 24 fd 86 04 08 movl $0x80486fd,(%esp) 
80485ba: e8 51 fe ff ff   call 8048410 <[email protected]> 
80485bf: 89 74 24 08    mov %esi,0x8(%esp) 
80485c3: c7 44 24 04 00 02 00 movl $0x200,0x4(%esp) 
80485ca: 00 
80485cb: 8d 44 24 10    lea 0x10(%esp),%eax 
80485cf: 89 04 24    mov %eax,(%esp) 
80485d2: e8 09 fe ff ff   call 80483e0 <[email protected]> 
80485d7: 85 c0     test %eax,%eax 
80485d9: 74 22     je  80485fd <main+0x93> 
80485db: 8b 14 9f    mov (%edi,%ebx,4),%edx 
80485de: 89 54 24 04    mov %edx,0x4(%esp) 
80485e2: 89 04 24    mov %eax,(%esp) 
80485e5: e8 56 fe ff ff   call 8048440 <[email protected]> //call to strcmp, so the two parameters (my guess vs. key) must be stored before it. 
80485ea: 85 c0     test %eax,%eax 
80485ec: 74 05    break<main+0x89> 
80485ee: e8 4d ff ff ff   call 8048540 <bomb> 
80485f3: 83 c3 01    add $0x1,%ebx 
80485f6: 83 fb 05    cmp $0x5,%ebx 
80485f9: 7e ac     jle 80485a7 <main+0x3d> 
80485fb: eb 05     jmp 8048602 <main+0x98> 
80485fd: 83 fb 05    cmp $0x5,%ebx 
8048600: 7e a5     jle 80485a7 <main+0x3d> 
8048602: e8 19 ff ff ff   call 8048520 <success> 
8048607: b8 00 00 00 00   mov $0x0,%eax 
804860c: 81 c4 14 02 00 00  add $0x214,%esp //epilogue code begins 
8048612: 5b      pop %ebx 
8048613: 5e      pop %esi 
8048614: 5f      pop %edi 
8048615: 89 ec     mov %ebp,%esp 
8048617: 5d      pop %ebp 
8048618: c3      ret  

До сих пор на этом проекте я использую отладчик GNU, чтобы попытаться пронизывают через программу. Однако я не могу понять это. Это мое первое знакомство с x86 asm. Моя теория заключается в том, что строки должны быть сохранены в% edi /% edx /% eax на строках 80485db/de/e2, но я не понимаю, как эти строки будут храниться там, а не как их получить. Я бы очень признателен за любую помощь от более опытных программистов, так как это несколько сбивало меня с толку.

+1

Вы не задали вопрос явно - пытаетесь ли вы найти правильную последовательность чисел или код проверки ввода патча, чтобы он всегда проходил? –

+1

Вероятно, нет строки символов, в которой хранится правильный номер. – immibis

+0

Попытка обратного инженерного кода перед тем, как бомба (которая контролирует ваши нажатия клавиш) уходит, еще лучшая игра ;-) –

ответ

1

Вы правильно определили критический участок вокруг 80485db. Давайте работать в обратном направлении от вызова strcmp. Для сравнения используются два операнда, они помещаются в стек в двух предыдущих строках из регистров %eax и %edx. Мы можем видеть, что %eax - это возвращаемое значение от fgets, которое является только введенным текстом. %edx загружен mov (%edi,%ebx,4),%edx который, к сожалению, зависит от двух других регистров. %edi является более простым, он задается mov $0x80498e4,%edi постоянному адресу. %ebx инициализируется до 1 по адресу 804859d, а затем увеличивается на 80485f3 и сравнивается с 5. Таким образом, мы видим, что это счетчик циклов, показывающий, какой вход мы обрабатываем. Объединение всего этого означает, что %edx загружается из массива, содержащего ожидаемые строки. Первая строка будет на 0x80498e4+4, потому что ebx начинается с 1. Таким образом, x/5s *0x80498e8 в gdb должен показать вам необходимый вход для разрядки бомбу.

+0

Это именно та помощь, в которой я нуждался, спасибо вам большое. Меня смущала операция, выполняемая на% edi, прежде чем она была помещена в% edx. Я смог понять это, как только вы объяснили, что это значит, и я подумал о том, как я могу проследить содержимое регистров обратно через код из него. Отличная подготовка к следующему заданию, большое вам спасибо. –