mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 20:20: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