Recent Posts

Programming

lion_tiger_opcodes

Lions, and Tigers, and OP Codes, OH MY! – Hacking Java Bytecode for Programmers (Part2)

Posted on May 17, 2013
AT THE END OF MAY I AM INVITED TO SPEAK AT A LOCAL USER GROUP ABOUT JAVA BYTECODE HACKING. I FIGURED IT WOULD BE BENEFICIAL TO GET MY THOUGHTS DOWN CONCERNING THIS TOPIC. THEREFORE, YOU MY FRIENDS, ARE MY GUINEA PIGS. YAY! IF YOU FIND A MISTAKE, EMAIL, COMMENT, WHATEVER, SO THAT I CAN IMPROVE THE FLOW. WERD.

Index

  1. The Birds and the Bees of Hex Editing – Hacking Java Bytecode for Programmers (Part1)
  2. Lions, and Tigers, and OP Codes, OH MY! – Hacking Java Bytecode for Programmers (Part2)
  3. Coming Soon

In Part 1, I showed you the basics of Hexadecimal, Hex Editors, and Java Bytecode. Refer to that post if you need to catch up. The following will be a simple exercise showing you how to manipulate the Java Bytecode directly.

GOAAAAAAAAAAAAAAAL!

Lets set ourselves up with a goal for this exercise.

You should have the following User.java file on your system.

public class User {
 
        protected int status = 0;
 
        public boolean setStatusTrue() {
                return this.status == 1;
        }
 
        public static void main(String[] args) {
           System.out.println("Hacking Java Bytecode!");
        }
 
}

Which we compiled using javac.

thedude$ javac User.java

Thus, we should also have a User.class file.

thedude$ ls
User.class  User.java
thedude$

At this point, lets pretend that we were never given the source file. So for clarity, rename the source file to User.java.del.

thedude$ mv User.java User.java.del
thedude$ ls
User.class  User.java.del

In this scenario, despite the fact that you do not have the source code, you still have the compiled class file that the JVM can execute. Lets run it now.

thedude$ java User 
Hacking Java Bytecode!
thedude$

 Our goal will be to change the output from “Hacking Java Bytecode!” to “l33t hax0r bro” by modifying only the compiled source.

Understanding Java Opcodes (Operation Codes)

When we compiled our code using javac, it took the human readable goodness that we cooked up.

public class User {
 
        protected int status = 0;
 
        public boolean setStatusTrue() {
                return this.status == 1;
        }
 
        public static void main(String[] args) {
           System.out.println("Hacking Java Bytecode!");
        }
 
}

And turned it into the computer digestible binary awesome-sauce that the JVM needs. Below seen in hexadecimal using xxd.

