sudo apt update
sudo apt install libqt5gui5 libqt5xml5 libqt5printsupport5 libqt5network5 libqt5core5a libqt5dbus5 libxcb-xinerama0 qtbase-abi-5-9-5 libqt5svg5 qt5-gtk-platformtheme libqt5core5a libqt5dbus5 qtbase-abi-5-9-5 libqt5core5a libqt5widgets5 qtbase-abi-5-9-5 libqt5core5a libqt5core5a libdouble-conversion1 qttranslations5-l10n
wget https://d2ap6ypl1xbe4k.cloudfront.net/Hopper-v4-4.4.9-Linux.deb
sudo dpkg -i Hopper-v4-4.4.9-Linux.deb
In a Terminal window, execute these commands:
Enter a password of a and press Enter.wget https://samsclass.info/127/proj/pwd chmod +x pwd ./pwd
The program exits normally, wth the "Fail!" message, as shown below.
In the "Registration" box, click "Try the Demo", as shown below.
Hopper opens. Move the mouse into the dark gray bar at the top, and the menu items will appear, starting with "File", "Edit", and "Find", as shown below.
From the Hopper menu bar, click File, "Read Executable to Disassemble...".
Navigate to the pwd file you created above and double-click it.
In the "Read Executable" box, click OK.
You see the Hopper main window, as shown below.
Restarting Hopper
Every 30 minuntes, Hopper will die, just to irritate you into paying $90, with the message shown below.When this happens, do these things:
Click OK.
From the Ubuntu desktop, at the top left, click the square reddish Search button.
Click "Hopper Disassembler v3".
In the "Registration" box, click "Try the Demo".
From the Hopper menu bar, click File, "Read Executable to Disassemble...".
Navigate to the pwd file you created above and double-click it.
In the "Read Executable" box, click OK.
The first pass looks at the code as a series of Assembly Language instructions. This is the most basic function of a disassembler.
Now, finally, the whole window is available for assembly code, as shown below.
On the right edge, drag the scroll bar to the top. Click the very first line to select it.
The red arrow in the Navigation Bar is now at the left edge, as shown below.
In the Navigation bar, drag the little red arrow to the first yellow stripe.
Code appears, with a yellow-shaded background behind it, as shown below.
Notice these sections:
In the Preferences box, on the General tab, in the top right, in the "ASM Mode" pane, click "Show the hex column", as shown below.
Close the Preferences box.
Now the hexadecimal version of each assembly instruction is visible, as shown below.
The regions with a white background above and below the yellow-shaded region are "Code" regions--they appear to be assembly instructions, but Hopper isn't sure what they are for.
This section contains string constants, such as "Enter password" and "Fail!", as shown below.
This section contains the Global Offset Table, which we have used before in exploitation, as shown below.
Press the PrintScrn key to copy the whole desktop to the clipboard.
YOU MUST SUBMIT A FULL-SCREEN IMAGE FOR FULL CREDIT!
Paste the image into Paint.
Save the document with the filename "YOUR NAME Proj 7xa", replacing "YOUR NAME" with your real name.
A "Segments" window appears, as shown below.
This isn't much use for understanding program flow, but you can see the start of the program in memory.
In the Segments box, click 0x400000 and click the "Go To" button.
A series of bytes appears, beginning with ".ELF", as shown below.
To see the code in a more readable view, click Windows, "Show Hexadecimal Editor".
To return to normal view, click Windows, "Show Assembly".
A "Sections" window appears, as shown below.
This has several familiar items in it:
Close the "Sections" window.
On the left side, a list of friendly Labels appears.
In the left pane, click main. The assembly code for the main() routine appears, as shown below.
In the left pane, click test_pw. The assembly code for the test_pw() routine appears, as shown below.
Click Fail!.
The right pane shows the ASCII string "Fail!", as shown below.
Suppose we want to trick the code into accepting any password, and not printing "Fail!". We'd like to see the code that uses the string "Fail!".
In the right pane, to the right of the word "Fail!", there is a comment beginning with XREF=. Double-click the "main+18 text. The code appear in main() that prints "Fail!", as shown below.
At the top right of Hopper, click the "Control Flow Graph" button, as outlined in green in the image below.
The Control Flow Graph appears, as shown below.
It shows that main calls a subroutine named test_pw, then tests the return value, and jumps to one of two puts calls to print messages.
To return to normal view, click Windows, "Show Assembly".
The Pseudocode window appears, containing code written in a C-like language, as shown below.
This is much easier to read! It shows that the program prints "You win!" when test_pw returns zero.
To return to normal view, click Windows, "Show Assembly".
On the right side, in the line containing "Fail!", in the "XREF" note, as outlined in red in the image below, double-click the green main+18 address.
The assembly code that uses that string appears, as shown below.
Now the assembly code is easier to understand. Starting at address 4006d1, the code calls test_pw. It then uses test to see if the return value is zero. If it is, it jumps to location 4006e6 and prints "You Win!". Otherwise it doesn't jump, and prints "Fail!".
So a simple way to make the program accept any password is to fill the bytes outlined in green below with NOPs.
Press the PrintScrn key to copy the whole desktop to the clipboard.
YOU MUST SUBMIT A FULL-SCREEN IMAGE FOR FULL CREDIT!
Paste the image into Paint.
Save the document with the filename "YOUR NAME Proj 7xb", replacing "YOUR NAME" with your real name.
Close Hopper.
Enter the password student when you are prompted to.apt-get install hexedit -y
In a Terminal window, execute these commands to copy the pwd executable to a new file named pwd2, and open it in the hexedit hex editor:
The binary opens in hexedit, as shown below.cp pwd pwd2 hexedit pwd2
The first four characters are .ELF, shown on the right side in ASCII.
In hexedit, press Ctrl+S.
Enter this "hexa string":
Press Enter.BF95
The cursor moves to location 6DA, as shown below.
Carefully type 90 over twelve bytes, as shown below.
To save the file, press Ctrl+X, Y.
In a Terminal window, execute this command to run the file:
Enter any password, such as YOURNAME. You win, as shown below../pwd2
From the Hopper menu bar, click File, "Read Executable to Disassemble...".
Navigate to the pwd file you created above and double-click it.
In the "Read Executable" box, click OK.
On the left side, in the "Symbols" pane, on the Labels tab, click main.
From the Hopper menu bar, click Navigate, "Toggle Breakpoint".
A red dot appears, showing the breakpoint, as shown below.
A GDB window appears, as shown below.
The most useful buttons are labelled below.
The program launches, and stops at your breakpoint.
The disassembler window labels the breakpoint with a red RIP marker, indicating that the Instruction Pointer is here, as shown below.
It also labels this line with a red RAX.
The Debugger window shows the current contents of the processor's registers.
As shown above, both RIP and RAX have the same value--the address of the breakpoint.
In the Debugger window, the "Callstack" pane now shows a location of "main + 0x1", as shown below.
The Disassembler window also shows that the program has moved forward one instruction. The red RIP has moved down one line, and the red RAX still points to the first command in main().
In the Debugger window, click the "Step into" button twice more.
The "Callstack" pane now shows a location of "main + 0x9", as shown below.
The Disassembler window now shows that the RIP is now at the "call test_pw" instruction.
In the Debugger window, click the "Step into" button once more.
The "Callstack" pane now shows two lines: we are still in main, but also in the subroutine test_pw, called by main, as shown below.
This is the meaning of "Step into" -- it executes only a single instruction, even if that instruction is a call and enters a new subroutine.
The Disassembler window now shows that RIP is inside the "test_pw" function, as shown below.
In the Debugger window, click the "Step into" button nine more times.
The Disassembler window shows that we about to call the j_printf function, as shown below.
In the Debugger window, click the "Step into" button once more.
In the lower left of the window, the "Callstack" pane now shows three lines: we are still in main, and in the subroutine test_pw, but we are also in the subroutine j_printf, as shown below.
The Disassembler window now shows that we are inside the "j_printf" function.
We aren't interested in debugging the C library--we want to debug the C code we wrote. So it doesn't make sense to keep on using "Step in".
What we really want to do is "Step out", to get back to test_pw.
In the Debugger window, click the "Step out" button once.
In the lower left of the window, the "Callstack" pane now shows only two lines again: main, and test_pw, as shown below.
To stay at this level, we use the "Step over" button.
In the Debugger window, click the "Step over" button three times.
The "Callstack" pane now shows two lines, but they are grayed out, as shown below.
The Disassembler window no longer shows which instruction we are on, as shown below.
What has happened? We have stepped over the j_gets function, and the program is waiting for user input from inside that function.
The "Enter password:", prompt appears, as shown below.
In the bar at the bottom, type in your name (not the literal text "YOURNAME", as shown below) and press Enter.
Your name appears inside the window, as shown below.
Press the PrintScrn key to copy the whole desktop to the clipboard.
YOU MUST SUBMIT A FULL-SCREEN IMAGE FOR FULL CREDIT!
Paste the image into Paint.
Save the document with the filename "YOUR NAME Proj 7xc", replacing "YOUR NAME" with your real name.
Binary Patching. The Brute Force of Reverse Engineering with IDA and Hopper (And a Hex Editor).