CS 105

Using hex2raw

hex2raw takes as input a hex-formatted string. In this format, each byte value is represented by two hex digits. For example, the string 012345 could be entered in hex format as 30 31 32 33 34 35 00. Recall that the ASCII code for decimal digit x is 0x3x; the end of a string is indicated by a null byte.

The hex characters you pass to hex2raw should be separated by whitespace (blanks or newlines). We recommend separating different parts of your exploit string with newlines while you're working on it. hex2raw supports C-style block comments, so you can mark off sections of your exploit string.

Be sure to leave space around both the starting and ending comment strings (/*, */), so that the comments will be properly ignored.

For example,

48 c7 c1 f0 11 40 00 /* mov    $0x40011f0,%rcx */

If you generate a hex-formatted exploit string in the file exploit.txt, you can apply the raw string to ctarget or rtarget in several different ways:

  1. You can set up a series of pipes to pass the string through hex2raw.

    In general, a pipe (|) passes the output from one command as input to the next, e.g., in foo | bar, the output from program foo that would have printed to the console will instead be passed as input to program bar.

    For example,

    ./hex2raw -i exploit.txt | ./ctarget
    

    or

    ./hex2raw < exploit.txt | ./ctarget
    
  2. You can store the raw string in a file and use I/O redirection.

    With I/O redirection, you can direct output that would have printed to the console to instead be saved to a file (using >). You can also give input to a program using the contents of a file (using <).

    For example,

    ./hex2raw < exploit.txt > exploit-raw.txt
    ./ctarget < exploit-raw.txt
    

    This approach can also be used when running from within gdb:

    gdb ctarget
    (gdb) run < exploit-raw.txt
    

    Note that by default, under both the zsh and bash shells, the hex2raw command will not work if exploit-raw.txt already exists. The clumsy way to work around that problem is to remember to delete exploit-raw.txt before you rebuilt it. The more elegant way is to append an exclamation point (for zsh) or a vertical bar (for bash) immediately after the greater-than sign (no spaces allowed):

    zsh> ./hex2raw < exploit.txt >! exploit-raw.txt
    bash> ./hex2raw < exploit.txt >| exploit-raw.txt
    
  3. You can store the raw string in a file and provide the file name as a command-line argument:

    ./hex2raw < exploit.txt > exploit-raw.txt
    ./ctarget -i exploit-raw.txt
    

    This approach can also be used when running from within gdb.

Generating Byte Codes

Using gcc as an assembler and objdump as a disassembler makes it convenient to generate the byte codes for instruction sequences.

For example, suppose you write a file example.s with the following assembly code:

# Example of hand-generated assembly code
pushq   $0xabcdef          # Push value onto stack
addq    $17,%rax           # Add 17 to %rax
movl    %eax,%edx          # Copy lower 32 bits to %edx

The code can contain a mixture of instructions and data. Anything to the right of a # character is considered to be a comment.

You can now assemble and disassemble this file:

gcc -c example.s
objdump -d example.o > example.d

The generated file example.d contains

example.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:   68 ef cd ab 00          pushq  $0xabcdef
   5:   48 83 c0 11             add    $0x11,%rax
   9:   89 c2                   mov    %eax,%edx

The lines at the bottom show the machine code generated from the assembly language instructions. Each line has a hexadecimal number on the left indicating the instruction's starting address (starting with 0), while the hex digits after the : character indicate the byte codes for the instruction. Thus we can see that the instruction push $0xABCDEF has hex-formatted byte code 68 ef cd ab 00.

From this file, you can get the byte sequence for the code:

68 ef cd ab 00 48 83 c0 11 89 c2

This string can then be passed through hex2raw to generate an input string for the target programs.. Alternatively, you can edit example.d by hand to omit extraneous values and to contain C-style comments for readability, yielding something like

   68 ef cd ab 00   /* pushq  $0xabcdef  */
   48 83 c0 11      /* add    $0x11,%rax */
   89 c2            /* mov    %eax,%edx  */

This format is also a valid input for passing through hex2raw before sending to one of the target programs.

(When logged in, completion status appears here.)