mirror of
https://github.com/revanced/smali.git
synced 2025-05-28 11:50:12 +02:00
Initial commit
git-svn-id: https://smali.googlecode.com/svn/trunk@2 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
06a26914de
commit
f10d1a3598
56
pom.xml
Normal file
56
pom.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>smali</groupId>
|
||||
<artifactId>smali</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr3-maven-plugin</artifactId>
|
||||
<version>3.1.3-1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>smali</id>
|
||||
<goals>
|
||||
<goal>antlr</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes><exclude>org/JesusFreke/smali/smaliTreeWalker.g</exclude></excludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>smaliTreeWalker</id>
|
||||
<goals>
|
||||
<goal>antlr</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes><exclude>org/JesusFreke/smali/smali.g</exclude></excludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr-runtime</artifactId>
|
||||
<version>3.1.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
594
src/main/antlr3/org/JesusFreke/smali/smali.g
Normal file
594
src/main/antlr3/org/JesusFreke/smali/smali.g
Normal file
@ -0,0 +1,594 @@
|
||||
/*
|
||||
* The comment lexical rule, and the number, string and character constant
|
||||
* lexical rules are derived from rules from the Java 1.6 grammar which can be
|
||||
* found here: http://openjdk.java.net/projects/compiler-grammar/antlrworks/Java.g
|
||||
*
|
||||
* Specifically, these rules:
|
||||
*
|
||||
* COMMENT, LONG_LITERAL, INT_LITERAL, Integer_number, Hex_prefix, Hex_digit,
|
||||
* Long_suffix, Non_integer_number_SIMPLE_NAME, Non_integer_number,
|
||||
* Decimal_exponent, Hex_exponent, Float_suffix, Double_suffix,
|
||||
* FLOAT_LITERAL_SIMPLE_NAME, FLOAT_LITERAL, DOUBLE_LITERAL_SIMPLE_NAME,
|
||||
* DOUBLE_LITERAL, CHAR_LITERAL, STRING_LITERAL, EscapeSequence
|
||||
*
|
||||
* These rules were originally copyrighted by Terence Parr, and are used here in
|
||||
* accordance with the following license
|
||||
*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2007-2008 Terence Parr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* The remainder of this grammar is released by me (Ben Gruver) under the
|
||||
* following license:
|
||||
*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
grammar smali;
|
||||
|
||||
options {
|
||||
output=AST;
|
||||
ASTLabelType=CommonTree;
|
||||
}
|
||||
|
||||
tokens {
|
||||
//I_* tokens are imaginary tokens used as parent AST nodes
|
||||
I_CLASS_DEF;
|
||||
I_SUPER;
|
||||
I_ACCESS_LIST;
|
||||
I_METHODS;
|
||||
I_FIELDS;
|
||||
I_FIELD;
|
||||
I_FIELD_TYPE;
|
||||
I_FIELD_INITIAL_VALUE;
|
||||
I_METHOD;
|
||||
I_METHOD_PROTOTYPE;
|
||||
I_METHOD_RETURN_TYPE;
|
||||
I_REGISTERS;
|
||||
I_STATEMENTS;
|
||||
I_INVOKE_STATEMENT;
|
||||
I_INVOKE_RANGE_STATEMENT;
|
||||
I_BARE_STATEMENT;
|
||||
I_STATIC_FIELD_STATEMENT;
|
||||
I_INSTANCE_FIELD_STATEMENT;
|
||||
I_CONST_STRING_STATEMENT;
|
||||
I_NEW_INSTANCE_STATEMENT;
|
||||
I_SINGLE_REGISTER_STATEMENT;
|
||||
I_REGISTER_RANGE;
|
||||
I_REGISTER_LIST;
|
||||
}
|
||||
|
||||
@parser::header {
|
||||
package org.JesusFreke.smali;
|
||||
}
|
||||
|
||||
@lexer::header {
|
||||
package org.JesusFreke.smali;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
}
|
||||
|
||||
@lexer::init {
|
||||
state.token = Token.INVALID_TOKEN;
|
||||
}
|
||||
|
||||
@lexer::members {
|
||||
protected ArrayDeque<Token> tokens = new ArrayDeque<Token>();
|
||||
|
||||
public void reset() {
|
||||
super.reset();
|
||||
state.token = Token.INVALID_TOKEN;
|
||||
tokens.clear();
|
||||
}
|
||||
|
||||
public Token nextToken() {
|
||||
while (true) {
|
||||
if (tokens.size() > 0) {
|
||||
Token token = tokens.poll();
|
||||
if (token == Token.SKIP_TOKEN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
state.channel = Token.DEFAULT_CHANNEL;
|
||||
state.tokenStartCharIndex = input.index();
|
||||
state.tokenStartCharPositionInLine = input.getCharPositionInLine();
|
||||
state.tokenStartLine = input.getLine();
|
||||
state.text = null;
|
||||
if ( input.LA(1)==CharStream.EOF ) {
|
||||
return Token.EOF_TOKEN;
|
||||
}
|
||||
try {
|
||||
mTokens();
|
||||
|
||||
if (tokens.size() == 0) {
|
||||
emit();
|
||||
}
|
||||
}
|
||||
catch (NoViableAltException nva) {
|
||||
reportError(nva);
|
||||
recover(nva); // throw out current char and try again
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
reportError(re);
|
||||
// match() routine has already called recover()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void skip() {
|
||||
tokens.add(Token.SKIP_TOKEN);
|
||||
}
|
||||
|
||||
public void emit(Token token) {
|
||||
tokens.add(token);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
smali_file: header methods_and_fields -> ^(I_CLASS_DEF header methods_and_fields);
|
||||
|
||||
header : class_spec super_spec;
|
||||
|
||||
class_spec
|
||||
: '.class' access_list class_name -> class_name access_list;
|
||||
|
||||
super_spec
|
||||
: first_token='.super' class_name -> ^(I_SUPER[$first_token, "I_SUPER"] class_name);
|
||||
|
||||
access_list
|
||||
: first_token=ACCESS_SPEC ACCESS_SPEC* -> ^(I_ACCESS_LIST[$first_token,"I_ACCESS_LIST"] ACCESS_SPEC+);
|
||||
|
||||
methods_and_fields
|
||||
: (method | field)* -> ^(I_METHODS method*) ^(I_FIELDS field*);
|
||||
|
||||
field : first_token='.field' access_list member_name field_type_descriptor ('=' literal)?
|
||||
-> ^(I_FIELD[$first_token, "I_FIELD"] member_name access_list ^(I_FIELD_TYPE field_type_descriptor) ^(I_FIELD_INITIAL_VALUE literal)?);
|
||||
|
||||
method : first_token='.method' access_list method_name_and_prototype locals_directive statements '.end method'
|
||||
-> ^(I_METHOD[$first_token, "I_METHOD"] method_name_and_prototype access_list locals_directive statements);
|
||||
|
||||
method_prototype
|
||||
: first_token='(' field_type_list ')' type_descriptor
|
||||
-> ^(I_METHOD_PROTOTYPE[$first_token, "I_METHOD_PROTOTYPE"] ^(I_METHOD_RETURN_TYPE type_descriptor) field_type_list?);
|
||||
|
||||
method_name_and_prototype
|
||||
: member_name method_prototype;
|
||||
|
||||
field_type_list
|
||||
: field_type_descriptor*;
|
||||
|
||||
locals_directive
|
||||
: first_token='.registers' INT_LITERAL
|
||||
-> ^(I_REGISTERS[$first_token, "I_REGISTERS"] INT_LITERAL);
|
||||
|
||||
|
||||
full_method_name_and_prototype
|
||||
: QUALIFIED_MEMBER__CLASS_NAME QUALIFIED_MEMBER__MEMBER_NAME method_prototype;
|
||||
|
||||
full_field_name_and_type
|
||||
: QUALIFIED_MEMBER__CLASS_NAME QUALIFIED_MEMBER__MEMBER_NAME field_type_descriptor;
|
||||
|
||||
statements
|
||||
: statement* -> ^(I_STATEMENTS statement*);
|
||||
|
||||
statement
|
||||
: instruction;
|
||||
|
||||
instruction
|
||||
//e.g. return
|
||||
: BARE_INSTRUCTION_NAME
|
||||
-> ^(I_BARE_STATEMENT[$start, "I_BARE_STATEMENT"] BARE_INSTRUCTION_NAME)
|
||||
| //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
|
||||
INVOKE_INSTRUCTION_NAME '{' register_list '}' full_method_name_and_prototype
|
||||
-> ^(I_INVOKE_STATEMENT[$start, "I_INVOKE_STATEMENT"] INVOKE_INSTRUCTION_NAME register_list full_method_name_and_prototype)
|
||||
| //e.g. invoke-virtual/range {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||
INVOKE_RANGE_INSTRUCTION_NAME '{' register_range '}' full_method_name_and_prototype
|
||||
-> ^(I_INVOKE_RANGE_STATEMENT[$start, "I_INVOKE_RANGE_STATEMENT"] INVOKE_RANGE_INSTRUCTION_NAME register_range full_method_name_and_prototype)
|
||||
| //e.g. sget_object v0 java/lang/System/out LJava/io/PrintStream;
|
||||
STATIC_FIELD_INSTRUCTION_NAME REGISTER full_field_name_and_type
|
||||
-> ^(I_STATIC_FIELD_STATEMENT[$start, "I_STATIC_FIELD_STATEMENT"] STATIC_FIELD_INSTRUCTION_NAME REGISTER full_field_name_and_type)
|
||||
| //e.g. iput-object v1 v0 org/JesusFreke/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
|
||||
INSTANCE_FIELD_INSTRUCTION_NAME REGISTER REGISTER full_field_name_and_type
|
||||
-> ^(I_INSTANCE_FIELD_STATEMENT[$start, "I_INSTANCE_FIELD_STATEMENT"] INSTANCE_FIELD_INSTRUCTION_NAME REGISTER REGISTER full_field_name_and_type)
|
||||
| //e.g. const-string v1 "Hello World!"
|
||||
CONST_STRING_INSTRUCTION_NAME REGISTER STRING_LITERAL
|
||||
-> ^(I_CONST_STRING_STATEMENT[$start, "I_CONST_STRING_STATMENT"] CONST_STRING_INSTRUCTION_NAME REGISTER STRING_LITERAL)
|
||||
| //e.g. new-instance v1 android/widget/TextView
|
||||
NEW_INSTANCE_INSTRUCTION_NAME REGISTER class_name
|
||||
-> ^(I_NEW_INSTANCE_STATEMENT[$start, "I_NEW_INSTANCE_STATEMENT"] NEW_INSTANCE_INSTRUCTION_NAME REGISTER class_name)
|
||||
| //e.g. move-result-object v1
|
||||
SINGLE_REGISTER_INSTRUCTION_NAME REGISTER
|
||||
-> ^(I_SINGLE_REGISTER_STATEMENT[$start, "I_SINGLE_REGISTER_STATEMENT"] SINGLE_REGISTER_INSTRUCTION_NAME REGISTER)
|
||||
;
|
||||
|
||||
|
||||
register_list
|
||||
: first_token=REGISTER? (',' REGISTER)* -> ^(I_REGISTER_LIST[$first_token, "I_REGISTER_LIST"] REGISTER*);
|
||||
|
||||
register_range
|
||||
: first_token=REGISTER ('..' REGISTER)? -> ^(I_REGISTER_RANGE[$first_token, "I_REGISTER_RANGE"] REGISTER REGISTER?);
|
||||
|
||||
/*since there are no reserved words in the dex specification, there are a
|
||||
number of tokens that can be a valid simple_name, in addition to just
|
||||
SIMPLE_NAME. We need to match any token that could also be considered a valid
|
||||
SIMPLE_NAME. In the case of floating point literals, some could be considered
|
||||
a valid SIMPLE_NAME while others couldn't. The lexer will generate a separate
|
||||
FLOAT_LITERAL_SIMPLE_NAME OR DOUBLE_LITERAL_SIMPLE_NAME token for literals
|
||||
that can be considered a valid SIMPLE_NAME*/
|
||||
simple_name
|
||||
: SIMPLE_NAME
|
||||
| ACCESS_SPEC
|
||||
| instruction_name
|
||||
| INT_LITERAL
|
||||
| LONG_LITERAL
|
||||
| FLOAT_LITERAL_SIMPLE_NAME
|
||||
| DOUBLE_LITERAL_SIMPLE_NAME
|
||||
| BOOL_LITERAL
|
||||
| PRIMITIVE_TYPE
|
||||
;
|
||||
|
||||
instruction_name
|
||||
: INVOKE_INSTRUCTION_NAME
|
||||
| INVOKE_RANGE_INSTRUCTION_NAME
|
||||
| STATIC_FIELD_INSTRUCTION_NAME
|
||||
| INSTANCE_FIELD_INSTRUCTION_NAME
|
||||
| BARE_INSTRUCTION_NAME
|
||||
| CONST_STRING_INSTRUCTION_NAME
|
||||
| NEW_INSTANCE_INSTRUCTION_NAME
|
||||
| SINGLE_REGISTER_INSTRUCTION_NAME
|
||||
;
|
||||
|
||||
member_name
|
||||
: simple_name
|
||||
| MEMBER_NAME
|
||||
;
|
||||
|
||||
class_name
|
||||
: SIMPLE_NAME | CLASS_WITH_PACKAGE_NAME;
|
||||
|
||||
field_type_descriptor
|
||||
: PRIMITIVE_TYPE
|
||||
| CLASS_DESCRIPTOR
|
||||
| ARRAY_TYPE
|
||||
;
|
||||
|
||||
type_descriptor
|
||||
: VOID_TYPE
|
||||
| field_type_descriptor
|
||||
;
|
||||
|
||||
literal : INT_LITERAL
|
||||
| LONG_LITERAL
|
||||
| float_literal
|
||||
| double_literal
|
||||
| CHAR_LITERAL
|
||||
| STRING_LITERAL
|
||||
| BOOL_LITERAL;
|
||||
|
||||
float_literal
|
||||
: FLOAT_LITERAL -> FLOAT_LITERAL
|
||||
| FLOAT_LITERAL_SIMPLE_NAME -> FLOAT_LITERAL[$FLOAT_LITERAL_SIMPLE_NAME, $FLOAT_LITERAL_SIMPLE_NAME.text];
|
||||
|
||||
double_literal
|
||||
: DOUBLE_LITERAL -> DOUBLE_LITERAL
|
||||
| DOUBLE_LITERAL_SIMPLE_NAME -> DOUBLE_LITERAL[$DOUBLE_LITERAL_SIMPLE_NAME, $DOUBLE_LITERAL_SIMPLE_NAME.text];
|
||||
|
||||
ACCESS_SPEC
|
||||
: 'public' | 'private' | 'static' | 'constructor' | 'final';
|
||||
|
||||
INVOKE_INSTRUCTION_NAME
|
||||
: 'invoke-virtual'
|
||||
| 'invoke-super'
|
||||
| 'invoke-direct'
|
||||
| 'invoke-static'
|
||||
| 'invoke-interface'
|
||||
;
|
||||
|
||||
INVOKE_RANGE_INSTRUCTION_NAME
|
||||
: 'invoke-virtual/range'
|
||||
| 'invoke-super/range'
|
||||
| 'invoke-direct/range'
|
||||
| 'invoke-static/range'
|
||||
| 'invoke-interface/range'
|
||||
;
|
||||
|
||||
STATIC_FIELD_INSTRUCTION_NAME
|
||||
: 'sget'
|
||||
| 'sget-wide'
|
||||
| 'sget-object'
|
||||
| 'sget-boolean'
|
||||
| 'sget-byte'
|
||||
| 'sget-char'
|
||||
| 'sget-short'
|
||||
| 'sput'
|
||||
| 'sput-wide'
|
||||
| 'sput-object'
|
||||
| 'sput-boolean'
|
||||
| 'sput-byte'
|
||||
| 'sput-char'
|
||||
| 'sput-short'
|
||||
;
|
||||
|
||||
INSTANCE_FIELD_INSTRUCTION_NAME
|
||||
: 'iget'
|
||||
| 'iget-wide'
|
||||
| 'iget-object'
|
||||
| 'iget-boolean'
|
||||
| 'iget-byte'
|
||||
| 'iget-char'
|
||||
| 'iget-short'
|
||||
| 'iput'
|
||||
| 'iput-wide'
|
||||
| 'iput-object'
|
||||
| 'iput-boolean'
|
||||
| 'iput-byte'
|
||||
| 'iput-char'
|
||||
| 'iput-short'
|
||||
;
|
||||
|
||||
BARE_INSTRUCTION_NAME
|
||||
: 'return-void'
|
||||
| 'nop';
|
||||
|
||||
|
||||
CONST_STRING_INSTRUCTION_NAME
|
||||
: 'const-string';
|
||||
|
||||
NEW_INSTANCE_INSTRUCTION_NAME
|
||||
: 'new-instance';
|
||||
|
||||
SINGLE_REGISTER_INSTRUCTION_NAME
|
||||
: 'move-result'
|
||||
| 'move-result-wide'
|
||||
| 'move-result-object'
|
||||
| 'move-exception'
|
||||
| 'return'
|
||||
| 'return-wide'
|
||||
| 'return-object'
|
||||
| 'monitor-enter'
|
||||
| 'monitor-exit'
|
||||
| 'throw';
|
||||
|
||||
|
||||
/*since SIMPLE_NAME is so all-encompassing, it includes all integer literals
|
||||
and a subset of the possible floating point literals. For floating point
|
||||
literals, we need to generate a separate token depending on whether the token
|
||||
could also be considered a SIMPLE_NAME or not.
|
||||
|
||||
The floating point related tokens with a _SIMPLE_NAME suffix could also be
|
||||
considered valid SIMPLE_NAME tokens, while the plain version of the token
|
||||
(without the suffix) could not be considered a valid SIMPLE_NAME token*/
|
||||
|
||||
LONG_LITERAL
|
||||
: Integer_number Long_suffix;
|
||||
|
||||
INT_LITERAL
|
||||
: Integer_number;
|
||||
|
||||
fragment Integer_number
|
||||
: '-'? '0'
|
||||
| '-'? ('1'..'9') ('0'..'9')*
|
||||
| '0' ('0'..'7')+
|
||||
| Hex_prefix Hex_digit+
|
||||
;
|
||||
|
||||
fragment Hex_prefix
|
||||
: '0x'|'0X';
|
||||
|
||||
fragment Hex_digit
|
||||
: ('0'..'9'|'a'..'f'|'A'..'F');
|
||||
|
||||
fragment Long_suffix
|
||||
: 'l'|'L';
|
||||
|
||||
fragment Non_integer_number_SIMPLE_NAME
|
||||
: ('0'..'9')+ Decimal_exponent
|
||||
| ('0'..'9')+
|
||||
| Hex_prefix (Hex_digit)* Hex_exponent
|
||||
;
|
||||
|
||||
|
||||
fragment Non_integer_number
|
||||
: ('0'..'9')+ '.' ('0'..'9')* Decimal_exponent?
|
||||
| '.' ('0'..'9')+ Decimal_exponent?
|
||||
| Hex_prefix (Hex_digit)* '.' (Hex_digit)* Hex_exponent
|
||||
;
|
||||
|
||||
fragment Decimal_exponent
|
||||
: ('e'|'E') '-'? ('0'..'9')+;
|
||||
|
||||
fragment Hex_exponent
|
||||
: ('p'|'P') '-'? ('0'..'9')+;
|
||||
|
||||
fragment Float_suffix
|
||||
: 'f'|'F';
|
||||
|
||||
fragment Double_suffix
|
||||
: 'd'|'D';
|
||||
|
||||
FLOAT_LITERAL_SIMPLE_NAME
|
||||
: Non_integer_number_SIMPLE_NAME Float_suffix;
|
||||
|
||||
FLOAT_LITERAL
|
||||
: Non_integer_number Float_suffix;
|
||||
|
||||
DOUBLE_LITERAL_SIMPLE_NAME
|
||||
: Non_integer_number_SIMPLE_NAME Double_suffix?;
|
||||
|
||||
DOUBLE_LITERAL
|
||||
: Non_integer_number Double_suffix?;
|
||||
|
||||
CHAR_LITERAL
|
||||
|
||||
: '\'' {StringBuilder sb = new StringBuilder();}
|
||||
( Escape_sequence[sb] {setText(sb.toString());}
|
||||
| ~( '\'' | '\\' | '\r' | '\n' )
|
||||
)
|
||||
'\''
|
||||
;
|
||||
|
||||
STRING_LITERAL
|
||||
: '"' {StringBuilder sb = new StringBuilder();}
|
||||
( Escape_sequence[sb]
|
||||
| ~( '\\' | '"' | '\r' | '\n' ) {sb.append((char)input.LA(-1));}
|
||||
)*
|
||||
'"' {setText(sb.toString());}
|
||||
;
|
||||
|
||||
|
||||
Hex_digits
|
||||
: Hex_digit Hex_digit Hex_digit Hex_digit;
|
||||
|
||||
fragment
|
||||
Escape_sequence[StringBuilder sb]
|
||||
: '\\'
|
||||
(
|
||||
'b' {sb.append("\b");}
|
||||
| 't' {sb.append("\t");}
|
||||
| 'n' {sb.append("\n");}
|
||||
| 'f' {sb.append("\f");}
|
||||
| 'r' {sb.append("\r");}
|
||||
| '\"' {sb.append("\"");}
|
||||
| '\'' {sb.append("'");}
|
||||
| '\\' {sb.append("\\");}
|
||||
| 'u' Hex_digits {sb.append((char)Integer.parseInt($Hex_digits.text, 16));}
|
||||
/* | octdigits=(('0'..'3') ('0'..'7') ('0'..'7')) {$value = (char)Integer.parseInt("0" + $octdigits.text);}
|
||||
| octdigits=(('0'..'7') ('0'..'7')) {$value = (char)Integer.parseInt("0" + $octdigits.text);}
|
||||
| octdigits=(('0'..'7')) {$value = (char)Integer.parseInt("0" + $octdigits.text);}*/
|
||||
);
|
||||
|
||||
BOOL_LITERAL
|
||||
: 'true'|'false';
|
||||
|
||||
|
||||
|
||||
WHITESPACE
|
||||
: (' '|'\t'|'\n'|'\r')+ {$channel = HIDDEN;};
|
||||
|
||||
REGISTER: 'v' ('0'..'9')+;
|
||||
|
||||
|
||||
/*a token of type QUALIFIED_MEMBER is never generated. This rule emits 2 sub-tokens
|
||||
that represent the class name and the member name, so that they don't have to be
|
||||
parsed out later*/
|
||||
QUALIFIED_MEMBER
|
||||
: class_name=QUALIFIED_MEMBER__CLASS_NAME '.' member_name=QUALIFIED_MEMBER__MEMBER_NAME
|
||||
{
|
||||
$class_name.setType(QUALIFIED_MEMBER__CLASS_NAME);
|
||||
$member_name.setType(QUALIFIED_MEMBER__MEMBER_NAME);
|
||||
emit($class_name);
|
||||
emit($member_name);
|
||||
};
|
||||
|
||||
fragment QUALIFIED_MEMBER__CLASS_NAME
|
||||
: (SIMPLE_NAME '/')* SIMPLE_NAME;
|
||||
|
||||
fragment QUALIFIED_MEMBER__MEMBER_NAME
|
||||
: MEMBER_NAME | SIMPLE_NAME;
|
||||
|
||||
|
||||
ARRAY_TYPE
|
||||
:
|
||||
ARRAY_CHAR_LIST[255] (PRIMITIVE_TYPE | CLASS_DESCRIPTOR);
|
||||
|
||||
|
||||
//match from 1 to maxCount '[' characters
|
||||
fragment
|
||||
ARRAY_CHAR_LIST[int maxCount]
|
||||
: {$maxCount > 1}?=> '[' ARRAY_CHAR_LIST[$maxCount - 1]
|
||||
| '['
|
||||
;
|
||||
|
||||
MEMBER_NAME
|
||||
: '<' SIMPLE_NAME '>';
|
||||
|
||||
VOID_TYPE
|
||||
: 'V';
|
||||
|
||||
PRIMITIVE_TYPE
|
||||
: 'Z'
|
||||
| 'B'
|
||||
| 'S'
|
||||
| 'C'
|
||||
| 'I'
|
||||
| 'J'
|
||||
| 'F'
|
||||
| 'D'
|
||||
;
|
||||
|
||||
CLASS_WITH_PACKAGE_NAME
|
||||
: (SIMPLE_NAME '/')+ SIMPLE_NAME;
|
||||
|
||||
CLASS_DESCRIPTOR
|
||||
: 'L' (SIMPLE_NAME | CLASS_WITH_PACKAGE_NAME) ';';
|
||||
|
||||
SIMPLE_NAME:
|
||||
( 'A'..'Z'
|
||||
| 'a'..'z'
|
||||
| '0'..'9'
|
||||
| '$'
|
||||
| '-'
|
||||
| '_'
|
||||
| '\u00a1'..'\u1fff'
|
||||
| '\u2010'..'\u2027'
|
||||
| '\u2030'..'\ud7ff'
|
||||
| '\ue000'..'\uffef'
|
||||
)+;
|
||||
|
||||
COMMENT
|
||||
: (';' ~('\n'|'\r')* ('\r\n' | '\r' | '\n')
|
||||
| ';' ~('\n'|'\r')*)
|
||||
{
|
||||
$channel = HIDDEN;
|
||||
}
|
||||
;
|
437
src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g
Normal file
437
src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g
Normal file
@ -0,0 +1,437 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
tree grammar smaliTreeWalker;
|
||||
|
||||
options {
|
||||
tokenVocab=smali;
|
||||
ASTLabelType=CommonTree;
|
||||
}
|
||||
|
||||
@header {
|
||||
package org.JesusFreke.smali;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
import org.JesusFreke.dexlib.EncodedValue.*;
|
||||
import org.JesusFreke.dexlib.util.*;
|
||||
import org.JesusFreke.dexlib.code.*;
|
||||
import org.JesusFreke.dexlib.code.Format.*;
|
||||
}
|
||||
|
||||
@members {
|
||||
public DexFile dexFile;
|
||||
public ClassDefItem classDefItem;
|
||||
public ClassDataItem classDataItem;
|
||||
|
||||
|
||||
private static byte parseRegister_nibble(String register) {
|
||||
//register should be in the format "v12"
|
||||
byte val = Byte.parseByte(register.substring(1));
|
||||
if (val >= 2<<4) {
|
||||
//TODO: throw correct exception type
|
||||
throw new RuntimeException("The maximum allowed register in this context is list of registers is v15");
|
||||
}
|
||||
//the parser wouldn't accept a negative register, i.e. v-1, so we don't have to check for val<0;
|
||||
return val;
|
||||
}
|
||||
|
||||
//return a short, because java's byte is signed
|
||||
private static short parseRegister_byte(String register) {
|
||||
//register should be in the format "v123"
|
||||
short val = Short.parseShort(register.substring(1));
|
||||
if (val >= 2<<8) {
|
||||
//TODO: throw correct exception type
|
||||
throw new RuntimeException("The maximum allowed register in this context is v255");
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
//return an int because java's short is signed
|
||||
private static int parseRegister_short(String register) {
|
||||
//register should be in the format "v12345"
|
||||
int val = Integer.parseInt(register.substring(1));
|
||||
if (val >= 2<<16) {
|
||||
//TODO: throw correct exception type
|
||||
throw new RuntimeException("The maximum allowed register in this context is v65535");
|
||||
}
|
||||
//the parser wouldn't accept a negative register, i.e. v-1, so we don't have to check for val<0;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
smali_file returns[ClassDefItem classDefItem]
|
||||
: ^(I_CLASS_DEF header methods fields);
|
||||
|
||||
header : class_spec super_spec
|
||||
{
|
||||
classDataItem = new ClassDataItem(dexFile, 0);
|
||||
classDefItem = new ClassDefItem(dexFile, $class_spec.type, $class_spec.accessFlags, $super_spec.type, classDataItem);
|
||||
};
|
||||
|
||||
class_spec returns[TypeIdItem type, int accessFlags]
|
||||
: class_name access_list
|
||||
{
|
||||
$type = $class_name.type;
|
||||
$accessFlags = $access_list.value;
|
||||
};
|
||||
|
||||
super_spec returns[TypeIdItem type]
|
||||
: ^(I_SUPER class_name)
|
||||
{
|
||||
$type = $class_name.type;
|
||||
};
|
||||
|
||||
access_list returns [int value]
|
||||
@init
|
||||
{
|
||||
$value = 0;
|
||||
}
|
||||
: ^(I_ACCESS_LIST
|
||||
(
|
||||
ACCESS_SPEC
|
||||
{
|
||||
$value |= AccessFlags.getValueForAccessFlag($ACCESS_SPEC.getText());
|
||||
}
|
||||
)+);
|
||||
|
||||
fields : ^(I_FIELDS
|
||||
(field
|
||||
{
|
||||
classDefItem.addField($field.encodedField, $field.encodedValue);
|
||||
})*);
|
||||
|
||||
methods : ^(I_METHODS
|
||||
(method
|
||||
{
|
||||
classDataItem.addMethod($method.encodedMethod);
|
||||
})*);
|
||||
|
||||
field returns[ClassDataItem.EncodedField encodedField, EncodedValue encodedValue]
|
||||
:^(I_FIELD member_name access_list ^(I_FIELD_TYPE field_type_descriptor) field_initial_value)
|
||||
{
|
||||
TypeIdItem classType = classDefItem.getClassType();
|
||||
StringIdItem memberName = new StringIdItem(dexFile, $member_name.memberName);
|
||||
TypeIdItem fieldType = $field_type_descriptor.type;
|
||||
|
||||
FieldIdItem fieldIdItem = new FieldIdItem(dexFile, classType, memberName, fieldType);
|
||||
$encodedField = new ClassDataItem.EncodedField(dexFile, fieldIdItem, $access_list.value);
|
||||
|
||||
if ($field_initial_value.encodedValue != null) {
|
||||
if (($access_list.value & AccessFlags.STATIC) == 0) {
|
||||
//TODO: change to an appropriate exception type?
|
||||
throw new RuntimeException("Initial field values can only be specified for static fields.");
|
||||
}
|
||||
|
||||
$encodedValue = $field_initial_value.encodedValue;
|
||||
} else {
|
||||
$encodedValue = null;
|
||||
}
|
||||
};
|
||||
|
||||
field_initial_value returns[EncodedValue encodedValue]
|
||||
: ^(I_FIELD_INITIAL_VALUE
|
||||
( int_literal { $encodedValue = new EncodedValue(dexFile, new IntEncodedValueSubField($int_literal.value)); }
|
||||
| long_literal { $encodedValue = new EncodedValue(dexFile, new LongEncodedValueSubField($long_literal.value)); }
|
||||
| float_literal { $encodedValue = new EncodedValue(dexFile, new FloatEncodedValueSubField($float_literal.value)); }
|
||||
| double_literal { $encodedValue = new EncodedValue(dexFile, new DoubleEncodedValueSubField($double_literal.value)); }
|
||||
| char_literal { $encodedValue = new EncodedValue(dexFile, new CharEncodedValueSubField($char_literal.value)); }
|
||||
| string_literal { $encodedValue = new EncodedValue(dexFile, new EncodedIndexedItemReference(dexFile, new StringIdItem(dexFile, $string_literal.value))); }
|
||||
| bool_literal { $encodedValue = new EncodedValue(dexFile, new BoolEncodedValueSubField($bool_literal.value)); }
|
||||
))
|
||||
| ;
|
||||
|
||||
|
||||
method returns[ClassDataItem.EncodedMethod encodedMethod]
|
||||
: ^(I_METHOD method_name_and_prototype access_list locals_directive statements)
|
||||
{
|
||||
MethodIdItem methodIdItem = $method_name_and_prototype.methodIdItem;
|
||||
int registers = $locals_directive.registers;
|
||||
int access = $access_list.value;
|
||||
boolean isStatic = (access & AccessFlags.STATIC) != 0;
|
||||
ArrayList<Instruction> instructions = $statements.instructions;
|
||||
|
||||
CodeItem codeItem = new CodeItem(dexFile, registers, methodIdItem.getParameterWordCount(isStatic), instructions);
|
||||
|
||||
$encodedMethod = new ClassDataItem.EncodedMethod(dexFile, methodIdItem, access, codeItem);
|
||||
};
|
||||
|
||||
method_prototype returns[ProtoIdItem protoIdItem]
|
||||
: ^(I_METHOD_PROTOTYPE ^(I_METHOD_RETURN_TYPE type_descriptor) field_type_list)
|
||||
{
|
||||
TypeIdItem returnType = $type_descriptor.type;
|
||||
ArrayList<TypeIdItem> parameterTypes = $field_type_list.types;
|
||||
|
||||
$protoIdItem = new ProtoIdItem(dexFile, returnType, parameterTypes);
|
||||
};
|
||||
|
||||
method_name_and_prototype returns[MethodIdItem methodIdItem]
|
||||
: member_name method_prototype
|
||||
{
|
||||
TypeIdItem classType = classDefItem.getClassType();
|
||||
String methodNameString = $member_name.memberName;
|
||||
StringIdItem methodName = new StringIdItem(dexFile, methodNameString);
|
||||
ProtoIdItem protoIdItem = $method_prototype.protoIdItem;
|
||||
|
||||
$methodIdItem = new MethodIdItem(dexFile, classType, methodName, protoIdItem);
|
||||
};
|
||||
|
||||
field_type_list returns[ArrayList<TypeIdItem> types]
|
||||
@init
|
||||
{
|
||||
$types = new ArrayList<TypeIdItem>();
|
||||
}
|
||||
: (
|
||||
field_type_descriptor
|
||||
{
|
||||
$types.add($field_type_descriptor.type);
|
||||
}
|
||||
)*;
|
||||
|
||||
locals_directive returns[int registers]
|
||||
: ^(I_REGISTERS INT_LITERAL) {$registers = Integer.parseInt($INT_LITERAL.text);};
|
||||
|
||||
full_method_name_and_prototype returns[MethodIdItem methodIdItem]
|
||||
: QUALIFIED_MEMBER__CLASS_NAME QUALIFIED_MEMBER__MEMBER_NAME method_prototype
|
||||
{
|
||||
TypeIdItem classType = new TypeIdItem(dexFile, "L" + $QUALIFIED_MEMBER__CLASS_NAME.text + ";");
|
||||
StringIdItem methodName = new StringIdItem(dexFile, $QUALIFIED_MEMBER__MEMBER_NAME.text);
|
||||
ProtoIdItem prototype = $method_prototype.protoIdItem;
|
||||
$methodIdItem = new MethodIdItem(dexFile, classType, methodName, prototype);
|
||||
};
|
||||
|
||||
full_field_name_and_type returns[FieldIdItem fieldIdItem]
|
||||
: QUALIFIED_MEMBER__CLASS_NAME QUALIFIED_MEMBER__MEMBER_NAME field_type_descriptor
|
||||
{
|
||||
TypeIdItem classType = new TypeIdItem(dexFile, "L" + $QUALIFIED_MEMBER__CLASS_NAME.text + ";");
|
||||
StringIdItem fieldName = new StringIdItem(dexFile, $QUALIFIED_MEMBER__MEMBER_NAME.text);
|
||||
TypeIdItem fieldType = $field_type_descriptor.type;
|
||||
$fieldIdItem = new FieldIdItem(dexFile, classType, fieldName, fieldType);
|
||||
};
|
||||
|
||||
statements returns[ArrayList<Instruction> instructions]
|
||||
@init
|
||||
{
|
||||
$instructions = new ArrayList<Instruction>();
|
||||
}
|
||||
: ^(I_STATEMENTS
|
||||
(instruction
|
||||
{
|
||||
$instructions.add($instruction.instruction);
|
||||
})*);
|
||||
|
||||
|
||||
instruction returns[Instruction instruction]
|
||||
//e.g. return
|
||||
: ^(I_BARE_STATEMENT BARE_INSTRUCTION_NAME)
|
||||
{
|
||||
Opcode opcode = Opcode.getOpcodeByName($BARE_INSTRUCTION_NAME.text);
|
||||
$instruction = Format10x.Format.make(dexFile, opcode.value);
|
||||
}
|
||||
| //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
|
||||
^(I_INVOKE_STATEMENT INVOKE_INSTRUCTION_NAME register_list full_method_name_and_prototype)
|
||||
{
|
||||
Opcode opcode = Opcode.getOpcodeByName($INVOKE_INSTRUCTION_NAME.text);
|
||||
|
||||
//this depends on the fact that register_list returns a byte[5]
|
||||
byte[] registers = $register_list.registers;
|
||||
byte registerCount = $register_list.registerCount;
|
||||
|
||||
MethodIdItem methodIdItem = $full_method_name_and_prototype.methodIdItem;
|
||||
|
||||
$instruction = Format35c.Format.make(dexFile, opcode.value, registerCount, registers[0], registers[1], registers[2], registers[3], registers[4], methodIdItem);
|
||||
}
|
||||
| //e.g. invoke-virtual/range {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||
^(I_INVOKE_RANGE_STATEMENT INVOKE_RANGE_INSTRUCTION_NAME register_range full_method_name_and_prototype)
|
||||
{
|
||||
Opcode opcode = Opcode.getOpcodeByName($INVOKE_RANGE_INSTRUCTION_NAME.text);
|
||||
int startRegister = $register_range.startRegister;
|
||||
int endRegister = $register_range.endRegister;
|
||||
|
||||
int registerCount = endRegister-startRegister+1;
|
||||
if (registerCount > 256) {
|
||||
//TODO: throw appropriate exception type
|
||||
throw new RuntimeException("A register range can span a maximum of 256 registers");
|
||||
}
|
||||
if (registerCount < 1) {
|
||||
//TODO: throw appropriate exception type
|
||||
throw new RuntimeException("A register range must have the lower register listed first");
|
||||
}
|
||||
|
||||
MethodIdItem methodIdItem = $full_method_name_and_prototype.methodIdItem;
|
||||
|
||||
//not supported yet
|
||||
$instruction = Format3rc.Format.make(dexFile, opcode.value, (short)registerCount, startRegister, methodIdItem);
|
||||
}
|
||||
| //e.g. sget_object v0 java/lang/System/out LJava/io/PrintStream;
|
||||
^(I_STATIC_FIELD_STATEMENT STATIC_FIELD_INSTRUCTION_NAME REGISTER full_field_name_and_type)
|
||||
{
|
||||
Opcode opcode = Opcode.getOpcodeByName($STATIC_FIELD_INSTRUCTION_NAME.text);
|
||||
short regA = parseRegister_byte($REGISTER.text);
|
||||
|
||||
FieldIdItem fieldIdItem = $full_field_name_and_type.fieldIdItem;
|
||||
|
||||
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, fieldIdItem);
|
||||
}
|
||||
| //e.g. iput-object v1 v0 org/JesusFreke/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
|
||||
^(I_INSTANCE_FIELD_STATEMENT INSTANCE_FIELD_INSTRUCTION_NAME registerA=REGISTER registerB=REGISTER full_field_name_and_type)
|
||||
{
|
||||
Opcode opcode = Opcode.getOpcodeByName($INSTANCE_FIELD_INSTRUCTION_NAME.text);
|
||||
byte regA = parseRegister_nibble($registerA.text);
|
||||
byte regB = parseRegister_nibble($registerB.text);
|
||||
|
||||
FieldIdItem fieldIdItem = $full_field_name_and_type.fieldIdItem;
|
||||
|
||||
$instruction = Format22c.Format.make(dexFile, opcode.value, regA, regB, fieldIdItem);
|
||||
}
|
||||
| //e.g. const-string v1 "Hello World!"
|
||||
^(I_CONST_STRING_STATEMENT CONST_STRING_INSTRUCTION_NAME REGISTER string_literal)
|
||||
{
|
||||
Opcode opcode = Opcode.getOpcodeByName($CONST_STRING_INSTRUCTION_NAME.text);
|
||||
short regA = parseRegister_byte($REGISTER.text);
|
||||
|
||||
StringIdItem stringIdItem = new StringIdItem(dexFile, $string_literal.value);
|
||||
|
||||
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, stringIdItem);
|
||||
}
|
||||
| //e.g. new-instance v1 android/widget/TextView
|
||||
^(I_NEW_INSTANCE_STATEMENT NEW_INSTANCE_INSTRUCTION_NAME REGISTER class_name)
|
||||
{
|
||||
Opcode opcode = Opcode.getOpcodeByName($NEW_INSTANCE_INSTRUCTION_NAME.text);
|
||||
short regA = parseRegister_byte($REGISTER.text);
|
||||
|
||||
TypeIdItem typeIdItem = $class_name.type;
|
||||
|
||||
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, typeIdItem);
|
||||
}
|
||||
| //e.g. move-result-object v1
|
||||
^(I_SINGLE_REGISTER_STATEMENT SINGLE_REGISTER_INSTRUCTION_NAME REGISTER)
|
||||
{
|
||||
Opcode opcode = Opcode.getOpcodeByName($SINGLE_REGISTER_INSTRUCTION_NAME.text);
|
||||
short regA = parseRegister_byte($REGISTER.text);
|
||||
|
||||
$instruction = Format11x.Format.make(dexFile, opcode.value, regA);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
register_list returns[byte[\] registers, byte registerCount]
|
||||
@init
|
||||
{
|
||||
$registers = new byte[5];
|
||||
$registerCount = 0;
|
||||
}
|
||||
: ^(I_REGISTER_LIST
|
||||
(REGISTER
|
||||
{
|
||||
if ($registerCount == 5) {
|
||||
//TODO: throw the correct type of exception
|
||||
throw new RuntimeException("A list of registers can only have a maximum of 5 registers. Use the <op>/range alternate opcode instead.");
|
||||
}
|
||||
$registers[$registerCount++] = parseRegister_nibble($REGISTER.text);
|
||||
})*);
|
||||
|
||||
register_range returns[int startRegister, int endRegister]
|
||||
: ^(I_REGISTER_RANGE startReg=REGISTER endReg=REGISTER?)
|
||||
{
|
||||
$startRegister = parseRegister_short($startReg.text);
|
||||
if ($endReg == null) {
|
||||
$endRegister = $startRegister;
|
||||
} else {
|
||||
$endRegister = parseRegister_short($endReg.text);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
simple_name
|
||||
: SIMPLE_NAME
|
||||
| ACCESS_SPEC
|
||||
| INT_LITERAL
|
||||
| LONG_LITERAL
|
||||
| FLOAT_LITERAL_SIMPLE_NAME
|
||||
| DOUBLE_LITERAL_SIMPLE_NAME
|
||||
| BOOL_LITERAL
|
||||
| PRIMITIVE_TYPE
|
||||
| instruction_name
|
||||
;
|
||||
|
||||
instruction_name returns[String value]
|
||||
: INVOKE_INSTRUCTION_NAME
|
||||
| INVOKE_RANGE_INSTRUCTION_NAME
|
||||
| STATIC_FIELD_INSTRUCTION_NAME
|
||||
| INSTANCE_FIELD_INSTRUCTION_NAME
|
||||
| BARE_INSTRUCTION_NAME
|
||||
| CONST_STRING_INSTRUCTION_NAME
|
||||
| NEW_INSTANCE_INSTRUCTION_NAME
|
||||
;
|
||||
|
||||
member_name returns[String memberName]
|
||||
: (simple_name
|
||||
| MEMBER_NAME) {$memberName = $start.getText();}
|
||||
;
|
||||
|
||||
class_name returns [TypeIdItem type]
|
||||
: token=(SIMPLE_NAME | CLASS_WITH_PACKAGE_NAME)
|
||||
{
|
||||
$type = new TypeIdItem(dexFile, 'L'+$token.text+';');
|
||||
};
|
||||
|
||||
field_type_descriptor returns [TypeIdItem type]
|
||||
: token=(PRIMITIVE_TYPE
|
||||
| CLASS_DESCRIPTOR
|
||||
| ARRAY_TYPE)
|
||||
{
|
||||
$type = new TypeIdItem(dexFile, $token.text);
|
||||
};
|
||||
|
||||
type_descriptor returns [TypeIdItem type]
|
||||
: VOID_TYPE {$type = new TypeIdItem(dexFile, "V");}
|
||||
| field_type_descriptor {$type = $field_type_descriptor.type;}
|
||||
;
|
||||
|
||||
int_literal returns[int value]
|
||||
: INT_LITERAL { $value = Integer.parseInt($INT_LITERAL.text); };
|
||||
|
||||
long_literal returns[long value]
|
||||
: LONG_LITERAL { $value = Long.parseLong($LONG_LITERAL.text); };
|
||||
|
||||
float_literal returns[float value]
|
||||
: FLOAT_LITERAL { $value = Float.parseFloat($FLOAT_LITERAL.text); };
|
||||
|
||||
double_literal returns[double value]
|
||||
: DOUBLE_LITERAL { $value = Double.parseDouble($DOUBLE_LITERAL.text); };
|
||||
|
||||
char_literal returns[char value]
|
||||
: CHAR_LITERAL { $value = $CHAR_LITERAL.text.charAt(0); };
|
||||
|
||||
string_literal returns[String value]
|
||||
: STRING_LITERAL { $value = $STRING_LITERAL.text; };
|
||||
|
||||
bool_literal returns[boolean value]
|
||||
: BOOL_LITERAL { $value = Boolean.parseBoolean($BOOL_LITERAL.text); };
|
133
src/main/java/org/JesusFreke/dexlib/AnnotationDirectoryItem.java
Normal file
133
src/main/java/org/JesusFreke/dexlib/AnnotationDirectoryItem.java
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
//TODO: fix field names in dex-format.html and submit
|
||||
public class AnnotationDirectoryItem extends OffsettedItem<AnnotationDirectoryItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final ArrayList<FieldAnnotation> fieldAnnotationList = new ArrayList<FieldAnnotation>();
|
||||
private final ArrayList<MethodAnnotation> methodAnnotationList = new ArrayList<MethodAnnotation>();
|
||||
private final ArrayList<ParameterAnnotation> parameterAnnotationList = new ArrayList<ParameterAnnotation>();
|
||||
|
||||
private final OffsettedItemReference<AnnotationSetItem> classAnnotations;
|
||||
private final ListSizeField annotatedFieldsCount;
|
||||
private final ListSizeField annotatedMethodsCount;
|
||||
private final ListSizeField annotatedParametersCount;
|
||||
private final FieldListField<FieldAnnotation> fieldAnnotations;
|
||||
private final FieldListField<MethodAnnotation> methodAnnotations;
|
||||
private final FieldListField<ParameterAnnotation> parameterAnnotations;
|
||||
|
||||
public AnnotationDirectoryItem(final DexFile dexFile, int offset) {
|
||||
super(offset);
|
||||
|
||||
fields = new Field[] {
|
||||
classAnnotations = new OffsettedItemReference<AnnotationSetItem>(dexFile.AnnotationSetsSection, new IntegerField()),
|
||||
annotatedFieldsCount = new ListSizeField(fieldAnnotationList, new IntegerField()),
|
||||
annotatedMethodsCount = new ListSizeField(methodAnnotationList, new IntegerField()),
|
||||
annotatedParametersCount = new ListSizeField(parameterAnnotationList, new IntegerField()),
|
||||
fieldAnnotations = new FieldListField<FieldAnnotation>(fieldAnnotationList) {
|
||||
protected FieldAnnotation make() {
|
||||
return new FieldAnnotation(dexFile);
|
||||
}
|
||||
},
|
||||
methodAnnotations = new FieldListField<MethodAnnotation>(methodAnnotationList) {
|
||||
protected MethodAnnotation make() {
|
||||
return new MethodAnnotation(dexFile);
|
||||
}
|
||||
},
|
||||
parameterAnnotations = new FieldListField<ParameterAnnotation>(parameterAnnotationList) {
|
||||
protected ParameterAnnotation make() {
|
||||
return new ParameterAnnotation(dexFile);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM;
|
||||
}
|
||||
|
||||
public class FieldAnnotation extends CompositeField<FieldAnnotation> {
|
||||
private final Field[] fields;
|
||||
|
||||
public FieldAnnotation(DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
new IndexedItemReference<FieldIdItem>(dexFile.FieldIdsSection, new IntegerField()),
|
||||
new OffsettedItemReference<AnnotationSetItem>(dexFile.AnnotationSetsSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
|
||||
public class MethodAnnotation extends CompositeField<MethodAnnotation> {
|
||||
private final Field[] fields;
|
||||
|
||||
public MethodAnnotation(DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
new IndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection, new IntegerField()),
|
||||
new OffsettedItemReference<AnnotationSetItem>(dexFile.AnnotationSetsSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
|
||||
public class ParameterAnnotation extends CompositeField<ParameterAnnotation> {
|
||||
private final Field[] fields;
|
||||
|
||||
public ParameterAnnotation(DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
new IndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection, new IntegerField()),
|
||||
new OffsettedItemReference<AnnotationSetItem>(dexFile.AnnotationSetsSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
}
|
81
src/main/java/org/JesusFreke/dexlib/AnnotationItem.java
Normal file
81
src/main/java/org/JesusFreke/dexlib/AnnotationItem.java
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.EncodedValue.AnnotationEncodedValueSubField;
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
|
||||
public class AnnotationItem extends OffsettedItem<AnnotationItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final ByteField visibility;
|
||||
private final AnnotationEncodedValueSubField annotation;
|
||||
|
||||
public AnnotationItem(DexFile dexFile, int offset) {
|
||||
super(offset);
|
||||
|
||||
fields = new Field[] {
|
||||
visibility = new ByteField(),
|
||||
annotation = new AnnotationEncodedValueSubField(dexFile)
|
||||
};
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_ANNOTATION_ITEM;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, AnnotationItem copy) {
|
||||
visibility.copyTo(dexFile, copy.visibility);
|
||||
annotation.copyTo(dexFile, copy.annotation);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return visibility.hashCode() * 31 + annotation.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof AnnotationItem)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AnnotationItem other = (AnnotationItem)o;
|
||||
|
||||
if (!visibility.equals(other.visibility))
|
||||
return false;
|
||||
return annotation.equals(other.annotation);
|
||||
}
|
||||
}
|
68
src/main/java/org/JesusFreke/dexlib/AnnotationSetItem.java
Normal file
68
src/main/java/org/JesusFreke/dexlib/AnnotationSetItem.java
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class AnnotationSetItem extends OffsettedItem<AnnotationSetItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final ArrayList<OffsettedItemReference<AnnotationItem>> annotationReferences =
|
||||
new ArrayList<OffsettedItemReference<AnnotationItem>>();
|
||||
|
||||
private final ListSizeField annotationCount;
|
||||
private final FieldListField<OffsettedItemReference<AnnotationItem>> annotations;
|
||||
|
||||
public AnnotationSetItem(final DexFile dexFile, int offset) {
|
||||
super(offset);
|
||||
|
||||
fields = new Field[] {
|
||||
annotationCount = new ListSizeField(annotationReferences, new IntegerField()),
|
||||
annotations = new FieldListField<OffsettedItemReference<AnnotationItem>>(annotationReferences) {
|
||||
protected OffsettedItemReference<AnnotationItem> make() {
|
||||
return new OffsettedItemReference<AnnotationItem>(dexFile.AnnotationsSection, new IntegerField());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_ANNOTATION_SET_ITEM;
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class AnnotationSetRefList extends OffsettedItem<AnnotationSetRefList> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final ArrayList<OffsettedItemReference<AnnotationSetItem>> annotationSetReferences =
|
||||
new ArrayList<OffsettedItemReference<AnnotationSetItem>>();
|
||||
|
||||
private final ListSizeField annotationSetCount;
|
||||
private final FieldListField<OffsettedItemReference<AnnotationSetItem>> annotationSets;
|
||||
|
||||
public AnnotationSetRefList(final DexFile dexFile, int offset) {
|
||||
super(offset);
|
||||
|
||||
fields = new Field[] {
|
||||
annotationSetCount = new ListSizeField(annotationSetReferences, new IntegerField()),
|
||||
annotationSets = new FieldListField<OffsettedItemReference<AnnotationSetItem>>(annotationSetReferences) {
|
||||
protected OffsettedItemReference<AnnotationSetItem> make() {
|
||||
return new OffsettedItemReference<AnnotationSetItem>(dexFile.AnnotationSetsSection, new IntegerField());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_ANNOTATION_SET_REF_LIST;
|
||||
}
|
||||
}
|
63
src/main/java/org/JesusFreke/dexlib/ByteField.java
Normal file
63
src/main/java/org/JesusFreke/dexlib/ByteField.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class ByteField extends CachedIntegerValueField {
|
||||
protected byte value;
|
||||
|
||||
public ByteField() {
|
||||
}
|
||||
|
||||
public ByteField(byte value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.writeByte(value);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = in.readByte();
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
public int getCachedValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void cacheValue(int value) {
|
||||
this.value = (byte)value;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
public abstract class CachedIntegerValueField implements Field<CachedIntegerValueField> {
|
||||
public abstract int getCachedValue();
|
||||
public abstract void cacheValue(int value);
|
||||
|
||||
public void copyTo(DexFile dexFile, CachedIntegerValueField copy) {
|
||||
copy.cacheValue(getCachedValue());
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return ((Integer)getCachedValue()).hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CachedIntegerValueField other = (CachedIntegerValueField)o;
|
||||
|
||||
return getCachedValue() == other.getCachedValue();
|
||||
}
|
||||
}
|
351
src/main/java/org/JesusFreke/dexlib/ClassDataItem.java
Normal file
351
src/main/java/org/JesusFreke/dexlib/ClassDataItem.java
Normal file
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.AccessFlags;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
public class ClassDataItem extends OffsettedItem<ClassDataItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final ArrayList<EncodedField> staticFieldList = new ArrayList<EncodedField>();
|
||||
private final ArrayList<EncodedField> instanceFieldList = new ArrayList<EncodedField>();
|
||||
private final ArrayList<EncodedMethod> directMethodList = new ArrayList<EncodedMethod>();
|
||||
private final ArrayList<EncodedMethod> virtualMethodList = new ArrayList<EncodedMethod>();
|
||||
|
||||
private final ListSizeField staticFieldsCount;
|
||||
private final ListSizeField instanceFieldsCount;
|
||||
private final ListSizeField directMethodsCount;
|
||||
private final ListSizeField virtualMethodsCount;
|
||||
private final EncodedMemberList<EncodedField> staticFields;
|
||||
private final EncodedMemberList<EncodedField> instanceFields;
|
||||
private final EncodedMemberList<EncodedMethod> directMethods;
|
||||
private final EncodedMemberList<EncodedMethod> virtualMethods;
|
||||
|
||||
|
||||
public ClassDataItem(final DexFile dexFile, int offset) {
|
||||
super(offset);
|
||||
|
||||
fields = new Field[] {
|
||||
staticFieldsCount = new ListSizeField(staticFieldList, new Leb128Field()),
|
||||
instanceFieldsCount = new ListSizeField(instanceFieldList, new Leb128Field()),
|
||||
directMethodsCount = new ListSizeField(directMethodList, new Leb128Field()),
|
||||
virtualMethodsCount = new ListSizeField(virtualMethodList, new Leb128Field()),
|
||||
staticFields = new EncodedMemberList<EncodedField>(staticFieldList) {
|
||||
protected EncodedField make(EncodedField previousField) {
|
||||
return new EncodedField(dexFile, previousField);
|
||||
}
|
||||
},
|
||||
instanceFields = new EncodedMemberList<EncodedField>(instanceFieldList) {
|
||||
protected EncodedField make(EncodedField previousField) {
|
||||
return new EncodedField(dexFile, previousField);
|
||||
}
|
||||
},
|
||||
directMethods = new EncodedMemberList<EncodedMethod>(directMethodList) {
|
||||
protected EncodedMethod make(EncodedMethod previousMethod) {
|
||||
return new EncodedMethod(dexFile, previousMethod);
|
||||
}
|
||||
},
|
||||
virtualMethods = new EncodedMemberList<EncodedMethod>(virtualMethodList) {
|
||||
protected EncodedMethod make(EncodedMethod previousMethod) {
|
||||
return new EncodedMethod(dexFile, previousMethod);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void addMethod(EncodedMethod encodedMethod) {
|
||||
if (encodedMethod.isDirect()) {
|
||||
directMethodList.add(encodedMethod);
|
||||
} else {
|
||||
virtualMethodList.add(encodedMethod);
|
||||
}
|
||||
}
|
||||
|
||||
public int addField(EncodedField encodedField) {
|
||||
if (encodedField.isStatic()) {
|
||||
staticFieldList.add(encodedField);
|
||||
Collections.sort(staticFieldList);
|
||||
return Collections.binarySearch(staticFieldList, encodedField);
|
||||
} else {
|
||||
instanceFieldList.add(encodedField);
|
||||
Collections.sort(instanceFieldList);
|
||||
return Collections.binarySearch(instanceFieldList, encodedField);
|
||||
}
|
||||
}
|
||||
|
||||
public EncodedField getStaticFieldAtIndex(int i)
|
||||
{
|
||||
return staticFieldList.get(i);
|
||||
}
|
||||
|
||||
private static abstract class EncodedMember<T extends EncodedMember<T>> extends CompositeField<T> implements Field<T>, Comparable<T>
|
||||
{
|
||||
protected abstract void setPreviousMember(T previousMember);
|
||||
}
|
||||
|
||||
private static abstract class EncodedMemberList<T extends EncodedMember<T>> implements Field<EncodedMemberList<T>> {
|
||||
private final ArrayList<T> list;
|
||||
|
||||
public EncodedMemberList(ArrayList<T> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
for (T field: list) {
|
||||
field.writeTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract T make(T previousField);
|
||||
|
||||
public void readFrom(Input in) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
T previousField = null;
|
||||
if (i > 0) {
|
||||
previousField = list.get(i-1);
|
||||
}
|
||||
T field = make(previousField);
|
||||
list.set(i, field);
|
||||
field.readFrom(in);
|
||||
}
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
Collections.sort(list);
|
||||
|
||||
T previousMember = null;
|
||||
for (T encodedMember: list) {
|
||||
encodedMember.setPreviousMember(previousMember);
|
||||
offset = encodedMember.place(offset);
|
||||
previousMember = encodedMember;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, EncodedMemberList<T> copy) {
|
||||
copy.list.clear();
|
||||
copy.list.ensureCapacity(list.size());
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
T previousField = null;
|
||||
if (i > 0) {
|
||||
previousField = copy.list.get(i-1);
|
||||
}
|
||||
T fieldCopy = copy.make(previousField);
|
||||
list.get(i).copyTo(dexFile, fieldCopy);
|
||||
copy.list.add(fieldCopy);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int h = 1;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
h = h * 31 + list.get(i).hashCode();
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof EncodedMemberList)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EncodedMemberList<T> other = (EncodedMemberList<T>)o;
|
||||
if (list.size() != other.list.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (!list.get(i).equals(other.list.get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EncodedField extends EncodedMember<EncodedField> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final IndexedItemReference<FieldIdItem> field;
|
||||
private final Leb128DeltaField fieldIndexField;
|
||||
private final Leb128Field accessFlags;
|
||||
|
||||
public EncodedField(DexFile dexFile, final EncodedField previousField) {
|
||||
Leb128DeltaField previousIndexField = null;
|
||||
if (previousField != null) {
|
||||
previousIndexField = previousField.fieldIndexField;
|
||||
}
|
||||
|
||||
|
||||
fields = new Field[] {
|
||||
field = new IndexedItemReference<FieldIdItem>(dexFile.FieldIdsSection,
|
||||
fieldIndexField = new Leb128DeltaField(previousIndexField)),
|
||||
accessFlags = new Leb128Field()
|
||||
};
|
||||
}
|
||||
|
||||
public EncodedField(DexFile dexFile, FieldIdItem field, int accessFlags) {
|
||||
fields = new Field[] {
|
||||
this.field = new IndexedItemReference<FieldIdItem>(dexFile, field,
|
||||
fieldIndexField = new Leb128DeltaField(null)),
|
||||
this.accessFlags = new Leb128Field(accessFlags)
|
||||
};
|
||||
}
|
||||
|
||||
protected void setPreviousMember(EncodedField previousField) {
|
||||
if (previousField != null) {
|
||||
fieldIndexField.setPreviousField(previousField.fieldIndexField);
|
||||
} else {
|
||||
fieldIndexField.setPreviousField(null);
|
||||
}
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public int compareTo(EncodedField other)
|
||||
{
|
||||
return field.getReference().compareTo(other.field.getReference());
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return (accessFlags.getCachedValue() & AccessFlags.STATIC) != 0;
|
||||
}
|
||||
|
||||
public FieldIdItem getField() {
|
||||
return field.getReference();
|
||||
}
|
||||
}
|
||||
|
||||
public static class EncodedMethod extends EncodedMember<EncodedMethod> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final IndexedItemReference<MethodIdItem> method;
|
||||
private final Leb128DeltaField methodIndexField;
|
||||
private final Leb128Field accessFlags;
|
||||
private final OffsettedItemReference<CodeItem> codeItem;
|
||||
|
||||
public EncodedMethod(DexFile dexFile, final EncodedMethod previousMethod) {
|
||||
Leb128DeltaField previousIndexField = null;
|
||||
if (previousMethod != null) {
|
||||
previousIndexField = previousMethod.methodIndexField;
|
||||
}
|
||||
|
||||
fields = new Field[] {
|
||||
method = new IndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection,
|
||||
methodIndexField = new Leb128DeltaField(previousIndexField)),
|
||||
accessFlags = new Leb128Field(),
|
||||
codeItem = new OffsettedItemReference<CodeItem>(dexFile.CodeItemsSection, new Leb128Field())
|
||||
};
|
||||
}
|
||||
|
||||
public EncodedMethod(DexFile dexFile, MethodIdItem methodIdItem, int accessFlags, CodeItem codeItem) {
|
||||
fields = new Field[] {
|
||||
this.method = new IndexedItemReference<MethodIdItem>(dexFile, methodIdItem,
|
||||
methodIndexField = new Leb128DeltaField(null)),
|
||||
this.accessFlags = new Leb128Field(accessFlags),
|
||||
this.codeItem = new OffsettedItemReference<CodeItem>(dexFile, codeItem, new Leb128Field())
|
||||
};
|
||||
}
|
||||
|
||||
protected void setPreviousMember(EncodedMethod previousMethod) {
|
||||
if (previousMethod != null) {
|
||||
methodIndexField.setPreviousField(previousMethod.methodIndexField);
|
||||
} else {
|
||||
methodIndexField.setPreviousField(null);
|
||||
}
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public int compareTo(EncodedMethod other)
|
||||
{
|
||||
return method.getReference().compareTo(other.method.getReference());
|
||||
}
|
||||
|
||||
public boolean isDirect() {
|
||||
return ((accessFlags.getCachedValue() & (AccessFlags.STATIC | AccessFlags.PRIVATE | AccessFlags.CONSTRUCTOR)) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An Leb128 integer that encodes its value as the difference between
|
||||
* itself and the previous Leb128DeltaField in the list. The first
|
||||
* item encodes the value as per normal
|
||||
*/
|
||||
protected static class Leb128DeltaField extends Leb128Field {
|
||||
private Leb128DeltaField previousField;
|
||||
|
||||
public Leb128DeltaField(Leb128DeltaField previousField) {
|
||||
this.previousField = previousField;
|
||||
}
|
||||
|
||||
public void setPreviousField(Leb128DeltaField previousField) {
|
||||
this.previousField = previousField;
|
||||
}
|
||||
|
||||
public int getCachedValue() {
|
||||
if (previousField != null) {
|
||||
return previousField.getCachedValue() + super.getCachedValue();
|
||||
} else {
|
||||
return super.getCachedValue();
|
||||
}
|
||||
}
|
||||
|
||||
public void cacheValue(int value) {
|
||||
if (previousField != null) {
|
||||
super.cacheValue(value - previousField.getCachedValue());
|
||||
} else {
|
||||
super.cacheValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_CLASS_DATA_ITEM;
|
||||
}
|
||||
}
|
229
src/main/java/org/JesusFreke/dexlib/ClassDefItem.java
Normal file
229
src/main/java/org/JesusFreke/dexlib/ClassDefItem.java
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
import org.JesusFreke.dexlib.EncodedValue.EncodedValue;
|
||||
import org.JesusFreke.dexlib.EncodedValue.EncodedValueSubField;
|
||||
import org.JesusFreke.dexlib.util.TypeUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ClassDefItem extends IndexedItem<ClassDefItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final IndexedItemReference<TypeIdItem> classType;
|
||||
private final IntegerField accessFlags;
|
||||
private final IndexedItemReference<TypeIdItem> superclassType;
|
||||
private final OffsettedItemReference<TypeListItem> classInterfacesList;
|
||||
private final IndexedItemReference<StringIdItem> sourceFile;
|
||||
private final OffsettedItemReference<AnnotationDirectoryItem> classAnnotations;
|
||||
private final OffsettedItemReference<ClassDataItem> classData;
|
||||
private final OffsettedItemReference<EncodedArrayItem> staticFieldInitialValues;
|
||||
|
||||
private ArrayList<EncodedValue> staticFieldInitialValuesList;
|
||||
|
||||
private final DexFile dexFile;
|
||||
|
||||
public ClassDefItem(DexFile dexFile, int index) {
|
||||
super(index);
|
||||
|
||||
this.dexFile = dexFile;
|
||||
|
||||
fields = new Field[] {
|
||||
classType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, new IntegerField()),
|
||||
accessFlags = new IntegerField(),
|
||||
superclassType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, new IntegerField()),
|
||||
classInterfacesList = new OffsettedItemReference<TypeListItem>(dexFile.TypeListsSection, new IntegerField()),
|
||||
sourceFile = new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new IntegerField()),
|
||||
classAnnotations = new OffsettedItemReference<AnnotationDirectoryItem>(dexFile.AnnotationDirectoriesSection, new IntegerField()),
|
||||
classData = new OffsettedItemReference<ClassDataItem>(dexFile.ClassDataSection, new IntegerField()),
|
||||
staticFieldInitialValues = new OffsettedItemReference<EncodedArrayItem>(dexFile.EncodedArraysSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public ClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags, TypeIdItem superType, ClassDataItem classDataItem) {
|
||||
super(-1);
|
||||
|
||||
this.dexFile = dexFile;
|
||||
|
||||
fields = new Field[] {
|
||||
this.classType = new IndexedItemReference<TypeIdItem>(dexFile, classType, new IntegerField()),
|
||||
this.accessFlags = new IntegerField(accessFlags),
|
||||
superclassType = new IndexedItemReference<TypeIdItem>(dexFile, superType, new IntegerField()),
|
||||
classInterfacesList = new OffsettedItemReference<TypeListItem>(dexFile.TypeListsSection, new IntegerField()),
|
||||
sourceFile = new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new IntegerField()),
|
||||
classAnnotations = new OffsettedItemReference<AnnotationDirectoryItem>(dexFile.AnnotationDirectoriesSection, new IntegerField()),
|
||||
classData = new OffsettedItemReference<ClassDataItem>(dexFile, classDataItem, new IntegerField()),
|
||||
staticFieldInitialValues = new OffsettedItemReference<EncodedArrayItem>(dexFile.EncodedArraysSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public TypeIdItem getSuperclass() {
|
||||
return superclassType.getReference();
|
||||
}
|
||||
|
||||
public TypeIdItem getClassType() {
|
||||
return classType.getReference();
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_CLASS_DEF_ITEM;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return classType.getReference().toString();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getClassName();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return classType.getReference().hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof ClassDefItem)) {
|
||||
return false;
|
||||
}
|
||||
ClassDefItem other = (ClassDefItem)o;
|
||||
return classType.equals(other.classType);
|
||||
}
|
||||
|
||||
public int compareTo(ClassDefItem o) {
|
||||
//sorting is implemented in SortClassDefItemSection, so this class doesn't
|
||||
//need an implementation of compareTo
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void addMethod(ClassDataItem.EncodedMethod encodedMethod) {
|
||||
}
|
||||
|
||||
public void addField(ClassDataItem.EncodedField encodedField, EncodedValue initialValue) {
|
||||
if (!encodedField.isStatic() && initialValue != null) {
|
||||
throw new RuntimeException("Initial values are only allowed for static fields.");
|
||||
}
|
||||
|
||||
ClassDataItem classDataItem = this.classData.getReference();
|
||||
|
||||
int fieldIndex = classDataItem.addField(encodedField);
|
||||
if (initialValue != null) {
|
||||
if (staticFieldInitialValuesList == null) {
|
||||
staticFieldInitialValuesList = new ArrayList<EncodedValue>();
|
||||
|
||||
EncodedArrayItem encodedArrayItem = new EncodedArrayItem(dexFile, staticFieldInitialValuesList);
|
||||
staticFieldInitialValues.setReference(encodedArrayItem);
|
||||
}
|
||||
|
||||
//All static fields before this one must have an initial value. Add any default values as needed
|
||||
for (int i=staticFieldInitialValuesList.size(); i < fieldIndex; i++) {
|
||||
ClassDataItem.EncodedField staticField = classDataItem.getStaticFieldAtIndex(i);
|
||||
EncodedValueSubField subField = TypeUtils.makeDefaultValueForType(dexFile, staticField.getField().getFieldType().toString());
|
||||
EncodedValue encodedValue = new EncodedValue(dexFile, subField);
|
||||
staticFieldInitialValuesList.add(i, encodedValue);
|
||||
}
|
||||
|
||||
staticFieldInitialValuesList.add(fieldIndex, initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static int placeClassDefItems(IndexedSection<ClassDefItem> section, int offset) {
|
||||
ClassDefPlacer cdp = new ClassDefPlacer(section);
|
||||
return cdp.placeSection(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class places the items within a ClassDefItem section, such that superclasses and interfaces are
|
||||
* placed before sub/implementing classes
|
||||
*/
|
||||
private static class ClassDefPlacer {
|
||||
private final IndexedSection<ClassDefItem> section;
|
||||
private final HashMap<TypeIdItem, ClassDefItem> classDefsByType = new HashMap<TypeIdItem, ClassDefItem>();
|
||||
|
||||
private int currentIndex = 0;
|
||||
private int currentOffset;
|
||||
|
||||
public ClassDefPlacer(IndexedSection<ClassDefItem> section) {
|
||||
this.section = section;
|
||||
|
||||
for (ClassDefItem classDefItem: section.items) {
|
||||
TypeIdItem typeIdItem = classDefItem.classType.getReference();
|
||||
classDefsByType.put(typeIdItem, classDefItem);
|
||||
}
|
||||
}
|
||||
|
||||
public int placeSection(int offset) {
|
||||
currentOffset = offset;
|
||||
for (ClassDefItem classDefItem: section.items) {
|
||||
placeClass(classDefItem);
|
||||
}
|
||||
|
||||
for (ClassDefItem classDefItem: classDefsByType.values()) {
|
||||
section.items.set(classDefItem.getIndex(), classDefItem);
|
||||
}
|
||||
|
||||
return currentOffset;
|
||||
}
|
||||
|
||||
private void placeClass(ClassDefItem classDefItem) {
|
||||
if (!classDefItem.isPlaced()) {
|
||||
TypeIdItem superType = classDefItem.superclassType.getReference();
|
||||
ClassDefItem superClassDefItem = classDefsByType.get(superType);
|
||||
|
||||
if (superClassDefItem != null) {
|
||||
placeClass(superClassDefItem);
|
||||
}
|
||||
|
||||
TypeListItem interfaces = classDefItem.classInterfacesList.getReference();
|
||||
|
||||
if (interfaces != null) {
|
||||
for (TypeIdItem interfaceType: interfaces.getTypes()) {
|
||||
ClassDefItem interfaceClass = classDefsByType.get(interfaceType);
|
||||
if (interfaceClass != null) {
|
||||
placeClass(interfaceClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentOffset = classDefItem.place(currentIndex++, currentOffset);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
384
src/main/java/org/JesusFreke/dexlib/CodeItem.java
Normal file
384
src/main/java/org/JesusFreke/dexlib/CodeItem.java
Normal file
@ -0,0 +1,384 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.code.Instruction;
|
||||
import org.JesusFreke.dexlib.code.Opcode;
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CodeItem extends OffsettedItem<CodeItem> {
|
||||
private final Field[] fields;
|
||||
private final ArrayList<Instruction> instructionList;
|
||||
private final ArrayList<TryItem> tryItems = new ArrayList<TryItem>();
|
||||
private final ArrayList<EncodedCatchHandler> catchHandlerList = new ArrayList<EncodedCatchHandler>();
|
||||
|
||||
private final ShortIntegerField registersCount;
|
||||
private final ShortIntegerField inArgumentCount;
|
||||
private final ShortIntegerField outArgumentCount;
|
||||
private final ListSizeField triesCount;
|
||||
private final OffsettedItemReference<DebugInfoItem> debugInfo;
|
||||
private final IntegerField instructionsSize;
|
||||
private final InstructionListField instructionListField;
|
||||
private final PaddingField padding;
|
||||
private final FieldListField<TryItem> tries;
|
||||
private final EncodedCatchHandlerList catchHandlers;
|
||||
|
||||
public CodeItem(final DexFile dexFile, int offset) {
|
||||
super(offset);
|
||||
|
||||
instructionList = new ArrayList<Instruction>();
|
||||
|
||||
fields = new Field[] {
|
||||
registersCount = new ShortIntegerField(),
|
||||
inArgumentCount = new ShortIntegerField(),
|
||||
outArgumentCount = new ShortIntegerField(),
|
||||
triesCount = new ListSizeField(tryItems, new ShortIntegerField()),
|
||||
debugInfo = new OffsettedItemReference<DebugInfoItem>(dexFile.DebugInfoItemsSection, new IntegerField()),
|
||||
instructionsSize = new IntegerField(),
|
||||
instructionListField = new InstructionListField(dexFile),
|
||||
padding = new PaddingField(),
|
||||
tries = new FieldListField<TryItem>(tryItems) {
|
||||
protected TryItem make() {
|
||||
return new TryItem();
|
||||
}
|
||||
},
|
||||
|
||||
catchHandlers = new EncodedCatchHandlerList(dexFile)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
public CodeItem(final DexFile dexFile, int registersCount, int inArguments, ArrayList<Instruction> instructions) {
|
||||
super(-1);
|
||||
|
||||
this.instructionList = new ArrayList<Instruction>(instructions);
|
||||
this.instructionListField = new InstructionListField(dexFile);
|
||||
|
||||
fields = new Field[] {
|
||||
this.registersCount = new ShortIntegerField(registersCount),
|
||||
this.inArgumentCount = new ShortIntegerField(inArguments),
|
||||
this.outArgumentCount = new ShortIntegerField(instructionListField.getOutArguments()),
|
||||
this.triesCount = new ListSizeField(tryItems, new ShortIntegerField(0)),
|
||||
this.debugInfo = new OffsettedItemReference<DebugInfoItem>(dexFile, null, new IntegerField()),
|
||||
this.instructionsSize = new IntegerField(instructionListField.getInstructionWordCount()),
|
||||
instructionListField,
|
||||
this.padding = new PaddingField(),
|
||||
this.tries = new FieldListField<TryItem>(tryItems) {
|
||||
protected TryItem make() {
|
||||
return new TryItem();
|
||||
}
|
||||
},
|
||||
this.catchHandlers = new EncodedCatchHandlerList(dexFile)
|
||||
};
|
||||
}
|
||||
|
||||
//TODO: take out
|
||||
public void writeTo(Output out) {
|
||||
super.writeTo(out);
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_CODE_ITEM;
|
||||
}
|
||||
|
||||
public Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public class TryItem extends CompositeField<TryItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
public TryItem() {
|
||||
fields = new Field[] {
|
||||
new IntegerField(),
|
||||
new ShortIntegerField(),
|
||||
new ShortIntegerField()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
|
||||
class EncodedCatchHandlerList extends CompositeField<EncodedCatchHandlerList> {
|
||||
private boolean fieldPresent = false;
|
||||
|
||||
private final DexFile dexFile;
|
||||
|
||||
public EncodedCatchHandlerList(DexFile dexFile) {
|
||||
this.dexFile = dexFile;
|
||||
}
|
||||
|
||||
private final Field[] fields = new Field[] {
|
||||
new ListSizeField(catchHandlerList, new Leb128Field()),
|
||||
new FieldListField<EncodedCatchHandler>(catchHandlerList) {
|
||||
protected EncodedCatchHandler make() {
|
||||
return new EncodedCatchHandler(dexFile);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void readFrom(Input in) {
|
||||
if (tryItems.size() > 0) {
|
||||
fieldPresent = true;
|
||||
super.readFrom(in);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
if (fieldPresent) {
|
||||
super.writeTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
if (tryItems.size() > 0) {
|
||||
fieldPresent = true;
|
||||
return super.place(offset);
|
||||
} else {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, EncodedCatchHandlerList copy) {
|
||||
super.copyTo(dexFile, copy);
|
||||
copy.fieldPresent = fieldPresent;
|
||||
}
|
||||
}
|
||||
|
||||
public class EncodedCatchHandler extends CompositeField<EncodedCatchHandler> {
|
||||
public final Field[] fields;
|
||||
private ArrayList<EncodedTypeAddrPair> list = new ArrayList<EncodedTypeAddrPair>();
|
||||
private boolean hasCatchAll = false;
|
||||
|
||||
public EncodedCatchHandler(final DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
new ListSizeField(list, new SignedLeb128Field() {
|
||||
public void readFrom(Input in) {
|
||||
super.readFrom(in);
|
||||
hasCatchAll = (getCachedValue() <= 0);
|
||||
}
|
||||
|
||||
public void cacheValue(int value) {
|
||||
super.cacheValue(value * (hasCatchAll?-1:1));
|
||||
}})
|
||||
,
|
||||
new FieldListField<EncodedTypeAddrPair>(list) {
|
||||
protected EncodedTypeAddrPair make() {
|
||||
return new EncodedTypeAddrPair(dexFile);
|
||||
}
|
||||
},
|
||||
new Leb128Field() {
|
||||
public void readFrom(Input in) {
|
||||
if (hasCatchAll) {
|
||||
super.readFrom(in);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
if (hasCatchAll) {
|
||||
super.writeTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
if (hasCatchAll) {
|
||||
return super.place(offset);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, EncodedCatchHandler copy) {
|
||||
super.copyTo(dexFile, copy);
|
||||
copy.hasCatchAll = hasCatchAll;
|
||||
}
|
||||
}
|
||||
|
||||
public class EncodedTypeAddrPair extends CompositeField<EncodedTypeAddrPair> {
|
||||
public final Field[] fields;
|
||||
|
||||
public EncodedTypeAddrPair(DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, new Leb128Field()),
|
||||
new Leb128Field()
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
|
||||
private class InstructionListField implements Field<InstructionListField> {
|
||||
private final DexFile dexFile;
|
||||
|
||||
public InstructionListField(DexFile dexFile) {
|
||||
this.dexFile = dexFile;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
int startPosition = out.getCursor();
|
||||
for (Instruction instruction: instructionList) {
|
||||
instruction.writeTo(out);
|
||||
}
|
||||
if ((out.getCursor() - startPosition) != (instructionsSize.getCachedValue() * 2)) {
|
||||
throw new RuntimeException("Did not write the expected amount of bytes");
|
||||
}
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
int numBytes = instructionsSize.getCachedValue() * 2;
|
||||
int startPosition = in.getCursor();
|
||||
|
||||
do {
|
||||
Instruction instruction = new Instruction(dexFile);
|
||||
instruction.readFrom(in);
|
||||
instructionList.add(instruction);
|
||||
} while (in.getCursor() - startPosition < numBytes);
|
||||
|
||||
if (in.getCursor() - startPosition != numBytes) {
|
||||
throw new RuntimeException("Read past the end of the code section");
|
||||
}
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + (instructionsSize.getCachedValue() * 2);
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, InstructionListField copy) {
|
||||
ArrayList<Instruction> copyInstructionList = copy.getInstructionList();
|
||||
copyInstructionList.clear();
|
||||
for (Instruction instruction: instructionList) {
|
||||
Instruction instructionCopy = new Instruction(dexFile);
|
||||
instruction.copyTo(dexFile, instructionCopy);
|
||||
copyInstructionList.add(instructionCopy);
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<Instruction> getInstructionList() {
|
||||
return instructionList;
|
||||
}
|
||||
|
||||
//return the word size of the instruction list
|
||||
public int getInstructionWordCount() {
|
||||
int bytes = 0;
|
||||
//TODO: what about option padding before the special opcodes?
|
||||
for (Instruction instruction: instructionList) {
|
||||
bytes += instruction.getBytes().length;
|
||||
}
|
||||
return bytes/2;
|
||||
}
|
||||
|
||||
//return the highest parameter word count of any method invokation
|
||||
public int getOutArguments() {
|
||||
int maxParamWordCount = 0;
|
||||
for (Instruction instruction: instructionList) {
|
||||
IndexedItem item = instruction.getReference();
|
||||
if (item instanceof MethodIdItem) {
|
||||
MethodIdItem methodIdItem = (MethodIdItem)item;
|
||||
Opcode opcode = instruction.getOpcode();
|
||||
|
||||
boolean isStatic = false;
|
||||
if (opcode == Opcode.INVOKE_STATIC || opcode == Opcode.INVOKE_STATIC_RANGE) {
|
||||
isStatic = true;
|
||||
}
|
||||
int paramWordCount = methodIdItem.getParameterWordCount(isStatic);
|
||||
|
||||
if (maxParamWordCount < paramWordCount) {
|
||||
maxParamWordCount = paramWordCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxParamWordCount;
|
||||
}
|
||||
}
|
||||
|
||||
private class PaddingField implements Field {
|
||||
|
||||
public PaddingField() {
|
||||
}
|
||||
|
||||
private boolean needsAlign() {
|
||||
return (triesCount.getCachedValue() > 0) && (instructionsSize.getCachedValue() % 2 == 1);
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
if (needsAlign()) {
|
||||
out.writeShort(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
if (needsAlign()) {
|
||||
in.skipBytes(2);
|
||||
}
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
if (needsAlign()) {
|
||||
return offset + 2;
|
||||
} else {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return getClass() == o.getClass();
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, Field field) {
|
||||
}
|
||||
}
|
||||
}
|
102
src/main/java/org/JesusFreke/dexlib/CompositeField.java
Normal file
102
src/main/java/org/JesusFreke/dexlib/CompositeField.java
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
|
||||
public abstract class CompositeField<T extends CompositeField<T>> implements Field<T> {
|
||||
/**
|
||||
* Every instance of a specific subclass should return an array with the same structure,
|
||||
* in other words have the same size, and the same type of field at each position.
|
||||
* @return An array of fields that represents the sub-fields that make up this CompositeField
|
||||
*/
|
||||
protected abstract Field[] getFields();
|
||||
|
||||
public void writeTo(Output out) {
|
||||
for (Field field: getFields()) {
|
||||
field.writeTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
for (Field field: getFields()) {
|
||||
field.readFrom(in);
|
||||
}
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
for (Field field: getFields()) {
|
||||
offset = field.place(offset);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, T copy) {
|
||||
Field[] fields = getFields();
|
||||
Field[] copyFields = copy.getFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
/**
|
||||
* This assumes that the fields will be the same for every instance
|
||||
* of a specific concrete subclass. By making this assumption, every subclass is
|
||||
* prevented from having to implement copyTo
|
||||
*/
|
||||
fields[i].copyTo(dexFile, copyFields[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int h = 1;
|
||||
for (Field field: getFields()) {
|
||||
h = h * 31 + field.hashCode();
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof CompositeField)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CompositeField other = (CompositeField)o;
|
||||
Field[] fields = getFields();
|
||||
Field[] otherFields = other.getFields();
|
||||
if (fields.length != otherFields.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
if (!fields[i].equals(otherFields[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
116
src/main/java/org/JesusFreke/dexlib/DebugInfoItem.java
Normal file
116
src/main/java/org/JesusFreke/dexlib/DebugInfoItem.java
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
import org.JesusFreke.dexlib.debug.DebugInstructionFactory;
|
||||
import org.JesusFreke.dexlib.debug.EndSequence;
|
||||
import org.JesusFreke.dexlib.debug.DebugInstruction;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DebugInfoItem extends OffsettedItem<DebugInfoItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final ArrayList<IndexedItemReference<StringIdItem>> parameterNames =
|
||||
new ArrayList<IndexedItemReference<StringIdItem>>();
|
||||
|
||||
private ArrayList<DebugInstruction> instructionFields = new ArrayList<DebugInstruction>();
|
||||
|
||||
public DebugInfoItem(final DexFile dexFile, int offset) {
|
||||
super(offset);
|
||||
|
||||
fields = new Field[] {
|
||||
new Leb128Field(),
|
||||
new ListSizeField(parameterNames, new Leb128Field()),
|
||||
new FieldListField<IndexedItemReference<StringIdItem>>(parameterNames) {
|
||||
protected IndexedItemReference<StringIdItem> make() {
|
||||
return new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new Leb128p1Field());
|
||||
}
|
||||
},
|
||||
new DebugInstructionList(dexFile)
|
||||
};
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_DEBUG_INFO_ITEM;
|
||||
}
|
||||
|
||||
private class DebugInstructionList implements Field<DebugInstructionList> {
|
||||
private final DexFile dexFile;
|
||||
private final ArrayList<DebugInstruction> list;
|
||||
|
||||
public DebugInstructionList(DexFile dexFile) {
|
||||
this.dexFile = dexFile;
|
||||
list = instructionFields;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
for (DebugInstruction debugInstruction: list) {
|
||||
debugInstruction.writeTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
DebugInstruction debugInstruction;
|
||||
do {
|
||||
debugInstruction = DebugInstructionFactory.readDebugInstruction(dexFile, in);
|
||||
list.add(debugInstruction);
|
||||
} while (!(debugInstruction instanceof EndSequence));
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
for (Field field: list) {
|
||||
offset = field.place(offset);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, DebugInstructionList copy) {
|
||||
copy.list.clear();
|
||||
copy.list.ensureCapacity(list.size());
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
DebugInstruction debugInstruction = list.get(i);
|
||||
DebugInstruction debugInstructionCopy = DebugInstructionFactory.makeDebugInstruction(dexFile, debugInstruction.getOpcode());
|
||||
debugInstruction.copyTo(dexFile, debugInstructionCopy);
|
||||
copy.list.add(debugInstructionCopy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
390
src/main/java/org/JesusFreke/dexlib/DexFile.java
Normal file
390
src/main/java/org/JesusFreke/dexlib/DexFile.java
Normal file
@ -0,0 +1,390 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.ByteArrayInput;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.FileUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.zip.Adler32;
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.DigestException;
|
||||
|
||||
public class DexFile
|
||||
{
|
||||
private final HashMap<ItemType, Section> sectionsByType;
|
||||
private final IndexedSection[] indexedSections;
|
||||
private final OffsettedSection[] offsettedSections;
|
||||
private int fileSize;
|
||||
private int dataOffset;
|
||||
private int dataSize;
|
||||
|
||||
private final DexFile dexFile = this;
|
||||
|
||||
private DexFile() {
|
||||
sectionsByType = new HashMap<ItemType, Section>(18);
|
||||
|
||||
sectionsByType.put(ItemType.TYPE_ANNOTATION_ITEM, AnnotationsSection);
|
||||
sectionsByType.put(ItemType.TYPE_ANNOTATION_SET_ITEM, AnnotationSetsSection);
|
||||
sectionsByType.put(ItemType.TYPE_ANNOTATION_SET_REF_LIST, AnnotationSetRefListsSection);
|
||||
sectionsByType.put(ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM, AnnotationDirectoriesSection);
|
||||
sectionsByType.put(ItemType.TYPE_CLASS_DATA_ITEM, ClassDataSection);
|
||||
sectionsByType.put(ItemType.TYPE_CLASS_DEF_ITEM, ClassDefsSection);
|
||||
sectionsByType.put(ItemType.TYPE_CODE_ITEM, CodeItemsSection);
|
||||
sectionsByType.put(ItemType.TYPE_DEBUG_INFO_ITEM, DebugInfoItemsSection);
|
||||
sectionsByType.put(ItemType.TYPE_ENCODED_ARRAY_ITEM, EncodedArraysSection);
|
||||
sectionsByType.put(ItemType.TYPE_FIELD_ID_ITEM, FieldIdsSection);
|
||||
sectionsByType.put(ItemType.TYPE_HEADER_ITEM, HeaderItemSection);
|
||||
sectionsByType.put(ItemType.TYPE_MAP_LIST, MapSection);
|
||||
sectionsByType.put(ItemType.TYPE_METHOD_ID_ITEM, MethodIdsSection);
|
||||
sectionsByType.put(ItemType.TYPE_PROTO_ID_ITEM, ProtoIdsSection);
|
||||
sectionsByType.put(ItemType.TYPE_STRING_DATA_ITEM, StringDataSection);
|
||||
sectionsByType.put(ItemType.TYPE_STRING_ID_ITEM, StringIdsSection);
|
||||
sectionsByType.put(ItemType.TYPE_TYPE_ID_ITEM, TypeIdsSection);
|
||||
sectionsByType.put(ItemType.TYPE_TYPE_LIST, TypeListsSection);
|
||||
|
||||
indexedSections = new IndexedSection[] {
|
||||
StringIdsSection,
|
||||
TypeIdsSection,
|
||||
ProtoIdsSection,
|
||||
FieldIdsSection,
|
||||
MethodIdsSection,
|
||||
ClassDefsSection
|
||||
};
|
||||
|
||||
offsettedSections = new OffsettedSection[] {
|
||||
AnnotationSetsSection,
|
||||
CodeItemsSection,
|
||||
AnnotationDirectoriesSection,
|
||||
TypeListsSection,
|
||||
StringDataSection,
|
||||
DebugInfoItemsSection,
|
||||
AnnotationsSection,
|
||||
EncodedArraysSection,
|
||||
ClassDataSection,
|
||||
|
||||
AnnotationSetRefListsSection
|
||||
};
|
||||
}
|
||||
|
||||
public DexFile(File file) {
|
||||
this();
|
||||
Input in = new ByteArrayInput(FileUtils.readFile(file));
|
||||
|
||||
HeaderItemSection.readFrom(1, in);
|
||||
HeaderItem headerItem = HeaderItemSection.items.get(0);
|
||||
|
||||
in.setCursor(headerItem.getMapOffset());
|
||||
|
||||
MapSection.readFrom(1, in);
|
||||
|
||||
for (MapField mapField: MapSection.items.get(0).getMapEntries()) {
|
||||
Section section = sectionsByType.get(mapField.getSectionItemType());
|
||||
if (section != null) {
|
||||
in.setCursor(mapField.getSectionOffset());
|
||||
section.readFrom(mapField.getSectionSize(), in);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static DexFile makeBlankDexFile() {
|
||||
DexFile dexFile = new DexFile();
|
||||
try
|
||||
{
|
||||
dexFile.HeaderItemSection.intern(dexFile, new HeaderItem(dexFile, 0));
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
dexFile.MapSection.intern(dexFile, MapItem.makeBlankMapItem(dexFile));
|
||||
return dexFile;
|
||||
}
|
||||
|
||||
|
||||
public <T extends Item> Section<T> getSectionForItem(T item) {
|
||||
return sectionsByType.get(item.getItemType());
|
||||
}
|
||||
|
||||
public Section getSectionForType(ItemType itemType) {
|
||||
return sectionsByType.get(itemType);
|
||||
}
|
||||
|
||||
public int getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
public int getDataOffset() {
|
||||
return dataOffset;
|
||||
}
|
||||
|
||||
public int getDataSize() {
|
||||
return dataSize;
|
||||
}
|
||||
|
||||
public void place() {
|
||||
int offset = 0;
|
||||
|
||||
offset = HeaderItemSection.place(offset);
|
||||
for (IndexedSection indexedSection: indexedSections) {
|
||||
indexedSection.unplace();
|
||||
offset = indexedSection.place(offset);
|
||||
}
|
||||
|
||||
dataOffset = offset;
|
||||
|
||||
for (OffsettedSection offsettedSection: offsettedSections) {
|
||||
offsettedSection.unplace();
|
||||
|
||||
offset = offsettedSection.place(offset);
|
||||
}
|
||||
|
||||
offset = MapSection.place(offset);
|
||||
|
||||
dataSize = offset - dataOffset;
|
||||
fileSize = offset;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
HeaderItemSection.writeTo(out);
|
||||
for (IndexedSection indexedSection: indexedSections) {
|
||||
indexedSection.writeTo(out);
|
||||
}
|
||||
|
||||
for (OffsettedSection offsettedSection: offsettedSections) {
|
||||
offsettedSection.writeTo(out);
|
||||
}
|
||||
|
||||
MapSection.writeTo(out);
|
||||
}
|
||||
|
||||
public ClassDefItem getClassByName(String className) {
|
||||
for (ClassDefItem classDefItem: ClassDefsSection.items) {
|
||||
if (classDefItem.getClassName().equals(className)) {
|
||||
return classDefItem;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("class not found");
|
||||
}
|
||||
|
||||
public MethodIdItem[] getMethodsByClass(TypeIdItem classType) {
|
||||
ArrayList<MethodIdItem> methods = new ArrayList<MethodIdItem>();
|
||||
|
||||
for (MethodIdItem methodIdItem: MethodIdsSection.items) {
|
||||
if (methodIdItem.getClassType() == classType) {
|
||||
methods.add(methodIdItem);
|
||||
}
|
||||
}
|
||||
|
||||
return methods.toArray(new MethodIdItem[0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public final IndexedSection<HeaderItem> HeaderItemSection = new IndexedSection<HeaderItem>() {
|
||||
protected HeaderItem make(int index) {
|
||||
try {
|
||||
return new HeaderItem(dexFile, index);
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
//TODO: handle this
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public final IndexedSection<StringIdItem> StringIdsSection = new IndexedSection<StringIdItem>() {
|
||||
protected StringIdItem make(int index) {
|
||||
return new StringIdItem(dexFile, index);
|
||||
}
|
||||
};
|
||||
|
||||
public final IndexedSection<TypeIdItem> TypeIdsSection = new IndexedSection<TypeIdItem>() {
|
||||
protected TypeIdItem make(int index) {
|
||||
return new TypeIdItem(dexFile, index);
|
||||
}
|
||||
};
|
||||
|
||||
public final IndexedSection<ProtoIdItem> ProtoIdsSection = new IndexedSection<ProtoIdItem>() {
|
||||
protected ProtoIdItem make(int index) {
|
||||
return new ProtoIdItem(dexFile, index);
|
||||
}
|
||||
};
|
||||
|
||||
public final IndexedSection<FieldIdItem> FieldIdsSection = new IndexedSection<FieldIdItem>() {
|
||||
protected FieldIdItem make(int index) {
|
||||
return new FieldIdItem(dexFile, index);
|
||||
}
|
||||
};
|
||||
|
||||
public final IndexedSection<MethodIdItem> MethodIdsSection = new IndexedSection<MethodIdItem>() {
|
||||
protected MethodIdItem make(int index) {
|
||||
return new MethodIdItem(dexFile, index);
|
||||
}
|
||||
};
|
||||
|
||||
public final IndexedSection<ClassDefItem> ClassDefsSection = new IndexedSection<ClassDefItem>() {
|
||||
protected ClassDefItem make(int index) {
|
||||
return new ClassDefItem(dexFile, index);
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
int ret = ClassDefItem.placeClassDefItems(this, offset);
|
||||
|
||||
this.offset = items.get(0).getOffset();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
public final IndexedSection<MapItem> MapSection = new IndexedSection<MapItem>() {
|
||||
protected MapItem make(int index) {
|
||||
return new MapItem(dexFile, index);
|
||||
}
|
||||
|
||||
public MapItem intern(DexFile dexFile, MapItem item) {
|
||||
this.items.add(item);
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
||||
public final OffsettedSection<TypeListItem> TypeListsSection = new OffsettedSection<TypeListItem>() {
|
||||
protected TypeListItem make(int offset) {
|
||||
return new TypeListItem(dexFile, offset);
|
||||
}
|
||||
};
|
||||
|
||||
public final OffsettedSection<AnnotationSetRefList> AnnotationSetRefListsSection =
|
||||
new OffsettedSection<AnnotationSetRefList>() {
|
||||
protected AnnotationSetRefList make(int offset) {
|
||||
return new AnnotationSetRefList(dexFile, offset);
|
||||
}
|
||||
};
|
||||
|
||||
public final OffsettedSection<AnnotationSetItem> AnnotationSetsSection =
|
||||
new OffsettedSection<AnnotationSetItem>() {
|
||||
protected AnnotationSetItem make(int offset) {
|
||||
return new AnnotationSetItem(dexFile, offset);
|
||||
}
|
||||
};
|
||||
|
||||
public final OffsettedSection<ClassDataItem> ClassDataSection = new OffsettedSection<ClassDataItem>() {
|
||||
protected ClassDataItem make(int offset) {
|
||||
return new ClassDataItem(dexFile, offset);
|
||||
}
|
||||
};
|
||||
|
||||
public final OffsettedSection<CodeItem> CodeItemsSection = new OffsettedSection<CodeItem>() {
|
||||
protected CodeItem make(int offset) {
|
||||
return new CodeItem(dexFile, offset);
|
||||
}
|
||||
};
|
||||
|
||||
public final OffsettedSection<StringDataItem> StringDataSection = new OffsettedSection<StringDataItem>() {
|
||||
protected StringDataItem make(int offset) {
|
||||
return new StringDataItem(offset);
|
||||
}
|
||||
};
|
||||
|
||||
public final OffsettedSection<DebugInfoItem> DebugInfoItemsSection = new OffsettedSection<DebugInfoItem>() {
|
||||
protected DebugInfoItem make(int offset) {
|
||||
return new DebugInfoItem(dexFile, offset);
|
||||
}
|
||||
};
|
||||
|
||||
public final OffsettedSection<AnnotationItem> AnnotationsSection = new OffsettedSection<AnnotationItem>() {
|
||||
protected AnnotationItem make(int offset) {
|
||||
return new AnnotationItem(dexFile, offset);
|
||||
}
|
||||
};
|
||||
|
||||
public final OffsettedSection<EncodedArrayItem> EncodedArraysSection = new OffsettedSection<EncodedArrayItem>() {
|
||||
protected EncodedArrayItem make(int offset) {
|
||||
return new EncodedArrayItem(dexFile, offset);
|
||||
}
|
||||
};
|
||||
|
||||
public final OffsettedSection<AnnotationDirectoryItem> AnnotationDirectoriesSection =
|
||||
new OffsettedSection<AnnotationDirectoryItem>() {
|
||||
protected AnnotationDirectoryItem make(int offset) {
|
||||
return new AnnotationDirectoryItem(dexFile, offset);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the signature for the <code>.dex</code> file in the
|
||||
* given array, and modify the array to contain it.
|
||||
*
|
||||
* @param bytes non-null; the bytes of the file
|
||||
*/
|
||||
public static void calcSignature(byte[] bytes) {
|
||||
MessageDigest md;
|
||||
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-1");
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
md.update(bytes, 32, bytes.length - 32);
|
||||
|
||||
try {
|
||||
int amt = md.digest(bytes, 12, 20);
|
||||
if (amt != 20) {
|
||||
throw new RuntimeException("unexpected digest write: " + amt +
|
||||
" bytes");
|
||||
}
|
||||
} catch (DigestException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the checksum for the <code>.dex</code> file in the
|
||||
* given array, and modify the array to contain it.
|
||||
*
|
||||
* @param bytes non-null; the bytes of the file
|
||||
*/
|
||||
public static void calcChecksum(byte[] bytes) {
|
||||
Adler32 a32 = new Adler32();
|
||||
|
||||
a32.update(bytes, 12, bytes.length - 12);
|
||||
|
||||
int sum = (int) a32.getValue();
|
||||
|
||||
bytes[8] = (byte) sum;
|
||||
bytes[9] = (byte) (sum >> 8);
|
||||
bytes[10] = (byte) (sum >> 16);
|
||||
bytes[11] = (byte) (sum >> 24);
|
||||
}
|
||||
}
|
91
src/main/java/org/JesusFreke/dexlib/EncodedArrayItem.java
Normal file
91
src/main/java/org/JesusFreke/dexlib/EncodedArrayItem.java
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
import org.JesusFreke.dexlib.EncodedValue.ArrayEncodedValueSubField;
|
||||
import org.JesusFreke.dexlib.EncodedValue.EncodedValue;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class EncodedArrayItem extends OffsettedItem<EncodedArrayItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final ArrayEncodedValueSubField encodedArray;
|
||||
|
||||
public EncodedArrayItem(DexFile dexFile, int offset) {
|
||||
super(offset);
|
||||
|
||||
fields = new Field[] {
|
||||
encodedArray = new ArrayEncodedValueSubField(dexFile)
|
||||
};
|
||||
}
|
||||
|
||||
public EncodedArrayItem(DexFile dexFile, ArrayList<EncodedValue> encodedValues) {
|
||||
super(-1);
|
||||
|
||||
fields = new Field[] {
|
||||
encodedArray = new ArrayEncodedValueSubField(dexFile, encodedValues)
|
||||
};
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
super.readFrom(in);
|
||||
}
|
||||
|
||||
public int place(int index, int offset) {
|
||||
return super.place(index, offset);
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
super.writeTo(out);
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return super.getOffset();
|
||||
}
|
||||
|
||||
public void add(int index, EncodedValue value) {
|
||||
encodedArray.add(index, value);
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_ENCODED_ARRAY_ITEM;
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
public class AnnotationElement extends CompositeField<AnnotationElement> {
|
||||
private Field[] fields;
|
||||
|
||||
private final IndexedItemReference<StringIdItem> elementName;
|
||||
private final EncodedValue encodedValue;
|
||||
|
||||
public AnnotationElement(final DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
elementName = new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new Leb128Field()),
|
||||
encodedValue = new EncodedValue(dexFile)
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class AnnotationEncodedValueSubField extends CompositeField<AnnotationEncodedValueSubField>
|
||||
implements EncodedValueSubField<AnnotationEncodedValueSubField> {
|
||||
|
||||
private final Field[] fields;
|
||||
private final ArrayList<AnnotationElement> annotationElementList = new ArrayList<AnnotationElement>();
|
||||
|
||||
private final IndexedItemReference<TypeIdItem> annotationType;
|
||||
private final ListSizeField annotationCount;
|
||||
private final FieldListField<AnnotationElement> annotationElements;
|
||||
|
||||
public AnnotationEncodedValueSubField(final DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
annotationType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, new Leb128Field()),
|
||||
annotationCount = new ListSizeField(annotationElementList, new Leb128Field()),
|
||||
annotationElements = new FieldListField<AnnotationElement>(annotationElementList) {
|
||||
protected AnnotationElement make() {
|
||||
return new AnnotationElement(dexFile);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public void setInitialValueArg(byte valueArg) {
|
||||
//valueArg is ignored for annotations
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return ValueType.VALUE_ANNOTATION;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ArrayEncodedValueSubField extends CompositeField<ArrayEncodedValueSubField>
|
||||
implements EncodedValueSubField<ArrayEncodedValueSubField>
|
||||
{
|
||||
|
||||
private final Field[] fields;
|
||||
private final ArrayList<EncodedValue> encodedValues;
|
||||
|
||||
public ArrayEncodedValueSubField(final DexFile dexFile) {
|
||||
encodedValues = new ArrayList<EncodedValue>();
|
||||
fields = new Field[] {
|
||||
new ListSizeField(encodedValues, new Leb128Field()),
|
||||
new FieldListField<EncodedValue>(encodedValues) {
|
||||
protected EncodedValue make() {
|
||||
return new EncodedValue(dexFile);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ArrayEncodedValueSubField(final DexFile dexFile, ArrayList<EncodedValue> encodedValues) {
|
||||
this.encodedValues = encodedValues;
|
||||
|
||||
fields = new Field[] {
|
||||
new ListSizeField(this.encodedValues, new Leb128Field()),
|
||||
new FieldListField<EncodedValue>(encodedValues) {
|
||||
protected EncodedValue make() {
|
||||
return new EncodedValue(dexFile);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public void setInitialValueArg(byte valueArg) {
|
||||
//valueArg is ignored for arrays
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return ValueType.VALUE_ARRAY;
|
||||
}
|
||||
|
||||
public void add(int index, EncodedValue encodedValue) {
|
||||
encodedValues.add(index, encodedValue);
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class BoolEncodedValueSubField
|
||||
extends SimpleEncodedValueSubField<Boolean, BoolEncodedValueSubField>
|
||||
{
|
||||
public BoolEncodedValueSubField() {
|
||||
}
|
||||
|
||||
public BoolEncodedValueSubField(boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = (valueArg != 0);
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return (byte)(value?1:0);
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return ValueType.VALUE_BOOLEAN;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class ByteEncodedValueSubField
|
||||
extends SimpleEncodedValueSubField<Byte, ByteEncodedValueSubField>
|
||||
{
|
||||
public ByteEncodedValueSubField() {
|
||||
}
|
||||
|
||||
public ByteEncodedValueSubField(byte value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.writeByte(value);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = in.readByte();
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return ValueType.VALUE_BYTE;
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.EncodedValueUtils;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class CharEncodedValueSubField
|
||||
extends SimpleEncodedValueSubField<Character, CharEncodedValueSubField>
|
||||
{
|
||||
public CharEncodedValueSubField() {
|
||||
}
|
||||
|
||||
public CharEncodedValueSubField(char value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.write(EncodedValueUtils.encodeUnsignedIntegralValue(value));
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = (char)EncodedValueUtils.decodeUnsignedIntegralValue(
|
||||
in.readBytes(valueArg + 1));
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + EncodedValueUtils.getRequiredBytesForUnsignedIntegralValue(value);
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return EncodedValueUtils.getRequiredBytesForUnsignedIntegralValue(value);
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return ValueType.VALUE_CHAR;
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.EncodedValueUtils;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class DoubleEncodedValueSubField
|
||||
extends SimpleEncodedValueSubField<Double, DoubleEncodedValueSubField>
|
||||
{
|
||||
public DoubleEncodedValueSubField() {
|
||||
}
|
||||
|
||||
public DoubleEncodedValueSubField(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.write(EncodedValueUtils.encodeRightZeroExtendedValue(
|
||||
Double.doubleToLongBits(value)));
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = Double.longBitsToDouble(EncodedValueUtils.decodeRightZeroExtendedValue(
|
||||
in.readBytes(valueArg + 1)));
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + EncodedValueUtils.getRequiredBytesForRightZeroExtendedValue(
|
||||
Double.doubleToLongBits(value));
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return (byte)(EncodedValueUtils.getRequiredBytesForRightZeroExtendedValue(
|
||||
Double.doubleToLongBits(value)) - 1);
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return ValueType.VALUE_DOUBLE;
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.EncodedValueUtils;
|
||||
|
||||
/** TODO: it should be possible to somehow use the IndexedItemReference class */
|
||||
public class EncodedIndexedItemReference<T extends IndexedItem<T>>
|
||||
extends ItemReference<T, EncodedIndexedItemReference<T>>
|
||||
implements EncodedValueSubField<EncodedIndexedItemReference<T>> {
|
||||
private int initialValueArg;
|
||||
private ValueType valueType;
|
||||
|
||||
public EncodedIndexedItemReference(IndexedSection<T> section, ValueType valueType) {
|
||||
super(section);
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
//TODO: implement support for enum values
|
||||
public EncodedIndexedItemReference(DexFile dexFile, T item) {
|
||||
super(dexFile, item);
|
||||
if (item.getClass() == StringIdItem.class) {
|
||||
valueType = ValueType.VALUE_STRING;
|
||||
} else if (item.getClass() == TypeIdItem.class) {
|
||||
valueType = ValueType.VALUE_TYPE;
|
||||
} else if (item.getClass() == FieldIdItem.class) {
|
||||
valueType = ValueType.VALUE_FIELD;
|
||||
} else if (item.getClass() == MethodIdItem.class) {
|
||||
valueType = ValueType.VALUE_METHOD;
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
T item = getReference();
|
||||
if (!item.isPlaced()) {
|
||||
throw new RuntimeException("Trying to write a reference to an item that hasn't been placed.");
|
||||
}
|
||||
out.write(EncodedValueUtils.encodeUnsignedIntegralValue(item.getIndex()));
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
setReference(((IndexedSection<T>)getSection()).getByIndex(
|
||||
(int)EncodedValueUtils.decodeUnsignedIntegralValue(in.readBytes(initialValueArg))));
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
T item = getReference();
|
||||
if (!item.isPlaced()) {
|
||||
throw new RuntimeException("Trying to place a reference to an item that hasn't been placed.");
|
||||
}
|
||||
return offset + EncodedValueUtils.getRequiredBytesForUnsignedIntegralValue(item.getIndex());
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return getReference();
|
||||
}
|
||||
|
||||
public void setInitialValueArg(byte valueArg)
|
||||
{
|
||||
initialValueArg = valueArg;
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return EncodedValueUtils.getRequiredBytesForUnsignedIntegralValue(getReference().getIndex());
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return valueType;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
public class EncodedValue extends CompositeField<EncodedValue> {
|
||||
private final Field[] fields;
|
||||
|
||||
private class ValueTypeArgField implements Field<ValueTypeArgField> {
|
||||
private ValueType valueType;
|
||||
private byte valueArg;
|
||||
|
||||
public ValueTypeArgField() {
|
||||
}
|
||||
|
||||
public ValueTypeArgField(ValueType valueType) {
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
|
||||
byte value = (byte)(valueType.getMapValue() | (valueArg << 5));
|
||||
out.writeByte(value);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
byte value = in.readByte();
|
||||
valueType = ValueType.fromByte((byte)(value & 0x1F));
|
||||
valueArg = (byte)((value & 0xFF) >>> 5);
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return valueType;
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return valueArg;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, ValueTypeArgField copy) {
|
||||
copy.valueType = valueType;
|
||||
copy.valueArg = valueArg;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return valueType.hashCode() * 31 + ((Byte)valueArg).hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof ValueTypeArgField)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ValueTypeArgField other = (ValueTypeArgField)o;
|
||||
return valueType.equals(other.valueType) && (valueArg == other.valueArg);
|
||||
}
|
||||
}
|
||||
|
||||
private class EncodedValueSubFieldWrapper implements Field<EncodedValueSubFieldWrapper> {
|
||||
private final DexFile dexFile;
|
||||
private EncodedValueSubField subField;
|
||||
|
||||
public EncodedValueSubFieldWrapper(DexFile dexFile) {
|
||||
this.dexFile = dexFile;
|
||||
}
|
||||
|
||||
public EncodedValueSubFieldWrapper(DexFile dexFile, EncodedValueSubField subField) {
|
||||
this.dexFile = dexFile;
|
||||
this.subField = subField;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
subField.writeTo(out);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
subField = EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, getValueType());
|
||||
subField.readFrom(in);
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return subField.place(offset);
|
||||
}
|
||||
|
||||
public EncodedValueSubField getEncodedValueSubField() {
|
||||
return subField;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, EncodedValueSubFieldWrapper copy) {
|
||||
EncodedValueSubField fieldCopy = EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, getValueType());
|
||||
copy.subField = fieldCopy;
|
||||
|
||||
//both fields should be the same type because they were both made with the a call to
|
||||
//EncodedValueSubFieldFactory.makeEncodedValueField using the same value type.
|
||||
subField.copyTo(dexFile, fieldCopy);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return subField.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof EncodedValueSubFieldWrapper)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EncodedValueSubFieldWrapper other = (EncodedValueSubFieldWrapper)o;
|
||||
return subField.equals(other.subField);
|
||||
}
|
||||
}
|
||||
|
||||
private final ValueTypeArgField valueTypeArg;
|
||||
private final EncodedValueSubFieldWrapper encodedValue;
|
||||
|
||||
public EncodedValue(final DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
valueTypeArg = new ValueTypeArgField(),
|
||||
encodedValue = new EncodedValueSubFieldWrapper(dexFile)
|
||||
};
|
||||
}
|
||||
|
||||
public EncodedValue(final DexFile dexFile, EncodedValueSubField subField) {
|
||||
fields = new Field[] {
|
||||
valueTypeArg = new ValueTypeArgField(subField.getValueType()),
|
||||
encodedValue = new EncodedValueSubFieldWrapper(dexFile, subField)
|
||||
};
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
offset = valueTypeArg.place(offset);
|
||||
int encodedValueStartOffset = offset;
|
||||
int ret = encodedValue.place(offset);
|
||||
|
||||
int encodedValueLength = ret - encodedValueStartOffset;
|
||||
if (encodedValueLength < 2 || valueTypeArg.valueType == ValueType.VALUE_ARRAY ||
|
||||
valueTypeArg.valueType == ValueType.VALUE_ANNOTATION) {
|
||||
valueTypeArg.valueArg = 0;
|
||||
} else {
|
||||
valueTypeArg.valueArg = (byte)(encodedValueLength - 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return valueTypeArg.getValueType();
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return valueTypeArg.getValueArg();
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.Field;
|
||||
|
||||
public interface EncodedValueSubField<T extends EncodedValueSubField> extends Field<T>
|
||||
{
|
||||
public void setInitialValueArg(byte valueArg);
|
||||
public byte getValueArg();
|
||||
public ValueType getValueType();
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
|
||||
public abstract class EncodedValueSubFieldFactory
|
||||
{
|
||||
public static EncodedValueSubField makeEncodedValueField(DexFile dexFile, ValueType valueType) {
|
||||
switch (valueType) {
|
||||
case VALUE_NULL:
|
||||
return new NullEncodedValueSubField();
|
||||
case VALUE_BOOLEAN:
|
||||
return new BoolEncodedValueSubField();
|
||||
case VALUE_BYTE:
|
||||
return new ByteEncodedValueSubField();
|
||||
case VALUE_CHAR:
|
||||
return new CharEncodedValueSubField();
|
||||
case VALUE_SHORT:
|
||||
return new ShortEncodedValueSubField();
|
||||
case VALUE_INT:
|
||||
return new IntEncodedValueSubField();
|
||||
case VALUE_LONG:
|
||||
return new LongEncodedValueSubField();
|
||||
case VALUE_FLOAT:
|
||||
return new FloatEncodedValueSubField();
|
||||
case VALUE_DOUBLE:
|
||||
return new DoubleEncodedValueSubField();
|
||||
case VALUE_STRING:
|
||||
return new EncodedIndexedItemReference<StringIdItem>(dexFile.StringIdsSection, valueType);
|
||||
case VALUE_TYPE:
|
||||
return new EncodedIndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, valueType);
|
||||
case VALUE_FIELD:
|
||||
return new EncodedIndexedItemReference<FieldIdItem>(dexFile.FieldIdsSection, valueType);
|
||||
case VALUE_ENUM:
|
||||
return new EncodedIndexedItemReference<FieldIdItem>(dexFile.FieldIdsSection, valueType);
|
||||
case VALUE_METHOD:
|
||||
return new EncodedIndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection, valueType);
|
||||
case VALUE_ARRAY:
|
||||
return new ArrayEncodedValueSubField(dexFile);
|
||||
case VALUE_ANNOTATION:
|
||||
return new AnnotationEncodedValueSubField(dexFile);
|
||||
default:
|
||||
throw new RuntimeException("Invalid ValueType");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.EncodedValueUtils;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class FloatEncodedValueSubField
|
||||
extends SimpleEncodedValueSubField<Float, FloatEncodedValueSubField>
|
||||
{
|
||||
public FloatEncodedValueSubField() {
|
||||
}
|
||||
|
||||
public FloatEncodedValueSubField(float value) {
|
||||
this.value = value;
|
||||
}
|
||||
public void writeTo(Output out) {
|
||||
out.write(EncodedValueUtils.encodeRightZeroExtendedValue(
|
||||
((long)Float.floatToIntBits(value)) << 32));
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
long longValue = EncodedValueUtils.decodeRightZeroExtendedValue(in.readBytes(valueArg + 1));
|
||||
value = Float.intBitsToFloat((int)((longValue >> 32) & 0xFFFFFFFF));
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + EncodedValueUtils.getRequiredBytesForRightZeroExtendedValue(
|
||||
((long)Float.floatToRawIntBits(value)) << 32);
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return (byte)(EncodedValueUtils.getRequiredBytesForRightZeroExtendedValue(
|
||||
Float.floatToIntBits(value)) - 1);
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return ValueType.VALUE_LONG;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.EncodedValueUtils;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class IntEncodedValueSubField
|
||||
extends SimpleEncodedValueSubField<Integer, IntEncodedValueSubField>
|
||||
{
|
||||
public IntEncodedValueSubField() {
|
||||
}
|
||||
|
||||
public IntEncodedValueSubField(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.write(EncodedValueUtils.encodeSignedIntegralValue(value));
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = (int)EncodedValueUtils.decodeSignedIntegralValue(in.readBytes(valueArg+1));
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + EncodedValueUtils.getRequiredBytesForSignedIntegralValue(value);
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return (byte)(EncodedValueUtils.getRequiredBytesForSignedIntegralValue(value) - 1);
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return ValueType.VALUE_INT;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.EncodedValueUtils;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class LongEncodedValueSubField
|
||||
extends SimpleEncodedValueSubField<Long, LongEncodedValueSubField>
|
||||
{
|
||||
public LongEncodedValueSubField() {
|
||||
}
|
||||
|
||||
public LongEncodedValueSubField(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.write(EncodedValueUtils.encodeSignedIntegralValue(value));
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = EncodedValueUtils.decodeSignedIntegralValue(in.readBytes(valueArg+1));
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + EncodedValueUtils.getRequiredBytesForSignedIntegralValue(value);
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return (byte)(EncodedValueUtils.getRequiredBytesForSignedIntegralValue(value) - 1);
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return ValueType.VALUE_LONG;
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class NullEncodedValueSubField
|
||||
extends SimpleEncodedValueSubField<Object, NullEncodedValueSubField>
|
||||
{
|
||||
public NullEncodedValueSubField() {
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = null;
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return ValueType.VALUE_NULL;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.EncodedValueUtils;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class ShortEncodedValueSubField
|
||||
extends SimpleEncodedValueSubField<Short, ShortEncodedValueSubField>
|
||||
{
|
||||
public ShortEncodedValueSubField() {
|
||||
}
|
||||
|
||||
public ShortEncodedValueSubField(short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.write(EncodedValueUtils.encodeSignedIntegralValue(value));
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = (short)EncodedValueUtils.decodeSignedIntegralValue(in.readBytes(valueArg+1));
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + EncodedValueUtils.getRequiredBytesForSignedIntegralValue(value);
|
||||
}
|
||||
|
||||
public byte getValueArg() {
|
||||
return (byte)(EncodedValueUtils.getRequiredBytesForSignedIntegralValue(value) - 1);
|
||||
}
|
||||
|
||||
public ValueType getValueType() {
|
||||
return ValueType.VALUE_SHORT;
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import org.JesusFreke.dexlib.DexFile;
|
||||
|
||||
public abstract class SimpleEncodedValueSubField<V, T extends SimpleEncodedValueSubField<V,T>> implements EncodedValueSubField<T>
|
||||
{
|
||||
protected V value;
|
||||
protected byte valueArg = 0;
|
||||
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setInitialValueArg(byte valueArg) {
|
||||
this.valueArg = valueArg;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, T copy) {
|
||||
copy.value = value;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (value == null) {
|
||||
return 0;
|
||||
}
|
||||
return value.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof SimpleEncodedValueSubField)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleEncodedValueSubField other = (SimpleEncodedValueSubField)o;
|
||||
if (value == null) {
|
||||
return other.value == null;
|
||||
}
|
||||
return value.equals(other.value);
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.EncodedValue;
|
||||
|
||||
import java.util.TreeMap;
|
||||
|
||||
public enum ValueType {
|
||||
|
||||
VALUE_BYTE((byte) 0x00),
|
||||
VALUE_SHORT((byte) 0x02),
|
||||
VALUE_CHAR((byte) 0x03),
|
||||
VALUE_INT((byte) 0x04),
|
||||
VALUE_LONG((byte) 0x06),
|
||||
VALUE_FLOAT((byte) 0x10),
|
||||
VALUE_DOUBLE((byte) 0x11),
|
||||
VALUE_STRING((byte) 0x17),
|
||||
VALUE_TYPE((byte) 0x18),
|
||||
VALUE_FIELD((byte) 0x19),
|
||||
VALUE_METHOD((byte) 0x1a),
|
||||
VALUE_ENUM((byte) 0x1b),
|
||||
VALUE_ARRAY((byte) 0x1c),
|
||||
VALUE_ANNOTATION((byte) 0x1d),
|
||||
VALUE_NULL((byte) 0x1e),
|
||||
VALUE_BOOLEAN((byte) 0x1f);
|
||||
|
||||
/**
|
||||
* A map to facilitate looking up an <code>ItemType</code> by ordinal
|
||||
*/
|
||||
private final static TreeMap<Byte, ValueType> valueTypeIntegerMap;
|
||||
|
||||
/** builds the <code>itemTypeIntegerMap</code> object */
|
||||
static {
|
||||
valueTypeIntegerMap = new TreeMap<Byte, ValueType>();
|
||||
|
||||
for (ValueType valueType : ValueType.values()) {
|
||||
valueTypeIntegerMap.put(valueType.getMapValue(), valueType);
|
||||
}
|
||||
}
|
||||
|
||||
private final byte mapValue;
|
||||
|
||||
private ValueType(byte mapValue) {
|
||||
this.mapValue = mapValue;
|
||||
}
|
||||
|
||||
public byte getMapValue() {
|
||||
return mapValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte value to the corresponding ValueType enum value,
|
||||
* or null if the value isn't a valid ValueType value
|
||||
*
|
||||
* @param valueType the int value to convert to a ValueType
|
||||
* @return the ValueType enum value corresponding to valueType, or null
|
||||
* if not a valid ValueType value
|
||||
*/
|
||||
public static ValueType fromByte(byte valueType) {
|
||||
return valueTypeIntegerMap.get(valueType);
|
||||
}
|
||||
}
|
39
src/main/java/org/JesusFreke/dexlib/Field.java
Normal file
39
src/main/java/org/JesusFreke/dexlib/Field.java
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public interface Field<T extends Field> {
|
||||
public void writeTo(Output out);
|
||||
public void readFrom(Input in);
|
||||
public int place(int offset);
|
||||
public void copyTo(DexFile dexFile, T copy);
|
||||
}
|
96
src/main/java/org/JesusFreke/dexlib/FieldIdItem.java
Normal file
96
src/main/java/org/JesusFreke/dexlib/FieldIdItem.java
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
|
||||
public class FieldIdItem extends IndexedItem<FieldIdItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final IndexedItemReference<TypeIdItem> classType;
|
||||
private final IndexedItemReference<TypeIdItem> fieldType;
|
||||
private final IndexedItemReference<StringIdItem> fieldName;
|
||||
|
||||
public FieldIdItem(DexFile dexFile, int index) {
|
||||
super(index);
|
||||
fields = new Field[] {
|
||||
classType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, new ShortIntegerField()),
|
||||
fieldType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, new ShortIntegerField()),
|
||||
fieldName = new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public FieldIdItem(DexFile dexFile, TypeIdItem classType, StringIdItem fieldName, TypeIdItem fieldType) {
|
||||
super(-1);
|
||||
fields = new Field[] {
|
||||
this.classType = new IndexedItemReference<TypeIdItem>(dexFile, classType, new ShortIntegerField()),
|
||||
this.fieldType = new IndexedItemReference<TypeIdItem>(dexFile, fieldType, new ShortIntegerField()),
|
||||
this.fieldName = new IndexedItemReference<StringIdItem>(dexFile, fieldName, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public FieldIdItem(DexFile dexFile, TypeIdItem classType, String fieldName, TypeIdItem fieldType) {
|
||||
this(dexFile, classType, new StringIdItem(dexFile, fieldName), fieldType);
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_FIELD_ID_ITEM;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return classType.toString() + " - " + fieldName.toString();
|
||||
}
|
||||
|
||||
public int compareTo(FieldIdItem o) {
|
||||
int result = classType.compareTo(o.classType);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = fieldName.compareTo(o.fieldName);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return fieldType.compareTo(o.fieldType);
|
||||
|
||||
}
|
||||
|
||||
public TypeIdItem getFieldType() {
|
||||
return fieldType.getReference();
|
||||
}
|
||||
}
|
105
src/main/java/org/JesusFreke/dexlib/FieldListField.java
Normal file
105
src/main/java/org/JesusFreke/dexlib/FieldListField.java
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class FieldListField<T extends Field> implements Field<FieldListField<T>> {
|
||||
private final ArrayList<T> list;
|
||||
|
||||
public FieldListField(ArrayList<T> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
for (Field field: list) {
|
||||
field.writeTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
T field = list.get(i);
|
||||
|
||||
if (field == null) {
|
||||
field = make();
|
||||
list.set(i, field);
|
||||
}
|
||||
field.readFrom(in);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract T make();
|
||||
|
||||
public int place(int offset) {
|
||||
for (Field field: list) {
|
||||
offset = field.place(offset);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, FieldListField<T> copy) {
|
||||
copy.list.clear();
|
||||
copy.list.ensureCapacity(list.size());
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
T fieldCopy = copy.make();
|
||||
list.get(i).copyTo(dexFile, fieldCopy);
|
||||
copy.list.add(fieldCopy);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int h = 1;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
h = h * 31 + list.get(i).hashCode();
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof FieldListField)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldListField other = (FieldListField)o;
|
||||
if (list.size() != other.list.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (!list.get(i).equals(other.list.get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
66
src/main/java/org/JesusFreke/dexlib/FixedByteArrayField.java
Normal file
66
src/main/java/org/JesusFreke/dexlib/FixedByteArrayField.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.ByteArray;
|
||||
|
||||
public class FixedByteArrayField implements Field<FixedByteArrayField> {
|
||||
protected byte[] value;
|
||||
|
||||
public FixedByteArrayField(int size) {
|
||||
value = new byte[size];
|
||||
}
|
||||
|
||||
public FixedByteArrayField(byte[] bytes) {
|
||||
this.value = bytes.clone();
|
||||
}
|
||||
|
||||
public FixedByteArrayField(ByteArray byteArray) {
|
||||
value = new byte[byteArray.size()];
|
||||
byteArray.getBytes(value, 0);
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.write(value);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
in.read(value);
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + value.length;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, FixedByteArrayField copy) {
|
||||
copy.value = value.clone();
|
||||
}
|
||||
}
|
169
src/main/java/org/JesusFreke/dexlib/HeaderItem.java
Normal file
169
src/main/java/org/JesusFreke/dexlib/HeaderItem.java
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public class HeaderItem extends IndexedItem<HeaderItem> {
|
||||
/**
|
||||
* non-null; the file format magic number, represented as the
|
||||
* low-order bytes of a string
|
||||
*/
|
||||
private static final String MAGIC = "dex\n035" + '\0';
|
||||
|
||||
/** size of this section, in bytes */
|
||||
private static final int HEADER_SIZE = 0x70;
|
||||
|
||||
/** the endianness tag */
|
||||
private static final int ENDIAN_TAG = 0x12345678;
|
||||
|
||||
private final Field[] fields;
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
private final FixedByteArrayField magic;
|
||||
private final IntegerField checksum;
|
||||
private final FixedByteArrayField signature;
|
||||
private final IntegerField fileSize;
|
||||
private final IntegerField headerSize;
|
||||
private final IntegerField endianTag;
|
||||
private final IntegerField linkSize;
|
||||
private final IntegerField linkOff;
|
||||
private final IntegerField mapOff;
|
||||
private final SectionHeaderInfo StringIdsInfo;
|
||||
private final SectionHeaderInfo TypeIdsInfo;
|
||||
private final SectionHeaderInfo ProtoIdsInfo;
|
||||
private final SectionHeaderInfo FieldIdsInfo;
|
||||
private final SectionHeaderInfo MethodIdsInfo;
|
||||
private final SectionHeaderInfo ClassDefsInfo;
|
||||
private final IntegerField dataSize;
|
||||
private final IntegerField dataOff;
|
||||
|
||||
public HeaderItem(final DexFile file, int index) throws UnsupportedEncodingException {
|
||||
super(index);
|
||||
|
||||
fields = new Field[] {
|
||||
magic = new FixedByteArrayField(MAGIC.getBytes("US-ASCII")),
|
||||
checksum = new IntegerField() {
|
||||
public void writeTo(Output out) {
|
||||
cacheValue(0);
|
||||
super.writeTo(out);
|
||||
}
|
||||
},
|
||||
signature = new FixedByteArrayField(20) {
|
||||
public void writeTo(Output out) {
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
value[i] = 0;
|
||||
}
|
||||
super.writeTo(out);
|
||||
}
|
||||
},
|
||||
fileSize = new IntegerField() {
|
||||
public void writeTo(Output out) {
|
||||
cacheValue(file.getFileSize());
|
||||
super.writeTo(out);
|
||||
}
|
||||
},
|
||||
headerSize = new IntegerField(HEADER_SIZE),
|
||||
endianTag = new IntegerField(ENDIAN_TAG),
|
||||
linkSize = new IntegerField(0),
|
||||
linkOff = new IntegerField(0),
|
||||
mapOff = new IntegerField() {
|
||||
public void writeTo(Output out) {
|
||||
cacheValue(file.MapSection.getOffset());
|
||||
super.writeTo(out);
|
||||
}
|
||||
},
|
||||
StringIdsInfo = new SectionHeaderInfo() {
|
||||
protected Section getSection() {
|
||||
return file.StringIdsSection;
|
||||
}
|
||||
},
|
||||
TypeIdsInfo = new SectionHeaderInfo() {
|
||||
protected Section getSection() {
|
||||
return file.TypeIdsSection;
|
||||
}
|
||||
},
|
||||
ProtoIdsInfo = new SectionHeaderInfo() {
|
||||
protected Section getSection() {
|
||||
return file.ProtoIdsSection;
|
||||
}
|
||||
},
|
||||
FieldIdsInfo = new SectionHeaderInfo() {
|
||||
protected Section getSection() {
|
||||
return file.FieldIdsSection;
|
||||
}
|
||||
},
|
||||
MethodIdsInfo = new SectionHeaderInfo() {
|
||||
protected Section getSection() {
|
||||
return file.MethodIdsSection;
|
||||
}
|
||||
},
|
||||
ClassDefsInfo = new SectionHeaderInfo() {
|
||||
protected Section getSection() {
|
||||
return file.ClassDefsSection;
|
||||
}
|
||||
},
|
||||
dataSize = new IntegerField() {
|
||||
public void writeTo(Output out) {
|
||||
cacheValue(file.getDataSize());
|
||||
super.writeTo(out);
|
||||
}
|
||||
},
|
||||
dataOff = new IntegerField() {
|
||||
public void writeTo(Output out) {
|
||||
cacheValue(file.getDataOffset());
|
||||
super.writeTo(out);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int getMapOffset() {
|
||||
return mapOff.getCachedValue();
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_HEADER_ITEM;
|
||||
}
|
||||
|
||||
public int compareTo(HeaderItem o) {
|
||||
//there is only 1 header item
|
||||
return 0;
|
||||
}
|
||||
}
|
46
src/main/java/org/JesusFreke/dexlib/IndexedItem.java
Normal file
46
src/main/java/org/JesusFreke/dexlib/IndexedItem.java
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
public abstract class IndexedItem<T extends IndexedItem> extends Item<T> implements Comparable<T> {
|
||||
private int index;
|
||||
|
||||
protected IndexedItem(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public int place(int index, int offset) {
|
||||
this.index = index;
|
||||
return super.place(index, offset);
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class IndexedItemReference<T extends IndexedItem<T>> extends
|
||||
ItemReference<T,IndexedItemReference<T>> implements Comparable<IndexedItemReference<T>> {
|
||||
private final CachedIntegerValueField underlyingField;
|
||||
|
||||
public IndexedItemReference(IndexedSection<T> section, CachedIntegerValueField underlyingField) {
|
||||
super(section);
|
||||
this.underlyingField = underlyingField;
|
||||
}
|
||||
|
||||
public IndexedItemReference(DexFile dexFile, T item, CachedIntegerValueField underlyingField) {
|
||||
super(dexFile, item);
|
||||
this.underlyingField = underlyingField;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
T item = getReference();
|
||||
if (item != null && !item.isPlaced()) {
|
||||
throw new RuntimeException("Trying to write a reference to an item that hasn't been placed.");
|
||||
}
|
||||
underlyingField.writeTo(out);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
underlyingField.readFrom(in);
|
||||
if (underlyingField.getCachedValue() != -1) {
|
||||
setReference(getSection().getByIndex(underlyingField.getCachedValue()));
|
||||
}
|
||||
}
|
||||
|
||||
public IndexedSection<T> getSection() {
|
||||
return (IndexedSection<T>)super.getSection();
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
if (getReference() != null) {
|
||||
underlyingField.cacheValue(getReference().getIndex());
|
||||
} else {
|
||||
underlyingField.cacheValue(-1);
|
||||
}
|
||||
return underlyingField.place(offset);
|
||||
}
|
||||
|
||||
public int compareTo(IndexedItemReference<T> o) {
|
||||
return getReference().compareTo(o.getReference());
|
||||
}
|
||||
}
|
88
src/main/java/org/JesusFreke/dexlib/IndexedSection.java
Normal file
88
src/main/java/org/JesusFreke/dexlib/IndexedSection.java
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public abstract class IndexedSection<T extends IndexedItem<T>> extends Section<T> {
|
||||
public IndexedSection() {
|
||||
}
|
||||
|
||||
public T getByIndex(int index) {
|
||||
for (int i = items.size(); i <= index; i++) {
|
||||
items.add(null);
|
||||
}
|
||||
T item = items.get(index);
|
||||
if (item == null) {
|
||||
item = make(index);
|
||||
items.set(index, item);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public void readFrom(int size, Input in) {
|
||||
super.setSize(size);
|
||||
|
||||
for (int i = 0; i < size(); i++) {
|
||||
T item = getByIndex(i);
|
||||
item.readFrom(in);
|
||||
in.alignTo(item.getAlignment());
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract T make(int index);
|
||||
|
||||
public T intern(DexFile dexFile, T item) {
|
||||
T itemToReturn = getInternedItem(item);
|
||||
|
||||
if (itemToReturn == null) {
|
||||
/**
|
||||
* Make a new item at the end of this section, and copy the fields
|
||||
* to the new item
|
||||
*/
|
||||
itemToReturn = getByIndex(size());
|
||||
item.copyTo(dexFile, itemToReturn);
|
||||
uniqueItems.put(itemToReturn, itemToReturn);
|
||||
}
|
||||
|
||||
return itemToReturn;
|
||||
}
|
||||
|
||||
protected void sortSection() {
|
||||
Collections.sort(items);
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
sortSection();
|
||||
|
||||
return super.place(offset);
|
||||
}
|
||||
}
|
70
src/main/java/org/JesusFreke/dexlib/IntegerField.java
Normal file
70
src/main/java/org/JesusFreke/dexlib/IntegerField.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class IntegerField extends CachedIntegerValueField {
|
||||
protected int value = 0;
|
||||
|
||||
public IntegerField() {
|
||||
}
|
||||
|
||||
public IntegerField(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.writeInt(value);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = in.readInt();
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the integer value that has been cached. This
|
||||
* value is either the value that the field was constructed with, the
|
||||
* value that was read via <code>readFrom</code>, or the value that was
|
||||
* cached when <code>place</code> was called
|
||||
* @return the cached value
|
||||
*/
|
||||
public int getCachedValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void cacheValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
142
src/main/java/org/JesusFreke/dexlib/Item.java
Normal file
142
src/main/java/org/JesusFreke/dexlib/Item.java
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
|
||||
public abstract class Item<T extends Item> {
|
||||
private int offset = -1;
|
||||
|
||||
protected Item() {
|
||||
}
|
||||
|
||||
protected Item(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public boolean isPlaced() {
|
||||
return offset > -1;
|
||||
}
|
||||
|
||||
public void unplace() {
|
||||
offset = -1;
|
||||
}
|
||||
|
||||
public int place(int index, int offset) {
|
||||
offset = alignOffset(offset);
|
||||
|
||||
//TODO: take out
|
||||
System.out.println("Placing item type " + getItemType().getTypeName() + " at offset " + ((Integer)offset).toString());
|
||||
|
||||
this.offset = offset;
|
||||
|
||||
Field[] fields = getFields();
|
||||
|
||||
for (Field field: fields) {
|
||||
offset = field.place(offset);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
for (Field field: getFields()) {
|
||||
field.readFrom(in);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.alignTo(getAlignment());
|
||||
|
||||
//TODO: take out
|
||||
System.out.println("Writing item type " + getItemType().getTypeName() + " at offset " + ((Integer)out.getCursor()).toString());
|
||||
|
||||
if (out.getCursor() != offset) {
|
||||
throw new RuntimeException("Item is being written somewhere other than where it was placed");
|
||||
}
|
||||
for (Field field: getFields()) {
|
||||
field.writeTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract int getAlignment();
|
||||
|
||||
protected int alignOffset(int offset) {
|
||||
int mask = getAlignment() - 1;
|
||||
|
||||
return (offset + mask) & ~mask;
|
||||
}
|
||||
|
||||
protected int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
protected abstract Field[] getFields();
|
||||
|
||||
public abstract ItemType getItemType();
|
||||
|
||||
public void copyTo(DexFile dexFile, T copy) {
|
||||
Field[] fields = getFields();
|
||||
Field[] fieldsCopy = copy.getFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
fields[i].copyTo(dexFile, fieldsCopy[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int h = 1;
|
||||
for (Field field: getFields()) {
|
||||
h = h*31 + field.hashCode();
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Item)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Item other = (Item)o;
|
||||
Field[] fields = getFields();
|
||||
Field[] otherFields = other.getFields();
|
||||
|
||||
if (fields.length != otherFields.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
if (!fields[i].equals(otherFields[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
87
src/main/java/org/JesusFreke/dexlib/ItemReference.java
Normal file
87
src/main/java/org/JesusFreke/dexlib/ItemReference.java
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
public abstract class ItemReference<T extends Item<T>, S extends ItemReference<T,S>> implements Field<S> {
|
||||
private T item = null;
|
||||
private Section<T> section;
|
||||
|
||||
public ItemReference(Section<T> section) {
|
||||
this.section = section;
|
||||
}
|
||||
|
||||
public ItemReference(DexFile dexFile, T item) {
|
||||
if (item != null) {
|
||||
section = dexFile.getSectionForItem(item);
|
||||
this.item = item;
|
||||
}
|
||||
}
|
||||
|
||||
public T getReference() {
|
||||
return item;
|
||||
}
|
||||
|
||||
protected void setReference(T item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public Section<T> getSection() {
|
||||
return section;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, S copy) {
|
||||
T referencedItem = getReference();
|
||||
if (referencedItem == null) {
|
||||
return;
|
||||
}
|
||||
Section<T> section = copy.getSection();
|
||||
T copiedItem = section.intern(dexFile, referencedItem);
|
||||
copy.setReference(copiedItem);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (item == null) {
|
||||
return 0;
|
||||
}
|
||||
return item.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof ItemReference)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemReference other = (ItemReference)o;
|
||||
if (item != null) {
|
||||
return item.equals(other.item);
|
||||
} else {
|
||||
return other.item == null;
|
||||
}
|
||||
}
|
||||
}
|
106
src/main/java/org/JesusFreke/dexlib/ItemType.java
Normal file
106
src/main/java/org/JesusFreke/dexlib/ItemType.java
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Enumeration of all the top-level item types.
|
||||
*/
|
||||
public enum ItemType {
|
||||
TYPE_HEADER_ITEM( 0x0000, "header_item"),
|
||||
TYPE_STRING_ID_ITEM( 0x0001, "string_id_item"),
|
||||
TYPE_TYPE_ID_ITEM( 0x0002, "type_id_item"),
|
||||
TYPE_PROTO_ID_ITEM( 0x0003, "proto_id_item"),
|
||||
TYPE_FIELD_ID_ITEM( 0x0004, "field_id_item"),
|
||||
TYPE_METHOD_ID_ITEM( 0x0005, "method_id_item"),
|
||||
TYPE_CLASS_DEF_ITEM( 0x0006, "class_def_item"),
|
||||
TYPE_MAP_LIST( 0x1000, "map_list"),
|
||||
TYPE_TYPE_LIST( 0x1001, "type_list"),
|
||||
TYPE_ANNOTATION_SET_REF_LIST( 0x1002, "annotation_set_ref_list"),
|
||||
TYPE_ANNOTATION_SET_ITEM( 0x1003, "annotation_set_item"),
|
||||
TYPE_CLASS_DATA_ITEM( 0x2000, "class_data_item"),
|
||||
TYPE_CODE_ITEM( 0x2001, "code_item"),
|
||||
TYPE_STRING_DATA_ITEM( 0x2002, "string_data_item"),
|
||||
TYPE_DEBUG_INFO_ITEM( 0x2003, "debug_info_item"),
|
||||
TYPE_ANNOTATION_ITEM( 0x2004, "annotation_item"),
|
||||
TYPE_ENCODED_ARRAY_ITEM( 0x2005, "encoded_array_item"),
|
||||
TYPE_ANNOTATIONS_DIRECTORY_ITEM(0x2006, "annotations_directory_item"),
|
||||
TYPE_MAP_ITEM( -1, "map_item"),
|
||||
TYPE_TYPE_ITEM( -1, "type_item"),
|
||||
TYPE_EXCEPTION_HANDLER_ITEM( -1, "exception_handler_item"),
|
||||
TYPE_ANNOTATION_SET_REF_ITEM( -1, "annotation_set_ref_item");
|
||||
|
||||
/** A map to facilitate looking up an <code>ItemType</code> by ordinal */
|
||||
private final static TreeMap<Integer, ItemType> itemTypeIntegerMap;
|
||||
|
||||
/** builds the <code>itemTypeIntegerMap</code> object */
|
||||
static {
|
||||
itemTypeIntegerMap = new TreeMap<Integer, ItemType>();
|
||||
|
||||
for (ItemType itemType: ItemType.values()) {
|
||||
itemTypeIntegerMap.put(itemType.getMapValue(), itemType);
|
||||
}
|
||||
}
|
||||
|
||||
/** value when represented in a MapItem */
|
||||
private final int mapValue;
|
||||
|
||||
/** non-null; name of the type */
|
||||
private final String typeName;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param mapValue value when represented in a MapItem
|
||||
* @param typeName non-null; name of the type
|
||||
*/
|
||||
private ItemType(int mapValue, String typeName) {
|
||||
this.mapValue = mapValue;
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the map value.
|
||||
*
|
||||
* @return the map value
|
||||
*/
|
||||
public int getMapValue() {
|
||||
return mapValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type name.
|
||||
*
|
||||
* @return non-null; the type name
|
||||
*/
|
||||
public String getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an int value to the corresponding ItemType enum value,
|
||||
* or null if the value isn't a valid ItemType value
|
||||
*
|
||||
* @param itemType the int value to convert to an ItemType
|
||||
* @return the ItemType enum value corresponding to itemType, or null
|
||||
* if not a valid ItemType value
|
||||
*/
|
||||
public static ItemType fromInt(int itemType) {
|
||||
return itemTypeIntegerMap.get(itemType);
|
||||
}
|
||||
}
|
64
src/main/java/org/JesusFreke/dexlib/Leb128Field.java
Normal file
64
src/main/java/org/JesusFreke/dexlib/Leb128Field.java
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.Leb128Utils;
|
||||
|
||||
public class Leb128Field extends CachedIntegerValueField {
|
||||
protected int value;
|
||||
|
||||
public Leb128Field() {
|
||||
}
|
||||
|
||||
public Leb128Field(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.writeUnsignedLeb128(value);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = in.readUnsignedLeb128();
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + Leb128Utils.unsignedLeb128Size(value);
|
||||
}
|
||||
|
||||
public int getCachedValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void cacheValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
64
src/main/java/org/JesusFreke/dexlib/Leb128p1Field.java
Normal file
64
src/main/java/org/JesusFreke/dexlib/Leb128p1Field.java
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.Leb128Utils;
|
||||
|
||||
public class Leb128p1Field extends CachedIntegerValueField {
|
||||
protected int value;
|
||||
|
||||
public Leb128p1Field() {
|
||||
}
|
||||
|
||||
public Leb128p1Field(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.writeUnsignedLeb128(value + 1);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = in.readUnsignedLeb128() - 1;
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + Leb128Utils.unsignedLeb128Size(value + 1);
|
||||
}
|
||||
|
||||
public int getCachedValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void cacheValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
90
src/main/java/org/JesusFreke/dexlib/ListSizeField.java
Normal file
90
src/main/java/org/JesusFreke/dexlib/ListSizeField.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ListSizeField extends CachedIntegerValueField {
|
||||
private final ArrayList<?> list;
|
||||
private final CachedIntegerValueField underlyingField;
|
||||
|
||||
public ListSizeField(ArrayList list, CachedIntegerValueField underlyingField) {
|
||||
this.list = list;
|
||||
this.underlyingField = underlyingField;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
underlyingField.writeTo(out);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
underlyingField.readFrom(in);
|
||||
/** the absolute value operation is needed for the case when a list sized is
|
||||
* encoded as the absolute value of a signed integer
|
||||
*/
|
||||
int listSize = Math.abs(underlyingField.getCachedValue());
|
||||
|
||||
list.clear();
|
||||
list.ensureCapacity(listSize);
|
||||
for (int i = 0; i < listSize; i++) {
|
||||
list.add(null);
|
||||
}
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
underlyingField.cacheValue(list.size());
|
||||
return underlyingField.place(offset);
|
||||
}
|
||||
|
||||
public int getCachedValue() {
|
||||
return underlyingField.getCachedValue();
|
||||
}
|
||||
|
||||
public void cacheValue(int value) {
|
||||
underlyingField.cacheValue(value);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
//don't affect hash code calculations
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof ListSizeField)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ListSizeField other = (ListSizeField)o;
|
||||
|
||||
return list.size() == other.list.size();
|
||||
}
|
||||
}
|
88
src/main/java/org/JesusFreke/dexlib/MapField.java
Normal file
88
src/main/java/org/JesusFreke/dexlib/MapField.java
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
|
||||
public class MapField extends CompositeField<MapField> {
|
||||
private final Field[] fields;
|
||||
|
||||
public ItemType getSectionItemType() {
|
||||
return ItemType.fromInt(sectionType.getCachedValue());
|
||||
}
|
||||
|
||||
public int getSectionSize() {
|
||||
return sectionInfo.getSectionSize();
|
||||
}
|
||||
|
||||
public int getSectionOffset() {
|
||||
return sectionInfo.getSectionOffset();
|
||||
}
|
||||
|
||||
private final ShortIntegerField sectionType;
|
||||
private final ShortIntegerField unused;
|
||||
private final SectionHeaderInfo sectionInfo;
|
||||
|
||||
public MapField(final DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
sectionType = new ShortIntegerField(),
|
||||
unused = new ShortIntegerField((short)0),
|
||||
sectionInfo = new SectionHeaderInfo() {
|
||||
protected Section getSection() {
|
||||
return dexFile.getSectionForType(getSectionItemType());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public MapField(final DexFile dexFile, short sectionType) {
|
||||
fields = new Field[] {
|
||||
this.sectionType = new ShortIntegerField(sectionType),
|
||||
this.unused = new ShortIntegerField((short)0),
|
||||
this.sectionInfo = new SectionHeaderInfo() {
|
||||
protected Section getSection() {
|
||||
return dexFile.getSectionForType(getSectionItemType());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return super.place(offset);
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
super.writeTo(out);
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
}
|
135
src/main/java/org/JesusFreke/dexlib/MapItem.java
Normal file
135
src/main/java/org/JesusFreke/dexlib/MapItem.java
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class MapItem extends IndexedItem<MapItem> {
|
||||
private final Field[] fields;
|
||||
private ArrayList<MapField> mapEntries = new ArrayList<MapField>();
|
||||
|
||||
public MapItem(final DexFile dexFile, int index) {
|
||||
super(index);
|
||||
|
||||
fields = new Field[] {
|
||||
new ListSizeField(mapEntries, new IntegerField()),
|
||||
new FieldListField<MapField>(mapEntries) {
|
||||
protected MapField make() {
|
||||
return new MapField(dexFile);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int place(int index, int offset) {
|
||||
for (int i=0; i<mapEntries.size(); i++) {
|
||||
MapField mapField = mapEntries.get(i);
|
||||
mapField.place(offset);
|
||||
if (mapField.getSectionSize() == 0 /*&& mapField.getSectionItemType().getMapValue() > 0x06*/) {
|
||||
mapEntries.remove(i--);
|
||||
}
|
||||
}
|
||||
|
||||
return super.place(index, offset);
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
Collections.sort(mapEntries, new Comparator<MapField>() {
|
||||
|
||||
public int compare(MapField o1, MapField o2) {
|
||||
return ((Integer)o1.getSectionOffset()).compareTo(o2.getSectionOffset());
|
||||
}
|
||||
});
|
||||
|
||||
super.writeTo(out);
|
||||
}
|
||||
|
||||
public static MapItem makeBlankMapItem(DexFile dexFile) {
|
||||
MapItem mapItem = new MapItem(dexFile, 0);
|
||||
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x0000));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x0001));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x0002));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x0003));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x0004));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x0005));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x0006));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x1003));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x2001));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x2006));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x1001));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x2002));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x2003));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x2004));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x2005));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x2000));
|
||||
mapItem.mapEntries.add(new MapField(dexFile, (short)0x1000));
|
||||
|
||||
|
||||
return mapItem;
|
||||
}
|
||||
|
||||
public MapField[] getMapEntries() {
|
||||
return mapEntries.toArray(new MapField[1]);
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_MAP_LIST;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, MapItem copy) {
|
||||
//nothing to do
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return getClass() == o.getClass();
|
||||
}
|
||||
|
||||
public int compareTo(MapItem o) {
|
||||
//there is only 1 map item
|
||||
return 1;
|
||||
}
|
||||
}
|
106
src/main/java/org/JesusFreke/dexlib/MethodIdItem.java
Normal file
106
src/main/java/org/JesusFreke/dexlib/MethodIdItem.java
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
public class MethodIdItem extends IndexedItem<MethodIdItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final IndexedItemReference<TypeIdItem> classType;
|
||||
private final IndexedItemReference<ProtoIdItem> prototype;
|
||||
private final IndexedItemReference<StringIdItem> methodName;
|
||||
|
||||
public MethodIdItem(DexFile dexFile, int index) {
|
||||
super(index);
|
||||
fields = new Field[] {
|
||||
classType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, new ShortIntegerField()),
|
||||
prototype = new IndexedItemReference<ProtoIdItem>(dexFile.ProtoIdsSection, new ShortIntegerField()),
|
||||
methodName = new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public MethodIdItem(DexFile dexFile, TypeIdItem classType, StringIdItem methodName, ProtoIdItem prototype) {
|
||||
super(-1);
|
||||
fields = new Field[] {
|
||||
this.classType = new IndexedItemReference<TypeIdItem>(dexFile, classType, new ShortIntegerField()),
|
||||
this.prototype = new IndexedItemReference<ProtoIdItem>(dexFile, prototype, new ShortIntegerField()),
|
||||
this.methodName = new IndexedItemReference<StringIdItem>(dexFile, methodName, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public MethodIdItem(DexFile dexFile, TypeIdItem classType, String methodName, ProtoIdItem prototype) {
|
||||
this(dexFile, classType, new StringIdItem(dexFile, methodName), prototype);
|
||||
}
|
||||
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_METHOD_ID_ITEM;
|
||||
}
|
||||
|
||||
public TypeIdItem getClassType() {
|
||||
return classType.getReference();
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return methodName.getReference().toString();
|
||||
}
|
||||
|
||||
public void setClassType(TypeIdItem newClassType) {
|
||||
classType.setReference(newClassType);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return classType.getReference().toString() + " - " + methodName.getReference().toString();
|
||||
}
|
||||
|
||||
public int getParameterWordCount(boolean isStatic) {
|
||||
return prototype.getReference().getParameterWordCount() + (isStatic?0:1);
|
||||
}
|
||||
|
||||
public int compareTo(MethodIdItem o) {
|
||||
int result = classType.compareTo(o.classType);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = methodName.compareTo(o.methodName);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return prototype.compareTo(o.prototype);
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.ByteArray;
|
||||
|
||||
public class NullTerminatedByteArrayField implements Field<NullTerminatedByteArrayField> {
|
||||
protected byte[] value;
|
||||
|
||||
public NullTerminatedByteArrayField() {
|
||||
}
|
||||
|
||||
public NullTerminatedByteArrayField(byte[] value) {
|
||||
this.value = value.clone();
|
||||
}
|
||||
|
||||
public NullTerminatedByteArrayField(ByteArray byteArray) {
|
||||
value = new byte[byteArray.size()];
|
||||
byteArray.getBytes(value, 0);
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.write(value);
|
||||
out.writeByte(0);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
int startPosition = in.getCursor();
|
||||
while (in.readByte() != 0);
|
||||
int size = in.getCursor() - startPosition - 1;
|
||||
|
||||
in.setCursor(startPosition);
|
||||
value = in.readBytes(size);
|
||||
in.skipBytes(1);
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + value.length + 1;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, NullTerminatedByteArrayField copy) {
|
||||
copy.value = value;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int h=1;
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
h = h*7 + value[i];
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof NullTerminatedByteArrayField)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NullTerminatedByteArrayField other = (NullTerminatedByteArrayField)o;
|
||||
if (value.length != other.value.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
if (value[i] != other.value[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
36
src/main/java/org/JesusFreke/dexlib/OffsettedItem.java
Normal file
36
src/main/java/org/JesusFreke/dexlib/OffsettedItem.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
public abstract class OffsettedItem<T extends OffsettedItem<T>> extends Item<T> {
|
||||
|
||||
public OffsettedItem(int offset) {
|
||||
super(offset);
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class OffsettedItemReference<T extends OffsettedItem<T>> extends
|
||||
ItemReference<T,OffsettedItemReference<T>> {
|
||||
private final CachedIntegerValueField underlyingField;
|
||||
|
||||
public OffsettedItemReference(OffsettedSection<T> section, CachedIntegerValueField underlyingField) {
|
||||
super(section);
|
||||
this.underlyingField = underlyingField;
|
||||
}
|
||||
|
||||
public OffsettedItemReference(DexFile dexFile, T item, CachedIntegerValueField underlyingField) {
|
||||
super(dexFile, item);
|
||||
this.underlyingField = underlyingField;
|
||||
}
|
||||
|
||||
public OffsettedSection<T> getSection() {
|
||||
return (OffsettedSection<T>)super.getSection();
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
T item = getReference();
|
||||
if (item != null && !item.isPlaced()) {
|
||||
throw new RuntimeException("Trying to write reference to an item that hasn't been placed.");
|
||||
}
|
||||
|
||||
/*if (out.getCursor() != underlyingField.getCachedValue()) {
|
||||
throw new RuntimeException("Trying to write a reference in a difference location from where it was placed");
|
||||
}*/
|
||||
//TODO: this is a hack to force it to reload the correct offset value
|
||||
if (item == null) {
|
||||
underlyingField.cacheValue(0);
|
||||
} else {
|
||||
underlyingField.cacheValue(item.getOffset());
|
||||
}
|
||||
|
||||
underlyingField.writeTo(out);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
underlyingField.readFrom(in);
|
||||
if (underlyingField.getCachedValue() != 0) {
|
||||
setReference(getSection().getByOffset(underlyingField.getCachedValue()));
|
||||
}
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
if (getReference() != null) {
|
||||
underlyingField.cacheValue(getReference().getOffset());
|
||||
} else {
|
||||
underlyingField.cacheValue(0);
|
||||
}
|
||||
return underlyingField.place(offset);
|
||||
}
|
||||
}
|
83
src/main/java/org/JesusFreke/dexlib/OffsettedSection.java
Normal file
83
src/main/java/org/JesusFreke/dexlib/OffsettedSection.java
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class OffsettedSection<T extends OffsettedItem<T>> extends Section<T> {
|
||||
protected HashMap<Integer, T> itemsByOffset;
|
||||
|
||||
public OffsettedSection() {
|
||||
itemsByOffset = new HashMap<Integer, T>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the item that starts at the given offset, or null if
|
||||
* there are none found. This method is intended to only be used
|
||||
* while reading in a dex file.
|
||||
* TODO: find a better way to abstract this
|
||||
* @param offset the offset of the item to get
|
||||
* @return the item that starts at the given offset, or null if there
|
||||
* are none found
|
||||
*/
|
||||
public T getByOffset(int offset) {
|
||||
T item = itemsByOffset.get(offset);
|
||||
if (item == null) {
|
||||
item = make(offset);
|
||||
items.add(item);
|
||||
itemsByOffset.put(offset, item);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public void readFrom(int size, Input in) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
T item = getByOffset(in.getCursor());
|
||||
item.readFrom(in);
|
||||
in.alignTo(item.getAlignment());
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract T make(int offset);
|
||||
|
||||
public T intern(DexFile dexFile, T item) {
|
||||
T itemToReturn = getInternedItem(item);
|
||||
|
||||
if (itemToReturn == null) {
|
||||
itemToReturn = make(-1);
|
||||
items.add(itemToReturn);
|
||||
item.copyTo(dexFile, itemToReturn);
|
||||
uniqueItems.put(itemToReturn, itemToReturn);
|
||||
}
|
||||
|
||||
return itemToReturn;
|
||||
}
|
||||
}
|
112
src/main/java/org/JesusFreke/dexlib/ProtoIdItem.java
Normal file
112
src/main/java/org/JesusFreke/dexlib/ProtoIdItem.java
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ProtoIdItem extends IndexedItem<ProtoIdItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final IndexedItemReference<StringIdItem> shortyDescriptor;
|
||||
private final IndexedItemReference<TypeIdItem> returnType;
|
||||
private final OffsettedItemReference<TypeListItem> parameters;
|
||||
|
||||
public ProtoIdItem(DexFile dexFile, int index) {
|
||||
super(index);
|
||||
fields = new Field[] {
|
||||
shortyDescriptor = new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new IntegerField()),
|
||||
returnType = new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, new IntegerField()),
|
||||
parameters = new OffsettedItemReference<TypeListItem>(dexFile.TypeListsSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public ProtoIdItem(DexFile dexFile, TypeIdItem returnType, ArrayList<TypeIdItem> parameters)
|
||||
{
|
||||
super(-1);
|
||||
StringIdItem stringIdItem = new StringIdItem(dexFile, createShortyDescriptor(returnType, parameters));
|
||||
TypeListItem typeListItem = new TypeListItem(dexFile, parameters);
|
||||
|
||||
fields = new Field[] {
|
||||
this.shortyDescriptor = new IndexedItemReference<StringIdItem>(dexFile, stringIdItem, new IntegerField()),
|
||||
this.returnType = new IndexedItemReference<TypeIdItem>(dexFile, returnType, new IntegerField()),
|
||||
this.parameters = new OffsettedItemReference<TypeListItem>(dexFile, typeListItem, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
private String createShortyDescriptor(TypeIdItem returnType, ArrayList<TypeIdItem> parameters) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(returnType.toShorty());
|
||||
|
||||
for (TypeIdItem typeIdItem: parameters) {
|
||||
sb.append(typeIdItem.toShorty());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public int getParameterWordCount() {
|
||||
TypeListItem typeList = parameters.getReference();
|
||||
if (typeList == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return typeList.getWordCount();
|
||||
}
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_PROTO_ID_ITEM;
|
||||
}
|
||||
|
||||
public int compareTo(ProtoIdItem o) {
|
||||
int result = returnType.compareTo(o.returnType);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
TypeListItem thisParameters = parameters.getReference();
|
||||
if (thisParameters == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return thisParameters.compareTo(o.parameters.getReference());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return shortyDescriptor.toString();
|
||||
}
|
||||
}
|
133
src/main/java/org/JesusFreke/dexlib/Section.java
Normal file
133
src/main/java/org/JesusFreke/dexlib/Section.java
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class Section<T extends Item> {
|
||||
protected ArrayList<T> items;
|
||||
protected HashMap<T, T> uniqueItems = null;
|
||||
|
||||
/**
|
||||
* When offset > -1, this section is "placed" at the specified offset. All
|
||||
* items should have sequential indexes, and be placed appropriately.
|
||||
*
|
||||
* To unplace the section, set offset to -1, and set the offset of all
|
||||
* items to -1
|
||||
*/
|
||||
protected int offset = -1;
|
||||
|
||||
public Section() {
|
||||
items = new ArrayList<T>();
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
this.offset = offset;
|
||||
for (int i=0; i < items.size(); i++) {
|
||||
T item = items.get(i);
|
||||
if (item == null) {
|
||||
items.remove(i--);
|
||||
continue;
|
||||
}
|
||||
offset = item.place(i, offset);
|
||||
if (i == 0) {
|
||||
/** if this item type has an alignment requirement,
|
||||
* then item.getOffset() may be different than the
|
||||
* offset before item.place was called, so we have
|
||||
* to initialize the section offset to the actual
|
||||
* (post-alignment) offset of the first item
|
||||
*/
|
||||
this.offset = item.getOffset();
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void unplace() {
|
||||
for (Item item: items) {
|
||||
item.unplace();
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
for (int i = 0; i < size(); i++) {
|
||||
T item = items.get(i);
|
||||
if (item == null) {
|
||||
throw new RuntimeException("Cannot write section because all items haven't been initialized");
|
||||
}
|
||||
item.writeTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void readFrom(int size, Input in);
|
||||
|
||||
protected void setSize(int size) {
|
||||
if (items.size() > size) {
|
||||
throw new RuntimeException("This section contains references to items beyond the size of the section");
|
||||
}
|
||||
|
||||
items.ensureCapacity(size);
|
||||
for (int i = items.size(); i < size; i++) {
|
||||
items.add(null);
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
public boolean isPlaced() {
|
||||
return offset > -1;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
protected T getInternedItem(T item) {
|
||||
if (uniqueItems == null) {
|
||||
buildInternedItemMap();
|
||||
}
|
||||
return uniqueItems.get(item);
|
||||
}
|
||||
|
||||
protected void buildInternedItemMap() {
|
||||
uniqueItems = new HashMap<T,T>();
|
||||
for (T item: items) {
|
||||
uniqueItems.put(item, item);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract T intern(DexFile dexFile, T item);
|
||||
}
|
83
src/main/java/org/JesusFreke/dexlib/SectionHeaderInfo.java
Normal file
83
src/main/java/org/JesusFreke/dexlib/SectionHeaderInfo.java
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public abstract class SectionHeaderInfo implements Field<SectionHeaderInfo> {
|
||||
private int sectionSize;
|
||||
private int sectionOffset;
|
||||
|
||||
public SectionHeaderInfo() {
|
||||
}
|
||||
|
||||
protected abstract Section getSection();
|
||||
|
||||
public void writeTo(Output out) {
|
||||
Section section = getSection();
|
||||
|
||||
if (!section.isPlaced()) {
|
||||
throw new RuntimeException("Trying to write a reference to a section that hasn't been placed.");
|
||||
}
|
||||
sectionSize = section.size();
|
||||
sectionOffset = section.getOffset();
|
||||
|
||||
out.writeInt(sectionSize);
|
||||
out.writeInt(sectionOffset);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
sectionSize = in.readInt();
|
||||
sectionOffset = in.readInt();
|
||||
}
|
||||
|
||||
public int getSectionSize() {
|
||||
return sectionSize;
|
||||
}
|
||||
|
||||
public int getSectionOffset() {
|
||||
return sectionOffset;
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
Section section = getSection();
|
||||
sectionSize = section.size();
|
||||
sectionOffset = section.getOffset();
|
||||
|
||||
return offset+8;
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, SectionHeaderInfo copy) {
|
||||
/**
|
||||
* do nothing. the section size and offset are dynamically generated
|
||||
* when the copy is written
|
||||
*/
|
||||
}
|
||||
}
|
70
src/main/java/org/JesusFreke/dexlib/ShortIntegerField.java
Normal file
70
src/main/java/org/JesusFreke/dexlib/ShortIntegerField.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public class ShortIntegerField extends CachedIntegerValueField {
|
||||
protected int value = 0;
|
||||
|
||||
public ShortIntegerField() {
|
||||
}
|
||||
|
||||
public ShortIntegerField(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.writeShort(value);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = in.readShort();
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the short integer value that has been cached. This
|
||||
* value is either the value that the field was constructed with, the
|
||||
* value that was read via <code>readFrom</code>, or the value that was
|
||||
* cached when <code>place</code> was called
|
||||
* @return the cached value
|
||||
*/
|
||||
public int getCachedValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void cacheValue(int value) {
|
||||
this.value = (short)value;
|
||||
}
|
||||
}
|
64
src/main/java/org/JesusFreke/dexlib/SignedLeb128Field.java
Normal file
64
src/main/java/org/JesusFreke/dexlib/SignedLeb128Field.java
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.Leb128Utils;
|
||||
|
||||
public class SignedLeb128Field extends CachedIntegerValueField {
|
||||
protected int value;
|
||||
|
||||
public SignedLeb128Field() {
|
||||
}
|
||||
|
||||
public SignedLeb128Field(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
out.writeSignedLeb128(value);
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
value = in.readSignedLeb128();
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + Leb128Utils.signedLeb128Size(value);
|
||||
}
|
||||
|
||||
public int getCachedValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void cacheValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
85
src/main/java/org/JesusFreke/dexlib/StringDataItem.java
Normal file
85
src/main/java/org/JesusFreke/dexlib/StringDataItem.java
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import org.JesusFreke.dexlib.util.ByteArray;
|
||||
import org.JesusFreke.dexlib.util.Utf8Utils;
|
||||
|
||||
public class StringDataItem extends OffsettedItem<StringDataItem> implements Comparable<StringDataItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private String value = null;
|
||||
|
||||
private final Leb128Field stringSize;
|
||||
private final NullTerminatedByteArrayField stringByteArray;
|
||||
|
||||
public StringDataItem(int offset) {
|
||||
super(offset);
|
||||
|
||||
fields = new Field[] {
|
||||
stringSize = new Leb128Field(),
|
||||
stringByteArray = new NullTerminatedByteArrayField()
|
||||
};
|
||||
}
|
||||
|
||||
public StringDataItem(String value) {
|
||||
super(-1);
|
||||
|
||||
this.value = value;
|
||||
|
||||
fields = new Field[] {
|
||||
stringSize = new Leb128Field(value.length()),
|
||||
stringByteArray = new NullTerminatedByteArrayField(Utf8Utils.stringToUtf8Bytes(value))
|
||||
};
|
||||
}
|
||||
|
||||
public Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public int getAlignment() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_STRING_DATA_ITEM;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (value == null) {
|
||||
value = Utf8Utils.utf8BytesToString(new ByteArray(((NullTerminatedByteArrayField)fields[1]).value));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public int compareTo(StringDataItem o) {
|
||||
return toString().compareTo(o.toString());
|
||||
}
|
||||
}
|
75
src/main/java/org/JesusFreke/dexlib/StringIdItem.java
Normal file
75
src/main/java/org/JesusFreke/dexlib/StringIdItem.java
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
public class StringIdItem extends IndexedItem<StringIdItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final OffsettedItemReference<StringDataItem> stringData;
|
||||
|
||||
public StringIdItem(DexFile dexFile, int index) {
|
||||
super(index);
|
||||
fields = new Field[] {
|
||||
stringData = new OffsettedItemReference<StringDataItem>(dexFile.StringDataSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public StringIdItem(DexFile dexFile, StringDataItem stringDataItem) {
|
||||
super(-1);
|
||||
|
||||
fields = new Field[] {
|
||||
stringData = new OffsettedItemReference<StringDataItem>(dexFile, stringDataItem, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public StringIdItem(DexFile dexFile, String value) {
|
||||
this(dexFile, new StringDataItem(value));
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_STRING_ID_ITEM;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return stringData.getReference().toString();
|
||||
}
|
||||
|
||||
public int compareTo(StringIdItem o) {
|
||||
//sort by the string value
|
||||
return toString().compareTo(o.toString());
|
||||
}
|
||||
}
|
100
src/main/java/org/JesusFreke/dexlib/TypeIdItem.java
Normal file
100
src/main/java/org/JesusFreke/dexlib/TypeIdItem.java
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
public class TypeIdItem extends IndexedItem<TypeIdItem> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final IndexedItemReference<StringIdItem> type;
|
||||
|
||||
public TypeIdItem(DexFile dexFile, int index) {
|
||||
super(index);
|
||||
fields = new Field[] {
|
||||
type = new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public TypeIdItem(DexFile dexFile, StringIdItem stringIdItem) {
|
||||
super(-1);
|
||||
fields = new Field[] {
|
||||
type = new IndexedItemReference<StringIdItem>(dexFile, stringIdItem, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public TypeIdItem(DexFile dexFile, String value) {
|
||||
super(-1);
|
||||
StringDataItem stringDataItem = new StringDataItem(value);
|
||||
StringIdItem stringIdItem = new StringIdItem(dexFile, stringDataItem);
|
||||
fields = new Field[] {
|
||||
type = new IndexedItemReference<StringIdItem>(dexFile, stringIdItem, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public int getWordCount() {
|
||||
String type = this.toString();
|
||||
/** Only the long and double primitive types are 2 words,
|
||||
* everything else is a single word
|
||||
*/
|
||||
if (type.equals("J") || type.equals("D")) {
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_TYPE_ID_ITEM;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return type.getReference().toString();
|
||||
}
|
||||
|
||||
public int compareTo(TypeIdItem o) {
|
||||
//sort by the index of the StringIdItem
|
||||
return type.compareTo(o.type);
|
||||
}
|
||||
|
||||
public String toShorty() {
|
||||
String type = toString();
|
||||
if (type.length() > 1) {
|
||||
return "L";
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
114
src/main/java/org/JesusFreke/dexlib/TypeListItem.java
Normal file
114
src/main/java/org/JesusFreke/dexlib/TypeListItem.java
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TypeListItem extends OffsettedItem<TypeListItem> implements Comparable<TypeListItem> {
|
||||
private final Field[] fields;
|
||||
private final ArrayList<IndexedItemReference<TypeIdItem>> typeList = new ArrayList<IndexedItemReference<TypeIdItem>>();
|
||||
|
||||
public TypeListItem(final DexFile dexFile, int offset) {
|
||||
super(offset);
|
||||
|
||||
fields = new Field[] {
|
||||
new ListSizeField(typeList, new IntegerField()),
|
||||
new FieldListField<IndexedItemReference<TypeIdItem>>(typeList) {
|
||||
protected IndexedItemReference<TypeIdItem> make() {
|
||||
return new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, new ShortIntegerField());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public TypeListItem(final DexFile dexFile, List<TypeIdItem> types) {
|
||||
this(dexFile, 0);
|
||||
|
||||
for (TypeIdItem typeIdItem: types) {
|
||||
typeList.add(new IndexedItemReference<TypeIdItem>(dexFile, typeIdItem, new ShortIntegerField()));
|
||||
}
|
||||
}
|
||||
|
||||
public List<TypeIdItem> getTypes() {
|
||||
ArrayList<TypeIdItem> list = new ArrayList<TypeIdItem>(typeList.size());
|
||||
|
||||
for (IndexedItemReference<TypeIdItem> typeIdItemReference: typeList) {
|
||||
list.add(typeIdItemReference.getReference());
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public int getWordCount() {
|
||||
int wordCount = 0;
|
||||
for (IndexedItemReference<TypeIdItem> typeRef: typeList) {
|
||||
TypeIdItem item = typeRef.getReference();
|
||||
wordCount += item.getWordCount();
|
||||
}
|
||||
return wordCount;
|
||||
}
|
||||
|
||||
public int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public ItemType getItemType() {
|
||||
return ItemType.TYPE_TYPE_LIST;
|
||||
}
|
||||
|
||||
public int compareTo(TypeListItem o) {
|
||||
if (o == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int thisSize = typeList.size();
|
||||
int otherSize = o.typeList.size();
|
||||
int size = Math.min(thisSize, otherSize);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
int result = typeList.get(i).compareTo(o.typeList.get(i));
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (thisSize < otherSize) {
|
||||
return -1;
|
||||
} else if (thisSize > otherSize) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
43
src/main/java/org/JesusFreke/dexlib/code/Format/Format.java
Normal file
43
src/main/java/org/JesusFreke/dexlib/code/Format/Format.java
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.code.Format;
|
||||
|
||||
import org.JesusFreke.dexlib.code.Opcode;
|
||||
|
||||
public abstract class Format
|
||||
{
|
||||
public abstract int getByteCount();
|
||||
public abstract String getFormatName();
|
||||
|
||||
protected void checkOpcodeFormat(Opcode opcode) {
|
||||
if (!opcode.format.equals(getFormatName())) {
|
||||
throw new RuntimeException("Opcode " + opcode.name + " does not use format " + getFormatName());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.code.Format;
|
||||
|
||||
import org.JesusFreke.dexlib.code.Instruction;
|
||||
import org.JesusFreke.dexlib.code.Opcode;
|
||||
import org.JesusFreke.dexlib.DexFile;
|
||||
|
||||
public class Format10x extends Format
|
||||
{
|
||||
public static final Format10x Format = new Format10x();
|
||||
|
||||
private Format10x() {
|
||||
}
|
||||
|
||||
public Instruction make(DexFile dexFile, byte opcode) {
|
||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
||||
|
||||
checkOpcodeFormat(op);
|
||||
|
||||
return new Instruction(dexFile, new byte[]{opcode,0x00}, null);
|
||||
}
|
||||
|
||||
public int getByteCount()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public String getFormatName()
|
||||
{
|
||||
return "10x";
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.code.Format;
|
||||
|
||||
import org.JesusFreke.dexlib.code.Instruction;
|
||||
import org.JesusFreke.dexlib.code.Opcode;
|
||||
import org.JesusFreke.dexlib.DexFile;
|
||||
|
||||
public class Format11x extends Format
|
||||
{
|
||||
public static final Format11x Format = new Format11x();
|
||||
|
||||
private Format11x() {
|
||||
}
|
||||
|
||||
public Instruction make(DexFile dexFile, byte opcode, short regA) {
|
||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
||||
|
||||
checkOpcodeFormat(op);
|
||||
|
||||
if (regA >= 2<<8) {
|
||||
throw new RuntimeException("The register number must be less than v256");
|
||||
}
|
||||
|
||||
return new Instruction(dexFile, new byte[]{opcode,(byte)regA}, null);
|
||||
}
|
||||
|
||||
public int getByteCount()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public String getFormatName()
|
||||
{
|
||||
return "11x";
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.code.Format;
|
||||
|
||||
import org.JesusFreke.dexlib.code.Instruction;
|
||||
import org.JesusFreke.dexlib.code.Opcode;
|
||||
import org.JesusFreke.dexlib.DexFile;
|
||||
import org.JesusFreke.dexlib.IndexedItem;
|
||||
|
||||
public class Format21c extends Format
|
||||
{
|
||||
public static final Format21c Format = new Format21c();
|
||||
|
||||
private Format21c() {
|
||||
}
|
||||
|
||||
public Instruction make(DexFile dexFile, byte opcode, short regA, IndexedItem item) {
|
||||
byte[] bytes = new byte[4];
|
||||
|
||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
||||
|
||||
checkOpcodeFormat(op);
|
||||
|
||||
if (regA >= 2<<8) {
|
||||
throw new RuntimeException("The register number must be less than v256");
|
||||
}
|
||||
|
||||
bytes[0] = opcode;
|
||||
bytes[1] = (byte)regA;
|
||||
|
||||
return new Instruction(dexFile, bytes, item);
|
||||
}
|
||||
|
||||
public int getByteCount() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public String getFormatName() {
|
||||
return "21c";
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.code.Format;
|
||||
|
||||
import org.JesusFreke.dexlib.code.Instruction;
|
||||
import org.JesusFreke.dexlib.code.Opcode;
|
||||
import org.JesusFreke.dexlib.DexFile;
|
||||
import org.JesusFreke.dexlib.IndexedItem;
|
||||
|
||||
public class Format22c extends Format
|
||||
{
|
||||
public static final Format22c Format = new Format22c();
|
||||
|
||||
private Format22c() {
|
||||
}
|
||||
|
||||
public Instruction make(DexFile dexFile, byte opcode, byte regA, byte regB, IndexedItem item) {
|
||||
byte[] bytes = new byte[4];
|
||||
|
||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
||||
|
||||
checkOpcodeFormat(op);
|
||||
|
||||
if (regA >= 16 ||
|
||||
regB >= 16) {
|
||||
throw new RuntimeException("The register number must be less than v16");
|
||||
}
|
||||
|
||||
|
||||
bytes[0] = opcode;
|
||||
bytes[1] = (byte)((regB << 4) | regA);
|
||||
|
||||
return new Instruction(dexFile, bytes, item);
|
||||
}
|
||||
|
||||
public int getByteCount() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public String getFormatName() {
|
||||
return "22c";
|
||||
}
|
||||
}
|
114
src/main/java/org/JesusFreke/dexlib/code/Format/Format35c.java
Normal file
114
src/main/java/org/JesusFreke/dexlib/code/Format/Format35c.java
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.code.Format;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
import org.JesusFreke.dexlib.code.Instruction;
|
||||
import org.JesusFreke.dexlib.code.Opcode;
|
||||
import static org.JesusFreke.dexlib.code.Opcode.*;
|
||||
|
||||
public class Format35c extends Format
|
||||
{
|
||||
public static final Format35c Format = new Format35c();
|
||||
|
||||
private Format35c() {
|
||||
}
|
||||
|
||||
public Instruction make(DexFile dexFile, byte opcode, byte regCount, byte regD, byte regE, byte regF, byte regG, byte regA, IndexedItem item) {
|
||||
byte[] bytes = new byte[6];
|
||||
|
||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
||||
|
||||
checkOpcodeFormat(op);
|
||||
|
||||
if (regCount > 5) {
|
||||
throw new RuntimeException("regCount cannot be greater than 5");
|
||||
}
|
||||
if (regD >= 16 ||
|
||||
regE >= 16 ||
|
||||
regF >= 16 ||
|
||||
regG >= 16 ||
|
||||
regA >= 16) {
|
||||
throw new RuntimeException("All register args must fit in 4 bits");
|
||||
}
|
||||
|
||||
bytes[0] = opcode;
|
||||
bytes[1] = (byte)((regCount << 4) | regA);
|
||||
bytes[4] = (byte)((regE << 4) | regD);
|
||||
bytes[5] = (byte)((regG << 4) | regF);
|
||||
|
||||
//go ahead and make the instruction, to verify that item is the correct type. If it isn't,
|
||||
//the construction will throw an exception
|
||||
Instruction instruction = new Instruction(dexFile, bytes, item);
|
||||
|
||||
if (opcode == FILLED_NEW_ARRAY.value) {
|
||||
//check data for filled-new-array opcode
|
||||
String type = ((TypeIdItem)item).toString();
|
||||
if (type.charAt(0) != '[') {
|
||||
throw new RuntimeException("The type must be an array type");
|
||||
}
|
||||
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
|
||||
throw new RuntimeException("The type cannot be an array of longs or doubles");
|
||||
}
|
||||
} else if (opcode >= INVOKE_VIRTUAL.value && opcode <= INVOKE_INTERFACE.value) {
|
||||
//check data for invoke-* opcodes
|
||||
MethodIdItem methodIdItem = (MethodIdItem)item;
|
||||
if (methodIdItem.getParameterWordCount(opcode == INVOKE_STATIC.value) != regCount) {
|
||||
throw new RuntimeException("regCount does not match the number of arguments of the method");
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Opcode " + Integer.toHexString(opcode) + " does not use the 35c format");
|
||||
}
|
||||
|
||||
return instruction;
|
||||
}
|
||||
|
||||
public int getByteCount() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
public String getFormatName() {
|
||||
return "35c";
|
||||
}
|
||||
|
||||
/*@Test
|
||||
public void testInvoke() {
|
||||
DexFile dexFile = new DexFile();
|
||||
ArrayList<TypeIdItem> types = new ArrayList<TypeIdItem>();
|
||||
types.add(new TypeIdItem(dexFile, "I"));
|
||||
types.add(new TypeIdItem(dexFile, "I"));
|
||||
types.add(new TypeIdItem(dexFile, "I"));
|
||||
types.add(new TypeIdItem(dexFile, "I"));
|
||||
types.add(new TypeIdItem(dexFile, "I"));
|
||||
MethodIdItem method = new MethodIdItem(dexFile, new TypeIdItem(dexFile, "test"), "test", new ProtoIdItem(dexFile, new TypeIdItem(dexFile, "V"), types));
|
||||
|
||||
Instruction ins = make(dexFile, (byte)INVOKE_VIRTUAL.value, (byte)5, (byte)0, (byte)1, (byte)2, (byte)3, (byte)4, method);
|
||||
assertTrue("Is everything put in the right place?", java.util.Arrays.equals(ins.getBytes(), new byte[] {0x6e, 0x54, 0x00, 0x00, 0x10, 0x32}));
|
||||
}*/
|
||||
}
|
118
src/main/java/org/JesusFreke/dexlib/code/Format/Format3rc.java
Normal file
118
src/main/java/org/JesusFreke/dexlib/code/Format/Format3rc.java
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.code.Format;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
import org.JesusFreke.dexlib.code.Instruction;
|
||||
import org.JesusFreke.dexlib.code.Opcode;
|
||||
import static org.JesusFreke.dexlib.code.Opcode.*;
|
||||
|
||||
public class Format3rc extends Format
|
||||
{
|
||||
public static final Format3rc Format = new Format3rc();
|
||||
|
||||
public Format3rc() {
|
||||
}
|
||||
|
||||
public Instruction make(DexFile dexFile, byte opcode, short regCount, int startReg, IndexedItem item) {
|
||||
byte[] bytes = new byte[6];
|
||||
|
||||
Opcode op = Opcode.getOpcodeByValue(opcode);
|
||||
|
||||
checkOpcodeFormat(op);
|
||||
|
||||
if (regCount >= 2<<8) {
|
||||
throw new RuntimeException("regCount must be less than 256");
|
||||
}
|
||||
if (regCount < 0) {
|
||||
throw new RuntimeException("regCount cannot be negative");
|
||||
}
|
||||
|
||||
if (startReg >= 2<<16) {
|
||||
throw new RuntimeException("The beginning register of the range must be less than 65536");
|
||||
}
|
||||
if (startReg < 0) {
|
||||
throw new RuntimeException("The beginning register of the range cannot be negative");
|
||||
}
|
||||
|
||||
bytes[0] = opcode;
|
||||
bytes[1] = (byte)regCount;
|
||||
bytes[4] = (byte)startReg;
|
||||
bytes[5] = (byte)(startReg >> 8);
|
||||
|
||||
//go ahead and make the instruction now, which will verify that item is the correct type. If it isn't,
|
||||
//the construction will throw an exception
|
||||
Instruction instruction = new Instruction(dexFile, bytes, item);
|
||||
|
||||
if (opcode == FILLED_NEW_ARRAY_RANGE.value) {
|
||||
//check data for filled-new-array/range opcode
|
||||
String type = ((TypeIdItem)item).toString();
|
||||
if (type.charAt(0) != '[') {
|
||||
throw new RuntimeException("The type must be an array type");
|
||||
}
|
||||
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
|
||||
throw new RuntimeException("The type cannot be an array of longs or doubles");
|
||||
}
|
||||
} else if (opcode >= INVOKE_VIRTUAL_RANGE.value && opcode <= INVOKE_INTERFACE_RANGE.value) {
|
||||
//check data for invoke-*/range opcodes
|
||||
MethodIdItem methodIdItem = (MethodIdItem)item;
|
||||
if (methodIdItem.getParameterWordCount(opcode == INVOKE_STATIC.value) != regCount) {
|
||||
throw new RuntimeException("regCount does not match the number of arguments of the method");
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Opcode " + Integer.toHexString(opcode) + " does not use the 35c format");
|
||||
}
|
||||
|
||||
return instruction;
|
||||
}
|
||||
|
||||
public int getByteCount() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
public String getFormatName() {
|
||||
return "3rc";
|
||||
}
|
||||
|
||||
/*@Test
|
||||
public void testInvoke() {
|
||||
DexFile dexFile = DexFile.makeBlankDexFile();
|
||||
ArrayList<TypeIdItem> types = new ArrayList<TypeIdItem>();
|
||||
types.add(new TypeIdItem(dexFile, "I"));
|
||||
types.add(new TypeIdItem(dexFile, "I"));
|
||||
types.add(new TypeIdItem(dexFile, "I"));
|
||||
types.add(new TypeIdItem(dexFile, "I"));
|
||||
types.add(new TypeIdItem(dexFile, "I"));
|
||||
MethodIdItem method = new MethodIdItem(dexFile, new TypeIdItem(dexFile, "test"), "test", new ProtoIdItem(dexFile, new TypeIdItem(dexFile, "V"), types));
|
||||
|
||||
Instruction ins = Format.make(dexFile, (byte)INVOKE_VIRTUAL_RANGE.value, (short)6, 65500, method);
|
||||
byte[] bytes = new byte[] {0x74, 0x06, 0x00, 0x00, (byte)0xDC, (byte)0xFF};
|
||||
assertTrue("Is everything put in the right place?", java.util.Arrays.equals(ins.getBytes(), bytes));
|
||||
}*/
|
||||
}
|
194
src/main/java/org/JesusFreke/dexlib/code/Instruction.java
Normal file
194
src/main/java/org/JesusFreke/dexlib/code/Instruction.java
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.code;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
import org.JesusFreke.dexlib.util.Output;
|
||||
|
||||
//TODO: need to implement the "special" bytecode types, for switches etc.
|
||||
|
||||
public final class Instruction implements Field<Instruction> {
|
||||
private DexFile dexFile;
|
||||
private byte[] bytes;
|
||||
private Opcode opcode;
|
||||
|
||||
private IndexedItem reference;
|
||||
|
||||
public byte[] getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public Opcode getOpcode() {
|
||||
return opcode;
|
||||
}
|
||||
|
||||
public IndexedItem getReference() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
public Instruction(DexFile dexFile) {
|
||||
this.dexFile = dexFile;
|
||||
}
|
||||
|
||||
public Instruction(DexFile dexFile, byte[] bytes, IndexedItem item) {
|
||||
this.dexFile = dexFile;
|
||||
this.bytes = bytes;
|
||||
this.reference = item;
|
||||
this.opcode = Opcode.getOpcodeByValue(bytes[0]);
|
||||
if (!this.opcode.referenceType.checkItem(item)) {
|
||||
throw new RuntimeException("item is not the correct type for this opcode (got " + item.getClass().toString() + ", expecting " + opcode.referenceType.toString() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public void readFrom(Input in) {
|
||||
int startPos = in.getCursor();
|
||||
|
||||
byte opByte = in.readByte();
|
||||
|
||||
if (opByte == 0x00) {
|
||||
reference = null;
|
||||
byte secondByte = in.readByte();
|
||||
|
||||
int count;
|
||||
|
||||
|
||||
switch (secondByte) {
|
||||
case 0x00:
|
||||
/** nop */
|
||||
bytes = new byte[] { 0x00, 0x00 };
|
||||
return;
|
||||
case 0x01:
|
||||
/** packed switch */
|
||||
count = in.readShort();
|
||||
in.setCursor(startPos);
|
||||
bytes = in.readBytes((count * 4) + 8);
|
||||
return;
|
||||
case 0x02:
|
||||
/** sparse switch */
|
||||
count = in.readShort();
|
||||
in.setCursor(startPos);
|
||||
bytes = in.readBytes((count * 8) + 4);
|
||||
return;
|
||||
case 0x03:
|
||||
/** fill array data */
|
||||
int elementWidth = in.readShort();
|
||||
count = in.readInt();
|
||||
in.setCursor(startPos);
|
||||
bytes = in.readBytes(((elementWidth * count + 1)/2 + 4) * 2);
|
||||
return;
|
||||
default:
|
||||
throw new RuntimeException("Invalid 2nd byte for opcode 0x00");
|
||||
}
|
||||
}
|
||||
|
||||
this.opcode = Opcode.getOpcodeByValue(opByte);
|
||||
|
||||
if (opcode.referenceType != ReferenceType.none) {
|
||||
in.skipBytes(1);
|
||||
int referenceIndex = in.readShort();
|
||||
|
||||
//handle const string/jumbo as a special case
|
||||
if (opByte == 0x1b) {
|
||||
int hiWord = in.readShort();
|
||||
if (hiWord != 0) {
|
||||
throw new RuntimeException("32bit string indexes are not supported yet.");
|
||||
}
|
||||
}
|
||||
|
||||
switch (opcode.referenceType) {
|
||||
case string:
|
||||
reference = dexFile.StringIdsSection.getByIndex(referenceIndex);
|
||||
break;
|
||||
case type:
|
||||
reference = dexFile.TypeIdsSection.getByIndex(referenceIndex);
|
||||
break;
|
||||
case field:
|
||||
reference = dexFile.FieldIdsSection.getByIndex(referenceIndex);
|
||||
break;
|
||||
case method:
|
||||
reference = dexFile.MethodIdsSection.getByIndex(referenceIndex);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
reference = null;
|
||||
}
|
||||
|
||||
in.setCursor(startPos);
|
||||
bytes = in.readBytes(opcode.numBytes);
|
||||
}
|
||||
|
||||
public void writeTo(Output out) {
|
||||
if (bytes[0] == 0 && bytes[1] > 0) {
|
||||
//the "special instructions" must be 4 byte aligned
|
||||
out.alignTo(4);
|
||||
out.write(bytes);
|
||||
} else if (reference == null) {
|
||||
out.write(bytes);
|
||||
} else {
|
||||
out.write(bytes,0,2);
|
||||
if (bytes[0] == 0x1b) {
|
||||
out.writeInt(reference.getIndex());
|
||||
} else {
|
||||
int index = reference.getIndex();
|
||||
if (index > 0xFFFF) {
|
||||
throw new RuntimeException("String index doesn't fit.");
|
||||
}
|
||||
out.writeShort(reference.getIndex());
|
||||
out.write(bytes, 4, bytes.length - 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void copyTo(DexFile dexFile, Instruction copy) {
|
||||
copy.bytes = bytes;
|
||||
copy.opcode = opcode;
|
||||
|
||||
switch (opcode.referenceType) {
|
||||
case string:
|
||||
copy.reference = dexFile.StringIdsSection.intern(dexFile, (StringIdItem)reference);
|
||||
break;
|
||||
case type:
|
||||
copy.reference = dexFile.TypeIdsSection.intern(dexFile, (TypeIdItem)reference);
|
||||
break;
|
||||
case field:
|
||||
copy.reference = dexFile.FieldIdsSection.intern(dexFile, (FieldIdItem)reference);
|
||||
break;
|
||||
case method:
|
||||
copy.reference = dexFile.MethodIdsSection.intern(dexFile, (MethodIdItem)reference);
|
||||
break;
|
||||
case none:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public int place(int offset) {
|
||||
return offset + bytes.length;
|
||||
}
|
||||
}
|
300
src/main/java/org/JesusFreke/dexlib/code/Opcode.java
Normal file
300
src/main/java/org/JesusFreke/dexlib/code/Opcode.java
Normal file
@ -0,0 +1,300 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.code;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public enum Opcode
|
||||
{
|
||||
NOP((byte)0x00, "NOP", (byte)2, ReferenceType.none, "10x"),
|
||||
MOVE((byte)0x01, "MOVE", (byte)2, ReferenceType.none, "12x"),
|
||||
MOVE_FROM16((byte)0x02, "MOVE/FROM16", (byte)4, ReferenceType.none, "22x"),
|
||||
MOVE_16((byte)0x03, "MOVE/16", (byte)6, ReferenceType.none, "32x"),
|
||||
MOVE_WIDE((byte)0x04, "MOVE-WIDE", (byte)2, ReferenceType.none, "12x"),
|
||||
MOVE_WIDE_FROM16((byte)0x05, "MOVE-WIDE/FROM16", (byte)4, ReferenceType.none, "22x"),
|
||||
MOVE_WIDE_16((byte)0x06, "MOVE-WIDE/16", (byte)6, ReferenceType.none, "32x"),
|
||||
MOVE_OBJECT((byte)0x07, "MOVE-OBJECT", (byte)2, ReferenceType.none, "12x"),
|
||||
MOVE_OBJECT_FROM16((byte)0x08, "MOVE-OBJECT/FROM16", (byte)4, ReferenceType.none, "22x"),
|
||||
MOVE_OBJECT_16((byte)0x09, "MOVE-OBJECT/16", (byte)6, ReferenceType.none, "32x"),
|
||||
MOVE_RESULT((byte)0x0a, "MOVE-RESULT", (byte)2, ReferenceType.none, "11x"),
|
||||
MOVE_RESULT_WIDE((byte)0x0b, "MOVE-RESULT-WIDE", (byte)2, ReferenceType.none, "11x"),
|
||||
MOVE_RESULT_OBJECT((byte)0x0c, "MOVE-RESULT-OBJECT", (byte)2, ReferenceType.none, "11x"),
|
||||
MOVE_EXCEPTION((byte)0x0d, "MOVE-EXCEPTION", (byte)2, ReferenceType.none, "11x"),
|
||||
RETURN_VOID((byte)0x0e, "RETURN-VOID", (byte)2, ReferenceType.none, "10x"),
|
||||
RETURN((byte)0x0f, "RETURN", (byte)2, ReferenceType.none, "11x"),
|
||||
RETURN_WIDE((byte)0x10, "RETURN-WIDE", (byte)2, ReferenceType.none, "11x"),
|
||||
RETURN_OBJECT((byte)0x11, "RETURN-OBJECT", (byte)2, ReferenceType.none, "11x"),
|
||||
CONST_4((byte)0x12, "CONST-4", (byte)2, ReferenceType.none, "11n"),
|
||||
CONST_16((byte)0x13, "CONST/16", (byte)4, ReferenceType.none, "21s"),
|
||||
CONST((byte)0x14, "CONST", (byte)6, ReferenceType.none, "31i"),
|
||||
CONST_HIGH16((byte)0x15, "CONST/HIGH16", (byte)4, ReferenceType.none, "21h"),
|
||||
CONST_WIDE_16((byte)0x16, "CONST-WIDE/16", (byte)4, ReferenceType.none, "21s"),
|
||||
CONST_WIDE_32((byte)0x17, "CONST-WIDE/32", (byte)6, ReferenceType.none, "31i"),
|
||||
CONST_WIDE((byte)0x18, "CONST-WIDE", (byte)10, ReferenceType.none, "51l"),
|
||||
CONST_WIDE_HIGH16((byte)0x19, "CONST-WIDE/HIGH16", (byte)4, ReferenceType.none, "21h"),
|
||||
CONST_STRING((byte)0x1a, "CONST-STRING", (byte)4, ReferenceType.string, "21c"),
|
||||
CONST_STRING_JUMBO((byte)0x1b, "CONST-STRING/JUMBO", (byte)6, ReferenceType.string, "31c"),
|
||||
CONST_CLASS((byte)0x1c, "CONST-CLASS", (byte)4, ReferenceType.type, "21c"),
|
||||
MONITOR_ENTER((byte)0x1d, "MONITOR-ENTER", (byte)2, ReferenceType.none, "11x"),
|
||||
MONITOR_EXIT((byte)0x1e, "MONITOR-EXIT", (byte)2, ReferenceType.none, "11x"),
|
||||
CHECK_CAST((byte)0x1f, "CHECK-CAST", (byte)4, ReferenceType.type, "21c"),
|
||||
INSTANCE_OF((byte)0x20, "INSTANCE-OF", (byte)4, ReferenceType.type, "22c"),
|
||||
ARRAY_LENGTH((byte)0x21, "ARRAY-LENGTH", (byte)2, ReferenceType.none, "12x"),
|
||||
NEW_INSTANCE((byte)0x22, "NEW-INSTANCE", (byte)4, ReferenceType.type, "21c"),
|
||||
NEW_ARRAY((byte)0x23, "NEW-ARRAY", (byte)4, ReferenceType.type, "22c"),
|
||||
FILLED_NEW_ARRAY((byte)0x24, "FILLED-NEW-ARRAY", (byte)6, ReferenceType.type, "35c"),
|
||||
FILLED_NEW_ARRAY_RANGE((byte)0x25, "FILLED-NEW-ARRAY-RANGE", (byte)6, ReferenceType.type, "3rc"),
|
||||
FILL_ARRAY_DATA((byte)0x26, "FILL-ARRAY-DATA", (byte)6, ReferenceType.none, "31t"),
|
||||
THROW((byte)0x27, "THROW", (byte)2, ReferenceType.none, "11x"),
|
||||
GOTO((byte)0x28, "GOTO", (byte)2, ReferenceType.none, "10t"),
|
||||
GOTO_16((byte)0x29, "GOTO/16", (byte)4, ReferenceType.none, "20t"),
|
||||
GOTO_32((byte)0x2a, "GOTO/32", (byte)6, ReferenceType.none, "30t"),
|
||||
PACKED_SWITCH((byte)0x2b, "PACKED-SWITCH", (byte)6, ReferenceType.none, "31t"),
|
||||
SPARSE_SWITCH((byte)0x2c, "SPARSE-SWITCH", (byte)6, ReferenceType.none, "31t"),
|
||||
CMPL_FLOAT((byte)0x2d, "CMPL-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
||||
CMPG_FLOAT((byte)0x2e, "CMPG-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
||||
CMPL_DOUBLE((byte)0x2f, "CMPL-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
||||
CMPG_DOUBLE((byte)0x30, "CMPG-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
||||
CMP_LONG((byte)0x31, "CMP-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
IF_EQ((byte)0x32, "IF-EQ", (byte)4, ReferenceType.none, "22t"),
|
||||
IF_NE((byte)0x33, "IF-NE", (byte)4, ReferenceType.none, "22t"),
|
||||
IF_LT((byte)0x34, "IF-LT", (byte)4, ReferenceType.none, "22t"),
|
||||
IF_GE((byte)0x35, "IF-GE", (byte)4, ReferenceType.none, "22t"),
|
||||
IF_GT((byte)0x36, "IF-GT", (byte)4, ReferenceType.none, "22t"),
|
||||
IF_LE((byte)0x37, "IF-LE", (byte)4, ReferenceType.none, "22t"),
|
||||
IF_EQZ((byte)0x38, "IF-EQZ", (byte)4, ReferenceType.none, "21t"),
|
||||
IF_NEZ((byte)0x39, "IF-NEZ", (byte)4, ReferenceType.none, "21t"),
|
||||
IF_LTZ((byte)0x3a, "IF-LTZ", (byte)4, ReferenceType.none, "21t"),
|
||||
IF_GEZ((byte)0x3b, "IF-GEZ", (byte)4, ReferenceType.none, "21t"),
|
||||
IF_GTZ((byte)0x3c, "IF-GTZ", (byte)4, ReferenceType.none, "21t"),
|
||||
IF_LEZ((byte)0x3d, "IF-LEZ", (byte)4, ReferenceType.none, "21t"),
|
||||
AGET((byte)0x44, "AGET", (byte)4, ReferenceType.none, "23x"),
|
||||
AGET_WIDE((byte)0x45, "AGET-WIDE", (byte)4, ReferenceType.none, "23x"),
|
||||
AGET_OBJECT((byte)0x46, "AGET-OBJECT", (byte)4, ReferenceType.none, "23x"),
|
||||
AGET_BOOLEAN((byte)0x47, "AGET-BOOLEAN", (byte)4, ReferenceType.none, "23x"),
|
||||
AGET_BYTE((byte)0x48, "AGET-BYTE", (byte)4, ReferenceType.none, "23x"),
|
||||
AGET_CHAR((byte)0x49, "AGET-CHAR", (byte)4, ReferenceType.none, "23x"),
|
||||
AGET_SHORT((byte)0x4a, "AGET-SHORT", (byte)4, ReferenceType.none, "23x"),
|
||||
APUT((byte)0x4b, "APUT", (byte)4, ReferenceType.none, "23x"),
|
||||
APUT_WIDE((byte)0x4c, "APUT-WIDE", (byte)4, ReferenceType.none, "23x"),
|
||||
APUT_OBJECT((byte)0x4d, "APUT-OBJECT", (byte)4, ReferenceType.none, "23x"),
|
||||
APUT_BOOLEAN((byte)0x4e, "APUT-BOOLEAN", (byte)4, ReferenceType.none, "23x"),
|
||||
APUT_BYTE((byte)0x4f, "APUT-BYTE", (byte)4, ReferenceType.none, "23x"),
|
||||
APUT_CHAR((byte)0x50, "APUT-CHAR", (byte)4, ReferenceType.none, "23x"),
|
||||
APUT_SHORT((byte)0x51, "APUT-SHORT", (byte)4, ReferenceType.none, "23x"),
|
||||
IGET((byte)0x52, "IGET", (byte)4, ReferenceType.field, "22c"),
|
||||
IGET_WIDE((byte)0x53, "IGET-WIDE", (byte)4, ReferenceType.field, "22c"),
|
||||
IGET_OBJECT((byte)0x54, "IGET-OBJECT", (byte)4, ReferenceType.field, "22c"),
|
||||
IGET_BOOLEAN((byte)0x55, "IGET-BOOLEAN", (byte)4, ReferenceType.field, "22c"),
|
||||
IGET_BYTE((byte)0x56, "IGET-BYTE", (byte)4, ReferenceType.field, "22c"),
|
||||
IGET_CHAR((byte)0x57, "IGET-CHAR", (byte)4, ReferenceType.field, "22c"),
|
||||
IGET_SHORT((byte)0x58, "IGET-SHORT", (byte)4, ReferenceType.field, "22c"),
|
||||
IPUT((byte)0x59, "IPUT", (byte)4, ReferenceType.field, "22c"),
|
||||
IPUT_WIDE((byte)0x5a, "IPUT-WIDE", (byte)4, ReferenceType.field, "22c"),
|
||||
IPUT_OBJECT((byte)0x5b, "IPUT-OBJECT", (byte)4, ReferenceType.field, "22c"),
|
||||
IPUT_BOOLEAN((byte)0x5c, "IPUT-BOOLEAN", (byte)4, ReferenceType.field, "22c"),
|
||||
IPUT_BYTE((byte)0x5d, "IPUT-BYTE", (byte)4, ReferenceType.field, "22c"),
|
||||
IPUT_CHAR((byte)0x5e, "IPUT-CHAR", (byte)4, ReferenceType.field, "22c"),
|
||||
IPUT_SHORT((byte)0x5f, "IPUT-SHORT", (byte)4, ReferenceType.field, "22c"),
|
||||
SGET((byte)0x60, "SGET", (byte)4, ReferenceType.field, "21c"),
|
||||
SGET_WIDE((byte)0x61, "SGET-WIDE", (byte)4, ReferenceType.field, "21c"),
|
||||
SGET_OBJECT((byte)0x62, "SGET-OBJECT", (byte)4, ReferenceType.field, "21c"),
|
||||
SGET_BOOLEAN((byte)0x63, "SGET-BOOLEAN", (byte)4, ReferenceType.field, "21c"),
|
||||
SGET_BYTE((byte)0x64, "SGET-BYTE", (byte)4, ReferenceType.field, "21c"),
|
||||
SGET_CHAR((byte)0x65, "SGET-CHAR", (byte)4, ReferenceType.field, "21c"),
|
||||
SGET_SHORT((byte)0x66, "SGET-SHORT", (byte)4, ReferenceType.field, "21c"),
|
||||
SPUT((byte)0x67, "SPUT", (byte)4, ReferenceType.field, "21c"),
|
||||
SPUT_WIDE((byte)0x68, "SPUT-WIDE", (byte)4, ReferenceType.field, "21c"),
|
||||
SPUT_OBJECT((byte)0x69, "SPUT-OBJECT", (byte)4, ReferenceType.field, "21c"),
|
||||
SPUT_BOOLEAN((byte)0x6a, "SPUT-BOOLEAN", (byte)4, ReferenceType.field, "21c"),
|
||||
SPUT_BYTE((byte)0x6b, "SPUT-BYTE", (byte)4, ReferenceType.field, "21c"),
|
||||
SPUT_CHAR((byte)0x6c, "SPUT-CHAR", (byte)4, ReferenceType.field, "21c"),
|
||||
SPUT_SHORT((byte)0x6d, "SPUT-SHORT", (byte)4, ReferenceType.field, "21c"),
|
||||
INVOKE_VIRTUAL((byte)0x6e, "INVOKE-VIRTUAL", (byte)6, ReferenceType.method, "35c"),
|
||||
INVOKE_SUPER((byte)0x6f, "INVOKE-SUPER", (byte)6, ReferenceType.method, "35c"),
|
||||
INVOKE_DIRECT((byte)0x70, "INVOKE-DIRECT", (byte)6, ReferenceType.method, "35c"),
|
||||
INVOKE_STATIC((byte)0x71, "INVOKE-STATIC", (byte)6, ReferenceType.method, "35c"),
|
||||
INVOKE_INTERFACE((byte)0x72, "INVOKE-INTERFACE", (byte)6, ReferenceType.method, "35c"),
|
||||
INVOKE_VIRTUAL_RANGE((byte)0x74, "INVOKE-VIRTUAL/RANGE", (byte)6, ReferenceType.method, "3rc"),
|
||||
INVOKE_SUPER_RANGE((byte)0x75, "INVOKE-SUPER/RANGE", (byte)6, ReferenceType.method, "3rc"),
|
||||
INVOKE_DIRECT_RANGE((byte)0x76, "INVOKE-DIRECT/RANGE", (byte)6, ReferenceType.method, "3rc"),
|
||||
INVOKE_STATIC_RANGE((byte)0x77, "INVOKE-STATIC/RANGE", (byte)6, ReferenceType.method, "3rc"),
|
||||
INVOKE_INTERFACE_RANGE((byte)0x78, "INVOKE-INTERFACE/RANGE", (byte)6, ReferenceType.method, "3rc"),
|
||||
NEG_INT((byte)0x7b, "NEG-INT", (byte)2, ReferenceType.none, "12x"),
|
||||
NOT_INT((byte)0x7c, "NOT-INT", (byte)2, ReferenceType.none, "12x"),
|
||||
NEG_LONG((byte)0x7d, "NEG-LONG", (byte)2, ReferenceType.none, "12x"),
|
||||
NOT_LONG((byte)0x7e, "NOT-LONG", (byte)2, ReferenceType.none, "12x"),
|
||||
NEG_FLOAT((byte)0x7f, "NEG-FLOAT", (byte)2, ReferenceType.none, "12x"),
|
||||
NEG_DOUBLE((byte)0x80, "NEG-DOUBLE", (byte)2, ReferenceType.none, "12x"),
|
||||
INT_TO_LONG((byte)0x81, "INT-TO-LONG", (byte)2, ReferenceType.none, "12x"),
|
||||
INT_TO_FLOAT((byte)0x82, "INT-TO-FLOAT", (byte)2, ReferenceType.none, "12x"),
|
||||
INT_TO_DOUBLE((byte)0x83, "INT-TO-DOUBLE", (byte)2, ReferenceType.none, "12x"),
|
||||
LONG_TO_INT((byte)0x84, "LONG-TO-INT", (byte)2, ReferenceType.none, "12x"),
|
||||
LONG_TO_FLOAT((byte)0x85, "LONG-TO-FLOAT", (byte)2, ReferenceType.none, "12x"),
|
||||
LONG_TO_DOUBLE((byte)0x86, "LONG-TO-DOUBLE", (byte)2, ReferenceType.none, "12x"),
|
||||
FLOAT_TO_INT((byte)0x87, "FLOAT-TO-INT", (byte)2, ReferenceType.none, "12x"),
|
||||
FLOAT_TO_LONG((byte)0x88, "FLOAT-TO-LONG", (byte)2, ReferenceType.none, "12x"),
|
||||
FLOAT_TO_DOUBLE((byte)0x89, "FLOAT-TO-DOUBLE", (byte)2, ReferenceType.none, "12x"),
|
||||
DOUBLE_TO_INT((byte)0x8a, "DOUBLE-TO-INT", (byte)2, ReferenceType.none, "12x"),
|
||||
DOUBLE_TO_LONG((byte)0x8b, "DOUBLE-TO-LONG", (byte)2, ReferenceType.none, "12x"),
|
||||
DOUBLE_TO_FLOAT((byte)0x8c, "DOUBLE-TO-FLOAT", (byte)2, ReferenceType.none, "12x"),
|
||||
INT_TO_BYTE((byte)0x8d, "INT-TO-BYTE", (byte)2, ReferenceType.none, "12x"),
|
||||
INT_TO_CHAR((byte)0x8e, "INT-TO-CHAR", (byte)2, ReferenceType.none, "12x"),
|
||||
INT_TO_SHORT((byte)0x8f, "INT-TO-SHORT", (byte)2, ReferenceType.none, "12x"),
|
||||
ADD_INT((byte)0x90, "ADD-INT", (byte)4, ReferenceType.none, "23x"),
|
||||
SUB_INT((byte)0x91, "SUB-INT", (byte)4, ReferenceType.none, "23x"),
|
||||
MUL_INT((byte)0x92, "MUL-INT", (byte)4, ReferenceType.none, "23x"),
|
||||
DIV_INT((byte)0x93, "DIV-INT", (byte)4, ReferenceType.none, "23x"),
|
||||
REM_INT((byte)0x94, "REM-INT", (byte)4, ReferenceType.none, "23x"),
|
||||
AND_INT((byte)0x95, "AND-INT", (byte)4, ReferenceType.none, "23x"),
|
||||
OR_INT((byte)0x96, "OR-INT", (byte)4, ReferenceType.none, "23x"),
|
||||
XOR_INT((byte)0x97, "XOR-INT", (byte)4, ReferenceType.none, "23x"),
|
||||
SHL_INT((byte)0x98, "SHL-INT", (byte)4, ReferenceType.none, "23x"),
|
||||
SHR_INT((byte)0x99, "SHR-INT", (byte)4, ReferenceType.none, "23x"),
|
||||
USHR_INT((byte)0x9a, "USHR-INT", (byte)4, ReferenceType.none, "23x"),
|
||||
ADD_LONG((byte)0x9b, "ADD-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
SUB_LONG((byte)0x9c, "SUB-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
MUL_LONG((byte)0x9d, "MUL-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
DIV_LONG((byte)0x9e, "DIV-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
REM_LONG((byte)0x9f, "REM-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
AND_LONG((byte)0xa0, "AND-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
OR_LONG((byte)0xa1, "OR-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
XOR_LONG((byte)0xa2, "XOR-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
SHL_LONG((byte)0xa3, "SHL-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
SHR_LONG((byte)0xa4, "SHR-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
USHR_LONG((byte)0xa5, "USHR-LONG", (byte)4, ReferenceType.none, "23x"),
|
||||
ADD_FLOAT((byte)0xa6, "ADD-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
||||
SUB_FLOAT((byte)0xa7, "SUB-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
||||
MUL_FLOAT((byte)0xa8, "MUL-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
||||
DIV_FLOAT((byte)0xa9, "DIV-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
||||
REM_FLOAT((byte)0xaa, "REM-FLOAT", (byte)4, ReferenceType.none, "23x"),
|
||||
ADD_DOUBLE((byte)0xab, "ADD-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
||||
SUB_DOUBLE((byte)0xac, "SUB-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
||||
MUL_DOUBLE((byte)0xad, "MUL-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
||||
DIV_DOUBLE((byte)0xae, "DIV-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
||||
REM_DOUBLE((byte)0xaf, "REM-DOUBLE", (byte)4, ReferenceType.none, "23x"),
|
||||
ADD_INT_2ADDR((byte)0xb0, "ADD-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
SUB_INT_2ADDR((byte)0xb1, "SUB-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
MUL_INT_2ADDR((byte)0xb2, "MUL-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
DIV_INT_2ADDR((byte)0xb3, "DIV-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
REM_INT_2ADDR((byte)0xb4, "REM-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
AND_INT_2ADDR((byte)0xb5, "AND-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
OR_INT_2ADDR((byte)0xb6, "OR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
XOR_INT_2ADDR((byte)0xb7, "XOR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
SHL_INT_2ADDR((byte)0xb8, "SHL-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
SHR_INT_2ADDR((byte)0xb9, "SHR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
USHR_INT_2ADDR((byte)0xba, "USHR-INT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
ADD_LONG_2ADDR((byte)0xbb, "ADD-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
SUB_LONG_2ADDR((byte)0xbc, "SUB-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
MUL_LONG_2ADDR((byte)0xbd, "MUL-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
DIV_LONG_2ADDR((byte)0xbe, "DIV-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
REM_LONG_2ADDR((byte)0xbf, "REM-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
AND_LONG_2ADDR((byte)0xc0, "AND-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
OR_LONG_2ADDR((byte)0xc1, "OR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
XOR_LONG_2ADDR((byte)0xc2, "XOR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
SHL_LONG_2ADDR((byte)0xc3, "SHL-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
SHR_LONG_2ADDR((byte)0xc4, "SHR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
USHR_LONG_2ADDR((byte)0xc5, "USHR-LONG/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
ADD_FLOAT_2ADDR((byte)0xc6, "ADD-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
SUB_FLOAT_2ADDR((byte)0xc7, "SUB-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
MUL_FLOAT_2ADDR((byte)0xc8, "MUL-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
DIV_FLOAT_2ADDR((byte)0xc9, "DIV-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
REM_FLOAT_2ADDR((byte)0xca, "REM-FLOAT/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
ADD_DOUBLE_2ADDR((byte)0xcb, "ADD-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
SUB_DOUBLE_2ADDR((byte)0xcc, "SUB-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
MUL_DOUBLE_2ADDR((byte)0xcd, "MUL-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
DIV_DOUBLE_2ADDR((byte)0xce, "DIV-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
REM_DOUBLE_2ADDR((byte)0xcf, "REM-DOUBLE/2ADDR", (byte)2, ReferenceType.none, "12x"),
|
||||
ADD_INT_LIT16((byte)0xd0, "ADD-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
||||
RSUB_INT_LIT16((byte)0xd1, "RSUB-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
||||
MUL_INT_LIT16((byte)0xd2, "MUL-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
||||
DIV_INT_LIT16((byte)0xd3, "DIV-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
||||
REM_INT_LIT16((byte)0xd4, "REM-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
||||
AND_INT_LIT16((byte)0xd5, "AND-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
||||
OR_INT_LIT16((byte)0xd6, "OR-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
||||
XOR_INT_LIT16((byte)0xd7, "XOR-INT/LIT16", (byte)4, ReferenceType.none, "22s"),
|
||||
ADD_INT_LIT8((byte)0xd8, "ADD-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
||||
RSUB_INT_LIT8((byte)0xd9, "RSUB-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
||||
MUL_INT_LIT8((byte)0xda, "MUL-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
||||
DIV_INT_LIT8((byte)0xdb, "DIV-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
||||
REM_INT_LIT8((byte)0xdc, "REM-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
||||
AND_INT_LIT8((byte)0xdd, "AND-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
||||
OR_INT_LIT8((byte)0xde, "OR-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
||||
XOR_INT_LIT8((byte)0xdf, "XOR-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
||||
SHL_INT_LIT8((byte)0xe0, "SHL-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
||||
SHR_INT_LIT8((byte)0xe1, "SHR-INT/LIT8", (byte)4, ReferenceType.none, "22b"),
|
||||
USHR_INT_LIT8((byte)0xe2, "USHR-INT/LIT8", (byte)4, ReferenceType.none, "22b");
|
||||
|
||||
|
||||
|
||||
private static ArrayList<Opcode> opcodesByValue;
|
||||
private static HashMap<Integer, Opcode> opcodesByName;
|
||||
|
||||
static {
|
||||
try
|
||||
{
|
||||
opcodesByValue = new ArrayList<Opcode>();
|
||||
opcodesByName = new HashMap<Integer, Opcode>();
|
||||
|
||||
for (int i=0; i<0x100; i++) {
|
||||
opcodesByValue.add(null);
|
||||
}
|
||||
|
||||
for (Opcode opcode: Opcode.values()) {
|
||||
opcodesByValue.set((opcode.value & 0xFF), opcode);
|
||||
opcodesByName.put(opcode.name.toLowerCase().hashCode(), opcode);
|
||||
}
|
||||
}catch (Exception ex) {
|
||||
System.out.println(ex.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static Opcode getOpcodeByName(String opcodeName) {
|
||||
return opcodesByName.get(opcodeName.toLowerCase().hashCode());
|
||||
}
|
||||
|
||||
public static Opcode getOpcodeByValue(byte opcodeValue) {
|
||||
return opcodesByValue.get(opcodeValue);
|
||||
}
|
||||
|
||||
public final byte value;
|
||||
public final String name;
|
||||
public final byte numBytes;
|
||||
public final ReferenceType referenceType;
|
||||
public final String format;
|
||||
|
||||
Opcode(byte opcodeValue, String opcodeName, byte numBytes, ReferenceType referenceType, String format) {
|
||||
this.value = opcodeValue;
|
||||
this.name = opcodeName;
|
||||
this.numBytes = numBytes;
|
||||
this.referenceType = referenceType;
|
||||
this.format = format;
|
||||
}
|
||||
}
|
56
src/main/java/org/JesusFreke/dexlib/code/ReferenceType.java
Normal file
56
src/main/java/org/JesusFreke/dexlib/code/ReferenceType.java
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.code;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
public enum ReferenceType
|
||||
{
|
||||
string,
|
||||
type,
|
||||
field,
|
||||
method,
|
||||
none;
|
||||
|
||||
public boolean checkItem(IndexedItem item) {
|
||||
switch (this) {
|
||||
case string:
|
||||
return item instanceof StringIdItem;
|
||||
case type:
|
||||
return item instanceof TypeIdItem;
|
||||
case field:
|
||||
return item instanceof FieldIdItem;
|
||||
case method:
|
||||
return item instanceof MethodIdItem;
|
||||
case none:
|
||||
return item == null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
53
src/main/java/org/JesusFreke/dexlib/debug/AdvanceLine.java
Normal file
53
src/main/java/org/JesusFreke/dexlib/debug/AdvanceLine.java
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.CompositeField;
|
||||
import org.JesusFreke.dexlib.Field;
|
||||
import org.JesusFreke.dexlib.ByteField;
|
||||
import org.JesusFreke.dexlib.SignedLeb128Field;
|
||||
|
||||
public class AdvanceLine extends CompositeField<AdvanceLine> implements DebugInstruction<AdvanceLine> {
|
||||
private final Field[] fields;
|
||||
|
||||
public AdvanceLine() {
|
||||
fields = new Field[] {
|
||||
new ByteField((byte)0x02),
|
||||
new SignedLeb128Field()
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public byte getOpcode() {
|
||||
return 0x02;
|
||||
}
|
||||
}
|
50
src/main/java/org/JesusFreke/dexlib/debug/AdvancePC.java
Normal file
50
src/main/java/org/JesusFreke/dexlib/debug/AdvancePC.java
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
public class AdvancePC extends CompositeField<AdvancePC> implements DebugInstruction<AdvancePC> {
|
||||
private final Field[] fields;
|
||||
|
||||
public AdvancePC() {
|
||||
fields = new Field[] {
|
||||
new ByteField((byte)0x01),
|
||||
new Leb128Field()
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public byte getOpcode() {
|
||||
return 0x01;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.Field;
|
||||
|
||||
public interface DebugInstruction<T extends DebugInstruction> extends Field<T> {
|
||||
public byte getOpcode();
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.DexFile;
|
||||
import org.JesusFreke.dexlib.util.Input;
|
||||
|
||||
public abstract class DebugInstructionFactory {
|
||||
public static DebugInstruction readDebugInstruction(DexFile dexFile, Input in) {
|
||||
int startCursor = in.getCursor();
|
||||
byte opcode = in.readByte();
|
||||
in.setCursor(startCursor);
|
||||
|
||||
DebugInstruction debugInstruction = makeDebugInstruction(dexFile, opcode);
|
||||
debugInstruction.readFrom(in);
|
||||
return debugInstruction;
|
||||
}
|
||||
|
||||
public static DebugInstruction makeDebugInstruction(DexFile dexFile, byte opcode) {
|
||||
switch (opcode) {
|
||||
case 0x00:
|
||||
return new EndSequence();
|
||||
case 0x01:
|
||||
return new AdvancePC();
|
||||
case 0x02:
|
||||
return new AdvanceLine();
|
||||
case 0x03:
|
||||
return new StartLocal(dexFile);
|
||||
case 0x04:
|
||||
return new StartLocalExtended(dexFile);
|
||||
case 0x05:
|
||||
return new EndLocal();
|
||||
case 0x06:
|
||||
return new RestartLocal();
|
||||
case 0x07:
|
||||
return new SetPrologueEnd();
|
||||
case 0x08:
|
||||
return new SetEpilogueBegin();
|
||||
case 0x09:
|
||||
return new SetFile(dexFile);
|
||||
default:
|
||||
return new SpecialOpcode(opcode);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
50
src/main/java/org/JesusFreke/dexlib/debug/EndLocal.java
Normal file
50
src/main/java/org/JesusFreke/dexlib/debug/EndLocal.java
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
public class EndLocal extends CompositeField<EndLocal> implements DebugInstruction<EndLocal> {
|
||||
private final Field[] fields;
|
||||
|
||||
public EndLocal() {
|
||||
fields = new Field[] {
|
||||
new ByteField((byte)0x05),
|
||||
new Leb128Field()
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public byte getOpcode() {
|
||||
return 0x05;
|
||||
}
|
||||
}
|
51
src/main/java/org/JesusFreke/dexlib/debug/EndSequence.java
Normal file
51
src/main/java/org/JesusFreke/dexlib/debug/EndSequence.java
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.CompositeField;
|
||||
import org.JesusFreke.dexlib.Field;
|
||||
import org.JesusFreke.dexlib.ByteField;
|
||||
|
||||
public class EndSequence extends CompositeField<EndSequence> implements DebugInstruction<EndSequence> {
|
||||
private final Field[] fields;
|
||||
|
||||
public EndSequence() {
|
||||
fields = new Field[] {
|
||||
new ByteField((byte)0x00)
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public byte getOpcode() {
|
||||
return 0x00;
|
||||
}
|
||||
}
|
50
src/main/java/org/JesusFreke/dexlib/debug/RestartLocal.java
Normal file
50
src/main/java/org/JesusFreke/dexlib/debug/RestartLocal.java
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
public class RestartLocal extends CompositeField<RestartLocal> implements DebugInstruction<RestartLocal> {
|
||||
private final Field[] fields;
|
||||
|
||||
public RestartLocal() {
|
||||
fields = new Field[] {
|
||||
new ByteField((byte)0x06),
|
||||
new SignedLeb128Field()
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public byte getOpcode() {
|
||||
return 0x06;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.CompositeField;
|
||||
import org.JesusFreke.dexlib.Field;
|
||||
import org.JesusFreke.dexlib.ByteField;
|
||||
|
||||
public class SetEpilogueBegin extends CompositeField<SetEpilogueBegin> implements DebugInstruction<SetEpilogueBegin> {
|
||||
private final Field[] fields;
|
||||
|
||||
public SetEpilogueBegin() {
|
||||
fields = new Field[] {
|
||||
new ByteField((byte)0x08)
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public byte getOpcode() {
|
||||
return 0x08;
|
||||
}
|
||||
}
|
50
src/main/java/org/JesusFreke/dexlib/debug/SetFile.java
Normal file
50
src/main/java/org/JesusFreke/dexlib/debug/SetFile.java
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
public class SetFile extends CompositeField<SetFile> implements DebugInstruction<SetFile> {
|
||||
private final Field[] fields;
|
||||
|
||||
public SetFile(DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
new ByteField((byte)0x09),
|
||||
new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new Leb128p1Field())
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public byte getOpcode() {
|
||||
return 0x09;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.CompositeField;
|
||||
import org.JesusFreke.dexlib.Field;
|
||||
import org.JesusFreke.dexlib.ByteField;
|
||||
|
||||
public class SetPrologueEnd extends CompositeField<SetPrologueEnd> implements DebugInstruction<SetPrologueEnd> {
|
||||
private final Field[] fields;
|
||||
|
||||
public SetPrologueEnd() {
|
||||
fields = new Field[] {
|
||||
new ByteField((byte)0x07)
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public byte getOpcode() {
|
||||
return 0x07;
|
||||
}
|
||||
}
|
54
src/main/java/org/JesusFreke/dexlib/debug/SpecialOpcode.java
Normal file
54
src/main/java/org/JesusFreke/dexlib/debug/SpecialOpcode.java
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.CompositeField;
|
||||
import org.JesusFreke.dexlib.Field;
|
||||
import org.JesusFreke.dexlib.ByteField;
|
||||
|
||||
public class SpecialOpcode extends CompositeField<SpecialOpcode> implements DebugInstruction<SpecialOpcode> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final byte opcode;
|
||||
|
||||
public SpecialOpcode(byte opcode) {
|
||||
this.opcode = opcode;
|
||||
fields = new Field[] {
|
||||
new ByteField(opcode)
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public byte getOpcode() {
|
||||
return opcode;
|
||||
}
|
||||
}
|
52
src/main/java/org/JesusFreke/dexlib/debug/StartLocal.java
Normal file
52
src/main/java/org/JesusFreke/dexlib/debug/StartLocal.java
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
public class StartLocal extends CompositeField<StartLocal> implements DebugInstruction<StartLocal> {
|
||||
private final Field[] fields;
|
||||
|
||||
public StartLocal(DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
new ByteField((byte)0x03),
|
||||
new SignedLeb128Field(),
|
||||
new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new Leb128p1Field()),
|
||||
new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, new Leb128p1Field()),
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public byte getOpcode() {
|
||||
return 0x03;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.debug;
|
||||
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
public class StartLocalExtended extends CompositeField<StartLocalExtended> implements DebugInstruction<StartLocalExtended> {
|
||||
private final Field[] fields;
|
||||
|
||||
public StartLocalExtended(DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
new ByteField((byte)0x04),
|
||||
new SignedLeb128Field(),
|
||||
new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new Leb128p1Field()),
|
||||
new IndexedItemReference<TypeIdItem>(dexFile.TypeIdsSection, new Leb128p1Field()),
|
||||
new IndexedItemReference<StringIdItem>(dexFile.StringIdsSection, new Leb128p1Field())
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public byte getOpcode() {
|
||||
return 0x04;
|
||||
}
|
||||
}
|
59
src/main/java/org/JesusFreke/dexlib/util/AccessFlags.java
Normal file
59
src/main/java/org/JesusFreke/dexlib/util/AccessFlags.java
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class AccessFlags
|
||||
{
|
||||
public static final int PUBLIC = 0x01;
|
||||
public static final int PRIVATE = 0x02;
|
||||
public static final int STATIC = 0x08;
|
||||
public static final int CONSTRUCTOR = 0x10000;
|
||||
|
||||
private static HashMap<String, Integer> accessFlagValues;
|
||||
|
||||
static {
|
||||
accessFlagValues = new HashMap<String, Integer>();
|
||||
accessFlagValues.put("public", PUBLIC);
|
||||
accessFlagValues.put("private", PRIVATE);
|
||||
accessFlagValues.put("static", STATIC);
|
||||
accessFlagValues.put("constructor", CONSTRUCTOR);
|
||||
}
|
||||
|
||||
public static int getValueForAccessFlag(String accessFlag) {
|
||||
Integer retVal;
|
||||
retVal = accessFlagValues.get(accessFlag);
|
||||
if (retVal == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return retVal.intValue();
|
||||
}
|
||||
}
|
379
src/main/java/org/JesusFreke/dexlib/util/ByteArray.java
Normal file
379
src/main/java/org/JesusFreke/dexlib/util/ByteArray.java
Normal file
@ -0,0 +1,379 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Wrapper for a <code>byte[]</code>, which provides read-only access and
|
||||
* can "reveal" a partial slice of the underlying array.
|
||||
*
|
||||
* <b>Note:</b> Multibyte accessors all use big-endian order.
|
||||
*/
|
||||
public final class ByteArray {
|
||||
/** non-null; underlying array */
|
||||
private final byte[] bytes;
|
||||
|
||||
/** <code>>= 0</code>; start index of the slice (inclusive) */
|
||||
private final int start;
|
||||
|
||||
/** <code>>= 0, <= bytes.length</code>; size computed as
|
||||
* <code>end - start</code> (in the constructor) */
|
||||
private final int size;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param bytes non-null; the underlying array
|
||||
* @param start <code>>= 0</code>; start index of the slice (inclusive)
|
||||
* @param end <code>>= start, <= bytes.length</code>; end index of
|
||||
* the slice (exclusive)
|
||||
*/
|
||||
public ByteArray(byte[] bytes, int start, int end) {
|
||||
if (bytes == null) {
|
||||
throw new NullPointerException("bytes == null");
|
||||
}
|
||||
|
||||
if (start < 0) {
|
||||
throw new IllegalArgumentException("start < 0");
|
||||
}
|
||||
|
||||
if (end < start) {
|
||||
throw new IllegalArgumentException("end < start");
|
||||
}
|
||||
|
||||
if (end > bytes.length) {
|
||||
throw new IllegalArgumentException("end > bytes.length");
|
||||
}
|
||||
|
||||
this.bytes = bytes;
|
||||
this.start = start;
|
||||
this.size = end - start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance from an entire <code>byte[]</code>.
|
||||
*
|
||||
* @param bytes non-null; the underlying array
|
||||
*/
|
||||
public ByteArray(byte[] bytes) {
|
||||
this(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the array, in bytes.
|
||||
*
|
||||
* @return >= 0; the size
|
||||
*/
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a slice (that is, a sub-array) of this instance.
|
||||
*
|
||||
* @param start <code>>= 0</code>; start index of the slice (inclusive)
|
||||
* @param end <code>>= start, <= size()</code>; end index of
|
||||
* the slice (exclusive)
|
||||
* @return non-null; the slice
|
||||
*/
|
||||
public ByteArray slice(int start, int end) {
|
||||
checkOffsets(start, end);
|
||||
return new ByteArray(bytes, start + this.start, end + this.start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset into the given array represented by the given
|
||||
* offset into this instance.
|
||||
*
|
||||
* @param offset offset into this instance
|
||||
* @param bytes non-null; (alleged) underlying array
|
||||
* @return corresponding offset into <code>bytes</code>
|
||||
* @throws IllegalArgumentException thrown if <code>bytes</code> is
|
||||
* not the underlying array of this instance
|
||||
*/
|
||||
public int underlyingOffset(int offset, byte[] bytes) {
|
||||
if (bytes != this.bytes) {
|
||||
throw new IllegalArgumentException("wrong bytes");
|
||||
}
|
||||
|
||||
return start + offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>signed byte</code> value at a particular offset.
|
||||
*
|
||||
* @param off <code>>= 0, < size(); offset to fetch
|
||||
* @return <code>signed byte</code> at that offset
|
||||
*/
|
||||
public int getByte(int off) {
|
||||
checkOffsets(off, off + 1);
|
||||
return getByte0(off);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>signed short</code> value at a particular offset.
|
||||
*
|
||||
* @param off <code>>= 0, < (size() - 1); offset to fetch
|
||||
* @return <code>signed short</code> at that offset
|
||||
*/
|
||||
public int getShort(int off) {
|
||||
checkOffsets(off, off + 2);
|
||||
return (getByte0(off) << 8) | getUnsignedByte0(off + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>signed int</code> value at a particular offset.
|
||||
*
|
||||
* @param off <code>>= 0, < (size() - 3); offset to fetch
|
||||
* @return <code>signed int</code> at that offset
|
||||
*/
|
||||
public int getInt(int off) {
|
||||
checkOffsets(off, off + 4);
|
||||
return (getByte0(off) << 24) |
|
||||
(getUnsignedByte0(off + 1) << 16) |
|
||||
(getUnsignedByte0(off + 2) << 8) |
|
||||
getUnsignedByte0(off + 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>signed long</code> value at a particular offset.
|
||||
*
|
||||
* @param off <code>>= 0, < (size() - 7); offset to fetch
|
||||
* @return <code>signed int</code> at that offset
|
||||
*/
|
||||
public long getLong(int off) {
|
||||
checkOffsets(off, off + 8);
|
||||
int part1 = (getByte0(off) << 24) |
|
||||
(getUnsignedByte0(off + 1) << 16) |
|
||||
(getUnsignedByte0(off + 2) << 8) |
|
||||
getUnsignedByte0(off + 3);
|
||||
int part2 = (getByte0(off + 4) << 24) |
|
||||
(getUnsignedByte0(off + 5) << 16) |
|
||||
(getUnsignedByte0(off + 6) << 8) |
|
||||
getUnsignedByte0(off + 7);
|
||||
|
||||
return (part2 & 0xffffffffL) | ((long) part1) << 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>unsigned byte</code> value at a particular offset.
|
||||
*
|
||||
* @param off <code>>= 0, < size(); offset to fetch
|
||||
* @return <code>unsigned byte</code> at that offset
|
||||
*/
|
||||
public int getUnsignedByte(int off) {
|
||||
checkOffsets(off, off + 1);
|
||||
return getUnsignedByte0(off);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>unsigned short</code> value at a particular offset.
|
||||
*
|
||||
* @param off <code>>= 0, < (size() - 1); offset to fetch
|
||||
* @return <code>unsigned short</code> at that offset
|
||||
*/
|
||||
public int getUnsignedShort(int off) {
|
||||
checkOffsets(off, off + 2);
|
||||
return (getUnsignedByte0(off) << 8) | getUnsignedByte0(off + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the contents of this instance into the given raw
|
||||
* <code>byte[]</code> at the given offset. The given array must be
|
||||
* large enough.
|
||||
*
|
||||
* @param out non-null; array to hold the output
|
||||
* @param offset non-null; index into <code>out</code> for the first
|
||||
* byte of output
|
||||
*/
|
||||
public void getBytes(byte[] out, int offset) {
|
||||
if ((out.length - offset) < size) {
|
||||
throw new IndexOutOfBoundsException("(out.length - offset) < " +
|
||||
"size()");
|
||||
}
|
||||
|
||||
System.arraycopy(bytes, start, out, offset, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a range of offsets for validity, throwing if invalid.
|
||||
*
|
||||
* @param s start offset (inclusive)
|
||||
* @param e end offset (exclusive)
|
||||
*/
|
||||
private void checkOffsets(int s, int e) {
|
||||
if ((s < 0) || (e < s) || (e > size)) {
|
||||
throw new IllegalArgumentException("bad range: " + s + ".." + e +
|
||||
"; actual size " + size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>signed byte</code> value at the given offset,
|
||||
* without doing any argument checking.
|
||||
*
|
||||
* @param off offset to fetch
|
||||
* @return byte at that offset
|
||||
*/
|
||||
private int getByte0(int off) {
|
||||
return bytes[start + off];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>unsigned byte</code> value at the given offset,
|
||||
* without doing any argument checking.
|
||||
*
|
||||
* @param off offset to fetch
|
||||
* @return byte at that offset
|
||||
*/
|
||||
private int getUnsignedByte0(int off) {
|
||||
return bytes[start + off] & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a <code>DataInputStream</code> that reads from this instance,
|
||||
* with the cursor starting at the beginning of this instance's data.
|
||||
* <b>Note:</b> The returned instance may be cast to {@link #GetCursor}
|
||||
* if needed.
|
||||
*
|
||||
* @return non-null; an appropriately-constructed
|
||||
* <code>DataInputStream</code> instance
|
||||
*/
|
||||
public MyDataInputStream makeDataInputStream() {
|
||||
return new MyDataInputStream(makeInputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a <code>InputStream</code> that reads from this instance,
|
||||
* with the cursor starting at the beginning of this instance's data.
|
||||
* <b>Note:</b> The returned instance may be cast to {@link #GetCursor}
|
||||
* if needed.
|
||||
*
|
||||
* @return non-null; an appropriately-constructed
|
||||
* <code>InputStream</code> instancex
|
||||
*/
|
||||
public MyInputStream makeInputStream() {
|
||||
return new MyInputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper interface that allows one to get the cursor (of a stream).
|
||||
*/
|
||||
public interface GetCursor {
|
||||
/**
|
||||
* Gets the current cursor.
|
||||
*
|
||||
* @return 0..size(); the cursor
|
||||
*/
|
||||
public int getCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class for {@link #makeInputStream}, which implements the
|
||||
* stream functionality.
|
||||
*/
|
||||
public class MyInputStream extends InputStream {
|
||||
/** 0..size; the cursor */
|
||||
private int cursor;
|
||||
|
||||
/** 0..size; the mark */
|
||||
private int mark;
|
||||
|
||||
public MyInputStream() {
|
||||
cursor = 0;
|
||||
mark = 0;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
if (cursor >= size) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result = getUnsignedByte0(cursor);
|
||||
cursor++;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int read(byte[] arr, int offset, int length) {
|
||||
if ((offset + length) > arr.length) {
|
||||
length = arr.length - offset;
|
||||
}
|
||||
|
||||
int maxLength = size - cursor;
|
||||
if (length > maxLength) {
|
||||
length = maxLength;
|
||||
}
|
||||
|
||||
System.arraycopy(bytes, cursor, arr, offset, length);
|
||||
cursor += length;
|
||||
return length;
|
||||
}
|
||||
|
||||
public int available() {
|
||||
return size - cursor;
|
||||
}
|
||||
|
||||
public void mark(int reserve) {
|
||||
mark = cursor;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
cursor = mark;
|
||||
}
|
||||
|
||||
public boolean markSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current cursor.
|
||||
*
|
||||
* @return 0..size(); the cursor
|
||||
*/
|
||||
public int getCursor() {
|
||||
return cursor;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class for {@link #makeDataInputStream}. This is used
|
||||
* simply so that the cursor of a wrapped {@link #MyInputStream}
|
||||
* instance may be easily determined.
|
||||
*/
|
||||
public class MyDataInputStream extends DataInputStream {
|
||||
/** non-null; the underlying {@link #MyInputStream} */
|
||||
private final MyInputStream wrapped;
|
||||
|
||||
public MyDataInputStream(MyInputStream wrapped) {
|
||||
super(wrapped);
|
||||
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current cursor.
|
||||
*
|
||||
* @return 0..size(); the cursor
|
||||
*/
|
||||
public int getCursor() {
|
||||
return wrapped.getCursor();
|
||||
}
|
||||
}
|
||||
}
|
312
src/main/java/org/JesusFreke/dexlib/util/ByteArrayInput.java
Normal file
312
src/main/java/org/JesusFreke/dexlib/util/ByteArrayInput.java
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
/**
|
||||
* Implementation of {@link Input} which reads the data from a
|
||||
* <code>byte[]</code> instance.
|
||||
*
|
||||
* <p><b>Note:</b> As per the {@link Input } interface, multi-byte
|
||||
* reads all use little-endian order.</p>
|
||||
*/
|
||||
public class ByteArrayInput
|
||||
implements Input {
|
||||
|
||||
/** non-null; the data itself */
|
||||
private byte[] data;
|
||||
|
||||
/** >= 0; current read cursor */
|
||||
private int cursor;
|
||||
|
||||
/**
|
||||
* Constructs an instance with the given data
|
||||
*
|
||||
* @param data non-null; data array to use for input
|
||||
*/
|
||||
public ByteArrayInput(byte[] data) {
|
||||
if (data == null) {
|
||||
throw new NullPointerException("data == null");
|
||||
}
|
||||
|
||||
this.data = data;
|
||||
this.cursor = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying <code>byte[]</code> of this instance
|
||||
*
|
||||
* @return non-null; the <code>byte[]</code>
|
||||
*/
|
||||
public byte[] getArray() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getCursor() {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void setCursor(int cursor) {
|
||||
if (cursor < 0 || cursor >= data.length)
|
||||
throw new IndexOutOfBoundsException("The provided cursor value " +
|
||||
"is not within the bounds of this instance's data array");
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void assertCursor(int expectedCursor) {
|
||||
if (cursor != expectedCursor) {
|
||||
throw new ExceptionWithContext("expected cursor " +
|
||||
expectedCursor + "; actual value: " + cursor);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public byte readByte() {
|
||||
int readAt = cursor;
|
||||
int end = readAt + 1;
|
||||
|
||||
if (end > data.length) {
|
||||
throwBounds();
|
||||
}
|
||||
|
||||
cursor = end;
|
||||
return data[readAt];
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int readShort() {
|
||||
int readAt = cursor;
|
||||
int end = readAt + 2;
|
||||
|
||||
if (end > data.length) {
|
||||
throwBounds();
|
||||
}
|
||||
|
||||
cursor = end;
|
||||
return (int)((data[readAt] & 0xff) +
|
||||
((data[readAt + 1] & 0xff) << 8));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int readInt() {
|
||||
int readAt = cursor;
|
||||
int end = readAt + 4;
|
||||
|
||||
if (end > data.length) {
|
||||
throwBounds();
|
||||
}
|
||||
|
||||
cursor = end;
|
||||
return (data[readAt] & 0xff) +
|
||||
((data[readAt + 1] & 0xff) << 8) +
|
||||
((data[readAt + 2] & 0xff) << 16) +
|
||||
((data[readAt + 3] & 0xff) << 24);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public long readLong() {
|
||||
int readAt = cursor;
|
||||
int end = readAt + 8;
|
||||
|
||||
if (end > data.length) {
|
||||
throwBounds();
|
||||
}
|
||||
|
||||
cursor = end;
|
||||
|
||||
/**
|
||||
* TODO: is there a faster/better way to do this?
|
||||
*/
|
||||
return (long)((data[readAt] & 0xff) +
|
||||
((data[readAt + 1] & 0xff) << 8) +
|
||||
((data[readAt + 2] & 0xff) << 16) +
|
||||
((data[readAt + 3] & 0xff) << 24))
|
||||
|
||||
+
|
||||
|
||||
((long)((data[readAt + 4] & 0xff)+
|
||||
((data[readAt + 5] & 0xff) << 8) +
|
||||
((data[readAt + 6] & 0xff) << 16) +
|
||||
((data[readAt + 7] & 0xff) << 24)) << 32);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int readUnsignedLeb128() {
|
||||
int end = cursor;
|
||||
int currentByteValue;
|
||||
int result;
|
||||
|
||||
result = data[end++] & 0xff;
|
||||
if (result > 0x7f) {
|
||||
currentByteValue = data[end++] & 0xff;
|
||||
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
||||
if (currentByteValue > 0x7f) {
|
||||
currentByteValue = data[end++] & 0xff;
|
||||
result |= (currentByteValue & 0x7f) << 14;
|
||||
if (currentByteValue > 0x7f) {
|
||||
currentByteValue = data[end++] & 0xff;
|
||||
result |= (currentByteValue & 0x7f) << 21;
|
||||
if (currentByteValue > 0x7f) {
|
||||
currentByteValue = data[end++] & 0xff;
|
||||
if (currentByteValue > 0x0f) {
|
||||
throwInvalidLeb();
|
||||
}
|
||||
result |= currentByteValue << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cursor = end;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int readSignedLeb128() {
|
||||
int end = cursor;
|
||||
int currentByteValue;
|
||||
int result;
|
||||
|
||||
result = data[end++] & 0xff;
|
||||
if (result <= 0x7f) {
|
||||
result = (result << 25) >> 25;
|
||||
} else {
|
||||
currentByteValue = data[end++] & 0xff;
|
||||
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
||||
if (currentByteValue <= 0x7f) {
|
||||
result = (result << 18) >> 18;
|
||||
} else {
|
||||
currentByteValue = data[end++] & 0xff;
|
||||
result |= (currentByteValue & 0x7f) << 14;
|
||||
if (currentByteValue <= 0x7f) {
|
||||
result = (result << 11) >> 11;
|
||||
} else {
|
||||
currentByteValue = data[end++] & 0xff;
|
||||
result |= (currentByteValue & 0x7f) << 21;
|
||||
if (currentByteValue <= 0x7f) {
|
||||
result = (result << 4) >> 4;
|
||||
} else {
|
||||
currentByteValue = data[end++] & 0xff;
|
||||
if (currentByteValue > 0x0f) {
|
||||
throwInvalidLeb();
|
||||
}
|
||||
result |= currentByteValue << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cursor = end;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void read(byte[] bytes, int offset, int length) {
|
||||
int end = cursor + length;
|
||||
|
||||
if (end > data.length) {
|
||||
throwBounds();
|
||||
}
|
||||
|
||||
System.arraycopy(data, cursor, bytes, offset, length);
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void read(byte[] bytes) {
|
||||
int length = bytes.length;
|
||||
int end = cursor + length;
|
||||
|
||||
if (end > data.length) {
|
||||
throwBounds();
|
||||
}
|
||||
|
||||
System.arraycopy(data, cursor, bytes, 0, length);
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public byte[] readBytes(int length) {
|
||||
int end = cursor + length;
|
||||
|
||||
if (end > data.length) {
|
||||
throwBounds();
|
||||
}
|
||||
|
||||
byte[] result = new byte[length];
|
||||
System.arraycopy(data, cursor, result, 0, length);
|
||||
cursor = end;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void skipBytes(int count) {
|
||||
int end = cursor + count;
|
||||
|
||||
if (end > data.length) {
|
||||
throwBounds();
|
||||
}
|
||||
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void alignTo(int alignment) {
|
||||
int mask = alignment - 1;
|
||||
|
||||
if ((alignment < 0) || ((mask & alignment) != 0)) {
|
||||
throw new IllegalArgumentException("bogus alignment");
|
||||
}
|
||||
|
||||
int end = (cursor + mask) & ~mask;
|
||||
|
||||
if (end > data.length) {
|
||||
throwBounds();
|
||||
}
|
||||
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws the excpetion for when an attempt is made to read past the
|
||||
* end of the instance.
|
||||
*/
|
||||
private static void throwBounds() {
|
||||
throw new IndexOutOfBoundsException("attempt to read past the end");
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws the exception for when an invalid LEB128 value is encountered
|
||||
*/
|
||||
private static void throwInvalidLeb() {
|
||||
throw new RuntimeException("invalid LEB128 integer encountered");
|
||||
}
|
||||
}
|
582
src/main/java/org/JesusFreke/dexlib/util/ByteArrayOutput.java
Normal file
582
src/main/java/org/JesusFreke/dexlib/util/ByteArrayOutput.java
Normal file
@ -0,0 +1,582 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Implementation of {@link AnnotatedOutput} which stores the written data
|
||||
* into a <code>byte[]</code>.
|
||||
*
|
||||
* <p><b>Note:</b> As per the {@link Output} interface, multi-byte
|
||||
* writes all use little-endian order.</p>
|
||||
*/
|
||||
public final class ByteArrayOutput implements Output
|
||||
{
|
||||
/** default size for stretchy instances */
|
||||
private static final int DEFAULT_SIZE = 1000;
|
||||
|
||||
/**
|
||||
* whether the instance is stretchy, that is, whether its array
|
||||
* may be resized to increase capacity
|
||||
*/
|
||||
private final boolean stretchy;
|
||||
|
||||
/** non-null; the data itself */
|
||||
private byte[] data;
|
||||
|
||||
/** >= 0; current output cursor */
|
||||
private int cursor;
|
||||
|
||||
/** whether annotations are to be verbose */
|
||||
private boolean verbose;
|
||||
|
||||
/**
|
||||
* null-ok; list of annotations, or <code>null</code> if this instance
|
||||
* isn't keeping them
|
||||
*/
|
||||
private ArrayList<Annotation> annotations;
|
||||
|
||||
/** >= 40 (if used); the desired maximum annotation width */
|
||||
private int annotationWidth;
|
||||
|
||||
/**
|
||||
* >= 8 (if used); the number of bytes of hex output to use
|
||||
* in annotations
|
||||
*/
|
||||
private int hexCols;
|
||||
|
||||
/**
|
||||
* Constructs an instance with a fixed maximum size. Note that the
|
||||
* given array is the only one that will be used to store data. In
|
||||
* particular, no reallocation will occur in order to expand the
|
||||
* capacity of the resulting instance. Also, the constructed
|
||||
* instance does not keep annotations by default.
|
||||
*
|
||||
* @param data non-null; data array to use for output
|
||||
*/
|
||||
public ByteArrayOutput(byte[] data) {
|
||||
this(data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a "stretchy" instance. The underlying array may be
|
||||
* reallocated. The constructed instance does not keep annotations
|
||||
* by default.
|
||||
*/
|
||||
public ByteArrayOutput() {
|
||||
this(new byte[DEFAULT_SIZE], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal constructor.
|
||||
*
|
||||
* @param data non-null; data array to use for output
|
||||
* @param stretchy whether the instance is to be stretchy
|
||||
*/
|
||||
private ByteArrayOutput(byte[] data, boolean stretchy) {
|
||||
if (data == null) {
|
||||
throw new NullPointerException("data == null");
|
||||
}
|
||||
|
||||
this.stretchy = stretchy;
|
||||
this.data = data;
|
||||
this.cursor = 0;
|
||||
this.verbose = false;
|
||||
this.annotations = null;
|
||||
this.annotationWidth = 0;
|
||||
this.hexCols = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying <code>byte[]</code> of this instance, which
|
||||
* may be larger than the number of bytes written
|
||||
*
|
||||
* @see #toByteArray
|
||||
*
|
||||
* @return non-null; the <code>byte[]</code>
|
||||
*/
|
||||
public byte[] getArray() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns a new <code>byte[]</code> that contains
|
||||
* the written contents exactly (that is, with no extra unwritten
|
||||
* bytes at the end).
|
||||
*
|
||||
* @see #getArray
|
||||
*
|
||||
* @return non-null; an appropriately-constructed array
|
||||
*/
|
||||
public byte[] toByteArray() {
|
||||
byte[] result = new byte[cursor];
|
||||
System.arraycopy(data, 0, result, 0, cursor);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getCursor() {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void assertCursor(int expectedCursor) {
|
||||
if (cursor != expectedCursor) {
|
||||
throw new ExceptionWithContext("expected cursor " +
|
||||
expectedCursor + "; actual value: " + cursor);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeByte(int value) {
|
||||
int writeAt = cursor;
|
||||
int end = writeAt + 1;
|
||||
|
||||
if (stretchy) {
|
||||
ensureCapacity(end);
|
||||
} else if (end > data.length) {
|
||||
throwBounds();
|
||||
return;
|
||||
}
|
||||
|
||||
data[writeAt] = (byte) value;
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeShort(int value) {
|
||||
int writeAt = cursor;
|
||||
int end = writeAt + 2;
|
||||
|
||||
if (stretchy) {
|
||||
ensureCapacity(end);
|
||||
} else if (end > data.length) {
|
||||
throwBounds();
|
||||
return;
|
||||
}
|
||||
|
||||
data[writeAt] = (byte) value;
|
||||
data[writeAt + 1] = (byte) (value >> 8);
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeInt(int value) {
|
||||
int writeAt = cursor;
|
||||
int end = writeAt + 4;
|
||||
|
||||
if (stretchy) {
|
||||
ensureCapacity(end);
|
||||
} else if (end > data.length) {
|
||||
throwBounds();
|
||||
return;
|
||||
}
|
||||
|
||||
data[writeAt] = (byte) value;
|
||||
data[writeAt + 1] = (byte) (value >> 8);
|
||||
data[writeAt + 2] = (byte) (value >> 16);
|
||||
data[writeAt + 3] = (byte) (value >> 24);
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeLong(long value) {
|
||||
int writeAt = cursor;
|
||||
int end = writeAt + 8;
|
||||
|
||||
if (stretchy) {
|
||||
ensureCapacity(end);
|
||||
} else if (end > data.length) {
|
||||
throwBounds();
|
||||
return;
|
||||
}
|
||||
|
||||
int half = (int) value;
|
||||
data[writeAt] = (byte) half;
|
||||
data[writeAt + 1] = (byte) (half >> 8);
|
||||
data[writeAt + 2] = (byte) (half >> 16);
|
||||
data[writeAt + 3] = (byte) (half >> 24);
|
||||
|
||||
half = (int) (value >> 32);
|
||||
data[writeAt + 4] = (byte) half;
|
||||
data[writeAt + 5] = (byte) (half >> 8);
|
||||
data[writeAt + 6] = (byte) (half >> 16);
|
||||
data[writeAt + 7] = (byte) (half >> 24);
|
||||
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int writeUnsignedLeb128(int value) {
|
||||
int remaining = value >> 7;
|
||||
int count = 0;
|
||||
|
||||
while (remaining != 0) {
|
||||
writeByte((value & 0x7f) | 0x80);
|
||||
value = remaining;
|
||||
remaining >>= 7;
|
||||
count++;
|
||||
}
|
||||
|
||||
writeByte(value & 0x7f);
|
||||
return count + 1;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int writeSignedLeb128(int value) {
|
||||
int remaining = value >> 7;
|
||||
int count = 0;
|
||||
boolean hasMore = true;
|
||||
int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;
|
||||
|
||||
while (hasMore) {
|
||||
hasMore = (remaining != end)
|
||||
|| ((remaining & 1) != ((value >> 6) & 1));
|
||||
|
||||
writeByte((value & 0x7f) | (hasMore ? 0x80 : 0));
|
||||
value = remaining;
|
||||
remaining >>= 7;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void write(ByteArray bytes) {
|
||||
int blen = bytes.size();
|
||||
int writeAt = cursor;
|
||||
int end = writeAt + blen;
|
||||
|
||||
if (stretchy) {
|
||||
ensureCapacity(end);
|
||||
} else if (end > data.length) {
|
||||
throwBounds();
|
||||
return;
|
||||
}
|
||||
|
||||
bytes.getBytes(data, writeAt);
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void write(byte[] bytes, int offset, int length) {
|
||||
int writeAt = cursor;
|
||||
int end = writeAt + length;
|
||||
int bytesEnd = offset + length;
|
||||
|
||||
// twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)
|
||||
if (((offset | length | end) < 0) || (bytesEnd > bytes.length)) {
|
||||
throw new IndexOutOfBoundsException("bytes.length " +
|
||||
bytes.length + "; " +
|
||||
offset + "..!" + end);
|
||||
}
|
||||
|
||||
if (stretchy) {
|
||||
ensureCapacity(end);
|
||||
} else if (end > data.length) {
|
||||
throwBounds();
|
||||
return;
|
||||
}
|
||||
|
||||
System.arraycopy(bytes, offset, data, writeAt, length);
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void write(byte[] bytes) {
|
||||
write(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeZeroes(int count) {
|
||||
if (count < 0) {
|
||||
throw new IllegalArgumentException("count < 0");
|
||||
}
|
||||
|
||||
int end = cursor + count;
|
||||
|
||||
if (stretchy) {
|
||||
ensureCapacity(end);
|
||||
} else if (end > data.length) {
|
||||
throwBounds();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* There is no need to actually write zeroes, since the array is
|
||||
* already preinitialized with zeroes.
|
||||
*/
|
||||
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void alignTo(int alignment) {
|
||||
int mask = alignment - 1;
|
||||
|
||||
if ((alignment < 0) || ((mask & alignment) != 0)) {
|
||||
throw new IllegalArgumentException("bogus alignment");
|
||||
}
|
||||
|
||||
int end = (cursor + mask) & ~mask;
|
||||
|
||||
if (stretchy) {
|
||||
ensureCapacity(end);
|
||||
} else if (end > data.length) {
|
||||
throwBounds();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* There is no need to actually write zeroes, since the array is
|
||||
* already preinitialized with zeroes.
|
||||
*/
|
||||
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean annotates() {
|
||||
return (annotations != null);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean isVerbose() {
|
||||
return verbose;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void annotate(String msg) {
|
||||
if (annotations == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
endAnnotation();
|
||||
annotations.add(new Annotation(cursor, msg));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void annotate(int amt, String msg) {
|
||||
if (annotations == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
endAnnotation();
|
||||
|
||||
int asz = annotations.size();
|
||||
int lastEnd = (asz == 0) ? 0 : annotations.get(asz - 1).getEnd();
|
||||
int startAt;
|
||||
|
||||
if (lastEnd <= cursor) {
|
||||
startAt = cursor;
|
||||
} else {
|
||||
startAt = lastEnd;
|
||||
}
|
||||
|
||||
annotations.add(new Annotation(startAt, startAt + amt, msg));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void endAnnotation() {
|
||||
if (annotations == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int sz = annotations.size();
|
||||
|
||||
if (sz != 0) {
|
||||
annotations.get(sz - 1).setEndIfUnset(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getAnnotationWidth() {
|
||||
int leftWidth = 8 + (hexCols * 2) + (hexCols / 2);
|
||||
|
||||
return annotationWidth - leftWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that this instance should keep annotations. This method may
|
||||
* be called only once per instance, and only before any data has been
|
||||
* written to the it.
|
||||
*
|
||||
* @param annotationWidth >= 40; the desired maximum annotation width
|
||||
* @param verbose whether or not to indicate verbose annotations
|
||||
*/
|
||||
public void enableAnnotations(int annotationWidth, boolean verbose) {
|
||||
if ((annotations != null) || (cursor != 0)) {
|
||||
throw new RuntimeException("cannot enable annotations");
|
||||
}
|
||||
|
||||
if (annotationWidth < 40) {
|
||||
throw new IllegalArgumentException("annotationWidth < 40");
|
||||
}
|
||||
|
||||
int hexCols = (((annotationWidth - 7) / 15) + 1) & ~1;
|
||||
if (hexCols < 6) {
|
||||
hexCols = 6;
|
||||
} else if (hexCols > 10) {
|
||||
hexCols = 10;
|
||||
}
|
||||
|
||||
this.annotations = new ArrayList<Annotation>(1000);
|
||||
this.annotationWidth = annotationWidth;
|
||||
this.hexCols = hexCols;
|
||||
this.verbose = verbose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes up annotation processing. This closes off any open
|
||||
* annotations and removes annotations that don't refer to written
|
||||
* data.
|
||||
*/
|
||||
public void finishAnnotating() {
|
||||
// Close off the final annotation, if any.
|
||||
endAnnotation();
|
||||
|
||||
// Remove annotations that refer to unwritten data.
|
||||
if (annotations != null) {
|
||||
int asz = annotations.size();
|
||||
while (asz > 0) {
|
||||
Annotation last = annotations.get(asz - 1);
|
||||
if (last.getStart() > cursor) {
|
||||
annotations.remove(asz - 1);
|
||||
asz--;
|
||||
} else if (last.getEnd() > cursor) {
|
||||
last.setEnd(cursor);
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws the excpetion for when an attempt is made to write past the
|
||||
* end of the instance.
|
||||
*/
|
||||
private static void throwBounds() {
|
||||
throw new IndexOutOfBoundsException("attempt to write past the end");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reallocates the underlying array if necessary. Calls to this method
|
||||
* should be guarded by a test of {@link #stretchy}.
|
||||
*
|
||||
* @param desiredSize >= 0; the desired minimum total size of the array
|
||||
*/
|
||||
private void ensureCapacity(int desiredSize) {
|
||||
if (data.length < desiredSize) {
|
||||
byte[] newData = new byte[desiredSize * 2 + 1000];
|
||||
System.arraycopy(data, 0, newData, 0, cursor);
|
||||
data = newData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Annotation on output.
|
||||
*/
|
||||
private static class Annotation {
|
||||
/** >= 0; start of annotated range (inclusive) */
|
||||
private final int start;
|
||||
|
||||
/**
|
||||
* >= 0; end of annotated range (exclusive);
|
||||
* <code>Integer.MAX_VALUE</code> if unclosed
|
||||
*/
|
||||
private int end;
|
||||
|
||||
/** non-null; annotation text */
|
||||
private final String text;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param start >= 0; start of annotated range
|
||||
* @param end >= start; end of annotated range (exclusive) or
|
||||
* <code>Integer.MAX_VALUE</code> if unclosed
|
||||
* @param text non-null; annotation text
|
||||
*/
|
||||
public Annotation(int start, int end, String text) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance. It is initally unclosed.
|
||||
*
|
||||
* @param start >= 0; start of annotated range
|
||||
* @param text non-null; annotation text
|
||||
*/
|
||||
public Annotation(int start, String text) {
|
||||
this(start, Integer.MAX_VALUE, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the end as given, but only if the instance is unclosed;
|
||||
* otherwise, do nothing.
|
||||
*
|
||||
* @param end >= start; the end
|
||||
*/
|
||||
public void setEndIfUnset(int end) {
|
||||
if (this.end == Integer.MAX_VALUE) {
|
||||
this.end = end;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the end as given.
|
||||
*
|
||||
* @param end >= start; the end
|
||||
*/
|
||||
public void setEnd(int end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the start.
|
||||
*
|
||||
* @return the start
|
||||
*/
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the end.
|
||||
*
|
||||
* @return the end
|
||||
*/
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text.
|
||||
*
|
||||
* @return non-null; the text
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
143
src/main/java/org/JesusFreke/dexlib/util/EncodedValueUtils.java
Normal file
143
src/main/java/org/JesusFreke/dexlib/util/EncodedValueUtils.java
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
public class EncodedValueUtils {
|
||||
public static byte getRequiredBytesForSignedIntegralValue(long value) {
|
||||
/*
|
||||
* Figure out how many bits are needed to represent the value,
|
||||
* including a sign bit: The bit count is subtracted from 65
|
||||
* and not 64 to account for the sign bit. The xor operation
|
||||
* has the effect of leaving non-negative values alone and
|
||||
* unary complementing negative values (so that a leading zero
|
||||
* count always returns a useful number for our present
|
||||
* purpose).
|
||||
*/
|
||||
int requiredBits =
|
||||
65 - Long.numberOfLeadingZeros(value ^ (value >> 63));
|
||||
|
||||
// Round up the requiredBits to a number of bytes.
|
||||
return (byte)((requiredBits + 0x07) >> 3);
|
||||
}
|
||||
|
||||
public static long decodeSignedIntegralValue(byte[] bytes) {
|
||||
long value = 0;
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
value |= (((long)(bytes[i] & 0xFF)) << (i * 8));
|
||||
}
|
||||
|
||||
int shift = (8 - bytes.length) * 8;
|
||||
return value << shift >> shift;
|
||||
}
|
||||
|
||||
public static byte[] encodeSignedIntegralValue(long value) {
|
||||
int requiredBytes = getRequiredBytesForSignedIntegralValue(value);
|
||||
|
||||
byte[] bytes = new byte[requiredBytes];
|
||||
|
||||
for (int i = 0; i < requiredBytes; i++) {
|
||||
bytes[i] = (byte) value;
|
||||
value >>= 8;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static byte getRequiredBytesForUnsignedIntegralValue(long value) {
|
||||
// Figure out how many bits are needed to represent the value.
|
||||
int requiredBits = 64 - Long.numberOfLeadingZeros(value);
|
||||
if (requiredBits == 0) {
|
||||
requiredBits = 1;
|
||||
}
|
||||
|
||||
// Round up the requiredBits to a number of bytes.
|
||||
return (byte)((requiredBits + 0x07) >> 3);
|
||||
}
|
||||
|
||||
public static long decodeUnsignedIntegralValue(byte[] bytes) {
|
||||
long value = 0;
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
value |= (((long)(bytes[i] & 0xFF)) << i * 8);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static byte[] encodeUnsignedIntegralValue(long value) {
|
||||
int requiredBytes = getRequiredBytesForUnsignedIntegralValue(value);
|
||||
|
||||
byte[] bytes = new byte[requiredBytes];
|
||||
|
||||
for (int i = 0; i < requiredBytes; i++) {
|
||||
bytes[i] = (byte) value;
|
||||
value >>= 8;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static int getRequiredBytesForRightZeroExtendedValue(long value) {
|
||||
// Figure out how many bits are needed to represent the value.
|
||||
int requiredBits = 64 - Long.numberOfTrailingZeros(value);
|
||||
if (requiredBits == 0) {
|
||||
requiredBits = 1;
|
||||
}
|
||||
|
||||
// Round up the requiredBits to a number of bytes.
|
||||
return (requiredBits + 0x07) >> 3;
|
||||
}
|
||||
|
||||
public static long decodeRightZeroExtendedValue(byte[] bytes) {
|
||||
long value = 0;
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
value |= (((long)(bytes[i] & 0xFF)) << (i * 8));
|
||||
}
|
||||
return value << (8 - bytes.length) * 8;
|
||||
}
|
||||
|
||||
public static byte[] encodeRightZeroExtendedValue(long value) {
|
||||
int requiredBytes = getRequiredBytesForRightZeroExtendedValue(value);
|
||||
|
||||
// Scootch the first bits to be written down to the low-order bits.
|
||||
value >>= 64 - (requiredBytes * 8);
|
||||
|
||||
byte[] bytes = new byte[requiredBytes];
|
||||
|
||||
for(int i = 0; i < requiredBytes; i++) {
|
||||
bytes[i] = (byte)value;
|
||||
value >>= 8;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Exception which carries around structured context.
|
||||
*/
|
||||
public class ExceptionWithContext
|
||||
extends RuntimeException {
|
||||
/** non-null; human-oriented context of the exception */
|
||||
private StringBuffer context;
|
||||
|
||||
/**
|
||||
* Augments the given exception with the given context, and return the
|
||||
* result. The result is either the given exception if it was an
|
||||
* {@link ExceptionWithContext}, or a newly-constructed exception if it
|
||||
* was not.
|
||||
*
|
||||
* @param ex non-null; the exception to augment
|
||||
* @param str non-null; context to add
|
||||
* @return non-null; an appropriate instance
|
||||
*/
|
||||
public static ExceptionWithContext withContext(Throwable ex, String str) {
|
||||
ExceptionWithContext ewc;
|
||||
|
||||
if (ex instanceof ExceptionWithContext) {
|
||||
ewc = (ExceptionWithContext) ex;
|
||||
} else {
|
||||
ewc = new ExceptionWithContext(ex);
|
||||
}
|
||||
|
||||
ewc.addContext(str);
|
||||
return ewc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param message human-oriented message
|
||||
*/
|
||||
public ExceptionWithContext(String message) {
|
||||
this(message, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param cause null-ok; exception that caused this one
|
||||
*/
|
||||
public ExceptionWithContext(Throwable cause) {
|
||||
this(null, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param message human-oriented message
|
||||
* @param cause null-ok; exception that caused this one
|
||||
*/
|
||||
public ExceptionWithContext(String message, Throwable cause) {
|
||||
super((message != null) ? message :
|
||||
(cause != null) ? cause.getMessage() : null,
|
||||
cause);
|
||||
|
||||
if (cause instanceof ExceptionWithContext) {
|
||||
String ctx = ((ExceptionWithContext) cause).context.toString();
|
||||
context = new StringBuffer(ctx.length() + 200);
|
||||
context.append(ctx);
|
||||
} else {
|
||||
context = new StringBuffer(200);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void printStackTrace(PrintStream out) {
|
||||
super.printStackTrace(out);
|
||||
out.println(context);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void printStackTrace(PrintWriter out) {
|
||||
super.printStackTrace(out);
|
||||
out.println(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a line of context to this instance.
|
||||
*
|
||||
* @param str non-null; new context
|
||||
*/
|
||||
public void addContext(String str) {
|
||||
if (str == null) {
|
||||
throw new NullPointerException("str == null");
|
||||
}
|
||||
|
||||
context.append(str);
|
||||
if (!str.endsWith("\n")) {
|
||||
context.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the context.
|
||||
*
|
||||
* @return non-null; the context
|
||||
*/
|
||||
public String getContext() {
|
||||
return context.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message and context.
|
||||
*
|
||||
* @param out non-null; where to print to
|
||||
*/
|
||||
public void printContext(PrintStream out) {
|
||||
out.println(getMessage());
|
||||
out.print(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the message and context.
|
||||
*
|
||||
* @param out non-null; where to print to
|
||||
*/
|
||||
public void printContext(PrintWriter out) {
|
||||
out.println(getMessage());
|
||||
out.print(context);
|
||||
}
|
||||
}
|
92
src/main/java/org/JesusFreke/dexlib/util/FileUtils.java
Normal file
92
src/main/java/org/JesusFreke/dexlib/util/FileUtils.java
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* File I/O utilities.
|
||||
*/
|
||||
public final class FileUtils {
|
||||
/**
|
||||
* This class is uninstantiable.
|
||||
*/
|
||||
private FileUtils() {
|
||||
// This space intentionally left blank.
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the named file, translating {@link IOException} to a
|
||||
* {@link RuntimeException} of some sort.
|
||||
*
|
||||
* @param fileName non-null; name of the file to read
|
||||
* @return non-null; contents of the file
|
||||
*/
|
||||
public static byte[] readFile(String fileName) {
|
||||
File file = new File(fileName);
|
||||
return readFile(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the given file, translating {@link IOException} to a
|
||||
* {@link RuntimeException} of some sort.
|
||||
*
|
||||
* @param file non-null; the file to read
|
||||
* @return non-null; contents of the file
|
||||
*/
|
||||
public static byte[] readFile(File file) {
|
||||
if (!file.exists()) {
|
||||
throw new RuntimeException(file + ": file not found");
|
||||
}
|
||||
|
||||
if (!file.isFile()) {
|
||||
throw new RuntimeException(file + ": not a file");
|
||||
}
|
||||
|
||||
if (!file.canRead()) {
|
||||
throw new RuntimeException(file + ": file not readable");
|
||||
}
|
||||
|
||||
long longLength = file.length();
|
||||
int length = (int) longLength;
|
||||
if (length != longLength) {
|
||||
throw new RuntimeException(file + ": file too long");
|
||||
}
|
||||
|
||||
byte[] result = new byte[length];
|
||||
|
||||
try {
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
int at = 0;
|
||||
while (length > 0) {
|
||||
int amt = in.read(result, at, length);
|
||||
if (amt == -1) {
|
||||
throw new RuntimeException(file + ": unexpected EOF");
|
||||
}
|
||||
at += amt;
|
||||
length -= amt;
|
||||
}
|
||||
in.close();
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(file + ": trouble reading", ex);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
303
src/main/java/org/JesusFreke/dexlib/util/Hex.java
Normal file
303
src/main/java/org/JesusFreke/dexlib/util/Hex.java
Normal file
@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
/**
|
||||
* Utilities for formatting numbers as hexadecimal.
|
||||
*/
|
||||
public final class Hex {
|
||||
/**
|
||||
* This class is uninstantiable.
|
||||
*/
|
||||
private Hex() {
|
||||
// This space intentionally left blank.
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a <code>long</code> as an 8-byte unsigned hex value.
|
||||
*
|
||||
* @param v value to format
|
||||
* @return non-null; formatted form
|
||||
*/
|
||||
public static String u8(long v) {
|
||||
char[] result = new char[16];
|
||||
for (int i = 0; i < 16; i++) {
|
||||
result[15 - i] = Character.forDigit((int) v & 0x0f, 16);
|
||||
v >>= 4;
|
||||
}
|
||||
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an <code>int</code> as a 4-byte unsigned hex value.
|
||||
*
|
||||
* @param v value to format
|
||||
* @return non-null; formatted form
|
||||
*/
|
||||
public static String u4(int v) {
|
||||
char[] result = new char[8];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
result[7 - i] = Character.forDigit(v & 0x0f, 16);
|
||||
v >>= 4;
|
||||
}
|
||||
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an <code>int</code> as a 3-byte unsigned hex value.
|
||||
*
|
||||
* @param v value to format
|
||||
* @return non-null; formatted form
|
||||
*/
|
||||
public static String u3(int v) {
|
||||
char[] result = new char[6];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
result[5 - i] = Character.forDigit(v & 0x0f, 16);
|
||||
v >>= 4;
|
||||
}
|
||||
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an <code>int</code> as a 2-byte unsigned hex value.
|
||||
*
|
||||
* @param v value to format
|
||||
* @return non-null; formatted form
|
||||
*/
|
||||
public static String u2(int v) {
|
||||
char[] result = new char[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
result[3 - i] = Character.forDigit(v & 0x0f, 16);
|
||||
v >>= 4;
|
||||
}
|
||||
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an <code>int</code> as either a 2-byte unsigned hex value
|
||||
* (if the value is small enough) or a 4-byte unsigned hex value (if
|
||||
* not).
|
||||
*
|
||||
* @param v value to format
|
||||
* @return non-null; formatted form
|
||||
*/
|
||||
public static String u2or4(int v) {
|
||||
if (v == (char) v) {
|
||||
return u2(v);
|
||||
} else {
|
||||
return u4(v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an <code>int</code> as a 1-byte unsigned hex value.
|
||||
*
|
||||
* @param v value to format
|
||||
* @return non-null; formatted form
|
||||
*/
|
||||
public static String u1(int v) {
|
||||
char[] result = new char[2];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
result[1 - i] = Character.forDigit(v & 0x0f, 16);
|
||||
v >>= 4;
|
||||
}
|
||||
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an <code>int</code> as a 4-bit unsigned hex nibble.
|
||||
*
|
||||
* @param v value to format
|
||||
* @return non-null; formatted form
|
||||
*/
|
||||
public static String uNibble(int v) {
|
||||
char[] result = new char[1];
|
||||
|
||||
result[0] = Character.forDigit(v & 0x0f, 16);
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a <code>long</code> as an 8-byte signed hex value.
|
||||
*
|
||||
* @param v value to format
|
||||
* @return non-null; formatted form
|
||||
*/
|
||||
public static String s8(long v) {
|
||||
char[] result = new char[17];
|
||||
|
||||
if (v < 0) {
|
||||
result[0] = '-';
|
||||
v = -v;
|
||||
} else {
|
||||
result[0] = '+';
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
result[16 - i] = Character.forDigit((int) v & 0x0f, 16);
|
||||
v >>= 4;
|
||||
}
|
||||
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an <code>int</code> as a 4-byte signed hex value.
|
||||
*
|
||||
* @param v value to format
|
||||
* @return non-null; formatted form
|
||||
*/
|
||||
public static String s4(int v) {
|
||||
char[] result = new char[9];
|
||||
|
||||
if (v < 0) {
|
||||
result[0] = '-';
|
||||
v = -v;
|
||||
} else {
|
||||
result[0] = '+';
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
result[8 - i] = Character.forDigit(v & 0x0f, 16);
|
||||
v >>= 4;
|
||||
}
|
||||
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an <code>int</code> as a 2-byte signed hex value.
|
||||
*
|
||||
* @param v value to format
|
||||
* @return non-null; formatted form
|
||||
*/
|
||||
public static String s2(int v) {
|
||||
char[] result = new char[5];
|
||||
|
||||
if (v < 0) {
|
||||
result[0] = '-';
|
||||
v = -v;
|
||||
} else {
|
||||
result[0] = '+';
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
result[4 - i] = Character.forDigit(v & 0x0f, 16);
|
||||
v >>= 4;
|
||||
}
|
||||
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an <code>int</code> as a 1-byte signed hex value.
|
||||
*
|
||||
* @param v value to format
|
||||
* @return non-null; formatted form
|
||||
*/
|
||||
public static String s1(int v) {
|
||||
char[] result = new char[3];
|
||||
|
||||
if (v < 0) {
|
||||
result[0] = '-';
|
||||
v = -v;
|
||||
} else {
|
||||
result[0] = '+';
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
result[2 - i] = Character.forDigit(v & 0x0f, 16);
|
||||
v >>= 4;
|
||||
}
|
||||
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a hex dump of a portion of a <code>byte[]</code>. The result
|
||||
* is always newline-terminated, unless the passed-in length was zero,
|
||||
* in which case the result is always the empty string (<code>""</code>).
|
||||
*
|
||||
* @param arr non-null; array to format
|
||||
* @param offset >= 0; offset to the part to dump
|
||||
* @param length >= 0; number of bytes to dump
|
||||
* @param outOffset >= 0; first output offset to print
|
||||
* @param bpl >= 0; number of bytes of output per line
|
||||
* @param addressLength {2,4,6,8}; number of characters for each address
|
||||
* header
|
||||
* @return non-null; a string of the dump
|
||||
*/
|
||||
public static String dump(byte[] arr, int offset, int length,
|
||||
int outOffset, int bpl, int addressLength) {
|
||||
int end = offset + length;
|
||||
|
||||
// twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)
|
||||
if (((offset | length | end) < 0) || (end > arr.length)) {
|
||||
throw new IndexOutOfBoundsException("arr.length " +
|
||||
arr.length + "; " +
|
||||
offset + "..!" + end);
|
||||
}
|
||||
|
||||
if (outOffset < 0) {
|
||||
throw new IllegalArgumentException("outOffset < 0");
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuffer sb = new StringBuffer(length * 4 + 6);
|
||||
boolean bol = true;
|
||||
int col = 0;
|
||||
|
||||
while (length > 0) {
|
||||
if (col == 0) {
|
||||
String astr;
|
||||
switch (addressLength) {
|
||||
case 2: astr = Hex.u1(outOffset); break;
|
||||
case 4: astr = Hex.u2(outOffset); break;
|
||||
case 6: astr = Hex.u3(outOffset); break;
|
||||
default: astr = Hex.u4(outOffset); break;
|
||||
}
|
||||
sb.append(astr);
|
||||
sb.append(": ");
|
||||
} else if ((col & 1) == 0) {
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append(Hex.u1(arr[offset]));
|
||||
outOffset++;
|
||||
offset++;
|
||||
col++;
|
||||
if (col == bpl) {
|
||||
sb.append('\n');
|
||||
col = 0;
|
||||
}
|
||||
length--;
|
||||
}
|
||||
|
||||
if (col != 0) {
|
||||
sb.append('\n');
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
149
src/main/java/org/JesusFreke/dexlib/util/Input.java
Normal file
149
src/main/java/org/JesusFreke/dexlib/util/Input.java
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
/**
|
||||
* Interface for a source for binary input. This is similar to
|
||||
* <code>java.util.DataInput</code>, but no <code>IOExceptions</code>
|
||||
* are declared, and multibyte input is defined to be little-endian.
|
||||
*/
|
||||
public interface Input {
|
||||
/**
|
||||
* Gets the current cursor position. This is the same as the number of
|
||||
* bytes read from this instance.
|
||||
*
|
||||
* @return >= 0; the cursor position
|
||||
*/
|
||||
public int getCursor();
|
||||
|
||||
/**
|
||||
* Sets the current cursor position.
|
||||
*
|
||||
* @return >= 0; the cursor position
|
||||
*/
|
||||
public void setCursor(int cursor);
|
||||
|
||||
/**
|
||||
* Asserts that the cursor is the given value.
|
||||
*
|
||||
* @param expectedCursor the expected cursor value
|
||||
* @throws RuntimeException thrown if <code>getCursor() !=
|
||||
* expectedCursor</code>
|
||||
*/
|
||||
public void assertCursor(int expectedCursor);
|
||||
|
||||
/**
|
||||
* Reads a <code>byte</code> from this instance.
|
||||
*
|
||||
* @return the byte value that was read
|
||||
*/
|
||||
public byte readByte();
|
||||
|
||||
/**
|
||||
* Reads a <code>short</code> from this instance.
|
||||
*
|
||||
* @return the short value that was read, as an int
|
||||
*/
|
||||
public int readShort();
|
||||
|
||||
/**
|
||||
* Reads an <code>int</code> from this instance.
|
||||
*
|
||||
* @return the unsigned int value that was read
|
||||
*/
|
||||
public int readInt();
|
||||
|
||||
/**
|
||||
* Reads a <code>long</code> from this instance.
|
||||
*
|
||||
* @return the long value that was read
|
||||
*/
|
||||
public long readLong();
|
||||
|
||||
|
||||
/**
|
||||
* Reads a DWARFv3-style signed LEB128 integer. For details,
|
||||
* see the "Dalvik Executable Format" document or DWARF v3 section
|
||||
* 7.6.
|
||||
*
|
||||
* @return the integer value that was read
|
||||
*/
|
||||
public int readSignedLeb128();
|
||||
|
||||
/**
|
||||
* Reads a DWARFv3-style unsigned LEB128 integer. For details,
|
||||
* see the "Dalvik Executable Format" document or DWARF v3 section
|
||||
* 7.6.
|
||||
*
|
||||
* @return the integer value that was read
|
||||
*/
|
||||
public int readUnsignedLeb128();
|
||||
|
||||
/**
|
||||
* reads a <code>byte[]</code> from this instance.
|
||||
*
|
||||
* @param bytes non-null; the buffer to read the data into
|
||||
* @param offset >= 0; offset into <code>bytes</code> for the first
|
||||
* byte to write
|
||||
* @param length >= 0; number of bytes to read
|
||||
*/
|
||||
public void read(byte[] bytes, int offset, int length);
|
||||
|
||||
/**
|
||||
* reads a <code>byte[]</code> from this instance. This is just
|
||||
* a convenient shorthand for <code>read(bytes, 0, bytes.length)</code>.
|
||||
*
|
||||
* @param bytes non-null; the buffer to read the data into
|
||||
*/
|
||||
public void read(byte[] bytes);
|
||||
|
||||
|
||||
/**
|
||||
* reads a <code>byte[]</code> from this instance
|
||||
*
|
||||
* @param length >= 0; number of bytes to read
|
||||
* @return a byte array containing <code>length</code> bytes
|
||||
*/
|
||||
public byte[] readBytes(int length);
|
||||
|
||||
/**
|
||||
* Skips the given number of bytes.
|
||||
*
|
||||
* @param count >= 0; the number of bytes to skip
|
||||
*/
|
||||
public void skipBytes(int count);
|
||||
|
||||
/**
|
||||
* Skip extra bytes if necessary to force alignment of the output
|
||||
* cursor as given.
|
||||
*
|
||||
* @param alignment > 0; the alignment; must be a power of two
|
||||
*/
|
||||
public void alignTo(int alignment);
|
||||
}
|
78
src/main/java/org/JesusFreke/dexlib/util/Leb128Utils.java
Normal file
78
src/main/java/org/JesusFreke/dexlib/util/Leb128Utils.java
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
/**
|
||||
* LEB128 (little-endian base 128) utilities.
|
||||
*/
|
||||
public final class Leb128Utils {
|
||||
/**
|
||||
* This class is uninstantiable.
|
||||
*/
|
||||
private Leb128Utils() {
|
||||
// This space intentionally left blank.
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of bytes in the unsigned LEB128 encoding of the
|
||||
* given value.
|
||||
*
|
||||
* @param value the value in question
|
||||
* @return its write size, in bytes
|
||||
*/
|
||||
public static int unsignedLeb128Size(int value) {
|
||||
// TODO: This could be much cleverer.
|
||||
|
||||
int remaining = value >> 7;
|
||||
int count = 0;
|
||||
|
||||
while (remaining != 0) {
|
||||
value = remaining;
|
||||
remaining >>= 7;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of bytes in the signed LEB128 encoding of the
|
||||
* given value.
|
||||
*
|
||||
* @param value the value in question
|
||||
* @return its write size, in bytes
|
||||
*/
|
||||
public static int signedLeb128Size(int value) {
|
||||
// TODO: This could be much cleverer.
|
||||
|
||||
int remaining = value >> 7;
|
||||
int count = 0;
|
||||
boolean hasMore = true;
|
||||
int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;
|
||||
|
||||
while (hasMore) {
|
||||
hasMore = (remaining != end)
|
||||
|| ((remaining & 1) != ((value >> 6) & 1));
|
||||
|
||||
value = remaining;
|
||||
remaining >>= 7;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
129
src/main/java/org/JesusFreke/dexlib/util/Output.java
Normal file
129
src/main/java/org/JesusFreke/dexlib/util/Output.java
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
/**
|
||||
* Interface for a sink for binary output. This is similar to
|
||||
* <code>java.util.DataOutput</code>, but no <code>IOExceptions</code>
|
||||
* are declared, and multibyte output is defined to be little-endian.
|
||||
*/
|
||||
public interface Output {
|
||||
/**
|
||||
* Gets the current cursor position. This is the same as the number of
|
||||
* bytes written to this instance.
|
||||
*
|
||||
* @return >= 0; the cursor position
|
||||
*/
|
||||
public int getCursor();
|
||||
|
||||
/**
|
||||
* Asserts that the cursor is the given value.
|
||||
*
|
||||
* @param expectedCursor the expected cursor value
|
||||
* @throws RuntimeException thrown if <code>getCursor() !=
|
||||
* expectedCursor</code>
|
||||
*/
|
||||
public void assertCursor(int expectedCursor);
|
||||
|
||||
/**
|
||||
* Writes a <code>byte</code> to this instance.
|
||||
*
|
||||
* @param value the value to write; all but the low 8 bits are ignored
|
||||
*/
|
||||
public void writeByte(int value);
|
||||
|
||||
/**
|
||||
* Writes a <code>short</code> to this instance.
|
||||
*
|
||||
* @param value the value to write; all but the low 16 bits are ignored
|
||||
*/
|
||||
public void writeShort(int value);
|
||||
|
||||
/**
|
||||
* Writes an <code>int</code> to this instance.
|
||||
*
|
||||
* @param value the value to write
|
||||
*/
|
||||
public void writeInt(int value);
|
||||
|
||||
/**
|
||||
* Writes a <code>long</code> to this instance.
|
||||
*
|
||||
* @param value the value to write
|
||||
*/
|
||||
public void writeLong(long value);
|
||||
|
||||
/**
|
||||
* Writes a DWARFv3-style unsigned LEB128 integer. For details,
|
||||
* see the "Dalvik Executable Format" document or DWARF v3 section
|
||||
* 7.6.
|
||||
*
|
||||
* @param value value to write, treated as an unsigned value
|
||||
* @return 1..5; the number of bytes actually written
|
||||
*/
|
||||
public int writeUnsignedLeb128(int value);
|
||||
|
||||
/**
|
||||
* Writes a DWARFv3-style unsigned LEB128 integer. For details,
|
||||
* see the "Dalvik Executable Format" document or DWARF v3 section
|
||||
* 7.6.
|
||||
*
|
||||
* @param value value to write
|
||||
* @return 1..5; the number of bytes actually written
|
||||
*/
|
||||
public int writeSignedLeb128(int value);
|
||||
|
||||
/**
|
||||
* Writes a {@link ByteArray} to this instance.
|
||||
*
|
||||
* @param bytes non-null; the array to write
|
||||
*/
|
||||
public void write(ByteArray bytes);
|
||||
|
||||
/**
|
||||
* Writes a portion of a <code>byte[]</code> to this instance.
|
||||
*
|
||||
* @param bytes non-null; the array to write
|
||||
* @param offset >= 0; offset into <code>bytes</code> for the first
|
||||
* byte to write
|
||||
* @param length >= 0; number of bytes to write
|
||||
*/
|
||||
public void write(byte[] bytes, int offset, int length);
|
||||
|
||||
/**
|
||||
* Writes a <code>byte[]</code> to this instance. This is just
|
||||
* a convenient shorthand for <code>write(bytes, 0, bytes.length)</code>.
|
||||
*
|
||||
* @param bytes non-null; the array to write
|
||||
*/
|
||||
public void write(byte[] bytes);
|
||||
|
||||
/**
|
||||
* Writes the given number of <code>0</code> bytes.
|
||||
*
|
||||
* @param count >= 0; the number of zeroes to write
|
||||
*/
|
||||
public void writeZeroes(int count);
|
||||
|
||||
/**
|
||||
* Adds extra bytes if necessary (with value <code>0</code>) to
|
||||
* force alignment of the output cursor as given.
|
||||
*
|
||||
* @param alignment > 0; the alignment; must be a power of two
|
||||
*/
|
||||
public void alignTo(int alignment);
|
||||
}
|
63
src/main/java/org/JesusFreke/dexlib/util/TypeUtils.java
Normal file
63
src/main/java/org/JesusFreke/dexlib/util/TypeUtils.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 Ben Gruver
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.JesusFreke.dexlib.util;
|
||||
|
||||
import org.JesusFreke.dexlib.EncodedValue.EncodedValueSubFieldFactory;
|
||||
import org.JesusFreke.dexlib.EncodedValue.ValueType;
|
||||
import org.JesusFreke.dexlib.EncodedValue.EncodedValueSubField;
|
||||
import org.JesusFreke.dexlib.DexFile;
|
||||
|
||||
public class TypeUtils
|
||||
{
|
||||
public static EncodedValueSubField makeDefaultValueForType(DexFile dexFile, String type) {
|
||||
switch (type.charAt(0)) {
|
||||
case 'Z':
|
||||
return EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, ValueType.VALUE_BOOLEAN);
|
||||
case 'B':
|
||||
return EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, ValueType.VALUE_BYTE);
|
||||
case 'S':
|
||||
return EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, ValueType.VALUE_SHORT);
|
||||
case 'C':
|
||||
return EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, ValueType.VALUE_CHAR);
|
||||
case 'I':
|
||||
return EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, ValueType.VALUE_INT);
|
||||
case 'J':
|
||||
return EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, ValueType.VALUE_LONG);
|
||||
case 'F':
|
||||
return EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, ValueType.VALUE_FLOAT);
|
||||
case 'D':
|
||||
return EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, ValueType.VALUE_DOUBLE);
|
||||
case 'L':
|
||||
case '[':
|
||||
//TODO: is the default value for array types null or an empty array?
|
||||
return EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, ValueType.VALUE_NULL);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user