PLEASE NOTE: The protection scheme in 3.9.10+ has changed slightly. This method will no longer work, although there are a lot of similarities; certain inform.
- Hopper (December 9, 1906 – January 1, 1992) is credited with popularizing the term 'debugging' after finding an actual moth in her computer. There’s a photo of it on her official Navy page.
- Hopper is a debugger + disassembler intended for Linux and Mac OS. It is a good alternative to Ollydbg. Hopper is capable of simultaneously displaying assembly code and pseudo code. However, its free demo version has constraints such as saving & exporting modified binaries are not allowed.
Purpose
Hopper is a disassembler and debugger that runs on Mac OS X or Linux,but not Windows. It has similar functionalityto IDA Pro but costs 10x less. And the free versionworks on 64-bit executables.What You Need
A 64-bit Ubuntu 14.04 machine, real or virtual. I recommend using the Ubuntu 14.04.03 machine I put on Mega, which already has Hopper installed. Here's the link to get my VM:Ubuntu 14.04.03 with Hopper
Size: 2,198,435,208 bytes
SHA256( Ubuntux64-14.04.3-Hopper.7z)= 11d4cf7d54aca0b2c9d559f0ce16cdcfc2be4996491a2ddaab845d272fb2458e
Installing HopperIf you use the VM I put on Mega, hopper isalready installed. If you prefer to installit yourself, I did it this way. Note:the official Hopper repository for Ubuntudoes not work (as of 11-23-15) due toan invalid signature.I installed Ubuntu 14.04.03 x64 Desktop intoa fresh VM. Then, in a Terminal window,I executed these commands:
|
Starting Ubuntu
Launch the Ubuntu VM in VMware Playeror VMware Fusion.Log in with these credentials:
- Username: student
- Password: student
Downloading a Program to Debug
This is a simple vulnerable programwe've used before.In a Terminal window,execute these commands:
Enter a password of a andpress Enter.The program exits normally, wth the'Fail!' message, as shown below.
Starting Hopper
From the Ubuntu desktop,at the top left,click thesquare reddishSearch button.In the search field, type
In the search results, click'Hopper Disassembler v3',as shown below.In the 'Registration' box,click'Try the Demo',as shown below.
Hopper opens. Move the mouse intothe dark gray bar at the top, and themenu items will appear, starting with'File', 'Edit', and 'Find',as shown below.
From the Hopper menu bar, clickFile,'Read Executable to Disassemble...'.
Navigate to the pwd file youcreated above and double-click it.
In the 'Read Executable' box, clickOK.
You see the Hopper main window,as shown below.
Restarting HopperEvery 30 minuntes, Hopper will die,just to irritate you into paying$90, with the messageshown below.When this happens, do these things: Click OK. From the Ubuntu desktop,at the top left,click thesquare reddishSearch button. Click'Hopper Disassembler v3'. In the 'Registration' box,click'Try the Demo'. From the Hopper menu bar, clickFile,'Read Executable to Disassemble...'. Navigate to the pwd file youcreated above and double-click it. In the 'Read Executable' box, clickOK. |
The first pass looks at the code asa series of Assembly Language instructions.This is the most basic function of adisassembler.
Hiding the Inspector Pane
At the top right, click the rightmostof the three 'Show/Hide Panes' buttons.This gives you more room to see theAssembly Language pane.Hiding the 'Symbols & Strings' Pane
At the top right, click the leftmostof the three 'Show/Hide Panes' buttons.This allows theAssembly Language pane to usethe entire window width.Hiding the Message Pane
At the bottom, there is a pane containingmessages from Hopper, like'analysis section .got.plt'. Drag the topborder of that section to the bottom.Now, finally, the whole window is availablefor assembly code, as shown below.
On the right edge, drag the scroll bar tothe top. Click the very first lineto select it.
The Navigation Bar
At the top center, there's a coloredbar with a little red arrow. This is a lineargraph of the entire file, and the red arrowindicates your current position.The red arrow in the Navigation Bar is nowat the left edge,as shown below.
In the Navigation bar, drag the little redarrow to the first yellow stripe.
Code appears, with a yellow-shaded backgroundbehind it,as shown below.
Notice these sections:
- Address: in hexadecimal, 64 bits long
- Comments: Added by Hopper to make the code easier to understand
- Instructions: in assembly language
Displaying the Hex Column
One important thing that is missing fromthe Hopper display is theinstructions in theirraw hexadecimal form. To show them,from the Hopper menu bar, clickWindow, Preferences.In the Preferences box,On the General tab,click'Show the hex column',as shown below.
Click OK.
Now the hexadecimal version ofeach assembly instruction is visible,as shown below.
Color Codes in Hopper
Hopper assigns each byte of a file intoone of these five categories, each coded witha color:- Data(purple): a constant, like an array of integers
- ASCII(green): a NULL terminated C string
- Code(blue): an instruction
- Procedure(yellow): Part of a method that has been successfully reconstructed by Hopper
- Undefined(grey): an area not yet explored by Hopper
The regions with a white background aboveand below the yellow-shaded regionare 'Code' regions--they appear to beassembly instructions, but Hopper isn'tsure what they are for.
Viewing ASCII Strings
In the Navigation bar, drag the little redarrow into the green bar.This section contains string constants,such as 'Enter password' and'Fail!',as shown below.
Viewing Data
In the Navigation bar, drag the little redarrow into the purple bar at the farright, as shown below.This section containsthe Global Offset Table, whichwe have used before in exploitation,as shown below.
Saving a Screen Image
Make sure gets@GOT is visible,as shown above.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.
Memory Layout
Here are the main sections of memoryused by a Linux executable:Navigating by Segments
From the Hopper menu bar, clickNavigate,'Show Segment List'.A 'Segments' window appears,as shown below.
This isn't much use for understandingprogram flow, but you can see thestart of the program in memory.
In the Segments box, click0x400000 and click the'Go To' button.
A series of bytes appears,beginning with '.ELF',as shown below.
To see the code in a morereadable view, clickWindows,'Show Hexadecimal Editor'.
Close the 'Form' window (theHexadecimal Editor).
Navigating by Sections
From the Hopper menu bar, clickNavigate,'Show Section List'.A 'Sections' window appears,as shown below.
This has several familiar items init:
- _init : prepares to start the program
- _start : (.text section) More preparation to launch the program
- _GLOBAL_OFFSET_TABLE : (.got.plt section) pointers to library functions, which we have exploited in the past
Close the 'Sections' window.
Using Symbols
At the top right, click the leftmostof the three 'Show/Hide Panes' buttons.This shows the'Symbols & Strings' pane,as shown below.On the left side, a list offriendly Labelsappears.
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.
Using Strings
In the left pane, click theStrings tab.Click Fail!.
The right pane shows the ASCIIstring 'Fail!',as shown below.
Suppose we want to trick the codeinto accepting any password, andnot printing 'Fail!'.We'd like to see the codethat uses the string 'Fail!'.
In the right pane, to the right of the word'Fail!', there is a comment beginning withXREF=. Double-click the'main+18 text.The code appear in main() that prints'Fail!',as shown below.
Control Flow Graph
In the left pane,on the Labels tab,click main.At the top right of Hopper, clickthe 'Control Flow Graph'button, asoutlined in red in the imagebelow.
The Control Flow Graph appears,as shown below.
It shows that main callsa subroutine namedtest_pw, thentests the return value,and jumps to one of twoputs calls to printmessages.
The Control Flow Graph is pretty,but it doesn't show which choiceprints 'Win!' and which prints'Fail!'.
Close the Control Flow Graph.
Pseudocode
At the top right of Hopper, clickthe Pseudocodebutton,as shown in the imageabove.The Pseudocode window appears,containing code written in a C-likelanguage,as shown below.
This is much easier to read! It showsthat the program prints'You win!' when test_pw returns zero.
Close the Pseudocode window.
Understanding the Assembly Code
In the left pane,on the Strings tab,click Fail!.On the right side, in the linecontaining 'Fail!', in the'XREF' note, as outlined inred in the image below, double-click thegreen main+18 address.
The assembly code that uses thatstring appears, as shown below.
Now the assembly code iseasier to understand.Starting at address 4006d1,the code calls test_pw. Itthen usestest to see if the return valueis zero.If it is, it jumps to location4006e6 and prints'You Win!'.Otherwise it doesn't jump,and prints 'Fail!'.
So a simple way to make the program acceptany password is to fill thebytes outlined in green belowwith NOPs.
Saving a Screen Image
Make sure the hex codesstarting with BF95 and endingwith EB0A are visible,as shown above.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.
Exiting Hopper
The paid version of Hopper lets youmodify code and save the modified version,but not the free demo version.Close Hopper.
Modifying the Executable
In a Terminal window, execute thiscommand toinstall hexedit:Enter the password studentwhen you are prompted to.In a Terminal window, execute thesecommands to copy the pwdexecutable to a new file namedpwd2,and open it in thehexedit hex editor:
The binary opens in hexedit,as shown below.The first four characters are.ELF, shown on theright side in ASCII.
In hexedit, press Ctrl+S.
Enter this 'hexa string':
Press Enter.The cursor moves to location 6DA,as shown below.
Carefully type90over twelve bytes,as shown below.
To save the file,press Ctrl+X, Y, Enter.
In a Terminal window, execute thiscommand to run the file:
Hopper Guide Pt
Enter any password, such asYOURNAME. You win,as shown below.Hopper provides a graphical interfaceto the gdb debugger. We'll use thatnext.Starting the Hopper Debugger
From the Ubuntu desktop,at the top left,click thesquare reddishSearch button.In the search field, type
In the search results, click'Hopper Debugger v3',as shown below.A box appears, saying'Server is running...'as shown below.
Leave this box open.
Starting Hopper
From the Ubuntu desktop,at the top left,click thesquare reddishSearch button.In the search results, click'Hopper Disassembler v3'In the 'Registration' box,click'Try the Demo'.
Hopper opens.From the Hopper menu bar, clickFile,'Read Executable to Disassemble...'.
Navigate to the pwd file youcreated above and double-click it.
In the 'Read Executable' box, clickOK.
Setting a Breakpoint
Before opening the debugger, we'llset a breakpoint in Hopper.In the 'Symbols & Strings' pane,on the Tags tab,click main.
In the right pane, in the reddish vertical stripe,next to the first instruction in main,click the mouse. A red dot appears,showing that this is now a breakpoint,as shown below.
Starting the Debugger
At the top right of Hopper, clickthe Debugger button,as shown below.A GDB window appears,as shown below.
The most useful buttons are labelledbelow.
Starting the Program
In the GDB window, clickthe Continue button.The program launches, and stopsat your breakpoint.
The disassembler window labelsthe breakpoint with a red RIPmarker, indicating that the InstructionPointer is here,as shown below.
It also labels this line with a redRAX.
The GDB window shows the currentcontents of the processor's registers.
As shown below, both RIP and RAX havethe same value--the address of thebreakpoint.
TroubleshootingIf you make any sort of mistake usingthe debugger, you cannot easily closeit and restart it.Instead, you must use command-lineutilities to kill all hopper processes,as explained in the'Exiting the Debugger' sectionat the end of these instructions. |
Using 'Step into'
In the GDB window, click the'Step into' button.In the lower left of the window,the 'Callstack' pane now showsa location of }main + 0x1',as shown below.
The Disassembler window also showsthat the program has moved forwardone instruction,as shown below.
The red RIP has moved downone line, and the red RAXstill points to the first commandin main(),as shown below.
In the GDB window, click the'Step into' button twice more.
In the lower left of the window,the 'Callstack' pane now showsa location of }main + 0x9',as shown below.
The Disassembler window nowshows that we are at the'call test_pw' instruction,as shown below.
In the GDB window, click the'Step into' button once more.
In the lower left of the window,the 'Callstack' pane now showstwo 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 asingle instruction, even if that instructionis a call and enters a newsubroutine.
The Disassembler window nowshows that we are inside the'call test_pw' function,as shown below.
In the GDB window, click the'Step into' button nine moretimes.
The Disassembler windowshows that we about to call thej_printf function,as shown below.
In the GDB window, click the'Step into' button once more.
In the lower left of the window,the 'Callstack' pane now showsthree lines: we are still in main,and in the subroutine test_pw,but we are also in the subroutinej_printf,as shown below.
The Disassembler window nowshows that we are inside the'j_printf' function,as shown below.
Using 'Step out'
We are about to enter the Global OffsetTable and then enter the C library.We aren't interested in debugging theC library--we want to debug the C codewe wrote. So it doesn't make sense tokeep on using 'Step in'.
What we really want to do is'Step out', to get back totest_pw.In the GDB window, click the'Step out' button once.
In the lower left of the window,the 'Callstack' pane now showsonly two lines again:main,and test_pw,as shown below.
Using 'Step over'
This is the level we want to stayat, inside the code we wrote.To stay at this level, we use the'Step over' button.
In the GDB window, click the'Step over' button three times.
In the lower left of the window,the 'Callstack' pane now showstwo lines, but they are grayed out,as shown below.
The Disassembler window nolonger shows which instructionwe are on,as shown below.
What has happened? We have steppedover the j_gets function,and the program is waiting for userinput from inside that function.
Hopper Cannot Launch Debugger
Interacting with the Console
In the GDB window, click the'Application Output' tab.Here you see a warning message, followedby the 'Enter password:',prompt, as shown below.
In the bar at the bottom, type inyour name (not the literal text'YOURNAME', as shown below)and press Enter.
Your name appears inside thewindow,as shown below.
Saving a Screen Image
Make sure YOURNAME and 'Hopper Guide In Minecraft
ApplicationOutput' are visible, as shown above.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.
Exiting the Debugger
The clean way to exit is to first click thesquare Stop button in the debugger,then click the red X in the top leftto close the debugger window,and then close the Hopper disassembler.Hopper Guide
If that process fails (and it often does),do this:
In a Terminal window,execute this command:
Now use the kill command to killeach process, one by one, by process ID number,as shown below.