So I've been working on this binary bomb for days and I am nearly finished. Just two more phases to go, and it is due tomorrow night. I've worked through the disassembled code as posted below and I can't seem to figure out exactly what is happening.
What I do know is that the fscanf function is called and requests two inputs "%d %d" given by the string $0x8048baa. We'll call these inputs y and x in that order. After entering two inputs, the program will continue without exploding and see whether y is less than 4. Next, a comparison is done to see if y is positive, and if not, then it is changed to a positive and restored into %eax.
Next, the function f is called (disassembled code below) with y as a parameter. I am slightly confused on line <+4> of this function, as 0x20(%esp) lies outside of the space allocated for this function and into the previously stored items. 0x20(%esp) seems to refer to the pointer to y which was pushed to the stack earlier. I'm not sure if this is right, as I don't understand why the program would reference a pointer to y which was previously stored outside of the call to this method when y is already stored in the stack as an argument to the current function. Anyway, I don't know what else would be happening here so if that is what is happening, then y is stored into %ebx then if y is less than 1 the program jumps forward, otherwise a new address is loaded into eax and then the function is recursively called? I don't fully understand what happens here so I am just hoping that I can get by without having to go through the recursive call by setting y to something less than 1 initially. If y is less than 1 then the eax register is set to 1, y becomes 1, and then we return back to phase_4_of_5.
Now y is added to itself. After exiting the f function, y == 1 so y + y = 2. Next a comparison is done to see whether y and x are equal, and if they are then we skip to a second comparison making sure that x does not equal the value 240. If x != 240 then the program resets the stack pointer and returns.
By my (obviously flawed) logic, if y were initially -5 and x were initially 2, then I should make it through without blowing up the bomb.
Perhaps someone could point me in the right direction here? I am not sure exactly where I am going wrong and am having a hard time fully understand the f function. It is important to me that I actually understand my assignments, so if you would like to supply me with a working input so that I can walk through the program step by step with it, do so knowing that I am still learning.
Dump of assembler code for function phase_4_of_5:
0x08048890 <+0>: sub $0x2c,%esp ;allocate 44 bytes for stack
0x08048893 <+3>: lea 0x1c(%esp),%eax ;load address of x into eax
0x08048897 <+7>: mov %eax,0xc(%esp) ;prepare &x for function call
0x0804889b <+11>: lea 0x18(%esp),%eax ;load address of y into eax
0x0804889f <+15>: mov %eax,0x8(%esp) ;prepare &y for function call
0x080488a3 <+19>: movl $0x8048baa,0x4(%esp) ;prepare "%d %d" for call
0x080488ab <+27>: mov 0x804b040,%eax ;load call to fscanf into eax
0x080488b0 <+32>: mov %eax,(%esp) ;push call to fscanf onto stack
0x080488b3 <+35>: call 0x8048480 <__isoc99_fscanf@plt> ;call fscanf("%d %d", &y, &x);
0x080488b8 <+40>: cmp $0x2,%eax ;if((# of numbers entered == 2))
0x080488bb <+43>: je 0x80488c9 <phase_4_of_5+57> ;jump to <+57>
0x080488bd <+45>: movl $0x4,(%esp)
0x080488c4 <+52>: call 0x80486ef <explode>
0x080488c9 <+57>: mov 0x18(%esp),%eax ;move y into eax
0x080488cd <+61>: cmp $0x4,%eax ;if(y <= 4)
0x080488d0 <+64>: jle 0x80488de <phase_4_of_5+78> ;jump to <+78>
0x080488d2 <+66>: movl $0x4,(%esp)
0x080488d9 <+73>: call 0x80486ef <explode>
0x080488de <+78>: test %eax,%eax ;if(y >= 0)
0x080488e0 <+80>: jns 0x80488e8 <phase_4_of_5+88> ;jump to <+88>
0x080488e2 <+82>: neg %eax ;else y = -y;
0x080488e4 <+84>: mov %eax,0x18(%esp) ;update y
0x080488e8 <+88>: mov 0x18(%esp),%eax ;update eax (unnecessary?)
0x080488ec <+92>: mov %eax,(%esp) ;load y as argument to f
0x080488ef <+95>: call 0x8048869 <f> ;call f
0x080488f4 <+100>: add %eax,%eax
0x080488f6 <+102>: mov 0x1c(%esp),%edx
0x080488fa <+106>: cmp %eax,%edx
0x080488fc <+108>: je 0x804890a <phase_4_of_5+122>
0x080488fe <+110>: movl $0x4,(%esp)
0x08048905 <+117>: call 0x80486ef <explode>
0x0804890a <+122>: cmp $0xf0,%edx
0x08048910 <+128>: jne 0x804891e <phase_4_of_5+142>
0x08048912 <+130>: movl $0x8048c98,(%esp)
0x08048919 <+137>: call 0x80484d0 <puts@plt>
0x0804891e <+142>: add $0x2c,%esp
0x08048921 <+145>: ret
End of assembler dump.
Dump of assembler code for function f:
0x08048869 <+0>: push %ebx ;load new base pointer
0x0804886a <+1>: sub $0x18,%esp ;make more room on the stack
0x0804886d <+4>: mov 0x20(%esp),%ebx ;move arg(y) into ebx
0x08048871 <+8>: cmp $0x1,%ebx ;if(y <= 1)
0x08048874 <+11>: jle 0x8048886 <f+29> ;jump to <+29>
0x08048876 <+13>: lea -0x1(%ebx),%eax ;else ??? what is happening here? 1 byte below ebx? does this mean I am dealing with low order and high order areas on the stack?
0x08048879 <+16>: mov %eax,(%esp)
0x0804887c <+19>: call 0x8048869 <f> ;recursively call f until ebx <= 1
0x08048881 <+24>: imul %ebx,%eax ;eax = eax*ebx
0x08048884 <+27>: jmp 0x804888b <f+34> ;jump to <+34>
0x08048886 <+29>: mov $0x1,%eax ;Does this literally mean to store the value '1' into eax? If so, what was the point of imul?
0x0804888b <+34>: add $0x18,%esp ;return esp to loc before call to f.
0x0804888e <+37>: pop %ebx
0x0804888f <+38>: ret
End of assembler dump.