thedude@thedude-virtual-machine:~/hackingjavabytecode$ xxd User.class
0000000: cafe babe 0000 0033 0024 0a00 0700 1509  .......3.$......
0000010: 0006 0016 0900 1700 1808 0019 0a00 1a00  ................
0000020: 1b07 001c 0700 1d01 0006 7374 6174 7573  ..........status
0000030: 0100 0149 0100 063c 696e 6974 3e01 0003  ...I......
0000040: 2829 5601 0004 436f 6465 0100 0f4c 696e  ()V...Code...Lin
0000050: 654e 756d 6265 7254 6162 6c65 0100 0d73  eNumberTable...s
0000060: 6574 5374 6174 7573 5472 7565 0100 0328  etStatusTrue...(
0000070: 295a 0100 0d53 7461 636b 4d61 7054 6162  )Z...StackMapTab
0000080: 6c65 0100 046d 6169 6e01 0016 285b 4c6a  le...main...([Lj
0000090: 6176 612f 6c61 6e67 2f53 7472 696e 673b  ava/lang/String;
00000a0: 2956 0100 0a53 6f75 7263 6546 696c 6501  )V...SourceFile.
00000b0: 0009 5573 6572 2e6a 6176 610c 000a 000b  ..User.java.....
00000c0: 0c00 0800 0907 001e 0c00 1f00 2001 0016  ............ ...
00000d0: 4861 636b 696e 6720 4a61 7661 2042 7974  Hacking Java Byt
00000e0: 6563 6f64 6521 0700 210c 0022 0023 0100  ecode!..!..".#..
00000f0: 0455 7365 7201 0010 6a61 7661 2f6c 616e  .User...java/lan
0000100: 672f 4f62 6a65 6374 0100 106a 6176 612f  g/Object...java/
0000110: 6c61 6e67 2f53 7973 7465 6d01 0003 6f75  lang/System...ou
0000120: 7401 0015 4c6a 6176 612f 696f 2f50 7269  t...Ljava/io/Pri
0000130: 6e74 5374 7265 616d 3b01 0013 6a61 7661  ntStream;...java
0000140: 2f69 6f2f 5072 696e 7453 7472 6561 6d01  /io/PrintStream.
0000150: 0007 7072 696e 746c 6e01 0015 284c 6a61  ..println...(Lja
0000160: 7661 2f6c 616e 672f 5374 7269 6e67 3b29  va/lang/String;)
0000170: 5600 2100 0600 0700 0000 0100 0400 0800  V.!.............
0000180: 0900 0000 0300 0100 0a00 0b00 0100 0c00  ................
0000190: 0000 2600 0200 0100 0000 0a2a b700 012a  ..&........*...*
00001a0: 03b5 0002 b100 0000 0100 0d00 0000 0a00  ................
00001b0: 0200 0000 0100 0400 0300 0100 0e00 0f00  ................
00001c0: 0100 0c00 0000 3100 0200 0100 0000 0e2a  ......1........*
00001d0: b400 0204 a000 0704 a700 0403 ac00 0000  ................
00001e0: 0200 0d00 0000 0600 0100 0000 0600 1000  ................
00001f0: 0000 0500 020c 4001 0009 0011 0012 0001  ......@.........
0000200: 000c 0000 0025 0002 0001 0000 0009 b200  .....%..........
0000210: 0312 04b6 0005 b100 0000 0100 0d00 0000  ................
0000220: 0a00 0200 0000 0a00 0800 0b00 0100 1300  ................
0000230: 0000 0200 14

There are two primary things to know concerning compiled Java code.

The first is that Opcodes or “Operational Codes” created by the compiler are simply optimized and formatted instruction sets telling the JVM what to do. In programmer speak, they are reserved words that javac created on compilation.

Just for example, lets randomly take a look at byte 0×19 found on offset line 0×10 when we dumped our User.class file with xxd.

0000010: 0006 0016 0900 1700 1808 0019 0a00 1a00 ................

A logical question would be.

“Jared, how do we know that 0×19 is an instruction Opcode and how do we know what it actually does? ”

Lucky for us we can use a Java Bytecode Reference which tells us that the mnemonic for 0×19 is aload.  

This could lead to the next question.

“What is a mnemonic?”

Mnemonics are simply a way of organization. It is the process of taking something hard to remember (0×19) and associating it with something easier to remember (aload). You can think of mnemonics as a simple conversation.

You “What is the Opcode for aload?”

Me “0×19 is the Opcode you are looking for.”

Another way I visualize the functionality of a particular Opcode, is as a simple procedural function. Here is how it could look using Python.

def aload(stack, pointer):
    # load an object onto the stack
    stack.append(pointer)
    print "Object loaded!"
 
stack = []
pointer = "A string pretending to be an object"
aload(stack, pointer)
thedude$ python aload.py 
Object loaded!
thedude$

For now, we are not going to focus on the the low level details of Opcodes. We just need to be aware at a high level, that the JVM creates them upon compilation, that they are super important, and that we don’t want to accidentally squish them when we attempt to hack on the ASCII text.

The second is that we are accessing the binary data using a hexadecimal tool (xxd, Bless). Because of this, we need a comparison of Hacking Java Bytecode! in both ASCII and hexadecimal.

 H  a  c  k  i  n  g \s  J  a  v  a \s  B  y  t  e  c  o  d  e  !
48 61 63 6B 69 6E 67 20 4A 61 76 61 20 42 79 74 65 63 6F 64 65 21

Each hexadecimal number correspondes with the letter or special character in the example above. Also, an important tool you will rely on is a good calculator that easily converts ASCII, Binary, and Hexadecimal.

Bring on the hack

Now, even though the data is no longer ideal for human consumption or manipulation, this doesn’t mean we are actually prevented from hacking on it. It just means it will take a bit more work.

Take a look at these three lines from the xxd output of our User.class file.

00000c0: 0c00 0800 0907 001e 0c00 1f00 2001 0016  ............ ...
00000d0: 4861 636b 696e 6720 4a61 7661 2042 7974  Hacking Java Byt
00000e0: 6563 6f64 6521 0700 210c 0022 0023 0100  ecode!..!..".#..

You’ll notice that ASCII has been printed on the right, showing us these lines contain the data we are trying to manipulate.

Lets open up the User.class file with Bless. I’ve taken the liberty of highlighting the lines of interest in Bless.

User.class

You can use a tool like the following or hexdump from the command line to convert your string to hex.

thedude$ echo "l33t hax0r bro" | hexdump -v -e '/1 "%02X "' ; echo
6C 33 33 74 20 68 61 78 30 72 20 62 72 6F
thedude$

This means we need to replace the hexadecimal for Hacking Java Bytecode!  (48 61 63 6B 69 6E 67 20 4A 61 76 61 20 42 79 74 65 63 6F 64 65 21) with the hexadecimal for l33t hax0r bro (6C 33 33 74 20 68 61 78 30 72 20 62 72 6F).

Go ahead and run the program again.

thedude$ java User 
Hacking Java Bytecode!
thedude$

Now take the output of the previous hexdump from l33t hax0r bro and paste it over the hex for Hacking Java Bytecode! in Bless.

User.class after hack

Now run your program again.

thedude$ java User
Exception in thread "main" java.lang.ClassFormatError: Illegal UTF8 string in constant pool in class file User
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:787)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:447)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)
thedude$

