Danny Mandel
(dmandel@cs.arizona.edu)
Anna Segurson
(segurson@cs.arizona.edu)
This algorithm embeds a static watermark in a java *.jar file through the sandmark interface. It first converts the watermark (which is a String) to a number. This number is then encoded into the java byte code by adding bogus local variable to one method of one class in the *.jar file. The class in which the method is in is marked by a extra field variable that contains the name of the method.
Each number of the watermark is mapped to a specific type:
Number | Type |
0 | java.util.GregorianCalendar |
1 | java.lang.Thread |
2 | java.util.Vector |
3 | java.util.Stack |
4 | java.util.Date |
5 | java.io.InputStream |
6 | java.io.ObjectInputStream |
7 | java.lang.Math |
8 | java.io.OutputStream |
9 | java.lang.String |
A local variable of the proper type is created for each digit of the watermark and the digit's location in the watermark is stored in the name of the bogus local variable.
Embedding
The watermark is embedded in the first non-abstract method found in the
first class file of the jar file. The name of the method is recorded in
the name of a field with the value of a hockey player's name. These are
the local variables added to a class when the watermark ``Howdy!" was
embedded:
Math yzerman$0 = new Math(); String yzerman$1 = new String(); ObjectInputStream yzerman$2 = new ObjectInputStream(); Stack yzerman$3 = new Stack(); InputStream yzerman$4 = new InputStream(); Stack yzerman$5 = new Stack(); OutputStream yzerman$6 = new OutputStream(); InputStream yzerman$7 = new InputStream(); InputStream yzerman$8 = new InputStream(); OutputStream yzerman$9 = new OutputStream(); Thread yzerman$10 = new Thread(); Thread yzerman$11 = new Thread(); Thread yzerman$12 = new Thread(); ObjectInputStream yzerman$13 = new ObjectInputStream(); Stack yzerman$14 = new Stack();
This is the field that is added:
public static final String hat<init>Trick = "Vrbata";
where <init> is the name of the method the watermark is
in.
Recognition
The watermark is recognized when the proper field is present which
stores the name of the method. Every local variable that contains the
SECRET_NAME in that method is part of the watermark.
In the example listed above yzerman is the secret name. To
recover the number stored by the SECRET_NAME variables, the
algorithm initializes a number, wm, to zero then loops through
all of the locals in the method and adds the mapped value of the
variable times 10 to the power of the number after the $ to wm.
After the number is recovered it is converted back to the watermark
string.