Rookie Birds Make the First Pass of bomb lab

Keywords: C

The first question is relatively simple, but this dish chicken has also been made for two hours (')(

Firstly, open the bomb.s file which has been disassembled in advance. Through bomb.c, we know that each level is a function. Their name is phase_x. X represents the number of the level. If the input of a level is incorrect, the explode_bomb will be detonated. Let's first look at the lines of main function.

400e1e:   bf 38 23 40 00          mov    $0x402338,%edi
400e23:   e8 e8 fc ff ff          callq  400b10 <puts@plt>
400e28:   bf 78 23 40 00          mov    $0x402378,%edi
400e2d:   e8 de fc ff ff          callq  400b10 <puts@plt>
400e32:   e8 67 06 00 00          callq  40149e <read_line>
400e37:   48 89 c7                mov    %rax,%rdi
400e3a:   e8 a1 00 00 00          callq  400ee0 <phase_1>
400e3f:   e8 80 07 00 00          callq  4015c4 <phase_defused>
400e44:   bf a8 23 40 00          mov    $0x4023a8,%edi

Open gdb, break the line first * 0x400e23, then run up. Here you can see that the function put is called. Register% edi stores the first parameter of the function. We print out the results of the function x/s 0x402338 and x/s 0x402378, and find out the string output after running bomb. It means that the first pass begins here.

Since the return value is in% rax, here mov% rax% RDI indicates that the input is passed to phase_1. break phase_1 in gdb.

0000000000400ee0 <phase_1>:
    400ee0:   48 83 ec 08             sub    $0x8,%rsp
    400ee4:   be 00 24 40 00          mov    $0x402400,%esi
    400ee9:   e8 4a 04 00 00          callq  401338 <strings_not_equal>
    400eee:   85 c0                   test   %eax,%eax
    400ef0:   74 05                   je     400ef7 <phase_1+0x17>
    400ef2:   e8 43 05 00 00          callq  40143a <explode_bomb>
    400ef7:   48 83 c4 08             add    $0x8,%rsp
    400efb:   c3                      retq

Through the code here, we can analyze whether the input string is equal to the string stored in 0x402400 by calling string_not_equal to determine whether it is explode_bomb. Through this function name, you can also know that you must enter the same string as 0x402400 to pass the first pass. So break *0x400ee9 here, and then x/s 0x402400 prints out the string here. I'm Border relations with Canada have never been better. Then I enter the string, and the first pass is over.~

string_not_equal

Although this will pass, but I am still curious about the code here, after all, it is learning, look at the code here familiar with assembly.

0000000000401338 <strings_not_equal>:
  401338:   41 54                   push   %r12
  40133a:   55                      push   %rbp
  40133b:   53                      push   %rbx
  40133c:   48 89 fb                mov    %rdi,%rbx
  40133f:   48 89 f5                mov    %rsi,%rbp
  401342:   e8 d4 ff ff ff          callq  40131b <string_length>
  401347:   41 89 c4                mov    %eax,%r12d
  40134a:   48 89 ef                mov    %rbp,%rdi
  40134d:   e8 c9 ff ff ff          callq  40131b <string_length>
  401352:   ba 01 00 00 00          mov    $0x1,%edx
  401357:   41 39 c4                cmp    %eax,%r12d
  40135a:   75 3f                   jne    40139b <strings_not_equal+0x63>
  40135c:   0f b6 03                movzbl (%rbx),%eax
  40135f:   84 c0                   test   %al,%al
  401361:   74 25                   je     401388 <strings_not_equal+0x50>
  401363:   3a 45 00                cmp    0x0(%rbp),%al
  401366:   74 0a                   je     401372 <strings_not_equal+0x3a>
  401368:   eb 25                   jmp    40138f <strings_not_equal+0x57>
  40136a:   3a 45 00                cmp    0x0(%rbp),%al
  40136d:   0f 1f 00                nopl   (%rax)
  401370:   75 24                   jne    401396 <strings_not_equal+0x5e>
  401372:   48 83 c3 01             add    $0x1,%rbx
  401376:   48 83 c5 01             add    $0x1,%rbp
  40137a:   0f b6 03                movzbl (%rbx),%eax
  40137d:   84 c0                   test   %al,%al
  40137f:   75 e9                   jne    40136a <strings_not_equal+0x32>
  401381:   ba 00 00 00 00          mov    $0x0,%edx
  401386:   eb 13                   jmp    40139b <strings_not_equal+0x63>
  401388:   ba 00 00 00 00          mov    $0x0,%edx
  40138d:   eb 0c                   jmp    40139b <strings_not_equal+0x63>
  40138f:   ba 01 00 00 00          mov    $0x1,%edx
  401394:   eb 05                   jmp    40139b <strings_not_equal+0x63>
  401396:   ba 01 00 00 00          mov    $0x1,%edx
  40139b:   89 d0                   mov    %edx,%eax
  40139d:   5b                      pop    %rbx
  40139e:   5d                      pop    %rbp
  40139f:   41 5c                   pop    %r12
  4013a1:   c3                      retq

Looking at the code, I found that it is very consistent with the book, and% r12,% rbp,% rbx are registers saved by the callee.

Firstly, 0x401342 ~ 0x40135a is used to judge whether they are the same length. If the length is different, then they are not the same string. Mov $0x1,% EDX and mov% edx,% eax returns 1.

Lines 0x405c ~ 0x401361 determine whether the first character of the input string is gill 0. Since the length of the command has been determined to be the same, if the first character of one of the strings is 0, then the other must be the same (all strings must contain a 0), so it returns 0 directly here.

0x401361 ~ 0x40137f is a loop, it traverses two strings, each character is the same, until encounter gill 0.

string_length

000000000040131b <string_length>:
  40131b:   80 3f 00                cmpb   $0x0,(%rdi)
  40131e:   74 12                   je     401332 <string_length+0x17>
  401320:   48 89 fa                mov    %rdi,%rdx
  401323:   48 83 c2 01             add    $0x1,%rdx
  401327:   89 d0                   mov    %edx,%eax
  401329:   29 f8                   sub    %edi,%eax
  40132b:   80 3a 00                cmpb   $0x0,(%rdx)
  40132e:   75 f3                   jne    401323 <string_length+0x8>
  401330:   f3 c3                   repz retq
  401332:   b8 00 00 00 00          mov    $0x0,%eax
  401337:   c3                      retq

This function is relatively simple, in fact, is to find the location of 0, and then return the difference between the other first address, that is, length. This translation can be written in C.

int string_length(char *s)
{
    char *b = a;
    
    while (*b != 0)
        b = b + 1;
    
    return (int) (b - a);
}

This article is the author's understanding and summary when reading "Deep Understanding of Computer Systems" and completing bomb lab. It is hereby recorded and has been read in the future. At the same time, I would like to share this knowledge with all my colleagues. Due to the limited level of the author, if there are any mistakes, I would like to thank you for your kind advice.

Posted by jeancharles on Sun, 03 Feb 2019 12:15:15 -0800