Doh! What happened?

It is rather simple. When you compiled User.class using javac, the compiler took a count of all the characters in that string and prepended a value in hexadecimal to help validate the strings length.

Let’s count the characters.

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22
 H  a  c  k  i  n  g \s  J  a  v  a \s  B  y  t  e  c  o  d  e  !

This shows us that our original string has twenty-two characters and if we convert the number 22 to hexadecimal we get 0×16. And if you look at the beginning of our line in Bless, you will see that exact value.

Screen Shot 2013-05-17 at 9.31.45 AM

The problem is that now we have changed that string. Which means we need to also change that character count to match the new string.

 1  2  3  4  5  6  7  8  9 10 11 12 13 14
 l  3  3  t \s  h  a  x  0  r \s  b  r  o

You can see that our new string has fourteen characters. So if we convert 14 to hexadecimal we get 0x0E. Now you just need to replace that 0×16 byte with the 0x0E byte and save the file.

Screen Shot 2013-05-17 at 9.34.56 AM

Run the command again!

thedude$ java User
l33t hax0r bro
thedude$

Success!!!

Conclusion

You should now have a decent understanding of JavaBytecode, High Level comprehension concerning Java Opcodes, and the ability to manipulate basic strings inside of compiled source.

In our next installment we are going to talk about more advanced techniques in how to bypass certain code blocks by manipulating the Bytecode directly. We will also start discussing tools that will help us in our effort of reverse engineering.

hacker_cat

The Birds and the Bees of Hex Editing – Hacking Java Bytecode for Programmers (Part1)

Posted on May 14, 2013
At the end of May I am invited to speak at a local user group about Java bytecode hacking. I figured it would BE beneficial to get my thoughts down concerning this topic. Therefore, you my friends, are my guinea pigs. Yay! If you find a mistake, email, comment, whatever, so that I can improve the flow. Werd.

Tools & References

  • Ubuntu 12.10
  • Java 1.7.0_15
  • Python 2.7
  • xxd
  • Bless Hex Editor
  • Jd-gui
  • http://en.wikipedia.org/wiki/Java_bytecode
  • http://en.wikipedia.org/wiki/Hexadecimal
  • http://linuxcommand.org/man_pages/xxd1.html

Audience

Required – You should be comfortable in Linux ( 1+ years )
Required – You should be comfortable writing scripts ( 1+ years )
Desired – You have written web, desktop, or mobile applications ( 1+ years )
Desired – You have programmed in Java and Python ( 6 months )

What is Hexadecimal?

Computers execute binary code. But neck beards were fairly frustrated when editing a binary file and having to parse and edit huge number blocks of ones and zeros. The internet tells me that IBM came along and formalized a hexadecimal standard in the 1950s to pacify their geeks.

Wikipedia puts it nicely.

“the primary use of hexadecimal notation is a human-friendly representation of binary-coded values”

Essentially, hexadecimal makes it much easier to read and edit binary data.

What is a Hex Editor?

A Hex Editor is a handy program that makes editing binary data easier. We will use xxd from the command line. But later we will use Bless which is a GUI Hex editing program.

What is Java Bytecode?

Bytecode is compiled Java code that the JVM (Java Virtual Machine) executes.

That simplistic syllabus doesn’t really tell you much so lets actually show you what is up.

Say you have a User.java class file.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class User {
 
        protected int status = 0;
 
        public boolean setStatusTrue() {
                return this.status == 1;
        }
 
        public static void main(String[] args) {
           System.out.println("Hacking Java Bytecode!");
        }
 
}

Now lets compile it with the Java compiler javac.

thedude$ javac User.java

This will create a compiled User.class file containing data.

thedude$ ls
User.class  User.java
thedude$

Now lets run the program.

thedude$ java User 
Hacking Java Bytecode!
thedude$

But lets actually take a look at the User.class file by dumping it with cat.

thedude$ cat User.class 
����3$
		
StackMapTablemain([Ljava/lang/String;)VrTable
SourceFile	User.java
 
	
          Hacking Java Bytecode!!
                                    "#Userjava/lang/Objectjava/lang/SystemoutLjava/io/PrintStream;java/io/PrintStreamprintln(Ljava/lang/String;)V!
 

 &
*�*��

 1*����
     @	
           %	���

 
thedude$

Well that sucks. What we need to do instead is dump the User.class file with the command line hexadecimal application xxd.

thedude$ xxd User.class 
0000000: cafe babe 0000 0033 0016 0a00 0400 1209  .......3........
0000010: 0003 0013 0700 1407 0015 0100 0673 7461  .............sta
0000020: 7475 7301 0001 4901 0006 3c69 6e69 743e  tus...I...
0000030: 0100 0328 2956 0100 0443 6f64 6501 000f  ...()V...Code...
0000040: 4c69 6e65 4e75 6d62 6572 5461 626c 6501  LineNumberTable.
0000050: 000d 7365 7453 7461 7475 7354 7275 6501  ..setStatusTrue.
0000060: 0003 2829 5a01 000d 5374 6163 6b4d 6170  ..()Z...StackMap
0000070: 5461 626c 6501 0004 6d61 696e 0100 1628  Table...main...(
0000080: 5b4c 6a61 7661 2f6c 616e 672f 5374 7269  [Ljava/lang/Stri
0000090: 6e67 3b29 5601 000a 536f 7572 6365 4669  ng;)V...SourceFi
00000a0: 6c65 0100 0955 7365 722e 6a61 7661 0c00  le...User.java..
00000b0: 0700 080c 0005 0006 0100 0455 7365 7201  ...........User.
00000c0: 0010 6a61 7661 2f6c 616e 672f 4f62 6a65  ..java/lang/Obje
00000d0: 6374 0021 0003 0004 0000 0001 0004 0005  ct.!............
00000e0: 0006 0000 0003 0001 0007 0008 0001 0009  ................
00000f0: 0000 0026 0002 0001 0000 000a 2ab7 0001  ...&........*...
0000100: 2a03 b500 02b1 0000 0001 000a 0000 000a  *...............
0000110: 0002 0000 0001 0004 0003 0001 000b 000c  ................
0000120: 0001 0009 0000 0031 0002 0001 0000 000e  .......1........
0000130: 2ab4 0002 04a0 0007 04a7 0004 03ac 0000  *...............
0000140: 0002 000a 0000 0006 0001 0000 0006 000d  ................
0000150: 0000 0005 0002 0c40 0100 0900 0e00 0f00  .......@........
0000160: 0100 0900 0000 1900 0000 0100 0000 01b1  ................
0000170: 0000 0001 000a 0000 0006 0001 0000 000b  ................
0000180: 0001 0010 0000 0002 0011                 ..........
thedude$

Voila! Much better. A hex dump containing bytecode. Right?! RIGHT?!?

Well, kinda. If you are a newb (don’t worry, everyone is, we are all just faking it) then there are three distinct logical groupings to account for.

Hexcode Viewer Breakdown

The Offset is on the left and is not part of the file but rather derived from the Hex editing/dumping application. You can think of the offset as the line number of a hex dump. Kind of like when you edit the source code of a file.

In the middle is the Bytecode represented using Hexadecimal. This is the actual data of the file we are editing. Eventually this is the portion we will manipulate to change our application’s behavior.

Finally there is the ASCII viewer on the right.The viewer tries its best to display ASCII when it detects and decodes the text in the file. When it can decode the ASCII text correctly, you wil find it displayed. At times though ASCII cannot be rendered. Here you’ll usually see a dot “.” indicating a special character.

bytecode_highlights

 

Hexcode Viewer Gotcha

Unlike source code where the line number “1″ is always going to be the line number “1″, you can change the offset of your hex editor. Having the correct offset is critical. In my opinion, a problem with some GUI hex editors is that when you resize your editor window, most of them will automagically adjust the offset.

To illustrate this, here is the default xxd output of our User.class file using 16 columns as well as the output of xxd using 10 columns. This should prove that nothing has fundamentally changed about the bytecode data stored in our file. The only thing that has changed is the way the data is being displayed.

(I’ve bolded, italicized, and highlighted the exact same byte in blue.)

thedude$ xxd User.class
0000000: cafe babe 0000 0033 0016 0a00 0400 1209 .......3........
0000010: 0003 0013 0700 1407 0015 0100 0673 7461 .............sta
0000020: 7475 7301 0001 4901 0006 3c69 6e69 743e tus...I...
0000030: 0100 0328 2956 0100 0443 6f64 6501 000f ...()V...Code...
0000040: 4c69 6e65 4e75 6d62 6572 5461 626c 6501 LineNumberTable.
0000050: 000d 7365 7453 7461 7475 7354 7275 6501 ..setStatusTrue.
0000060: 0003 2829 5a01 000d 5374 6163 6b4d 6170 ..()Z...StackMap
0000070: 5461 626c 6501 0004 6d61 696e 0100 1628 Table...main...(
0000080: 5b4c 6a61 7661 2f6c 616e 672f 5374 7269 [Ljava/lang/Stri
0000090: 6e67 3b29 5601 000a 536f 7572 6365 4669 ng;)V...SourceFi
00000a0: 6c65 0100 0955 7365 722e 6a61 7661 0c00 le...User.java..
00000b0: 0700 080c 0005 0006 0100 0455 7365 7201 ...........User.
00000c0: 0010 6a61 7661 2f6c 616e 672f 4f62 6a65 ..java/lang/Obje
00000d0: 6374 0021 0003 0004 0000 0001 0004 0005 ct.!............
00000e0: 0006 0000 0003 0001 0007 0008 0001 0009 ................
00000f0: 0000 0026 0002 0001 0000 000a 2ab7 0001 ...&........*...
0000100: 2a03 b500 02b1 0000 0001 000a 0000 000a *...............
0000110: 0002 0000 0001 0004 0003 0001 000b 000c ................
0000120: 0001 0009 0000 0031 0002 0001 0000 000e .......1........
0000130: 2ab4 0002 04a0 0007 04a7 0004 03ac 0000 *...............
0000140: 0002 000a 0000 0006 0001 0000 0006 000d ................
0000150: 0000 0005 0002 0c40 0100 0900 0e00 0f00 .......@........
0000160: 0100 0900 0000 1900 0000 0100 0000 01b1 ................
0000170: 0000 0001 000a 0000 0006 0001 0000 000b ................
0000180: 0001 0010 0000 0002 0011 ..........
thedude$

thedude$ xxd -c 10 User.class
0000000: cafe babe 0000 0033 0016 .......3..
000000a: 0a00 0400 1209 0003 0013 ..........
0000014: 0700 1407 0015 0100 0673 .........s
000001e: 7461 7475 7301 0001 4901 tatus...I.
0000028: 0006 3c69 6e69 743e 0100 ....
0000032: 0328 2956 0100 0443 6f64 .()V...Cod
000003c: 6501 000f 4c69 6e65 4e75 e...LineNu
0000046: 6d62 6572 5461 626c 6501 mberTable.
0000050: 000d 7365 7453 7461 7475 ..setStatu
000005a: 7354 7275 6501 0003 2829 sTrue...()
0000064: 5a01 000d 5374 6163 6b4d Z...StackM
000006e: 6170 5461 626c 6501 0004 apTable...
0000078: 6d61 696e 0100 1628 5b4c main...([L
0000082: 6a61 7661 2f6c 616e 672f java/lang/
000008c: 5374 7269 6e67 3b29 5601 String;)V.
0000096: 000a 536f 7572 6365 4669 ..SourceFi
00000a0: 6c65 0100 0955 7365 722e le...User.
00000aa: 6a61 7661 0c00 0700 080c java......
00000b4: 0005 0006 0100 0455 7365 .......Use
00000be: 7201 0010 6a61 7661 2f6c r...java/l
00000c8: 616e 672f 4f62 6a65 6374 ang/Object
00000d2: 0021 0003 0004 0000 0001 .!........
00000dc: 0004 0005 0006 0000 0003 ..........
00000e6: 0001 0007 0008 0001 0009 ..........
00000f0: 0000 0026 0002 0001 0000 ...&......
00000fa: 000a 2ab7 0001 2a03 b500 ..*...*...
0000104: 02b1 0000 0001 000a 0000 ..........
000010e: 000a 0002 0000 0001 0004 ..........
0000118: 0003 0001 000b 000c 0001 ..........
0000122: 0009 0000 0031 0002 0001 .....1....
000012c: 0000 000e 2ab4 0002 04a0 ....*.....
0000136: 0007 04a7 0004 03ac 0000 ..........
0000140: 0002 000a 0000 0006 0001 ..........
000014a: 0000 0006 000d 0000 0005 ..........
0000154: 0002 0c40 0100 0900 0e00 ...@......
000015e: 0f00 0100 0900 0000 1900 ..........
0000168: 0000 0100 0000 01b1 0000 ..........
0000172: 0001 000a 0000 0006 0001 ..........
000017c: 0000 000b 0001 0010 0000 ..........
0000186: 0002 0011 ....
thedude$

How I (a programmer) think about Bytecode

How I like to think about Bytecode is usually in two ways.

(1)

If I’m operating in a Hex editing application I usually just think of the bytecode as a multidimensional array.

Lets take a look at the first two lines of our User.class dumped using 16 column formatting.

0000000: cafe babe 0000 0033 0016 0a00 0400 1209  .......3........
0000010: 0003 0013 0700 1407 0015 0100 0673 7461  .............sta

Then lets strip out the Offset and the ASCII text.

cafe babe 0000 0033 0016 0a00 0400 1209
0003 0013 0700 1407 0015 0100 0673 7461

And finally we take those bytes and create a multidimensional array using Python to illustrate this.

Python

bytecode_multi_array = [
  ['ca','fe','ba','be','00','00','00','33','00','16','0a','00','04','00','12','09'],
  ['00','03','00','13','07','00','14','07','00','15','01','00','06','73','74','61']
]
# print array 0 which is actually the first line of our bytecode dump 
print bytecode_multi_array[0]

 (2)

The other way is a bit more hardcore. I simply just visualize the bytecode stream.

Take this bytecode_stream.py script I wrote.

import os
_directory = './'
_file = 'User.class'
if os.path.exists(_directory):
        with open(_file, "rb") as f:
                print "read file: %s" % _file
                stream = f.read()
                f.close
                print "print the bytecode stream"
                print stream.encode('hex')

If you run it from the same directory that our User.class file is stored in you’ll get the following.

thedude$ python bytecode_stream.py 
read file: User.class
print the bytecode stream
cafebabe0000003300160a000400120900030013070014070015010006737461747573010001490100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c6501000d7365745374617475735472756501000328295a01000d537461636b4d61705461626c650100046d61696e010016285b4c6a6176612f6c616e672f537472696e673b295601000a536f7572636546696c65010009557365722e6a6176610c000700080c00050006010004557365720100106a6176612f6c616e672f4f626a65637400210003000400000001000400050006000000030001000700080001000900000026000200010000000a2ab700012a03b50002b100000001000a0000000a000200000001000400030001000b000c0001000900000031000200010000000e2ab4000204a0000704a7000403ac00000002000a00000006000100000006000d0000000500020c40010009000e000f00010009000000190000000100000001b100000001000a0000000600010000000b00010010000000020011
thedude$

Essentially the bytecode is just one long string.

cafebabe0000003300160a000400120900030013070014070015010006737461747573010001490100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c6501000d7365745374617475735472756501000328295a01000d537461636b4d61705461626c650100046d61696e010016285b4c6a6176612f6c616e672f537472696e673b295601000a536f7572636546696c65010009557365722e6a6176610c000700080c00050006010004557365720100106a6176612f6c616e672f4f626a65637400210003000400000001000400050006000000030001000700080001000900000026000200010000000a2ab700012a03b50002b100000001000a0000000a000200000001000400030001000b000c0001000900000031000200010000000e2ab4000204a0000704a7000403ac00000002000a00000006000100000006000d0000000500020c40010009000e000f00010009000000190000000100000001b100000001000a0000000600010000000b00010010000000020011

Conclusion

Hopefully you have a decent understanding on how to view compiled Java Bytecode using the hex dumping program xxd.

You also should understand how, when using Python, we opened the compiled Java Bytecode file and dumped it to screen in hex format. We will be using Python to do some hacking in the future.

In Part 2 we will take a look at Java Op codes and actually manipulating the compiled Bytecode by hand using a hex editor.

Google Nexus 4 Alert – Powered By Twilio

Posted on January 8, 2013

1221580Seeing as I’m switching jobs and my soon-to-be previous employer kindly provided my current cell phone, I am in need of a new one.

After review, I made the decision to purchase the Nexus 4. An unlocked phone that I can bounce around between pre-paid networks seems like a killer deal. But upon checking Google’s site, I was bummed to learn that it was sold out. So I checked the status the following day. Sold out. I checked the next day. Still sold out. And the next. Sold out.

I investigated Ebay hoping that maybe the premium wouldn’t be too painful. Unfortunately most sellers prices are adding a $150-$300 dollar premium. Which is when I decided to hack.

Using Twilio’s API, I built a small bot that notifies me via txt message when the Nexus 4 becomes available again. I’ve uploaded the code to github. Enjoy.

How To: Install FreeTDS and UnixODBC On OSX Using Homebrew For Use With Ruby, Php, And Perl

This little project started out as a basic script to connect to a Microsoft SqlServer and get data. It was a nightmare as I probably spent 15 hours learning about and troubleshooting both FreeTDS and UnixODBC. My pain is now your gain.

NOTICE: I have homebrew configured to install all packages into my local directory /Users/jared/.homebrew/

1) Install UnixODBC

[jared@localhost]$ brew install unixodbc
==> Downloading http://www.unixodbc.org/unixODBC-2.3.0.tar.gz
File already downloaded in /Users/jared/Library/Caches/Homebrew
==> ./configure --disable-debug --prefix=/Users/jared/.homebrew/Cellar/unixodbc/2.3.0 --enable-gui=no
==> make install
/Users/jared/.homebrew/Cellar/unixodbc/2.3.0: 24 files, 932K, built in 22 seconds
[jared@localhost]$

2) Edit the FreeTDS formula And install

What we are doing is changing the default tds version, enabling the msdblib, and pointing out where unixodbc installed.

require 'formula'
 
class Freetds > Formula
url 'http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-0.91.tar.gz'
homepage 'http://www.freetds.org/'
md5 'b14db5823980a32f0643d1a84d3ec3ad'
 
def install
system "./configure""--prefix=#{prefix}""--with-tdsver=7.0""--enable-msdblib",
"--with-unixodbc=/Users/USERNAME/.homebrew/Cellar/unixodbc/2.3.0",
"--mandir=#{man}"
system 'make'
ENV.j1 # Or fails to install on multi-core machines
system 'make install'
end
end
[jared@localhost]$ brew install freetds

3) Start a new terminal session to make sure all your paths update

4) Confirm that you can connect to the server

We need to make sure that you can connect to the sqlserver and that the port is open and available to you.

To do this we use telnet. If you see the following, success! The port is open on the server.

[jared@localhost]$ telnet server.example.com 1433
Trying 192.168.1.101...
Connected to server.example.com.
Escape character is '^]'.

If you see the following. You failed. Check the Sqlserver configuration, firewalls, or network configuration.

[jared@localhost]$ telnet server.example.com 1433
Trying 192.168.1.101...
telnet: connect to address 192.168.1.101: Connection refused
telnet: Unable to connect to remote host

Note: Press the ctrl + ] keys to break to a prompt and then type exit.

5) Tsql

FreeTDS comes with a couple cli applications. One of them is tsql. It isn’t great, but I use it test and see if at least FreeTDS is working correctly. After you install FreeTDS using homebrew try and connect to the host using the following command.

[jared@localhost]$ tsql -H server.example.com -U USERNAME -P PASSWORD -v
 
locale is "en_US.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
1>exit

If you see a prompt, you haz awesome!

6) Sym link the FreeTDS and UnixODBC conf files

I create 3 sym links to the following files just for simplicity.

ln -s /Users/jared/.homebrew/Cellar/freetds/0.91/etc/freetds.conf ~/.freetds.conf
ln -s /Users/jared/.homebrew/Cellar/unixodbc/2.3.0/etc/odbc.ini ~/.odbc.ini
ln -s /Users/jared/.homebrew/Cellar/unixodbc/2.3.0/etc/odbcinst.ini ~/.odbcinst.ini

7) edit the .freetds.conf and add the following

[example]
host = server.example.com
port = 1433
tds version = 7.0

8 ) edit the odbcinst.ini and add the following

You are telling unixodbc where your FreeTDS drivers are located using this configuration file.

[FreeTDS]
Description = FreeTDS
Driver = /Users/jared/.homebrew/lib/libtdsodbc.so
Setup = /Users/jared/.homebrew/lib/libtdsodbc.so
UsageCount = 1

9) edit the .odbc.ini and add the following

[myexample]
Driver = FreeTDS // we just set this up a second ago
Description = MyExample
ServerName = example // this is the name of the configuration we used in the .freetds.conf file
UID = USERNAME
PWD = PASSWORD

10) isql should work

[jared@localhost]$ isql sqlinternal USERNAME PASSWORD
+---------------------------------------+
| Connected!
| sql-statement
| help [tablename]
| quit
+---------------------------------------+
SQL>quit

11) Osql Error

If you try osql, it throws an error.

[jared@localhost]$ osql -S myexample -U USERNAME -P PASSWORD
checking shared odbc libraries linked to isql for default directories...
/Users/jared/.homebrew/bin/osql: line 53: ldd: command not found
strings: can't open file: (No such file or directory)
osql: problem: no potential directory strings in "/Users/jared/.homebrew/bin/isql"
osql: advice: use "osql -I DIR" where DIR unixODBC\'s install prefix e.g. /usr/local
isql strings are:
checking odbc.ini files
reading /Users/jared/.odbc.ini
[myexample] found in /Users/jared/.odbc.ini
found this section:
[myexample]
Driver = FreeTDS
Description = MyExample
Servername = example
UID = USERNAME
PWD = PASSWORD
 
looking for driver for DSN [myexample] in /Users/jared/.odbc.ini
found driver line: " Driver = FreeTDS"
driver "FreeTDS" found for [myexample] in .odbc.ini
found driver named "FreeTDS"
"FreeTDS" is not an executable file
looking for entry named [FreeTDS] in /odbcinst.ini
found driver line: " Driver = /Users/jared/.homebrew/lib/libtdsodbc.so"
found driver /Users/jared/.homebrew/lib/libtdsodbc.so for [FreeTDS] in odbcinst.ini
/Users/jared/.homebrew/lib/libtdsodbc.so is not an executable file
osql: error: no driver found for sqlinternal
[jared@localhost]$

If you go through the error you will find that a certain driver is not executable. You just need to chmod the file.

[jared@localhost]$ chmod 554 /Users/jared/.homebrew/Cellar/freetds/0.91/lib/libtdsodbc.0.so

Now run it again.

[jared@localhost]$ osql -S myexample -U USERNAME -P PASSWORD
checking shared odbc libraries linked to isql for default directories...
/Users/jared/.homebrew/bin/osql: line 53: ldd: command not found
strings: can't open file: (No such file or directory)
osql: problem: no potential directory strings in "/Users/jared/.homebrew/bin/isql"
osql: advice: use "osql -I DIR" where DIR unixODBC\'s install prefix e.g. /usr/local
isql strings are:
checking odbc.ini files
reading /Users/jared/.odbc.ini
[myexample] found in /Users/jared/.odbc.ini
found this section:
[myexample]
Driver = FreeTDS
Description = myexamples
Servername = myexample
UID = USERNAME
PWD = PASSWORD
 
looking for driver for DSN [myexample] in /Users/jared/.odbc.ini
found driver line: " Driver = FreeTDS"
driver "FreeTDS" found for [myexample] in .odbc.ini
found driver named "FreeTDS"
"FreeTDS" is not an executable file
looking for entry named [FreeTDS] in /odbcinst.ini
found driver line: " Driver = /Users/jared/.homebrew/lib/libtdsodbc.so"
found driver /Users/jared/.homebrew/lib/libtdsodbc.so for [FreeTDS] in odbcinst.ini
/Users/jared/.homebrew/lib/libtdsodbc.so is an executable file
Using ODBC-Combined strategy
DSN [myexample] has servername "myexample" (from /Users/jared/.odbc.ini)
/Users/jared/.freetds.conf is a readable file
looking for [myexample] in /Users/jared/.freetds.conf
found this section:
[myexample]
host = myexample.bendcable.net
port = 1433
tds version = 7.0
 
Configuration looks OK. Connection details:
 
DSN: myexample
odbc.ini: /Users/jared/.odbc.ini
Driver: /Users/jared/.homebrew/lib/libtdsodbc.so
Server hostname: myexample.bendcable.net
Address: 192.168.12.103
 
Attempting connection as username ...
+ isql myexample USERNAME PASSWORD -v
+---------------------------------------+
| Connected!
| sql-statement
| help [tablename]
| quit
+---------------------------------------+
SQL> quit

SUCCESS!!!

Some other useful commands.

Useful commands

odbcinst -j
 
odbcinst -q -d
 
odbcinst -q -s
Older Posts