Started to clean up the code:
- remove BuffHandle/Buff classes
- use logger
- remove all non necessary stuff

See ya !
This commit is contained in:
totoag 2022-06-30 21:10:31 +02:00
parent 8d091cbb30
commit 56faaa7135
539 changed files with 372 additions and 4614 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "libraries/axplorer"]
path = libraries/axplorer
url = https://github.com/reddr/axplorer.git

View File

@ -21,7 +21,7 @@ Androguard is a full python tool to play with Android files.
* Android's binary xml
* Android resources
* Disassemble DEX/ODEX bytecodes
* Decompiler for DEX/ODEX files
* Basic Decompiler for DEX/ODEX files
## Authors: Androguard Team
@ -60,7 +60,7 @@ You are using Androguard and are not listed here? Just create a [ticket](https:/
### Androguard
Copyright (C) 2012 - 2016, Anthony Desnos (desnos at t0t0.fr)
Copyright (C) 2012 - 2022, Anthony Desnos (desnos at t0t0.fr)
All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,4 +1,4 @@
# The current version of Androguard
# Please use only this variable in any scripts,
# to keep the version number the same everywhere.
__version__ = "3.4.0a1"
__version__ = "4.0"

View File

@ -1 +0,0 @@

View File

@ -1,8 +1,10 @@
# Androguard
from androguard.core import androconf
from androguard.util import read, get_certificate_name_string
from androguard.core.bytecodes.axml import ARSCParser, AXMLPrinter, ARSCResTableConfig, AXMLParser, format_value, START_TAG, END_TAG, TEXT, END_DOCUMENT
from androguard.core.axml import ARSCParser, AXMLPrinter, ARSCResTableConfig, AXMLParser, format_value, START_TAG, END_TAG, TEXT, END_DOCUMENT
# Python core
import io
from zlib import crc32
import os
@ -13,13 +15,17 @@ import logging
from struct import unpack
import hashlib
import warnings
import sys
# External dependecies
from loguru import logger
import lxml.sax
from xml.dom.pulldom import SAX2DOM
# Used for reading Certificates
from asn1crypto import cms, x509, keys
logger.add(sys.stderr, format="{time} {level} {message}", filter="apk", level="INFO")
NS_ANDROID_URI = 'http://schemas.android.com/apk/res/android'
NS_ANDROID = '{{{}}}'.format(NS_ANDROID_URI) # Namespace as used by etree
@ -236,7 +242,7 @@ class APK:
"""
if magic_file:
log.warning("You set magic_file but this parameter is actually unused. You should remove it.")
logger.warning("You set magic_file but this parameter is actually unused. You should remove it.")
self.filename = filename
@ -272,7 +278,7 @@ class APK:
self.zip = zipfile.ZipFile(filename, mode="r")
if testzip:
log.info("Testing zip file integrity, this might take a while...")
logger.info("Testing zip file integrity, this might take a while...")
# Test the zipfile for integrity before continuing.
# This process might be slow, as the whole file is read.
# Therefore it is possible to enable it as a separate feature.
@ -306,27 +312,27 @@ class APK:
extracted from the Manifest.
"""
i = "AndroidManifest.xml"
log.info("Starting analysis on {}".format(i))
logger.info("Starting analysis on {}".format(i))
try:
manifest_data = self.zip.read(i)
except KeyError:
log.warning("Missing AndroidManifest.xml. Is this an APK file?")
logger.warning("Missing AndroidManifest.xml. Is this an APK file?")
else:
ap = AXMLPrinter(manifest_data)
if not ap.is_valid():
log.error("Error while parsing AndroidManifest.xml - is the file valid?")
logger.error("Error while parsing AndroidManifest.xml - is the file valid?")
return
self.axml[i] = ap
self.xml[i] = self.axml[i].get_xml_obj()
if self.axml[i].is_packed():
log.warning("XML Seems to be packed, operations on the AndroidManifest.xml might fail.")
logger.warning("XML Seems to be packed, operations on the AndroidManifest.xml might fail.")
if self.xml[i] is not None:
if self.xml[i].tag != "manifest":
log.error("AndroidManifest.xml does not start with a <manifest> tag! Is this a valid APK?")
logger.error("AndroidManifest.xml does not start with a <manifest> tag! Is this a valid APK?")
return
self.package = self.get_attribute_value("manifest", "package")
@ -363,7 +369,7 @@ class APK:
self.declared_permissions[d_perm_name] = d_perm_details
self.valid_apk = True
log.info("APK file was successfully validated!")
logger.info("APK file was successfully validated!")
self.permission_module = androconf.load_api_specific_resource_module(
"aosp_permissions", self.get_target_sdk_version())
@ -418,7 +424,7 @@ class APK:
try:
maxSdkVersion = int(self.get_value_from_tag(item, "maxSdkVersion"))
except ValueError:
log.warning(self.get_max_sdk_version() + 'is not a valid value for <uses-permission> maxSdkVersion')
logger.warning(self.get_max_sdk_version() + 'is not a valid value for <uses-permission> maxSdkVersion')
except TypeError:
pass
return maxSdkVersion
@ -469,7 +475,7 @@ class APK:
if app_name is None:
# No App name set
# TODO return packagename instead?
log.warning("It looks like that no app name is set for the main activity!")
logger.warning("It looks like that no app name is set for the main activity!")
return ""
if app_name.startswith("@"):
@ -486,12 +492,12 @@ class APK:
if package == 'android':
# TODO: we can not resolve this, as we lack framework-res.apk
# one exception would be when parsing framework-res.apk directly.
log.warning("Resource ID with android package name encountered! "
logger.warning("Resource ID with android package name encountered! "
"Will not resolve, framework-res.apk would be required.")
return app_name
else:
# TODO should look this up, might be in the resources
log.warning("Resource ID with Package name '{}' encountered! Will not resolve".format(package))
logger.warning("Resource ID with Package name '{}' encountered! Will not resolve".format(package))
return app_name
try:
@ -586,7 +592,7 @@ class APK:
app_icon = file_name
current_dpi = dpi
except Exception as e:
log.warning("Exception selecting app icon: %s" % e)
logger.warning("Exception selecting app icon: %s" % e)
return app_icon
@ -2167,8 +2173,10 @@ def get_apkid(apkfile):
hex value that starts with @).
"""
logger.debug("GET_APKID")
if not os.path.exists(apkfile):
log.error("'{apkfile}' does not exist!".format(apkfile=apkfile))
logger.error("'{apkfile}' does not exist!".format(apkfile=apkfile))
appid = None
versionCode = None

View File

@ -1,7 +1,5 @@
from androguard.core import bytecode
from androguard.core.resources import public
from androguard.core.bytecodes.axml.types import *
from .types import *
from struct import pack, unpack
from xml.sax.saxutils import escape
@ -9,13 +7,14 @@ import collections
from collections import defaultdict
from lxml import etree
from loguru import logger
import logging
import re
import sys
import binascii
import io
import sys
log = logging.getLogger("androguard.axml")
logger.add(sys.stderr, format="{time} {level} {message}", filter="axml", level="INFO")
# Constants for ARSC Files
# see http://androidxref.com/9.0.0_r3/xref/frameworks/base/libs/androidfw/include/androidfw/ResourceTypes.h#215
@ -128,7 +127,7 @@ class StringBlock:
# Check if they supplied a stylesOffset even if the count is 0:
if self.styleCount == 0 and self.stylesOffset > 0:
log.info("Styles Offset given, but styleCount is zero. "
logger.info("Styles Offset given, but styleCount is zero. "
"This is not a problem but could indicate packers.")
self.m_stringOffsets = []
@ -155,7 +154,7 @@ class StringBlock:
size = self.stylesOffset - self.stringsOffset
if (size % 4) != 0:
log.warning("Size of strings is not aligned by four bytes.")
logger.warning("Size of strings is not aligned by four bytes.")
self.m_charbuff = buff.read(size)
@ -163,7 +162,7 @@ class StringBlock:
size = self.header.size - self.stylesOffset
if (size % 4) != 0:
log.warning("Size of styles is not aligned by four bytes.")
logger.warning("Size of styles is not aligned by four bytes.")
for i in range(0, size // 4):
self.m_styles.append(unpack('<I', buff.read(4))[0])
@ -279,7 +278,7 @@ class StringBlock:
"""
string = data.decode(encoding, 'replace')
if len(string) != str_len:
log.warning("invalid decoded string length")
logger.warning("invalid decoded string length")
return string
def _decode_length(self, offset, sizeof_char):
@ -371,29 +370,32 @@ class AXMLParser:
See http://androidxref.com/9.0.0_r3/xref/frameworks/base/libs/androidfw/include/androidfw/ResourceTypes.h#563
"""
def __init__(self, raw_buff):
logger.info("AXMLParser")
self._reset()
self._valid = True
self.axml_tampered = False
self.buff = bytecode.BuffHandle(raw_buff)
self.buff = io.BufferedReader(io.BytesIO(raw_buff))
self.buff_size = self.buff.raw.getbuffer().nbytes
# Minimum is a single ARSCHeader, which would be a strange edge case...
if self.buff.size() < 8:
log.error("Filesize is too small to be a valid AXML file! Filesize: {}".format(self.buff.size()))
if self.buff_size < 8:
logger.error("Filesize is too small to be a valid AXML file! Filesize: {}".format(self.buff.size()))
self._valid = False
return
# This would be even stranger, if an AXML file is larger than 4GB...
# But this is not possible as the maximum chunk size is a unsigned 4 byte int.
if self.buff.size() > 0xFFFFFFFF:
log.error("Filesize is too large to be a valid AXML file! Filesize: {}".format(self.buff.size()))
if self.buff_size > 0xFFFFFFFF:
logger.error("Filesize is too large to be a valid AXML file! Filesize: {}".format(self.buff.size()))
self._valid = False
return
try:
axml_header = ARSCHeader(self.buff)
except ResParserError as e:
log.error("Error parsing first resource header: %s", e)
logger.error("Error parsing first resource header: %s", e)
self._valid = False
return
@ -402,29 +404,29 @@ class AXMLParser:
if axml_header.header_size == 28024:
# Can be a common error: the file is not an AXML but a plain XML
# The file will then usually start with '<?xm' / '3C 3F 78 6D'
log.warning("Header size is 28024! Are you trying to parse a plain XML file?")
logger.warning("Header size is 28024! Are you trying to parse a plain XML file?")
if axml_header.header_size != 8:
log.error("This does not look like an AXML file. header size does not equal 8! header size = {}".format(axml_header.header_size))
logger.error("This does not look like an AXML file. header size does not equal 8! header size = {}".format(axml_header.header_size))
self._valid = False
return
if self.filesize > self.buff.size():
log.error("This does not look like an AXML file. Declared filesize does not match real size: {} vs {}".format(self.filesize, self.buff.size()))
if self.filesize > self.buff_size:
logger.error("This does not look like an AXML file. Declared filesize does not match real size: {} vs {}".format(self.filesize, self.buff.size()))
self._valid = False
return
if self.filesize < self.buff.size():
if self.filesize < self.buff_size:
# The file can still be parsed up to the point where the chunk should end.
self.axml_tampered = True
log.warning("Declared filesize ({}) is smaller than total file size ({}). "
logger.warning("Declared filesize ({}) is smaller than total file size ({}). "
"Was something appended to the file? Trying to parse it anyways.".format(self.filesize, self.buff.size()))
# Not that severe of an error, we have plenty files where this is not
# set correctly
if axml_header.type != RES_XML_TYPE:
self.axml_tampered = True
log.warning("AXML file has an unusual resource type! "
logger.warning("AXML file has an unusual resource type! "
"Malware likes to to such stuff to anti androguard! "
"But we try to parse it anyways. Resource Type: 0x{:04x}".format(axml_header.type))
@ -432,12 +434,12 @@ class AXMLParser:
try:
header = ARSCHeader(self.buff, expected_type=RES_STRING_POOL_TYPE)
except ResParserError as e:
log.error("Error parsing resource header of string pool: %s", e)
logger.error("Error parsing resource header of string pool: %s", e)
self._valid = False
return
if header.header_size != 0x1C:
log.error("This does not look like an AXML file. String chunk header size does not equal 28! header size = {}".format(header.header_size))
logger.error("This does not look like an AXML file. String chunk header size does not equal 28! header size = {}".format(header.header_size))
self._valid = False
return
@ -455,6 +457,7 @@ class AXMLParser:
if an error happend somewhere in the process of parsing the file,
this flag is set to False.
"""
logger.debug(self._valid)
return self._valid
def _reset(self):
@ -478,7 +481,7 @@ class AXMLParser:
self._reset()
while self._valid:
# Stop at the declared filesize or at the end of the file
if self.buff.end() or self.buff.get_idx() == self.filesize:
if self.buff.tell() == self.filesize:
self.m_event = END_DOCUMENT
break
@ -486,18 +489,18 @@ class AXMLParser:
try:
h = ARSCHeader(self.buff)
except ResParserError as e:
log.error("Error parsing resource header: %s", e)
logger.error("Error parsing resource header: %s", e)
self._valid = False
return
# Special chunk: Resource Map. This chunk might be contained inside
# the file, after the string pool.
if h.type == RES_XML_RESOURCE_MAP_TYPE:
log.debug("AXML contains a RESOURCE MAP")
logger.debug("AXML contains a RESOURCE MAP")
# Check size: < 8 bytes mean that the chunk is not complete
# Should be aligned to 4 bytes.
if h.size < 8 or (h.size % 4) != 0:
log.error("Invalid chunk size in chunk XML_RESOURCE_MAP")
logger.error("Invalid chunk size in chunk XML_RESOURCE_MAP")
self._valid = False
return
@ -512,13 +515,13 @@ class AXMLParser:
# h.size is the size of the whole chunk including the header.
# We read already 8 bytes of the header, thus we need to
# subtract them.
log.error("Not a XML resource chunk type: 0x{:04x}. Skipping {} bytes".format(h.type, h.size))
self.buff.set_idx(h.end)
logger.error("Not a XML resource chunk type: 0x{:04x}. Skipping {} bytes".format(h.type, h.size))
self.buff.seek(h.end)
continue
# Check that we read a correct header
if h.header_size != 0x10:
log.error("XML Resource Type Chunk header size does not match 16! " \
logger.error("XML Resource Type Chunk header size does not match 16! " \
"At chunk type 0x{:04x}, declared header size={}, chunk size={}".format(h.type, h.header_size, h.size))
self._valid = False
return
@ -530,7 +533,7 @@ class AXMLParser:
self.m_comment_index, = unpack('<L', self.buff.read(4))
if self.m_comment_index != 0xFFFFFFFF and h.type in [RES_XML_START_NAMESPACE_TYPE, RES_XML_END_NAMESPACE_TYPE]:
log.warning("Unhandled Comment at namespace chunk: '{}'".format(self.sb[self.m_comment_index]))
logger.warning("Unhandled Comment at namespace chunk: '{}'".format(self.sb[self.m_comment_index]))
if h.type == RES_XML_START_NAMESPACE_TYPE:
prefix, = unpack('<L', self.buff.read(4))
@ -539,14 +542,14 @@ class AXMLParser:
s_prefix = self.sb[prefix]
s_uri = self.sb[uri]
log.debug("Start of Namespace mapping: prefix {}: '{}' --> uri {}: '{}'".format(prefix, s_prefix, uri, s_uri))
logger.debug("Start of Namespace mapping: prefix {}: '{}' --> uri {}: '{}'".format(prefix, s_prefix, uri, s_uri))
if s_uri == '':
log.warning("Namespace prefix '{}' resolves to empty URI. "
logger.warning("Namespace prefix '{}' resolves to empty URI. "
"This might be a packer.".format(s_prefix))
if (prefix, uri) in self.namespaces:
log.info("Namespace mapping ({}, {}) already seen! "
logger.info("Namespace mapping ({}, {}) already seen! "
"This is usually not a problem but could indicate packers or broken AXML compilers.".format(prefix, uri))
self.namespaces.append((prefix, uri))
@ -563,7 +566,7 @@ class AXMLParser:
if (prefix, uri) in self.namespaces:
self.namespaces.remove((prefix, uri))
else:
log.warning("Reached a NAMESPACE_END without having the namespace stored before? "
logger.warning("Reached a NAMESPACE_END without having the namespace stored before? "
"Prefix ID: {}, URI ID: {}".format(prefix, uri))
# We can continue with the next chunk, as we store the namespace
@ -640,7 +643,7 @@ class AXMLParser:
# For now, we ingore these values
size, res0, dataType, data = unpack("<HBBL", self.buff.read(8))
log.debug("found a CDATA Chunk: "
logger.debug("found a CDATA Chunk: "
"index={: 6d}, size={: 4d}, res0={: 4d}, dataType={: 4d}, data={: 4d}".format(self.m_name,
size,
res0,
@ -651,8 +654,8 @@ class AXMLParser:
break
# Still here? Looks like we read an unknown XML header, try to skip it...
log.warning("Unknown XML Chunk: 0x{:04x}, skipping {} bytes.".format(h.type, h.size))
self.buff.set_idx(h.end)
logger.warning("Unknown XML Chunk: 0x{:04x}, skipping {} bytes.".format(h.type, h.size))
self.buff.seek(h.end)
@property
def name(self):
@ -753,11 +756,11 @@ class AXMLParser:
Return the start inside the m_attributes array for a given attribute
"""
if self.m_event != START_TAG:
log.warning("Current event is not START_TAG.")
logger.warning("Current event is not START_TAG.")
offset = index * ATTRIBUTE_LENGHT
if offset >= len(self.m_attributes):
log.warning("Invalid attribute index")
logger.warning("Invalid attribute index")
return offset
@ -775,6 +778,8 @@ class AXMLParser:
"""
Returns the numeric ID for the namespace URI of an attribute
"""
logger.debug(index)
offset = self._get_attribute_offset(index)
uri = self.m_attributes[offset + ATTRIBUTE_IX_NAMESPACE_URI]
@ -784,6 +789,8 @@ class AXMLParser:
"""
Return the Namespace URI (if any) for the attribute
"""
logger.debug(index)
uri = self.getAttributeUri(index)
# No Namespace
@ -796,6 +803,7 @@ class AXMLParser:
"""
Returns the String which represents the attribute name
"""
logger.debug(index)
offset = self._get_attribute_offset(index)
name = self.m_attributes[offset + ATTRIBUTE_IX_NAME]
@ -818,6 +826,8 @@ class AXMLParser:
:param index: index of the attribute
"""
logger.debug(index)
offset = self._get_attribute_offset(index)
return self.m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]
@ -827,6 +837,8 @@ class AXMLParser:
:param index: index of the attribute
"""
logger.debug(index)
offset = self._get_attribute_offset(index)
return self.m_attributes[offset + ATTRIBUTE_IX_VALUE_DATA]
@ -839,6 +851,8 @@ class AXMLParser:
:param index: index of the attribute
:return:
"""
logger.debug(index)
offset = self._get_attribute_offset(index)
valueType = self.m_attributes[offset + ATTRIBUTE_IX_VALUE_TYPE]
if valueType == TYPE_STRING:
@ -929,11 +943,11 @@ class AXMLPrinter:
comment = self.axml.comment
if comment:
if self.root is None:
log.warning("Can not attach comment with content '{}' without root!".format(comment))
logger.warning("Can not attach comment with content '{}' without root!".format(comment))
else:
cur[-1].append(etree.Comment(comment))
log.debug("START_TAG: {} (line={})".format(tag, self.axml.m_lineNumber))
logger.debug("START_TAG: {} (line={})".format(tag, self.axml.m_lineNumber))
elem = etree.Element(tag, nsmap=self.axml.nsmap)
for i in range(self.axml.getAttributeCount()):
@ -941,9 +955,9 @@ class AXMLPrinter:
uri, name = self._fix_name(uri, self.axml.getAttributeName(i))
value = self._fix_value(self._get_attribute_value(i))
log.debug("found an attribute: {}{}='{}'".format(uri, name, value.encode("utf-8")))
logger.debug("found an attribute: {}{}='{}'".format(uri, name, value.encode("utf-8")))
if "{}{}".format(uri, name) in elem.attrib:
log.warning("Duplicate attribute '{}{}'! Will overwrite!".format(uri, name))
logger.warning("Duplicate attribute '{}{}'! Will overwrite!".format(uri, name))
elem.set("{}{}".format(uri, name), value)
if self.root is None:
@ -951,28 +965,28 @@ class AXMLPrinter:
else:
if not cur:
# looks like we lost the root?
log.error("No more elements available to attach to! Is the XML malformed?")
logger.error("No more elements available to attach to! Is the XML malformed?")
break
cur[-1].append(elem)
cur.append(elem)
if _type == END_TAG:
if not cur:
log.warning("Too many END_TAG! No more elements available to attach to!")
logger.warning("Too many END_TAG! No more elements available to attach to!")
name = self.axml.name
uri = self._print_namespace(self.axml.namespace)
tag = "{}{}".format(uri, name)
if cur[-1].tag != tag:
log.warning("Closing tag '{}' does not match current stack! At line number: {}. Is the XML malformed?".format(self.axml.name, self.axml.m_lineNumber))
logger.warning("Closing tag '{}' does not match current stack! At line number: {}. Is the XML malformed?".format(self.axml.name, self.axml.m_lineNumber))
cur.pop()
if _type == TEXT:
log.debug("TEXT for {}".format(cur[-1]))
logger.debug("TEXT for {}".format(cur[-1]))
cur[-1].text = self.axml.text
if _type == END_DOCUMENT:
# Check if all namespace mappings are closed
if len(self.axml.namespaces) > 0:
log.warning("Not all namespace mappings were closed! Malformed AXML?")
logger.warning("Not all namespace mappings were closed! Malformed AXML?")
break
def get_buff(self):
@ -1055,13 +1069,13 @@ class AXMLPrinter:
:rtype: tuple
"""
if not name[0].isalpha() and name[0] != "_":
log.warning("Invalid start for name '{}'. "
logger.warning("Invalid start for name '{}'. "
"XML name must start with a letter.".format(name))
self.packerwarning = True
name = "_{}".format(name)
if name.startswith("android:") and prefix == '' and 'android' in self.axml.nsmap:
# Seems be a common thing...
log.info("Name '{}' starts with 'android:' prefix but 'android' is a known prefix. Replacing prefix.".format(name))
logger.info("Name '{}' starts with 'android:' prefix but 'android' is a known prefix. Replacing prefix.".format(name))
prefix = self._print_namespace(self.axml.nsmap['android'])
name = name[len("android:"):]
# It looks like this is some kind of packer... Not sure though.
@ -1070,15 +1084,15 @@ class AXMLPrinter:
self.packerwarning = True
embedded_prefix, new_name = name.split(":", 1)
if embedded_prefix in self.axml.nsmap:
log.info("Prefix '{}' is in namespace mapping, assume that it is a prefix.")
logger.info("Prefix '{}' is in namespace mapping, assume that it is a prefix.")
prefix = self._print_namespace(self.axml.nsmap[embedded_prefix])
name = new_name
else:
# Print out an extra warning
log.warning("Confused: name contains a unknown namespace prefix: '{}'. "
logger.warning("Confused: name contains a unknown namespace prefix: '{}'. "
"This is either a broken AXML file or some attempt to break stuff.".format(name))
if not re.match(r"^[a-zA-Z0-9._-]*$", name):
log.warning("Name '{}' contains invalid characters!".format(name))
logger.warning("Name '{}' contains invalid characters!".format(name))
self.packerwarning = True
name = re.sub(r"[^a-zA-Z0-9._-]", "_", name)
@ -1102,14 +1116,14 @@ class AXMLPrinter:
# Reading string until \x00. This is the same as aapt does.
if "\x00" in value:
self.packerwarning = True
log.warning("Null byte found in attribute value at position {}: "
logger.warning("Null byte found in attribute value at position {}: "
"Value(hex): '{}'".format(
value.find("\x00"),
binascii.hexlify(value.encode("utf-8"))))
value = value[:value.find("\x00")]
if not self.__charrange.match(value):
log.warning("Invalid character in value found. Replacing with '_'.")
logger.warning("Invalid character in value found. Replacing with '_'.")
self.packerwarning = True
value = self.__replacement.sub('_', value)
return value
@ -1207,9 +1221,10 @@ class ARSCParser:
"""
:param bytes raw_buff: the raw bytes of the file
"""
self.buff = bytecode.BuffHandle(raw_buff)
self.buff = io.BufferedReader(io.BytesIO(raw_buff))
self.buff_size = self.buff.raw.getbuffer().nbytes
if self.buff.size() < 8 or self.buff.size() > 0xFFFFFFFF:
if self.buff_size < 8 or self.buff_size > 0xFFFFFFFF:
raise ResParserError("Invalid file size {} for a resources.arsc file!".format(self.buff.size()))
self.analyzed = False
@ -1226,43 +1241,43 @@ class ARSCParser:
# More sanity checks...
if self.header.header_size != 12:
log.warning("The ResTable_header has an unexpected header size! Expected 12 bytes, got {}.".format(self.header.header_size))
logger.warning("The ResTable_header has an unexpected header size! Expected 12 bytes, got {}.".format(self.header.header_size))
if self.header.size > self.buff.size():
raise ResParserError("The file seems to be truncated. Refuse to parse the file! Filesize: {}, declared size: {}".format(self.buff.size(), self.header.size))
if self.header.size > self.buff_size:
raise ResParserError("The file seems to be truncated. Refuse to parse the file! Filesize: {}, declared size: {}".format(self.buff_size, self.header.size))
if self.header.size < self.buff.size():
log.warning("The Resource file seems to have data appended to it. Filesize: {}, declared size: {}".format(self.buff.size(), self.header.size))
if self.header.size < self.buff_size:
logger.warning("The Resource file seems to have data appended to it. Filesize: {}, declared size: {}".format(self.buff_size, self.header.size))
# The ResTable_header contains the packageCount, i.e. the number of ResTable_package
self.packageCount = unpack('<I', self.buff.read(4))[0]
# Even more sanity checks...
if self.packageCount < 1:
log.warning("The number of packages is smaller than one. There should be at least one package!")
logger.warning("The number of packages is smaller than one. There should be at least one package!")
log.debug("Parsed ResTable_header with {} package(s) inside.".format(self.packageCount))
logger.debug("Parsed ResTable_header with {} package(s) inside.".format(self.packageCount))
# skip to the start of the first chunk's data, skipping trailing header bytes (there should be none)
self.buff.set_idx(self.header.start + self.header.header_size)
self.buff.seek(self.header.start + self.header.header_size)
# Now parse the data:
# We should find one ResStringPool_header and one or more ResTable_package chunks inside
while self.buff.get_idx() <= self.header.end - ARSCHeader.SIZE:
while self.buff.tell() <= self.header.end - ARSCHeader.SIZE:
res_header = ARSCHeader(self.buff)
if res_header.end > self.header.end:
# this inner chunk crosses the boundary of the table chunk
log.warning("Invalid chunk found! It is larger than the outer chunk: %s", res_header)
logger.warning("Invalid chunk found! It is larger than the outer chunk: %s", res_header)
break
if res_header.type == RES_STRING_POOL_TYPE:
# There should be only one StringPool per resource table.
if self.stringpool_main:
log.warning("Already found a ResStringPool_header, but there should be only one! Will not parse the Pool again.")
logger.warning("Already found a ResStringPool_header, but there should be only one! Will not parse the Pool again.")
else:
self.stringpool_main = StringBlock(self.buff, res_header)
log.debug("Found the main string pool: %s", self.stringpool_main)
logger.debug("Found the main string pool: %s", self.stringpool_main)
elif res_header.type == RES_TABLE_PACKAGE_TYPE:
if len(self.packages) > self.packageCount:
@ -1272,12 +1287,12 @@ class ARSCParser:
package_name = current_package.get_name()
# After the Header, we have the resource type symbol table
self.buff.set_idx(current_package.header.start + current_package.typeStrings)
self.buff.seek(current_package.header.start + current_package.typeStrings)
type_sp_header = ARSCHeader(self.buff, expected_type=RES_STRING_POOL_TYPE)
mTableStrings = StringBlock(self.buff, type_sp_header)
# Next, we should have the resource key symbol table
self.buff.set_idx(current_package.header.start + current_package.keyStrings)
self.buff.seek(current_package.header.start + current_package.keyStrings)
key_sp_header = ARSCHeader(self.buff, expected_type=RES_STRING_POOL_TYPE)
mKeyStrings = StringBlock(self.buff, key_sp_header)
@ -1287,7 +1302,7 @@ class ARSCParser:
self.packages[package_name].append(mKeyStrings)
pc = PackageContext(current_package, self.stringpool_main, mTableStrings, mKeyStrings)
log.debug("Constructed a PackageContext: %s", pc)
logger.debug("Constructed a PackageContext: %s", pc)
# skip to the first header in this table package chunk
# FIXME is this correct? We have already read the first two sections!
@ -1299,18 +1314,18 @@ class ARSCParser:
if next_idx != self.buff.tell():
# If this happens, we have a testfile ;)
log.error("This looks like an odd resources.arsc file!")
log.error("Please report this error including the file you have parsed!")
log.error("next_idx = {}, current buffer position = {}".format(next_idx, self.buff.tell()))
log.error("Please open a issue at https://github.com/androguard/androguard/issues")
log.error("Thank you!")
logger.error("This looks like an odd resources.arsc file!")
logger.error("Please report this error including the file you have parsed!")
logger.error("next_idx = {}, current buffer position = {}".format(next_idx, self.buff.tell()))
logger.error("Please open a issue at https://github.com/androguard/androguard/issues")
logger.error("Thank you!")
self.buff.set_idx(next_idx)
self.buff.seek(next_idx)
# Read all other headers
while self.buff.get_idx() <= res_header.end - ARSCHeader.SIZE:
while self.buff.tell() <= res_header.end - ARSCHeader.SIZE:
pkg_chunk_header = ARSCHeader(self.buff)
log.debug("Found a header: {}".format(pkg_chunk_header))
logger.debug("Found a header: {}".format(pkg_chunk_header))
if pkg_chunk_header.start + pkg_chunk_header.size > res_header.end:
# we are way off the package chunk; bail out
break
@ -1327,7 +1342,7 @@ class ARSCParser:
self.packages[package_name].append(a_res_type)
self.resource_configs[package_name][a_res_type].add(a_res_type.config)
log.debug("Config: {}".format(a_res_type.config))
logger.debug("Config: {}".format(a_res_type.config))
entries = []
for i in range(0, a_res_type.entryCount):
@ -1337,9 +1352,6 @@ class ARSCParser:
self.packages[package_name].append(entries)
for entry, res_id in entries:
if self.buff.end():
break
if entry != -1:
ate = ARSCResTableEntry(self.buff, res_id, pc)
self.packages[package_name].append(ate)
@ -1351,21 +1363,21 @@ class ARSCParser:
# So we do some kind of hack here. We set the idx to the entry again...
# Now we will read all entries!
# Not sure if this is a good solution though
self.buff.set_idx(ate.start)
self.buff.seek(ate.start)
elif pkg_chunk_header.type == RES_TABLE_LIBRARY_TYPE:
log.warning("RES_TABLE_LIBRARY_TYPE chunk is not supported")
logger.warning("RES_TABLE_LIBRARY_TYPE chunk is not supported")
else:
# Unknown / not-handled chunk type
log.warning("Unknown chunk type encountered inside RES_TABLE_PACKAGE: %s", pkg_chunk_header)
logger.warning("Unknown chunk type encountered inside RES_TABLE_PACKAGE: %s", pkg_chunk_header)
# skip to the next chunk
self.buff.set_idx(pkg_chunk_header.end)
self.buff.seek(pkg_chunk_header.end)
else:
# Unknown / not-handled chunk type
log.warning("Unknown chunk type encountered: %s", res_header)
logger.warning("Unknown chunk type encountered: %s", res_header)
# move to the next resource chunk
self.buff.set_idx(res_header.end)
self.buff.seek(res_header.end)
def _analyse(self):
if self.analyzed:
@ -1475,7 +1487,7 @@ class ARSCParser:
DIMENSION_UNITS[ate.key.get_data() & COMPLEX_UNIT_MASK])
]
except IndexError:
log.debug("Out of range dimension unit index for {}: {}".format(
logger.debug("Out of range dimension unit index for {}: {}".format(
complexToFloat(ate.key.get_data()),
ate.key.get_data() & COMPLEX_UNIT_MASK))
return [ate.get_value(), ate.key.get_data()]
@ -1813,7 +1825,7 @@ class ARSCParser:
# Infinite loop detection:
# TODO should this stay here or should be detect the loop much earlier?
if res_id == parent.mResId:
log.warning("Infinite loop detected at resource item {}. It references itself!".format(parent))
logger.warning("Infinite loop detected at resource item {}. It references itself!".format(parent))
return
self._resolve_into_result(result, item.get_data(), self.wanted_config)
@ -1902,7 +1914,7 @@ class ARSCParser:
raise ValueError("'rid' must be an int")
if rid not in self.resource_values:
log.warning("The requested rid '0x{:08x}' could not be found in the list of resources.".format(rid))
logger.warning("The requested rid '0x{:08x}' could not be found in the list of resources.".format(rid))
return []
res_options = self.resource_values[rid]
@ -1910,7 +1922,7 @@ class ARSCParser:
if config in res_options:
return [(config, res_options[config])]
elif fallback and config == ARSCResTableConfig.default_config():
log.warning("No default resource config could be found for the given rid '0x{:08x}', using fallback!".format(rid))
logger.warning("No default resource config could be found for the given rid '0x{:08x}', using fallback!".format(rid))
return [list(self.resource_values[rid].items())[0]]
else:
return []
@ -2074,9 +2086,9 @@ class ARSCHeader:
:param androguard.core.bytecode.BuffHandle buff: the buffer set to the position where the header starts.
:param int expected_type: the type of the header which is expected.
"""
self.start = buff.get_idx()
self.start = buff.tell()
# Make sure we do not read over the buffer:
if buff.size() < self.start + self.SIZE:
if buff.raw.getbuffer().nbytes < self.start + self.SIZE:
raise ResParserError("Can not read over the buffer size! Offset={}".format(self.start))
self._type, self._header_size, self._size = unpack('<HHL', buff.read(self.SIZE))
@ -2148,11 +2160,9 @@ class ARSCResTablePackage:
"""
def __init__(self, buff, header):
self.header = header
self.start = buff.get_idx()
self.start = buff.tell()
self.id = unpack('<I', buff.read(4))[0]
# 128 times 16bit -> read 256 bytes
# TODO why not read a null terminated string in buffer (like the meth name suggests) instead of parsing it later in get_name()?
self.name = buff.readNullString(256)
self.name = buff.read(256)
self.typeStrings = unpack('<I', buff.read(4))[0]
self.lastPublicType = unpack('<I', buff.read(4))[0]
self.keyStrings = unpack('<I', buff.read(4))[0]
@ -2170,7 +2180,7 @@ class ARSCResTypeSpec:
See http://androidxref.com/9.0.0_r3/xref/frameworks/base/libs/androidfw/include/androidfw/ResourceTypes.h#1327
"""
def __init__(self, buff, parent=None):
self.start = buff.get_idx()
self.start = buff.tell()
self.parent = parent
self.id = unpack('<B', buff.read(1))[0]
self.res0 = unpack('<B', buff.read(1))[0]
@ -2194,7 +2204,7 @@ class ARSCResType:
See http://androidxref.com/9.0.0_r3/xref/frameworks/base/libs/androidfw/include/androidfw/ResourceTypes.h#1364
"""
def __init__(self, buff, parent=None):
self.start = buff.get_idx()
self.start = buff.tell()
self.parent = parent
self.id = unpack('<B', buff.read(1))[0]
@ -2211,7 +2221,7 @@ class ARSCResType:
self.config = ARSCResTableConfig(buff)
log.debug("Parsed %s", self)
logger.debug("Parsed {}".format(self))
def get_type(self):
return self.parent.mTableStrings.getString(self.id - 1)
@ -2248,7 +2258,7 @@ class ARSCResTableConfig:
def __init__(self, buff=None, **kwargs):
if buff is not None:
self.start = buff.get_idx()
self.start = buff.tell()
# uint32_t
self.size = unpack('<I', buff.read(4))[0]
@ -2293,7 +2303,7 @@ class ARSCResTableConfig:
# uint16_t smallestScreenWidthDp
self.screenConfig, = unpack('<I', buff.read(4))
else:
log.debug("This file does not have a screenConfig! size={}".format(self.size))
logger.debug("This file does not have a screenConfig! size={}".format(self.size))
self.screenConfig = 0
if self.size >= 36:
@ -2302,7 +2312,7 @@ class ARSCResTableConfig:
# uint16_t screenHeightDp
self.screenSizeDp, = unpack('<I', buff.read(4))
else:
log.debug("This file does not have a screenSizeDp! size={}".format(self.size))
logger.debug("This file does not have a screenSizeDp! size={}".format(self.size))
self.screenSizeDp = 0
if self.size >= 40:
@ -2312,12 +2322,12 @@ class ARSCResTableConfig:
# uint16_t screenConfigPad2
self.screenConfig2, = unpack("<I", buff.read(4))
else:
log.debug("This file does not have a screenConfig2! size={}".format(self.size))
logger.debug("This file does not have a screenConfig2! size={}".format(self.size))
self.screenConfig2 = 0
self.exceedingSize = self.size - (buff.tell() - self.start)
if self.exceedingSize > 0:
log.debug("Skipping padding bytes!")
logger.debug("Skipping padding bytes!")
self.padding = buff.read(self.exceedingSize)
else:
@ -2576,7 +2586,7 @@ class ARSCResTableEntry:
FLAG_WEAK = 4
def __init__(self, buff, mResId, parent=None):
self.start = buff.get_idx()
self.start = buff.tell()
self.mResId = mResId
self.parent = parent
@ -2592,7 +2602,7 @@ class ARSCResTableEntry:
self.key = ARSCResStringPoolRef(buff, self.parent)
if self.is_weak():
log.debug("Parsed %s", self)
logger.debug("Parsed {}".format(self))
def get_index(self):
return self.index
@ -2633,7 +2643,7 @@ class ARSCComplex:
and http://androidxref.com/9.0.0_r3/xref/frameworks/base/libs/androidfw/include/androidfw/ResourceTypes.h#1498 for `ResTable_map`
"""
def __init__(self, buff, parent=None):
self.start = buff.get_idx()
self.start = buff.tell()
self.parent = parent
self.id_parent = unpack('<I', buff.read(4))[0]
@ -2658,7 +2668,7 @@ class ARSCResStringPoolRef:
See: http://androidxref.com/9.0.0_r3/xref/frameworks/base/libs/androidfw/include/androidfw/ResourceTypes.h#262
"""
def __init__(self, buff, parent=None):
self.start = buff.get_idx()
self.start = buff.tell()
self.parent = parent
self.size, = unpack("<H", buff.read(2))

View File

@ -6,7 +6,7 @@ import json
import logging
from androguard.core.androconf import CONF, color_range
from androguard.core.bytecodes.dvm_types import Kind, Operand
from androguard.core.dex.dvm_types import Kind, Operand
log = logging.getLogger("androguard.bytecode")
@ -696,184 +696,6 @@ def object_to_bytes(obj):
return obj.get_raw()
class BuffHandle:
"""
BuffHandle is a wrapper around bytes.
It gives the ability to jump in the byte stream, just like with BytesIO.
"""
def __init__(self, buff):
self.__buff = bytearray(buff)
self.__idx = 0
def __getitem__(self, item):
"""
Get the byte at the position `item`
:param int item: offset in the buffer
:returns: byte at the position
:rtype: int
"""
return self.__buff[item]
def __len__(self):
return self.size()
def size(self):
"""
Get the total size of the buffer
:rtype: int
"""
return len(self.__buff)
def length_buff(self):
"""
Alias for :meth:`size`
"""
return self.size()
def set_idx(self, idx):
"""
Set the current offset in the buffer
:param int idx: offset to set
"""
self.__idx = idx
def get_idx(self):
"""
Get the current offset in the buffer
:rtype: int
"""
return self.__idx
def add_idx(self, idx):
"""
Advance the current offset by `idx`
:param int idx: number of bytes to advance
"""
self.__idx += idx
def tell(self):
"""
Alias for :meth:`get_idx`.
:rtype: int
"""
return self.__idx
def readNullString(self, size):
"""
Read a String with length `size` at the current offset
:param int size: length of the string
:rtype: bytearray
"""
data = self.read(size)
return data
def read_b(self, size):
"""
Read bytes with length `size` without incrementing the current offset
:param int size: length to read in bytes
:rtype: bytearray
"""
return self.__buff[self.__idx:self.__idx + size]
def peek(self, size):
"""
Alias for :meth:`read_b`
"""
return self.read_b(size)
def read_at(self, offset, size):
"""
Read bytes from the given offset with length `size` without incrementing
the current offset
:param int offset: offset to start reading
:param int size: length of bytes to read
:rtype: bytearray
"""
return self.__buff[offset:offset + size]
def readat(self, off):
"""
Read all bytes from the start of `off` until the end of the buffer
This method can be used to determine a checksum of a buffer from a given
point on.
:param int off: starting offset
:rtype: bytearray
"""
return self.__buff[off:]
def read(self, size):
"""
Read from the current offset a total number of `size` bytes
and increment the offset by `size`
:param int size: length of bytes to read
:rtype: bytearray
"""
buff = self.__buff[self.__idx:self.__idx + size]
self.__idx += size
return buff
def end(self):
"""
Test if the current offset is at the end or over the buffer boundary
:rtype: bool
"""
return self.__idx >= len(self.__buff)
def get_buff(self):
"""
Return the whole buffer
:rtype: bytearray
"""
return self.__buff
def set_buff(self, buff):
"""
Overwrite the current buffer with the content of `buff`
:param bytearray buff: the new buffer
"""
self.__buff = buff
def save(self, filename):
"""
Save the current buffer to `filename`
Exisiting files with the same name will be overwritten.
:param str filename: the name of the file to save to
"""
with open(filename, "wb") as fd:
fd.write(self.__buff)
class Buff:
def __init__(self, offset, buff):
self.offset = offset
self.buff = buff
self.size = len(buff)
# Here for legacy reasons. Might get removed some day...
_Bytecode = BuffHandle
def FormatClassToJava(i):
"""
Transform a java class name into the typed variant found in DEX files.

View File

@ -1,4 +1,5 @@
import sys
import io
import re
import struct
import binascii
@ -9,13 +10,15 @@ import warnings
import zlib
import hashlib
from enum import IntEnum
from loguru import logger
from androguard.core import bytecode
from androguard.core.bytecodes.apk import APK
from androguard.core.apk import APK
from androguard.core.androconf import CONF
from androguard.util import read_at
from androguard.core import mutf8
from androguard.core.bytecodes.dvm_types import (
from .dvm_types import (
TypeMapItem,
ACCESS_FLAGS,
TYPE_DESCRIPTOR,
@ -23,10 +26,9 @@ from androguard.core.bytecodes.dvm_types import (
Operand,
)
logger.add(sys.stderr, format="{time} {level} {message}", filter="dex", level="INFO")
log = logging.getLogger("androguard.dvm")
# TODO: have some more generic magic...
DEX_FILE_MAGIC_35 = b'dex\n035\x00'
DEX_FILE_MAGIC_36 = b'dex\n036\x00'
@ -109,8 +111,8 @@ def read_null_terminated_string(f):
if 0 in z:
s = z.split(b'\x00',1)
x.append(s[0])
idx = f.get_idx()
f.set_idx(idx - len(s[1]))
idx = f.tell()
f.seek(idx - len(s[1]))
break
else:
x.append(z)
@ -230,7 +232,7 @@ def readuleb128(cm, buff):
if cur > 0x7f:
cur = get_byte(cm, buff)
if cur > 0x0f:
log.warning("possible error while decoding number")
logger.warning("possible error while decoding number")
result |= cur << 28
return result
@ -377,7 +379,7 @@ def determineNext(i, cur_idx, m):
# emit an extra nop instruction as a spacer if such an instruction would otherwise be unaligned."
padding = (off + cur_idx) % 4
if padding != 0:
log.warning("Switch payload not aligned, assume stuff and add {} bytes...".format(padding))
logger.warning("Switch payload not aligned, assume stuff and add {} bytes...".format(padding))
data = code.get_ins_off(off + cur_idx + padding)
# TODO: some malware points to invalid code
@ -387,7 +389,7 @@ def determineNext(i, cur_idx, m):
for target in data.get_targets():
x.append(target * 2 + cur_idx)
else:
log.warning("Could not determine payload of switch command at offset {} inside {}! "
logger.warning("Could not determine payload of switch command at offset {} inside {}! "
"Possibly broken bytecode?".format(cur_idx, m))
return x
@ -460,23 +462,25 @@ class HeaderItem:
Also the Adler32 checksum of the file is calculated in order to detect file
corruption.
:param buff: a string which represents a Buff object of the header_item
:type androguard.core.bytecode.BuffHandle buff: Buff object
:type io.BufferedReader buff: Buff object
:param cm: a ClassManager object
:type cm: :class:`ClassManager`
"""
def __init__(self, size, buff, cm):
logger.debug("HeaderItem")
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
if self.offset != 0:
log.warning("Unusual DEX file, does not have the header at offset 0")
logger.warning("Unusual DEX file, does not have the header at offset 0")
if len(buff) < self.get_length():
if buff.raw.getbuffer().nbytes < self.get_length():
raise ValueError("Not a DEX file, Header too small.")
self.endian_tag, = unpack('<I', buff.read_at(40, 4))
self.endian_tag, = unpack('<I', read_at(buff, 40, 4))
cm.packer = DalvikPacker(self.endian_tag)
# Q is actually wrong, but we do not change it here and unpack our own
@ -512,15 +516,15 @@ class HeaderItem:
try:
self.dex_version = int(self.magic[4:7].decode('ascii'), 10)
except (UnicodeDecodeError, ValueError):
log.warning("Wrong DEX version: {}, trying to parse anyways".format(repr(self.magic)))
logger.warning("Wrong DEX version: {}, trying to parse anyways".format(repr(self.magic)))
self.dex_version = 35 # assume a common version...
if zlib.adler32(buff.readat(self.offset + 12)) != self.checksum:
if zlib.adler32(read_at(buff, self.offset + 12)) != self.checksum:
raise ValueError("Wrong Adler32 checksum for DEX file!")
if self.file_size != buff.size():
if self.file_size != buff.raw.getbuffer().nbytes:
# Maybe raise an error here too...
log.warning("DEX file size is different to the buffer. Trying to parse anyways.")
logger.warning("DEX file size is different to the buffer. Trying to parse anyways.")
if self.header_size != 0x70:
raise ValueError("This is not a DEX file! Wrong header size: '{}'".format(self.header_size))
@ -532,7 +536,7 @@ class HeaderItem:
raise ValueError("DEX file contains too many ({}) PROTO_IDs to be valid!".format(self.proto_ids_size))
if self.data_size % 4 != 0:
log.warning("data_size is not a multiple of sizeof(uint32_t), but try to parse anyways.")
logger.warning("data_size is not a multiple of sizeof(uint32_t), but try to parse anyways.")
self.map_off_obj = None
self.string_off_obj = None
@ -700,14 +704,14 @@ class AnnotationSetItem:
This class can parse an annotation_set_item of a dex file
:param buff: a string which represents a Buff object of the annotation_set_item
:type androguard.core.bytecode.BuffHandle buff: Buff object
:type io.BufferedReader buff: Buff object
:param cm: a ClassManager object
:type cm: :class:`ClassManager`
"""
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.size, = cm.packer["I"].unpack(buff.read(4))
self.annotation_off_item = [AnnotationOffItem(buff, cm) for _ in range(self.size)]
@ -796,7 +800,7 @@ class AnnotationSetRefList:
"""
def __init__(self, buff, cm):
self.offset = buff.get_idx()
self.offset = buff.tell()
self.CM = cm
self.size, = cm.packer["I"].unpack(buff.read(4))
@ -843,7 +847,7 @@ class FieldAnnotation:
"""
def __init__(self, buff, cm):
self.offset = buff.get_idx()
self.offset = buff.tell()
self.CM = cm
self.field_idx, self.annotations_off = cm.packer["2I"].unpack(buff.read(8))
@ -900,7 +904,7 @@ class MethodAnnotation:
"""
def __init__(self, buff, cm):
self.offset = buff.get_idx()
self.offset = buff.tell()
self.CM = cm
self.method_idx, \
@ -958,7 +962,7 @@ class ParameterAnnotation:
"""
def __init__(self, buff, cm):
self.offset = buff.get_idx()
self.offset = buff.tell()
self.CM = cm
self.method_idx, \
@ -1018,7 +1022,7 @@ class AnnotationsDirectoryItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.class_annotations_off, \
self.annotated_fields_size, \
@ -1170,14 +1174,14 @@ class HiddenApiClassDataItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.section_size, = cm.packer["I"].unpack(buff.read(4))
# Find the end of the offsets array (first non-zero offset entry is the start of `flags`)
offsets_size = 0
i = 0
while buff.get_idx() - self.offset < self.section_size:
while buff.tell() - self.offset < self.section_size:
if offsets_size != 0 and i >= offsets_size:
break
offset, = cm.packer["I"].unpack(buff.read(4))
@ -1302,7 +1306,7 @@ class TypeList:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.size, = cm.packer["I"].unpack(buff.read(4))
self.list = [TypeItem(buff, cm) for _ in range(self.size)]
@ -1423,7 +1427,7 @@ class DebugInfoItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.line_start = readuleb128(cm, buff)
self.parameters_size = readuleb128(cm, buff)
@ -1505,10 +1509,11 @@ class DebugInfoItem:
i.show()
def get_raw(self):
return [bytecode.Buff(self.__offset, writeuleb128(self.CM, self.line_start) + \
writeuleb128(self.CM, self.parameters_size) + \
b''.join(writeuleb128(self.CM, i) for i in self.parameter_names) + \
b''.join(i.get_raw() for i in self.bytecodes))]
pass
#return [bytecode.Buff(self.__offset, writeuleb128(self.CM, self.line_start) + \
# writeuleb128(self.CM, self.parameters_size) + \
# b''.join(writeuleb128(self.CM, i) for i in self.parameter_names) + \
# b''.join(i.get_raw() for i in self.bytecodes))]
def get_off(self):
return self.offset
@ -1518,7 +1523,7 @@ class DebugInfoItemEmpty:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.__buff = buff
self.__raw = ""
@ -1535,10 +1540,10 @@ class DebugInfoItemEmpty:
n = self.CM.get_next_offset_item(offset)
s_idx = self.__buff.get_idx()
self.__buff.set_idx(offset)
s_idx = self.__buff.tell()
self.__buff.seek(offset)
self.__raw = self.__buff.read(n - offset)
self.__buff.set_idx(s_idx)
self.__buff.seek(s_idx)
def show(self):
pass
@ -1565,7 +1570,7 @@ class EncodedArray:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.size = readuleb128(cm, buff)
@ -1667,7 +1672,7 @@ class EncodedValue:
else:
self.value = False
else:
log.warning("Unknown value 0x%x" % self.value_type)
logger.warning("Unknown value 0x%x" % self.value_type)
def get_value(self):
"""
@ -1725,7 +1730,7 @@ class AnnotationElement:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.name_idx = readuleb128(cm, buff)
self.value = EncodedValue(buff, cm)
@ -1773,7 +1778,7 @@ class EncodedAnnotation:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.type_idx = readuleb128(cm, buff)
self.size = readuleb128(cm, buff)
@ -1841,7 +1846,7 @@ class AnnotationItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.visibility = get_byte(cm, buff)
self.annotation = EncodedAnnotation(buff, cm)
@ -1896,7 +1901,7 @@ class EncodedArrayItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.value = EncodedArray(buff, cm)
def get_value(self):
@ -1950,7 +1955,7 @@ class StringDataItem:
python you ca use :meth:`get` which escapes invalid characters.
:param buff: a string which represents a Buff object of the string_data_item
:type buff: BuffHandle
:type buff: io.io.BufferedReader
:param cm: a ClassManager object
:type cm: :class:`ClassManager`
"""
@ -1958,7 +1963,7 @@ class StringDataItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
# Content of string_data_item
self.utf16_size = readuleb128(cm, buff)
@ -2031,7 +2036,7 @@ class StringIdItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.string_data_off, = cm.packer["I"].unpack(buff.read(4))
@ -2079,7 +2084,7 @@ class TypeIdItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.descriptor_idx, = cm.packer["I"].unpack(buff.read(4))
self.descriptor_idx_value = self.CM.get_string(self.descriptor_idx)
@ -2128,7 +2133,7 @@ class TypeHIdItem:
def __init__(self, size, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.type = [TypeIdItem(buff, cm) for i in range(0,size)]
@ -2182,7 +2187,7 @@ class ProtoIdItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.shorty_idx, \
self.return_type_idx, \
@ -2287,7 +2292,7 @@ class ProtoHIdItem:
def __init__(self, size, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.proto = [ProtoIdItem(buff, cm) for i in range(0, size)]
@ -2333,7 +2338,7 @@ class FieldIdItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.class_idx, \
self.type_idx, \
@ -2448,7 +2453,7 @@ class FieldHIdItem:
"""
def __init__(self, size, buff, cm):
self.offset = buff.get_idx()
self.offset = buff.tell()
self.elem = [FieldIdItem(buff, cm) for i in range(0, size)]
@ -2499,7 +2504,7 @@ class MethodIdItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.class_idx, \
self.proto_idx, \
@ -2627,7 +2632,7 @@ class MethodHIdItem:
def __init__(self, size, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.methods = [MethodIdItem(buff, cm) for i in range(0, size)]
@ -2735,7 +2740,7 @@ class EncodedField:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.field_idx_diff = readuleb128(cm, buff)
self.access_flags = readuleb128(cm, buff)
@ -2905,7 +2910,7 @@ class EncodedMethod:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.method_idx_diff = readuleb128(cm, buff) #: method index diff in the corresponding section
self.access_flags = readuleb128(cm, buff) #: access flags of the method
@ -3361,7 +3366,7 @@ class EncodedMethod:
:type idx: int
"""
if self.code is not None:
self.code.set_idx(idx)
self.code.seek(idx)
def set_name(self, value):
self.CM.set_hook_method_name(self, value)
@ -3391,7 +3396,7 @@ class ClassDataItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.static_fields_size = readuleb128(cm, buff)
self.instance_fields_size = readuleb128(cm, buff)
@ -3596,7 +3601,7 @@ class ClassDefItem:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.class_idx, \
self.access_flags, \
@ -3886,17 +3891,17 @@ class ClassHDefItem:
def __init__(self, size, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.class_def = []
for i in range(0, size):
idx = buff.get_idx()
idx = buff.tell()
class_def = ClassDefItem(buff, cm)
self.class_def.append(class_def)
buff.set_idx(idx + calcsize("8I"))
buff.seek(idx + calcsize("8I"))
def set_off(self, off):
self.offset = off
@ -3999,7 +4004,7 @@ class EncodedCatchHandler:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.size = readsleb128(cm, buff)
@ -4089,7 +4094,7 @@ class EncodedCatchHandlerList:
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.size = readuleb128(cm, buff)
self.list = [EncodedCatchHandler(buff, cm) for _ in range(self.size)]
@ -6414,7 +6419,7 @@ class LinearSweepAlgorithm:
"""
Yields all instructions for the given bytecode sequence.
If unknown/corrupt/unused instructions are encountered,
the loop will stop and an error is written to the log.
the loop will stop and an error is written to the logger.
That means that the bytecode read might be corrupt
or was crafted in this way, to break parsers.
@ -6431,7 +6436,7 @@ class LinearSweepAlgorithm:
max_idx = size * calcsize('H')
if max_idx > len(insn):
log.warning("Declared size of instructions is larger than the bytecode!")
logger.warning("Declared size of instructions is larger than the bytecode!")
max_idx = len(insn)
# Get instructions
@ -6457,7 +6462,7 @@ class LinearSweepAlgorithm:
obj = get_instruction(cm, op_value & 0xff, insn[idx:])
except InvalidInstruction as e:
# TODO somehow it would be nice to know that the parsing failed at the level of EncodedMethod or for the decompiler
log.error("Invalid instruction encountered! Stop parsing bytecode at idx %s. Message: %s", idx, e)
logger.error("Invalid instruction encountered! Stop parsing bytecode at idx %s. Message: %s", idx, e)
return
# emit instruction
yield obj
@ -6507,7 +6512,7 @@ class DCode:
self.insn = insn
self.size = len(self.insn)
def set_idx(self, idx):
def seek(self, idx):
"""
Set the start address of the buffer
@ -6648,13 +6653,13 @@ class TryItem:
This class represents the try_item format
:param buff: a raw buffer where are the try_item format
:type buff: BuffHandle
:type buff: io.BufferedReader
:param cm: the ClassManager
:type cm: ClassManager
"""
def __init__(self, buff, cm):
self.offset = buff.get_idx()
self.offset = buff.tell()
self.CM = cm
@ -6706,14 +6711,14 @@ class DalvikCode:
This class represents the instructions of a method
:param buff: a raw buffer where are the instructions
:type buff: BuffHandle
:type buff: io.BufferedReader
:param cm: the ClassManager
:type cm: :class:`ClassManager` object
"""
def __init__(self, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.registers_size, \
self.ins_size, \
@ -6724,7 +6729,7 @@ class DalvikCode:
ushort = calcsize('H')
self.code = DCode(self.CM, buff.get_idx(), self.insns_size, buff.read(self.insns_size * ushort))
self.code = DCode(self.CM, buff.tell(), self.insns_size, buff.read(self.insns_size * ushort))
if self.insns_size % 2 == 1 and self.tries_size > 0:
self.padding, = cm.packer["H"].unpack(buff.read(2))
@ -6817,19 +6822,19 @@ class DalvikCode:
"""
return self.code
def set_idx(self, idx):
self.code.set_idx(idx)
def seek(self, idx):
self.code.seek(idx)
def get_length(self):
return self.insns_size
def _begin_show(self):
log.debug("registers_size: %d" % self.registers_size)
log.debug("ins_size: %d" % self.ins_size)
log.debug("outs_size: %d" % self.outs_size)
log.debug("tries_size: %d" % self.tries_size)
log.debug("debug_info_off: %d" % self.debug_info_off)
log.debug("insns_size: %d" % self.insns_size)
logger.debug("registers_size: %d" % self.registers_size)
logger.debug("ins_size: %d" % self.ins_size)
logger.debug("outs_size: %d" % self.outs_size)
logger.debug("tries_size: %d" % self.tries_size)
logger.debug("debug_info_off: %d" % self.debug_info_off)
logger.debug("insns_size: %d" % self.insns_size)
bytecode._PrintBanner()
@ -6903,7 +6908,7 @@ class CodeItem:
def __init__(self, size, buff, cm):
self.CM = cm
self.offset = buff.get_idx()
self.offset = buff.tell()
self.code = []
self.__code_off = {}
@ -6912,9 +6917,9 @@ class CodeItem:
# As we read the DalvikCode items from the map, there might be
# padding bytes in between.
# We know, that the alignment is 4 bytes.
off = buff.get_idx()
off = buff.tell()
if off % 4 != 0:
buff.set_idx(off + (4 - (off % 4)))
buff.seek(off + (4 - (off % 4)))
x = DalvikCode(buff, cm)
self.code.append(x)
@ -6966,7 +6971,7 @@ class MapItem:
self.CM = cm
self.buff = buff
self.off = buff.get_idx()
self.off = buff.tell()
self.type = TypeMapItem(cm.packer["H"].unpack(buff.read(2))[0])
self.unused, \
@ -6994,7 +6999,7 @@ class MapItem:
return self.size
def parse(self):
log.debug("Starting parsing map_item '{}'".format(self.type.name))
logger.debug("Starting parsing map_item '{}'".format(self.type.name))
started_at = time.time()
# Not all items are aligned in the same way. Most are aligned by four bytes,
@ -7006,108 +7011,108 @@ class MapItem:
if TypeMapItem.STRING_ID_ITEM == self.type:
# Byte aligned
buff.set_idx(self.offset)
buff.seek(self.offset)
self.item = [StringIdItem(buff, cm) for _ in range(self.size)]
elif TypeMapItem.CODE_ITEM == self.type:
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
self.item = CodeItem(self.size, buff, cm)
elif TypeMapItem.TYPE_ID_ITEM == self.type:
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
self.item = TypeHIdItem(self.size, buff, cm)
elif TypeMapItem.PROTO_ID_ITEM == self.type:
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
self.item = ProtoHIdItem(self.size, buff, cm)
elif TypeMapItem.FIELD_ID_ITEM == self.type:
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
self.item = FieldHIdItem(self.size, buff, cm)
elif TypeMapItem.METHOD_ID_ITEM == self.type:
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
self.item = MethodHIdItem(self.size, buff, cm)
elif TypeMapItem.CLASS_DEF_ITEM == self.type:
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
self.item = ClassHDefItem(self.size, buff, cm)
elif TypeMapItem.HEADER_ITEM == self.type:
# FIXME probably not necessary to parse again here...
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
self.item = HeaderItem(self.size, buff, cm)
elif TypeMapItem.ANNOTATION_ITEM == self.type:
# Byte aligned
buff.set_idx(self.offset)
buff.seek(self.offset)
self.item = [AnnotationItem(buff, cm) for _ in range(self.size)]
elif TypeMapItem.ANNOTATION_SET_ITEM == self.type:
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
self.item = [AnnotationSetItem(buff, cm) for _ in range(self.size)]
elif TypeMapItem.ANNOTATIONS_DIRECTORY_ITEM == self.type:
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
self.item = [AnnotationsDirectoryItem(buff, cm) for _ in range(self.size)]
elif TypeMapItem.HIDDENAPI_CLASS_DATA_ITEM == self.type:
# Byte aligned
buff.set_idx(self.offset)
buff.seek(self.offset)
self.item = HiddenApiClassDataItem(buff, cm)
elif TypeMapItem.ANNOTATION_SET_REF_LIST == self.type:
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
self.item = [AnnotationSetRefList(buff, cm) for _ in range(self.size)]
elif TypeMapItem.TYPE_LIST == self.type:
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
self.item = [TypeList(buff, cm) for _ in range(self.size)]
elif TypeMapItem.STRING_DATA_ITEM == self.type:
# Byte aligned
buff.set_idx(self.offset)
buff.seek(self.offset)
self.item = [StringDataItem(buff, cm) for _ in range(self.size)]
elif TypeMapItem.DEBUG_INFO_ITEM == self.type:
# Byte aligned
buff.set_idx(self.offset)
buff.seek(self.offset)
self.item = DebugInfoItemEmpty(buff, cm)
elif TypeMapItem.ENCODED_ARRAY_ITEM == self.type:
# Byte aligned
buff.set_idx(self.offset)
buff.seek(self.offset)
self.item = [EncodedArrayItem(buff, cm) for _ in range(self.size)]
elif TypeMapItem.CLASS_DATA_ITEM == self.type:
# Byte aligned
buff.set_idx(self.offset)
buff.seek(self.offset)
self.item = [ClassDataItem(buff, cm) for _ in range(self.size)]
elif TypeMapItem.MAP_LIST == self.type:
# 4-byte aligned
buff.set_idx(self.offset + (self.offset % 4))
buff.seek(self.offset + (self.offset % 4))
pass # It's me I think !!! No need to parse again
else:
log.warning("Map item with id '{type}' offset: 0x{off:x} ({off}) "
logger.warning("Map item with id '{type}' offset: 0x{off:x} ({off}) "
"size: {size} is unknown. "
"Is this a newer DEX format?".format(type=self.type, off=buff.get_idx(), size=self.size))
"Is this a newer DEX format?".format(type=self.type, off=buff.tell(), size=self.size))
diff = time.time() - started_at
minutes, seconds = diff // 60, diff % 60
log.debug("End of parsing map_item '{}'. Required time {:.0f}:{:07.4f}".format(self.type.name, minutes, seconds))
logger.debug("End of parsing map_item '{}'. Required time {:.0f}:{:07.4f}".format(self.type.name, minutes, seconds))
def show(self):
bytecode._Print("\tMAP_TYPE_ITEM", self.type.name)
@ -7294,7 +7299,7 @@ class ClassManager:
def get_class_data_item(self, off):
i = self.__classdata_off.get(off)
if i is None:
log.warning("unknown class data item @ 0x%x" % off)
logger.warning("unknown class data item @ 0x%x" % off)
return i
@ -7350,13 +7355,13 @@ class ClassManager:
try:
off = self.__manage_item[TypeMapItem.STRING_ID_ITEM][idx].get_string_data_off()
except IndexError:
log.warning("unknown string item @ %d" % idx)
logger.warning("unknown string item @ %d" % idx)
return "AG:IS: invalid string"
try:
return self.__strings_off[off].get()
except KeyError:
log.warning("unknown string item @ 0x%x(%d)" % (off, idx))
logger.warning("unknown string item @ 0x%x(%d)" % (off, idx))
return "AG:IS: invalid string"
def get_type_list(self, off):
@ -7455,12 +7460,12 @@ class ClassManager:
name += "_" + bytecode.FormatDescriptorToPython(
encoded_method.get_descriptor())
log.debug("try deleting old name in python...")
logger.debug("try deleting old name in python...")
try:
delattr(class_def.M, name)
log.debug("success with regular name")
logger.debug("success with regular name")
except AttributeError:
log.debug("WARNING: fail with regular name")
logger.debug("WARNING: fail with regular name")
# python_export = False
try:
@ -7474,17 +7479,17 @@ class ClassManager:
try:
delattr(class_def.M, name)
log.debug("success with name containing prototype")
logger.debug("success with name containing prototype")
except AttributeError:
log.debug("WARNING: fail with name containing prototype")
logger.debug("WARNING: fail with name containing prototype")
python_export = False
if python_export:
name = bytecode.FormatNameToPython(value)
setattr(class_def.M, name, encoded_method)
log.debug("new name in python: created: %s." % name)
logger.debug("new name in python: created: %s." % name)
else:
log.debug("skipping creating new name in python")
logger.debug("skipping creating new name in python")
method.reload()
@ -7525,7 +7530,7 @@ class ClassManager:
return idx
def get_debug_off(self, off):
self.buff.set_idx(off)
self.buff.seek(off)
return DebugInfoItem(self.buff, self)
@ -7540,7 +7545,7 @@ class MapList:
def __init__(self, cm, off, buff):
self.CM = cm
buff.set_idx(off)
buff.seek(off)
self.offset = off
@ -7548,12 +7553,12 @@ class MapList:
self.map_item = []
for _ in range(0, self.size):
idx = buff.get_idx()
idx = buff.tell()
mi = MapItem(buff, self.CM)
self.map_item.append(mi)
buff.set_idx(idx + mi.get_length())
buff.seek(idx + mi.get_length())
load_order = TypeMapItem.determine_load_order()
ordered = sorted(self.map_item, key=lambda mi: load_order[mi.get_type()])
@ -7617,7 +7622,7 @@ class DalvikPacker:
"""
def __init__(self, endian_tag):
if endian_tag == 0x78563412:
log.error("DEX file with byte swapped endian tag is not supported!")
logger.error("DEX file with byte swapped endian tag is not supported!")
raise NotImplementedError("Byte swapped endian tag encountered!")
elif endian_tag == 0x12345678:
self.endian_tag = '<'
@ -7640,7 +7645,7 @@ class DalvikPacker:
self.__structs = {}
class DalvikVMFormat(bytecode.BuffHandle):
class DEX:
"""
This class can parse a classes.dex file of an Android application (APK).
@ -7651,10 +7656,12 @@ class DalvikVMFormat(bytecode.BuffHandle):
example::
d = DalvikVMFormat( read("classes.dex") )
d = DEX( read("classes.dex") )
"""
def __init__(self, buff, decompiler=None, config=None, using_api=None):
logger.debug("DEX {} {} {}".format(decompiler, config, using_api))
# to allow to pass apk object ==> we do not need to pass additionally target version
if isinstance(buff, APK):
self.api_version = buff.get_target_sdk_version()
@ -7664,7 +7671,8 @@ class DalvikVMFormat(bytecode.BuffHandle):
else:
self.api_version = CONF["DEFAULT_API"]
super().__init__(buff)
self.raw = io.BufferedReader(io.BytesIO(buff))
self._flush()
self.CM = ClassManager(self)
@ -7677,13 +7685,13 @@ class DalvikVMFormat(bytecode.BuffHandle):
pass
def _load(self, buff):
self.header = HeaderItem(0, self, self.CM)
self.header = HeaderItem(0, self.raw, self.CM)
if self.header.map_off == 0:
# TODO check if the header specifies items but does not have a map
log.warning("no map list! This DEX file is probably empty.")
logger.warning("no map list! This DEX file is probably empty.")
else:
self.map_list = MapList(self.CM, self.header.map_off, self)
self.map_list = MapList(self.CM, self.header.map_off, self.raw)
self.classes = self.map_list.get_item_type(TypeMapItem.CLASS_DEF_ITEM)
self.methods = self.map_list.get_item_type(TypeMapItem.METHOD_ID_ITEM)
@ -7720,14 +7728,14 @@ class DalvikVMFormat(bytecode.BuffHandle):
"""
.. deprecated:: 3.1.0
The :class:`~androguard.core.analysis.analysis.Analysis` is not
loaded anymore into :class:`DalvikVMFormat` in order to avoid
loaded anymore into :class:`DEX` in order to avoid
cyclic dependencies.
:class:`~androguard.core.analysis.analysis.Analysis` extends now
:class:`DalvikVMFormat`.
:class:`DEX`.
This Method does nothing anymore!
The Analysis Object should contain all the information required,
inclduing the DalvikVMFormats.
inclduing the DEX.
"""
warnings.warn("deprecated, this method does nothing!", DeprecationWarning)
@ -7735,14 +7743,14 @@ class DalvikVMFormat(bytecode.BuffHandle):
"""
.. deprecated:: 3.1.0
The :class:`~androguard.core.analysis.analysis.Analysis` is not
loaded anymore into :class:`DalvikVMFormat` in order to avoid
loaded anymore into :class:`DEX` in order to avoid
cyclic dependencies.
:class:`~androguard.core.analysis.analysis.Analysis` extends now
:class:`DalvikVMFormat`.
:class:`DEX`.
This Method does nothing anymore!
The Analysis Object should contain all the information required,
inclduing the DalvikVMFormats.
inclduing the DEX.
"""
warnings.warn("deprecated, this method does nothing!", DeprecationWarning)
@ -7866,9 +7874,9 @@ class DalvikVMFormat(bytecode.BuffHandle):
s[idx + length] = c_length
length += c_length
# log.debug("SAVE" + str(j) + " @ 0x%x" % (idx+length))
# logger.debug("SAVE" + str(j) + " @ 0x%x" % (idx+length))
log.debug("SAVE " + str(i[0]) + " @0x{:x} ({:x})".format(idx, length))
logger.debug("SAVE " + str(i[0]) + " @0x{:x} ({:x})".format(idx, length))
else:
if isinstance(i, MapList):
@ -7883,7 +7891,7 @@ class DalvikVMFormat(bytecode.BuffHandle):
s[idx] = length
log.debug("SAVE " + str(i) + " @0x{:x} ({:x})".format(idx, length))
logger.debug("SAVE " + str(i) + " @0x{:x} ({:x})".format(idx, length))
idx += length
@ -7905,7 +7913,7 @@ class DalvikVMFormat(bytecode.BuffHandle):
idx = h[i]
if idx != last_idx:
log.debug("Adjust alignment @{:x} with 00 {:x}".format(idx, idx - last_idx))
logger.debug("Adjust alignment @{:x} with 00 {:x}".format(idx, idx - last_idx))
buff += bytearray([0] * (idx - last_idx))
buff += i.get_raw()
@ -7913,7 +7921,7 @@ class DalvikVMFormat(bytecode.BuffHandle):
buff += b"\x00"
last_idx = idx + s[idx]
log.debug("GLOBAL SIZE %d" % len(buff))
logger.debug("GLOBAL SIZE %d" % len(buff))
return self.fix_checksums(buff)
@ -7930,8 +7938,8 @@ class DalvikVMFormat(bytecode.BuffHandle):
checksum = zlib.adler32(buff[12:])
buff = buff[:8] + self.CM.packer["I"].pack(checksum) + buff[12:]
log.debug("NEW SIGNATURE %s" % repr(signature))
log.debug("NEW CHECKSUM %x" % checksum)
logger.debug("NEW SIGNATURE %s" % repr(signature))
logger.debug("NEW CHECKSUM %x" % checksum)
return buff
@ -8354,7 +8362,7 @@ class DalvikVMFormat(bytecode.BuffHandle):
"""
for i in DCode(
self.CM, offset, size,
self.get_buff()[offset:offset + size]).get_instructions():
read_at(self.raw, offset, size)).get_instructions():
yield i
def _get_class_hierarchy(self):
@ -8508,7 +8516,7 @@ class OdexHeaderItem:
"""
def __init__(self, buff):
buff.set_idx(8)
buff.seek(8)
self.dex_offset = unpack("=I", buff.read(4))[0]
self.dex_length = unpack("=I", buff.read(4))[0]
@ -8579,7 +8587,7 @@ class OdexDependencies:
dependencies
class DalvikOdexVMFormat(DalvikVMFormat):
class ODEX(DEX):
"""
This class can parse an odex file
@ -8589,7 +8597,7 @@ class DalvikOdexVMFormat(DalvikVMFormat):
:type decompiler: object
:Example:
DalvikOdexVMFormat( read("classes.odex") )
ODEX( read("classes.odex") )
"""
def _preload(self, buff):
@ -8598,15 +8606,15 @@ class DalvikOdexVMFormat(DalvikVMFormat):
if self.magic in (ODEX_FILE_MAGIC_35, ODEX_FILE_MAGIC_36, ODEX_FILE_MAGIC_37):
self.odex_header = OdexHeaderItem(self)
self.set_idx(self.odex_header.deps_offset)
self.seek(self.odex_header.deps_offset)
self.dependencies = OdexDependencies(self)
self.padding = buff[self.odex_header.deps_offset +
self.odex_header.deps_length:]
self.set_idx(self.odex_header.dex_offset)
self.seek(self.odex_header.dex_offset)
self.set_buff(self.read(self.odex_header.dex_length))
self.set_idx(0)
self.seek(0)
def save(self):
"""

View File

@ -1,18 +1,15 @@
# External dependecies
from loguru import logger
import asn1crypto
# Functions that might be useful
# Stuff that might be useful
def read(filename, binary=True):
"""
Open and read a file
:param filename: filename to open and read
:param binary: True if the file should be read as binary
:return: bytes if binary is True, str otherwise
"""
with open(filename, 'rb' if binary else 'r') as f:
return f.read()
def read_at(buff, offset, size=-1):
idx = buff.tell()
buff.seek(offset)
d = buff.read(size)
buff.seek(idx)
return d
def get_certificate_name_string(name, short=False, delimiter=', '):
"""

View File

@ -3,17 +3,22 @@
"""Androguard is a full Python tool to play with Android files."""
# core modules
import sys
import logging
import sys, json
from loguru import logger
# 3rd party modules
import click
import androguard.core.apk
# local modules
import androguard
from androguard.core.androconf import show_logging
from androguard.cli import (androarsc_main,
from main import (androarsc_main,
androaxml_main,
androcg_main,
export_apps_to_format,
@ -23,6 +28,7 @@ from androguard.cli import (androarsc_main,
androdis_main
)
logger.add(sys.stderr, format="{time} {level} {message}", filter="cli", level="INFO")
@click.group(help=__doc__)
@click.version_option(version=androguard.__version__)
@ -30,16 +36,7 @@ from androguard.cli import (androarsc_main,
@click.option("--quiet", 'verbosity', flag_value='quiet', help="Print less (only warnings and above)")
@click.option("--silent", 'verbosity', flag_value='silent', help="Print no log messages")
def entry_point(verbosity):
level = logging.INFO
if verbosity == 'verbose':
level = logging.DEBUG
if verbosity == 'quiet':
level = logging.WARNING
# If something out of this module is imported, activate console logging
if verbosity != 'silent':
show_logging(level=level)
pass
@entry_point.command()
@ -155,17 +152,17 @@ def arsc(input_,
\b
$ androguard arsc app.apk
"""
logger.debug("ARSC")
from androguard.core import androconf
from androguard.core.bytecodes import apk
from androguard.core import axml, apk
if file_ and input_:
print("Can not give --input and positional argument! "
"Please use only one of them!",
file=sys.stderr)
logger.info("Can not give --input and positional argument! Please use only one of them!")
sys.exit(1)
if not input_ and not file_:
print("Give one file to decode!", file=sys.stderr)
logger.info("Give one file to decode!")
sys.exit(1)
if input_:
@ -178,16 +175,16 @@ def arsc(input_,
a = apk.APK(fname)
arscobj = a.get_android_resources()
if not arscobj:
print("The APK does not contain a resources file!", file=sys.stderr)
logger.error("The APK does not contain a resources file!")
sys.exit(0)
elif ret_type == "ARSC":
with open(fname, 'rb') as fp:
arscobj = apk.ARSCParser(fp.read())
arscobj = axml.ARSCParser(fp.read())
if not arscobj:
print("The resources file seems to be invalid!", file=sys.stderr)
logger.error("The resources file seems to be invalid!")
sys.exit(1)
else:
print("Unknown file type!", file=sys.stderr)
logger.error("Unknown file type!")
sys.exit(1)
if id_:
@ -435,12 +432,13 @@ def sign(hash_, print_all_hashes, show, apk):
)
def apkid(apks):
"""Return the packageName/versionCode/versionName per APK as JSON."""
import json
import logging
logging.getLogger("androguard.axml").setLevel(logging.ERROR)
from androguard.core.apk import get_apkid
logger.debug("APKID")
results = dict()
for apk in apks:
results[apk] = androguard.core.bytecodes.apk.get_apkid(apk)
results[apk] = get_apkid(apk)
print(json.dumps(results, indent=2))

Binary file not shown.

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.t0t0.androguard.TC"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name" android:icon="@drawable/icon">
<activity android:name="TCActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -1,30 +0,0 @@
<?xml version="1.0"?>
<parent id="androguard Test">
<main_path>./examples/android/TC/</main_path>
<libs_path>./libs/</libs_path>
<watermark>
<type>BM_A0</type>
<type>BM_A1</type>
<output>wm.xml</output>
</watermark>
<protect_code>
</protect_code>
<protect_names type="class">
<except_class>
<name>org/t0t0/androguard/TC/TCActivity</name>
</except_class>
<except_fields>
<class>org/t0t0/androguard/TC/TCMod1</class>
<name>TC1</name>
<descriptor>I</descriptor>
</except_fields>
</protect_names>
</parent>

Binary file not shown.

Binary file not shown.

View File

@ -1,17 +0,0 @@
# This file is used to override default values used by the Ant build system.
#
# This file must be checked in Version Control Systems, as it is
# integral to the build system of your project.
# This file is only used by the Ant script.
# You can use this to override default values such as
# 'source.dir' for the location of your java source folder and
# 'out.dir' for the location of your output folder.
# You can also use it define how the release builds are signed by declaring
# the following properties:
# 'key.store' for the location of your keystore and
# 'key.alias' for the name of the key to use.
# The password will be asked during the build when you use the 'release' target.

View File

@ -1,84 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="TC" default="help">
<!-- The local.properties file is created and updated by the 'android'
tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The build.properties file can be created by you and is never touched
by the 'android' tool. This is the place to change some of the
default property values used by the Ant rules.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="build.properties" />
<!-- The default.properties file is created and updated by the 'android'
tool, as well as ADT.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<property file="default.properties" />
<!-- Custom Android task to deal with the project target, and import the
proper rules.
This requires ant 1.6.0 or above. -->
<path id="android.antlibs">
<pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
<pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
<pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
</path>
<taskdef name="setup"
classname="com.android.ant.SetupTask"
classpathref="android.antlibs" />
<!-- extension targets. Uncomment the ones where you want to do custom work
in between standard targets -->
<!--
<target name="-pre-build">
</target>
<target name="-pre-compile">
</target>
[This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir}]
<target name="-post-compile">
</target>
-->
<!-- Execute the Android Setup task that will setup some properties
specific to the target, and import the build rules files.
The rules file is imported from
<SDK>/platforms/<target_platform>/ant/ant_rules_r#.xml
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<setup> task.
- customize it to your needs.
- Customize the whole script.
- copy/paste the content of the rules files (minus the top node)
into this file, *after* the <setup> task
- disable the import of the rules by changing the setup task
below to <setup import="false" />.
- customize to your needs.
-->
<setup />
</project>

View File

@ -1,11 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-8

View File

@ -1,10 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked in Version Control Systems,
# as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/home/desnos/android/android-sdk-linux_x86

View File

@ -1,34 +0,0 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, TCActivity"
/>
</LinearLayout>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TCActivity</string>
</resources>

View File

@ -1,33 +0,0 @@
package org.t0t0.androguard.TC;
public class TCA {
public int TC1 = 30;
private int TC2 = -6;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCA()
{
System.out.println("TCA TC1 == 30 : " + this.equal( this.TC1, "30" ));
System.out.println("TCA TC2 == -6 : " + this.equal( this.TC2, "-6" ));
TC1 = 20;
System.out.println("TCA TC1 == 20 : " + this.equal( this.TC1, "20" ));
}
public void T1()
{
TCC c = new TCC();
c.T1();
}
}

View File

@ -1,15 +0,0 @@
package org.t0t0.androguard.TC;
import android.app.Activity;
import android.os.Bundle;
public class TCActivity extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

View File

@ -1,32 +0,0 @@
package org.t0t0.androguard.TC;
public class TCB {
public int TC1 = 1337;
private int TC2 = -90000;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCB(TCA a)
{
System.out.println("TCB TC1 == 1337 : " + this.equal( this.TC1, "1337" ));
System.out.println("TCB TC2 == -90000 : " + this.equal( this.TC2, "-90000" ));
TC1 = 20;
System.out.println("TCB TC1 == 20 : " + this.equal( this.TC1, "20" ));
a.T1();
}
public void T1()
{
}
}

View File

@ -1,30 +0,0 @@
package org.t0t0.androguard.TC;
public class TCC {
public int TC1 = 30;
private int TC2 = -6;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCC()
{
System.out.println("TCC TC1 == 30 : " + this.equal( this.TC1, "30" ));
System.out.println("TCC TC2 == -6 : " + this.equal( this.TC2, "-6" ));
TC1 = 20;
System.out.println("TCC TC1 == 20 : " + this.equal( this.TC1, "20" ));
}
public void T1()
{
}
}

View File

@ -1,33 +0,0 @@
package org.t0t0.androguard.TC;
public class TCD {
public int TC1 = 1337;
private int TC2 = -90000;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCD()
{
System.out.println("TCD TC1 == 1337 : " + this.equal( this.TC1, "1337" ));
System.out.println("TCD TC2 == -90000 : " + this.equal( this.TC2, "-90000" ));
TC1 = 20;
System.out.println("TCD TC1 == 20 : " + this.equal( this.TC1, "20" ));
TCE e = new TCE();
e.T1();
}
public void T1()
{
}
}

View File

@ -1,75 +0,0 @@
package org.t0t0.androguard.TC;
public class TCE {
public int TC1 = 1337;
private int TC2 = -90000;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCE()
{
System.out.println("TCE TC1 == 1337 : " + this.equal( this.TC1, "1337" ));
System.out.println("TCE TC2 == -90000 : " + this.equal( this.TC2, "-90000" ));
this.TC1 = 20;
System.out.println("TCE TC1 == 20 : " + this.equal( this.TC1, "20" ));
this.TC2 = -30;
System.out.println("TCE TC2 == -30 : " + this.equal( this.TC2, "-30" ));
int y = 0;
for(int i = 0; i < (this.TC1 - this.TC2); i++) {
for(int j=0; j < i; j++) {
y = y + this.TCE_t1( 400 );
}
switch( this.TC1 ) {
case 0 : y += 1;
default : y = y + this.TCE_t2();
}
switch( this.TC2 ) {
case 0 : y += 30;
case 45 : y += 2;
case -6 : y = y + this.TCE_t3();
}
}
this.TC1 = y;
System.out.println("TCE TC1 == 3433300 : " + this.equal( this.TC1, "3433300" ));
TCC c = new TCC();
c.T1();
}
public int TCE_t1(int a)
{
return a * 7;
}
public int TCE_t2()
{
return 0x42;
}
public int TCE_t3()
{
return 0x45;
}
public void T1()
{
}
}

View File

@ -1,78 +0,0 @@
package org.t0t0.androguard.TC;
public class TCMod1 {
public int TC1 = 0;
private int TC2 = 3;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCMod1()
{
System.out.println("TC1 == 0 : " + this.equal( this.TC1, "0" ));
System.out.println("TC2 == 3 : " + this.equal( this.TC2, "3" ));
TC1 = 20;
System.out.println("TC1 == 20 : " + this.equal( this.TC1, "20" ));
}
public void T1()
{
int i;
for(i = 0; i < 30; i++)
{
this.TC1 += i;
}
System.out.println("TC1 == 455 : " + this.equal( this.TC1, "455" ));
int j = 40;
System.out.println("J == 40 : " + this.equal( j, "40" ));
for(; j < 40000; j++);
System.out.println("J == 40000 : " + this.equal( j, "40000" ));
this.TC1 += j;
System.out.println("TC1 == 40455 : " + this.equal( this.TC1, "40455" ));
int k[][] = { { 40, 30 }, { 60000, -788 }, { -2344556, 10000 } };
for(i = 0; i < k.length; i++) {
for(j=0; j < k[i].length; j++) {
this.TC1 += k[i][j];
}
}
TCA a = new TCA() ;
a.T1();
System.out.println("TC1 == -2234819 : " + this.equal( this.TC1, "-2234819" ));
i = 300; j =-188;
System.out.println("I == 300 : " + this.equal( i, "300" ));
System.out.println("J == -188 : " + this.equal( j, "-188" ));
TCD d = new TCD();
d.T1();
do {
this.TC2 += ( j - i );
j += 3;
i -= 2;
} while ( j < i );
System.out.println("TC2 == -24056 : " + this.equal( this.TC2, "-24056" ));
TCA a1 = new TCA() ;
a1.T1();
TCB b = new TCB( a );
b.T1();
}
}

View File

@ -1,23 +0,0 @@
package org.t0t0.androguard.TC;
public class TestType1
{
public TestType1()
{
long long_tc1 = 42;
long long_tc2 = -42;
long long_tc3 = 0;
int int_tc1 = 42;
int int_tc2 = -42;
int int_tc3 = 0;
double double_tc1 = 42.0;
double double_tc2 = -42.0;
double double_tc3 = 0.0;
float float_tc1 = 42.0f;
float float_tc2 = -42.0f;
float float_tc3 = 0.0f;
}
}

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.t0t0.androguard.TCDiff"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name" android:icon="@drawable/icon">
<activity android:name="TCActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -1,30 +0,0 @@
<?xml version="1.0"?>
<parent id="androguard Test">
<main_path>./examples/android/TCDiff/</main_path>
<libs_path>./libs/</libs_path>
<watermark>
<type>BM_A0</type>
<type>BM_A1</type>
<output>wm.xml</output>
</watermark>
<protect_code>
</protect_code>
<protect_names type="class">
<except_class>
<name>org/t0t0/androguard/TCDiff/TCActivity</name>
</except_class>
<except_fields>
<class>org/t0t0/androguard/TCDiff/TCMod1</class>
<name>TC1</name>
<descriptor>I</descriptor>
</except_fields>
</protect_names>
</parent>

View File

@ -1,17 +0,0 @@
# This file is used to override default values used by the Ant build system.
#
# This file must be checked in Version Control Systems, as it is
# integral to the build system of your project.
# This file is only used by the Ant script.
# You can use this to override default values such as
# 'source.dir' for the location of your java source folder and
# 'out.dir' for the location of your output folder.
# You can also use it define how the release builds are signed by declaring
# the following properties:
# 'key.store' for the location of your keystore and
# 'key.alias' for the name of the key to use.
# The password will be asked during the build when you use the 'release' target.

View File

@ -1,84 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="TCDiff" default="help">
<!-- The local.properties file is created and updated by the 'android'
tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The build.properties file can be created by you and is never touched
by the 'android' tool. This is the place to change some of the
default property values used by the Ant rules.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="build.properties" />
<!-- The default.properties file is created and updated by the 'android'
tool, as well as ADT.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<property file="default.properties" />
<!-- Custom Android task to deal with the project target, and import the
proper rules.
This requires ant 1.6.0 or above. -->
<path id="android.antlibs">
<pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
<pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
<pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
</path>
<taskdef name="setup"
classname="com.android.ant.SetupTask"
classpathref="android.antlibs" />
<!-- extension targets. Uncomment the ones where you want to do custom work
in between standard targets -->
<!--
<target name="-pre-build">
</target>
<target name="-pre-compile">
</target>
[This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir}]
<target name="-post-compile">
</target>
-->
<!-- Execute the Android Setup task that will setup some properties
specific to the target, and import the build rules files.
The rules file is imported from
<SDK>/platforms/<target_platform>/ant/ant_rules_r#.xml
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<setup> task.
- customize it to your needs.
- Customize the whole script.
- copy/paste the content of the rules files (minus the top node)
into this file, *after* the <setup> task
- disable the import of the rules by changing the setup task
below to <setup import="false" />.
- customize to your needs.
-->
<setup />
</project>

View File

@ -1,11 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-8

View File

@ -1,10 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked in Version Control Systems,
# as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/home/desnos/android/android-sdk-linux_x86

View File

@ -1,34 +0,0 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, TCActivity"
/>
</LinearLayout>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TCActivity</string>
</resources>

View File

@ -1,39 +0,0 @@
package org.t0t0.androguard.TCDiff;
public class TCA {
public int TC1 = 30;
private int TC2 = -6;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCA()
{
System.out.println("TCA TC1 == 30 : " + this.equal( this.TC1, "30" ));
System.out.println("TCA TC2 == -6 : " + this.equal( this.TC2, "-6" ));
TC1 = 20;
System.out.println("TCA TC1 == 20 : " + this.equal( this.TC1, "20" ));
}
public void T1()
{
TCC c = new TCC();
// PATCH
if ((TC2 % 2) == 1) {
TC1 = 3;
}
// END PATCH
c.T1();
}
}

View File

@ -1,15 +0,0 @@
package org.t0t0.androguard.TCDiff;
import android.app.Activity;
import android.os.Bundle;
public class TCActivity extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

View File

@ -1,32 +0,0 @@
package org.t0t0.androguard.TCDiff;
public class TCB {
public int TC1 = 1337;
private int TC2 = -90000;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCB(TCA a)
{
System.out.println("TCB TC1 == 1337 : " + this.equal( this.TC1, "1337" ));
System.out.println("TCB TC2 == -90000 : " + this.equal( this.TC2, "-90000" ));
TC1 = 20;
System.out.println("TCB TC1 == 20 : " + this.equal( this.TC1, "20" ));
a.T1();
}
public void T1()
{
}
}

View File

@ -1,30 +0,0 @@
package org.t0t0.androguard.TCDiff;
public class TCC {
public int TC1 = 30;
private int TC2 = -6;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCC()
{
System.out.println("TCC TC1 == 30 : " + this.equal( this.TC1, "30" ));
System.out.println("TCC TC2 == -6 : " + this.equal( this.TC2, "-6" ));
TC1 = 20;
System.out.println("TCC TC1 == 20 : " + this.equal( this.TC1, "20" ));
}
public void T1()
{
}
}

View File

@ -1,33 +0,0 @@
package org.t0t0.androguard.TCDiff;
public class TCD {
public int TC1 = 1337;
private int TC2 = -90000;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCD()
{
System.out.println("TCD TC1 == 1337 : " + this.equal( this.TC1, "1337" ));
System.out.println("TCD TC2 == -90000 : " + this.equal( this.TC2, "-90000" ));
TC1 = 20;
System.out.println("TCD TC1 == 20 : " + this.equal( this.TC1, "20" ));
TCE e = new TCE();
e.T1();
}
public void T1()
{
}
}

View File

@ -1,80 +0,0 @@
package org.t0t0.androguard.TCDiff;
public class TCE {
public int TC1 = 1337;
private int TC2 = -90000;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCE()
{
System.out.println("TCE TC1 == 1337 : " + this.equal( this.TC1, "1337" ));
System.out.println("TCE TC2 == -90000 : " + this.equal( this.TC2, "-90000" ));
this.TC1 = 20;
System.out.println("TCE TC1 == 20 : " + this.equal( this.TC1, "20" ));
this.TC2 = -30;
System.out.println("TCE TC2 == -30 : " + this.equal( this.TC2, "-30" ));
int y = 0;
for(int i = 0; i < (this.TC1 - this.TC2); i++) {
for(int j=0; j < i; j++) {
y = y + this.TCE_t1( 400 );
}
switch( this.TC1 ) {
case 0 : y += 1;
default : y = y + this.TCE_t2();
}
switch( this.TC2 ) {
case 0 : y += 30;
case 45 : y += 2;
case -6 : y = y + this.TCE_t3();
}
}
this.TC1 = y;
System.out.println("TCE TC1 == 3433300 : " + this.equal( this.TC1, "3433300" ));
TCC c = new TCC();
c.T1();
}
public int TCE_t1(int a)
{
return a * 7;
}
public int TCE_t2()
{
return 0x42;
}
public int TCE_t3()
{
return 0x45;
}
// NEW METHOD
public int TCE_t4()
{
return 0x90;
}
public void T1()
{
}
}

View File

@ -1,86 +0,0 @@
package org.t0t0.androguard.TCDiff;
public class TCMod1 {
public int TC1 = 0;
private int TC2 = 3;
public String equal(int a, String b)
{
String c = Integer.toString( a );
System.out.print(c + " " + b + " ---- ");
if (c.equals(b)) {
return " OK ";
}
return " X ";
}
public TCMod1()
{
System.out.println("TC1 == 0 : " + this.equal( this.TC1, "0" ));
System.out.println("TC2 == 3 : " + this.equal( this.TC2, "3" ));
TC1 = 20;
System.out.println("TC1 == 20 : " + this.equal( this.TC1, "20" ));
}
public void T1()
{
int i;
for(i = 0; i < 30; i++)
{
this.TC1 += i;
}
System.out.println("TC1 == 455 : " + this.equal( this.TC1, "455" ));
int j = 40;
System.out.println("J == 40 : " + this.equal( j, "40" ));
for(; j < 40000; j++);
System.out.println("J == 40000 : " + this.equal( j, "40000" ));
this.TC1 += j;
System.out.println("TC1 == 40455 : " + this.equal( this.TC1, "40455" ));
int k[][] = { { 40, 30 }, { 60000, -788 }, { -2344556, 10000 } };
for(i = 0; i < k.length; i++) {
for(j=0; j < k[i].length; j++) {
// PATCH
this.TC1 += k[i][j] + 1;
// END PATCH
}
}
TCA a = new TCA() ;
a.T1();
System.out.println("TC1 == -2234819 : " + this.equal( this.TC1, "-2234819" ));
i = 300; j =-188;
System.out.println("I == 300 : " + this.equal( i, "300" ));
System.out.println("J == -188 : " + this.equal( j, "-188" ));
TCD d = new TCD();
d.T1();
do {
this.TC2 += ( j - i );
j += 3;
// PATCH
if (j == 4) {
break;
}
// END PATCH
i -= 2;
} while ( j < i );
System.out.println("TC2 == -24056 : " + this.equal( this.TC2, "-24056" ));
TCA a1 = new TCA() ;
a1.T1();
TCB b = new TCB( a );
b.T1();
}
}

View File

@ -1,23 +0,0 @@
package org.t0t0.androguard.TCDiff;
public class TestType1
{
public TestType1()
{
long long_tc1 = 42;
long long_tc2 = -42;
long long_tc3 = 0;
int int_tc1 = 42;
int int_tc2 = -42;
int int_tc3 = 0;
double double_tc1 = 42.0;
double double_tc2 = -42.0;
double double_tc3 = 0.0;
float float_tc1 = 42.0f;
float float_tc2 = -42.0f;
float float_tc3 = 0.0f;
}
}

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="lib" path="libs/android-support-v4.jar"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>TestsAndroguard</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="tests.androguard"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="16" />
<application
android:allowBackup="false"
android:icon="@drawable/icon"
android:label="@string/app_name" >
<activity
android:name="TestActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -1,23 +0,0 @@
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package tests.androguard;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040001;
public static final int hello=0x7f040000;
}
}

View File

@ -1,14 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-10

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, TestActivity! kikoololmodif</string>
<string name="app_name">TestsAndroguardApplication</string>
</resources>

View File

@ -1,82 +0,0 @@
import java.util.ArrayList;
import java.util.List;
public class TestDefaultPackage {
static long [] test_;
private class TestInnerClass {
private int a, b;
private TestInnerClass(int a, int b)
{
this.a = a;
this.b = b;
}
public void Test(int d)
{
System.out.println("Test2: " + this.a + d + this.b);
}
private class TestInnerInnerClass {
private int a, c;
private TestInnerInnerClass(int a, int c)
{
this.a = a;
this.c = c;
}
public void Test(int b)
{
System.out.println("Test: " + this.a * b + this.c);
}
}
}
public void const4()
{
byte _ = -8;
byte a = -7;
byte b = -6;
byte c = -5;
byte d = -4;
byte e = -3;
byte f = -2;
byte g = -1;
byte h = 0;
byte i = 1;
byte j = 2;
byte k = 3;
byte l = 4;
byte m = 5;
byte n = 6;
byte o = 7;
System.out.println("" + _ + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o);
}
public static void main(String [] z)
{
int a = 5;
switch(a)
{
case 1:
case 2:
System.out.println("1 || 2");
break;
case 3:
System.out.print("3 || ");
case 4:
default:
System.out.println("4");
break;
case 5:
System.out.println("5");
}
TestDefaultPackage p = new TestDefaultPackage();
TestInnerClass t = p.new TestInnerClass(3, 4);
TestInnerClass.TestInnerInnerClass t2 = t.new TestInnerInnerClass(3, 4);
System.out.println("t.a = " + t.a);
}
}

View File

@ -1,36 +0,0 @@
package tests.androguard;
public class Eratosthene {
public static int[] eratosthenes(int n) {
boolean a[] = new boolean[n+1];
a[0] = true;
a[1] = true;
int sqn = (int)Math.sqrt(n);
for(int i = 2; i <= sqn; i++) {
if(!a[i]) {
int j = i*i;
while(j <= n) {
a[j] = true;
j += i;
}
}
}
int cnt = 0;
for(boolean b: a) {
if(!b) {
cnt++;
}
}
int j = 0;
int[] primes = new int[cnt];
for(int i = 0; i < a.length; i++) {
if(!a[i]) {
primes[j++] = i;
}
}
return primes;
}
}

View File

@ -1,59 +0,0 @@
package tests.androguard;
public class Lzss {
public static int lzss_decompress(byte[] in, byte[] out) {
int i = 0;
int j = 0;
int flags = 0;
int cnt = 7;
while(j < out.length) {
if(++cnt == 8) {
if(i >= in.length) {
break;
}
flags = in[i++] & 0xFF;
cnt = 0;
}
if((flags & 1) == 0) {
if(i >= in.length) {
break;
}
out[j] = in[i];
j++;
i++;
}
else {
if((i + 1) >= in.length) {
return -1;
}
int v = (in[i] & 0xFF) | (in[i+1] & 0xFF) << 8;
i += 2;
int offset = (v >> 4) + 1;
int length = (v & 0xF) + 3;
// not enough data decoded
if(offset > j) {
return -1;
}
// output buffer is too small
if((out.length - j) < length) {
return -1;
}
for(int k = 0; k < length; k++) {
out[j+k] = out[j+k-offset];
}
j += length;
}
flags >>= 1;
}
return j;
}
}

View File

@ -1,41 +0,0 @@
package tests.androguard;
public class RC4 {
public static void rc4_crypt(byte[] key, byte[] data) {
int keylen = key.length;
int datalen = data.length;
int i;
int j;
// key scheduling
byte[] sbox = new byte[256];
for(i = 0; i < 256; i++) {
sbox[i] = (byte)i;
}
j = 0;
for(i = 0; i < 256; i++) {
j = ((j + sbox[i] + key[i % keylen]) % 256) & 0xFF;
byte tmp = sbox[i];
sbox[i] = sbox[j];
sbox[j] = tmp;
}
// generate output
i = 0;
j = 0;
int index = 0;
while(index < datalen) {
i = ((i + 1) % 256) & 0xFF;
j = ((j + sbox[i]) % 256) & 0xFF;
byte tmp = sbox[i];
sbox[i] = sbox[j];
sbox[j] = tmp;
byte k = (byte)(sbox[((sbox[i] + sbox[j]) % 256) & 0xFF]);
data[index] ^= k;
index++;
}
}
}

View File

@ -1,373 +0,0 @@
package tests.androguard;
import java.io.PrintStream;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class TestActivity<T> extends Activity {
public int value;
public int value2;
private int test = 10;
private static final int test2 = 20;
public int test3 = 30;
public int tab[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
static {
int t = 5;
System.out.println("foobar");
}
public TestActivity() {
value = 100;
value2 = 200;
}
public TestActivity(int value, int value2) {
this.value = value;
this.value2 = value2;
}
public TestActivity(double value, double value2) {
this.test = 5;
this.value = (int) value;
this.value2 = (int) value2;
}
public int test_base(int _value, int _value2) {
int y = 0;
double sd = -6;
double zz = -5;
double yy = -4;
double xx = -3;
double w = -2;
double x = -1;
double k = 0.0;
double d = 1;
double b = 2;
double c = 3;
double f = 4;
double z = 5;
double cd = 6;
float g = 4.20f;
double useless = g * c + b - y + d;
System.out.println("VALUE = " + this.value + " VALUE 2 = "
+ this.value2);
for (int i = 0; i < (_value + _value2); i++) {
y = this.value + y - this.value2;
y = y & 200 * test1(20);
y = this.value2 - y;
}
try {
int[] t = new int[5];
t[6] = 1;
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
System.out.println("boom");
}
if (this.value > 0) {
this.value2 = y;
}
switch (this.value) {
case 0:
this.value2 = this.pouet();
break;
default:
this.value2 = this.pouet2();
}
switch (this.value) {
case 1:
this.value2 = this.pouet();
break;
case 2:
this.value2 = this.pouet2();
break;
case 3:
this.value2 = this.pouet3();
}
return y;
}
public int foo(int i, int j) {
while (true) {
try {
while (i < j)
i = j++ / i;
} catch (RuntimeException re) {
i = 10;
continue;
}
if (i == 0)
return j;
}
}
public int foobis(int i, int j) {
while (i < j && i != 10) {
try {
i = j++ / i;
} catch (RuntimeException re) {
i = 10;
continue;
}
}
return j;
}
public int foo2(int i, int j) {
while (true) {
if (i < j) {
try {
i = j++ / i;
} catch (RuntimeException re) {
i = 10;
continue;
}
}
if (i == 0)
return j;
}
}
public int foo4(int i, int j) {
while (i < j) {
try {
i = j++ / i;
} catch (RuntimeException re) {
i = 10;
}
}
return j;
}
public int test1(int val) {
int a = 0x10;
return val + a - 60 * this.value;
}
public int pouet() {
int v = this.value;
return v;
}
public void testVars(int z, char y) {
int a = this.value * 2;
int b = 3;
int c = 4;
int d = c + b * a - 1 / 3 * this.value;
int e = c + b - a;
int f = e + 2;
int g = 3 * d - c + f - 8;
int h = 10 + this.value + a + b + c + d + e + f + g;
int i = 150 - 40 + 12;
int j = h - i + g;
int k = 10;
int l = 5;
int m = 2;
int n = 10;
int o = k * l + m - n * this.value + c / e - f * g + h - j;
int p = a + b + c;
int q = p - k + o - l;
int r = a + b - c * d / e - f + g - h * i + j * k * l - m - n + o / p
* q;
System.out.println(" meh " + r);
System.out.println(y);
y += 'a';
this.testVars(a, y);
this.test1(10);
pouet2();
this.pouet2();
int s = pouet2();
}
public static void testDouble() {
double f = -5;
double g = -4;
double h = -3;
double i = -2;
double j = -1;
double k = 0;
double l = 1;
double m = 2;
double n = 3;
double o = 4;
double p = 5;
long ff = -5;
long gg = -4;
long hh = -3;
long ii = -2;
long jj = -1;
long kk = 0;
long ll = 1;
long mm = 2;
long nn = 3;
long oo = 4;
long pp = 5;
float fff = -5;
float ggg = -4;
float hhh = -3;
float iii = -2;
float jjj = -1;
float kkk = 0;
float lll = 1;
float mmm = 2;
float nnn = 3;
float ooo = 4;
float ppp = 5;
double abc = 65534;
double def = 65535;
double ghi = 65536;
double jkl = 65537;
double mno = 32769;
double pqr = 32768;
double stu = 32767;
double vwx = 32766;
long aabc = 65534;
long adef = 65535;
long aghi = 65536;
long ajkl = 65537;
long amno = 32769;
long apqr = 32768;
long astu = 32767;
long avwx = 32766;
float babc = 65534;
float bdef = 65535;
float bghi = 65536;
float bjkl = 65537;
float bmno = 32769;
float bpqr = 32768;
float bstu = 32767;
float bvwx = 32766;
double abcd = 5346952;
long dcba = 5346952;
float cabd = 5346952;
double zabc = 65534.50;
double zdef = 65535.50;
double zghi = 65536.50;
double zjkl = 65537.50;
double zmno = 32769.50;
double zpqr = 32768.50;
double zstu = 32767.50;
double zvwx = 32766.50;
float xabc = 65534.50f;
float xdef = 65535.50f;
float xghi = 65536.50f;
float xjkl = 65537.50f;
float xmno = 32769.50f;
float xpqr = 32768.50f;
float xstu = 32767.50f;
float xvwx = 32766.50f;
float ymno = -5f;
float ypqr = -65535f;
float ystu = -65536f;
float yvwx = -123456789123456789.555555555f;
double yvwx2 = -123456789123456789.555555555;
int boom = -606384730;
float reboom = -123456790519087104f;
float gettype = boom + 2 + 3.5f;
System.out.println(gettype);
}
public static void testCall1(float b) {
System.out.println("k" + b);
}
public static void testCall2(long i) {
new PrintStream(System.out).println("k" + i);
}
public static void testCalls(TestIfs d) {
testCall2(3);
TestIfs.testIF(5);
System.out.println(d.getClass());
}
public static void testLoop(double a) {
while (a < 10) {
System.out.println(a);
a *= 2;
}
}
public void testVarArgs(int p, long[] p2, String... p3) {
}
public void testString( )
{
String a = "foo";
String b = new String("bar");
System.out.println(a + b);
}
public synchronized int pouet2() {
int i = 0, j = 10;
System.out.println("test");
while (i < j) {
try {
i = j++ / i;
} catch (RuntimeException re) {
i = 10;
}
}
this.value = i;
return 90;
}
public int pouet3() {
return 80;
}
public int go() {
System.out.println(" test_base(500, 3) " + this.test_base(500, 3));
return test + test2 + 10;
}
public void testAccessField() {
TestArr$ays a = new TestArr$ays();
a.d = new byte[5];
a.d[2] = 'c';
System.out.println("test :" + a.d[2]);
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Toast toast = Toast.makeText(getApplicationContext(), "this is a test ! " + 42, Toast.LENGTH_LONG);
toast.show();
/*
TestLoops o = new TestLoops();
o.testIrreducible(test3, test2);
*/
}
}

View File

@ -1,44 +0,0 @@
package tests.androguard;
public class TestArr$ays {
public static class InternField {
public static byte[] b;
}
private byte[] b;
public byte[] d;
public TestArr$ays( ) {
b = new byte[5];
}
public TestArr$ays( byte [] b ) {
this.b = b;
}
public TestArr$ays( int i ) {
byte [] a = { 1, 2, 3, 4, 5 };
b = a;
}
public void testEmptyArrayByte( ) {
byte [] b = new byte[5];
InternField.b = b;
}
public void testFullArrayByte( ) {
byte[] b = { 1, 2, 4, 39, 20 };
this.b = b;
}
public void testModifArrayByte( ) {
b[2000000] = 2;
}
public void testInstanceInternArrayByte( ){
InternField f = new InternField();
f.b = new byte[5];
f.b[2] = 40;
}
}

View File

@ -1,146 +0,0 @@
package tests.androguard;
public class TestExceptions {
public int testException1( int a )
{
try {
a = 5 / 0;
} catch ( ArithmeticException e ) {
a = 3;
}
return a;
}
public static int testException2( int a, int b ) throws ArrayIndexOutOfBoundsException
{
int [] t = new int[b];
if ( b == 10 )
b++;
for( int i = 0; i < b; i++ )
{
t[i] = 5;
}
return a + t[0];
}
public int testException3( int a, int[] t )
{
int result = 0;
if ( a % 2 == 0 )
{
try {
result = t[a];
} catch (ArrayIndexOutOfBoundsException e) {
result = 1337;
}
}
else if ( a % 3 == 0 ) {
result = a * 2;
} else {
result = t[0] - 10;
}
return result;
}
public int testException4( int a )
{
int res = 15;
res += a;
try {
Runtime b = Runtime.getRuntime();
b.notifyAll();
} catch( RuntimeException e ) {
System.out.println("runtime " + e.getMessage());
}
try {
Runtime c = Runtime.getRuntime();
c.wait();
}
catch (RuntimeException e) {
System.out.println("runtime " + e.getMessage());
}
catch (Exception e) {
System.out.println("exception e " + e.getMessage());
}
try {
res /= a;
} catch (Exception e) {
System.out.println("exception e " + e.getMessage());
}
System.out.println("end");
return res;
}
public static void testTry1(int b)
{
int a = 15;
try {
if ( b % 2 == 0)
{
a = a / b;
if ( a - 3 == 4 )
System.out.println("lll");
}
else {
a = a * b;
System.out.println("ppp");
}
} catch(ArithmeticException e){
System.out.println("oupla");
}
}
public static void testCatch1(int b)
{
int a = 15;
try {
if ( b % 2 == 0 )
{
a = a / b;
if ( a - 3 == 4 )
System.out.println("mmm");
} else {
a = a * b;
System.out.println("qqq");
}
} catch(ArithmeticException e)
{
if ( a == 12 )
System.out.println("test");
else {
b += 3 * a;
System.out.println("test2 " + b);
}
}
}
public static void testExceptions( String [] z )
{
System.out.println( "Result test1 : " + new TestExceptions().testException1( 10 ) );
System.out.println( "=================================" );
try {
System.out.println( "Result test2 : " + testException2( 5, 10 ) );
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println( "Result test2 : " + testException2( 5, 9 ) );
}
System.out.println( "=================================" );
int [] t = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
System.out.println( "Result test3 : " + new TestExceptions().testException3( 8, t ) );
System.out.println( "Result test3 : " + new TestExceptions().testException3( 9, t ) );
System.out.println( "Result test3 : " + new TestExceptions().testException3( 7, t ) );
}
}

View File

@ -1,145 +0,0 @@
package tests.androguard;
public class TestIfs {
private boolean P, Q, R, S, T;
public static int testIF(int p) {
int i;
if (p > 0) {
i = p * 2;
} else {
i = p + 2;
}
return i;
}
public static int testIF2(int p) {
int i = 0;
if (p > 0) {
i = p * 2;
} else {
i = p + 2;
}
return i;
}
public static int testIF3(int p) {
int i = 0;
if (p > 0) {
i = p * 2;
}
return i;
}
public static int testIF4(int p, int i) {
if (p > 0 && p % 2 == 3) {
i += p * 3;
}
return i;
}
public static int testIF5(int p, int i) {
if ((p <= 0 && i == 0) || (p == i * 2 || i == p / 3)) {
i = -p;
}
return i;
}
public static int testIfBool(int p, boolean b) {
int i = 0;
if ( p > 0 && b )
i += p * 3;
else if (b)
i += 5;
else
i = 2;
return i;
}
public static int testShortCircuit(int p) {
int i = 0;
if (p > 0 && p % 2 == 3) {
i = p + 1;
} else {
i = -p;
}
return i;
}
public static int testShortCircuit2(int p) {
int i = 0;
if (p <= 0 || p % 2 != 3)
i = -p;
else
i = p + 1;
return i;
}
public static int testShortCircuit3(int p, int i) {
if ((p <= 0 && i == 0) || (p == i * 2 || i == p / 3)) {
i = -p;
} else {
i = p + 1;
}
return i;
}
public static int testShortCircuit4(int p, int i) {
if ((p <= 0 || i == 0) && (p == i * 2 || i == p / 3))
i = -p;
else
i = p + 1;
return i;
}
public void testCFG() {
int I = 1, J = 1, K = 1, L = 1;
do {
if (P) {
J = I;
if (Q)
L = 2;
else
L = 3;
K++;
} else {
K += 2;
}
System.out.println(I + "," + J + "," + K + "," + L);
do {
if (R)
L += 4;
} while (!S);
I += 6;
} while (!T);
}
public void testCFG2(int a, int b, int c) {
a += 5;
b += a * 5;
if (a < b) {
if (b < c) {
System.out.println("foo");
} else {
System.out.println("bar");
}
}
a = 10;
while (a < c) {
a += c;
do {
b = a++;
System.out.println("baz");
} while (c < b);
b++;
}
System.out.println("foobar");
if (a >= 5 || b * c <= c + 10) {
System.out.println("a = " + 5);
}
System.out.println("end");
}
}

View File

@ -1,50 +0,0 @@
package tests.androguard;
public class TestInvoke {
public TestInvoke( ) {
TestInvoke1(42 );
}
public int TestInvoke1( int a )
{
return TestInvoke2( a, 42 );
}
public int TestInvoke2( int a, int b )
{
return TestInvoke3( a, b, 42 );
}
public int TestInvoke3( int a, int b, int c )
{
return TestInvoke4( a, b, c, 42 );
}
public int TestInvoke4( int a, int b, int c, int d )
{
return TestInvoke5( a, b, c, d, 42 );
}
public int TestInvoke5(int a, int b, int c, int d, int e)
{
return TestInvoke6( a, b, c, d, e, 42 );
}
public int TestInvoke6( int a, int b, int c, int d, int e, int f )
{
return TestInvoke7( a, b, c, d, e, f, 42);
}
public int TestInvoke7( int a, int b, int c, int d, int e, int f, int g )
{
return TestInvoke8( a, b, c, d, e, f, g, 42);
}
public int TestInvoke8( int a, int b, int c, int d, int e, int f, int g, int h )
{
return a * b * c * d * e *f * g *h;
}
}

View File

@ -1,238 +0,0 @@
package tests.androguard;
import android.content.pm.LabeledIntent;
import android.util.Log;
public class TestLoops {
protected static class Loop {
public static int i;
public static int j;
}
public void testWhile() {
int i = 5, j = 10;
while (i < j) {
j += i / 2.0 + j;
i += i * 2;
}
Loop.i = i;
Loop.j = j;
}
public void testWhile2() {
while(true)
System.out.println("toto");
}
public void testWhile3(int i, int j)
{
while ( i < j && i % 2 == 0 )
{
i += j / 3;
}
}
public void testWhile4(int i, int j)
{
while ( i < j || i % 2 == 0 )
{
i += j / 3;
}
}
public void testWhile5(int i, int j, int k )
{
while ( ( i < j || i % 2 == 0 ) && ( j < k || k % 2 == 0) )
i += k - j;
}
public void testFor() {
int i, j;
for (i = 5, j = 10; i < j; i += i * 2) {
j += i / 2.0 + j;
}
Loop.i = i;
Loop.j = j;
}
public void testDoWhile() {
int i = 5, j = 10;
do {
j += i / 2.0 + j;
i += i * 2;
} while (i < j);
Loop.i = i;
Loop.j = j;
}
public int testNestedLoops(int a) {
if (a > 1000) {
return testNestedLoops(a / 2);
} else {
while (a > 0) {
a += 1;
while (a % 2 == 0) {
a *= 2;
while (a % 3 == 0) {
a -= 3;
}
}
}
}
return a;
}
public void testMultipleLoops() {
int a = 0;
while (a < 50)
a += 2;
while (a % 3 == 0)
a *= 5;
while (a < 789 && a > 901)
System.out.println("woo");
}
public int testDoWhileTrue(int n) {
do {
n--;
if (n == 2)
return 5;
if (n < 2)
n = 500;
} while (true);
}
public int testWhileTrue(int n) {
while (true) {
n--;
if (n == 2)
return 5;
if (n < 2)
n = 500;
}
}
public int testDiffWhileDoWhile(int n) {
while (n != 2) {
if (n < 2)
n = 500;
}
return 5;
}
public void testReducible(boolean x, boolean y) {
int a = 0, b = 0;
if (x)
while (y) {
a = b + 1;
b++;
}
else
while (y) {
b++;
a = b + 1;
}
Loop.i = a;
Loop.j = b;
}
public void testIrreducible(int a, int b) {
while (true) {
if (b < a) {
Log.i("test", "In BasicBlock A");
}
b = a - 1;
Log.i("test2", "In BasicBlock B");
}
}
public int testBreak( boolean b ) {
int a = 0, c = 0;
while(true) {
System.out.println("foo");
a += c;
c += 5;
if ( a == 50 )
b = true;
if ( b )
break;
}
return a + c;
}
public int testBreakbis( boolean b ) {
int a = 0, c = 0;
do {
System.out.println("foo");
a += c;
c += 5;
if ( a == 50 )
b = true;
if ( b )
break;
} while(true);
return a + c;
}
public int testBreakMid( boolean b ) {
int a = Loop.i, c = Loop.j;
while(true) {
System.out.println("foo");
a += c;
c += 5;
if ( a == 50 )
b = !b;
if ( b ) break;
System.out.println("bar");
a *= 2;
}
return a + c;
}
public int testBreakDoWhile( boolean b ) {
int a = 0, c = 0;
do {
System.out.println("foo");
a += c;
c += 5;
if ( a == 50 )
b = true;
}while ( b );
return a + c;
}
public int testBreak2( boolean b ) {
int a = 0, c = 0;
while (true) {
System.out.println("foo");
a += c;
c += 5;
if ( a == 50 && b )
break;
}
return a + c;
}
public void testBreak3( boolean b ) {
int a = 0, c = 0;
while ( true ){
System.out.println("foo");
a += c;
c += 5;
if ( a == 50 && b )
break;
}
}
public void testBreak4( boolean b, int d ) {
int a = 0, c = 0;
while ( c < 50 ) {
System.out.println("foo");
a += c;
c +=5;
if ( a == d )
break;
}
}
}

View File

@ -1,45 +0,0 @@
package tests.androguard;
public class TestQuickSort {
public int a = 10;
public static void Main(String[] args) {
int[] intArray = new int[args.length];
for (int i = 0; i < intArray.length; i++) {
intArray[i] = Integer.parseInt(args[i]);
}
QuickSort(intArray, 0, intArray.length - 1);
for (int i = 0; i < intArray.length; i++) {
System.out.println(intArray[i] + " ");
}
}
public static void QuickSort(int[] array, int left, int right) {
if (right > left) {
int pivotIndex = (left + right) / 2;
int pivotNew = Partition(array, left, right, pivotIndex);
QuickSort(array, left, pivotNew - 1);
QuickSort(array, pivotNew + 1, right);
}
}
static int Partition(int[] array, int left, int right, int pivotIndex) {
int pivotValue = array[pivotIndex];
Swap(array, pivotIndex, right);
int storeIndex = left;
for (int i = left; i < right; i++) {
if (array[i] <= pivotValue) {
Swap(array, storeIndex, i);
storeIndex++;
}
}
Swap(array, right, storeIndex);
return storeIndex;
}
static void Swap(int[] array, int index1, int index2) {
int tmp = array[index1];
array[index1] = array[index2];
array[index2] = tmp;
}
}

View File

@ -1,51 +0,0 @@
package tests.androguard;
public class TestQuickSort2 {
public int a = 10;
public static void Main(String[] args) {
int[] intArray = new int[args.length];
for (int i = 0; i < intArray.length; i++) {
intArray[i] = Integer.parseInt(args[i]);
}
quicksort(intArray, 0, intArray.length - 1);
for (int i = 0; i < intArray.length; i++) {
System.out.println(intArray[i] + " ");
}
}
public static void quicksort(int[] array, int lo, int hi) {
int i = lo;
int j = hi;
int pivot = array[lo + (hi - lo) / 2];
while(i <= j) {
while(array[i] < pivot) {
i++;
}
while(array[j] > pivot) {
j--;
}
if(i <= j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
}
if(lo < j) {
quicksort(array, lo, j);
}
if(i < hi) {
quicksort(array, i, hi);
}
}
}

View File

@ -1,76 +0,0 @@
package tests.androguard;
public class TestSynthetic {
public static void TestSynthetic1( ){
final Object o = new Object();
new Thread(){
public void run(){
System.out.println( "o : " + o.hashCode() );
}
}.start();
}
public static void TestSynthetic2() {
System.out.println( "o : " +
new Object(){
public int toto(char c){
return Integer.parseInt("" + c);
}
}.toto('k')
);
}
public static void TestSynthetic3( ){
Integer o = Integer.valueOf(5);
new Thread(){
Integer o = this.o;
public void run(){
System.out.println( "o : " + o.hashCode() );
}
}.start();
}
public static void TestSynthetic4( final int t ) {
final Object o = new Object();
new Thread(){
public void run(){
synchronized(o){
if ( t == 0 ) {
TestSynthetic1();
}
else {
TestSynthetic2();
}
}
}
}.start();
System.out.println("end");
}
public class Bridge<T> {
public T getT(T arg){
return arg;
}
}
public class BridgeExt extends Bridge<String>{
public String getT(String arg){
return arg;
}
}
public static void TestBridge( ){
TestSynthetic p = new TestSynthetic();
TestSynthetic.Bridge<Integer> x = p.new Bridge<Integer>();
System.out.println("bridge<integer> " + x.getT(5));
TestSynthetic.Bridge<String> w = p.new BridgeExt();
System.out.println("bridgeext " + w.getT("toto"));
}
}

View File

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015 Lawrence Nahum, Ottavio Fontolan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,75 +0,0 @@
ABCore - Android Bitcoin Core
=============================
[![Build Status](https://travis-ci.org/greenaddress/abcore.svg?branch=master)](https://travis-ci.org/greenaddress/abcore)
<a href="http://abco.re"> <img src="http://abco.re/assets/images/schema.png" alt="Infographic" width="650" height="650"></a>
Web site: <a href="http://abco.re">abco.re</a>
Warning: This app is still in a very Proof of Concept/Alpha stage.
<a href="https://f-droid.org/packages/com.greenaddress.abcore/" target="_blank">
<img src="https://f-droid.org/badge/get-it-on.png" height="90"/></a>
<a href="https://play.google.com/apps/testing/com.greenaddress.abcore" target="_blank">
<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" height="90"/></a>
If you want to try it, you can also get it directly from GitHub [here](https://github.com/greenaddress/abcore/releases/tag/v0.62alphaPoC).
What is Android Bitcoin Core?
-----------------------------
Android Bitcoin Core is an Android app that fetches bitcoin core daemon built for Android using the NDK and is meant to make it easier
to run Bitcoin Core daemon node on always on Android set top box devices and home appliances as well as mobile devices.
The full node software (Core 0.15.1 and Knots) is meant to be used as a personal node when on the go (either by using a mobile wallet that allows to connect to a remote and specific node or even directly on your mobile device).
ABCore works on x86, x86_64, armhf and arm64 Android (any version from Lollipop onwards - sdk 21). Mips is not supported.
License
-------
ABCore is released under the terms of the MIT license. See [COPYING](COPYING) for more
information or see https://opensource.org/licenses/MIT.
Privacy
-------
ABCore doesn't do any kind of phone home, doesn't have In-App Purchase or advertising.
During the initial configuration it connects to Github to fetch the required binaries and once it is installed it only communicates with the rest of the Bitcoin network like any normal full node.
Limitations
-----------
ABCore requires a fair amount of ram (tested with 2GB) and a fair amount of disk space (tested with 256GB for non pruned node) as well as a decent always on connection - 3G or 4G is not adviced.
We also do not advice to use this as a wallet at this time, we advice to use this as your personal blockchain anchor when on the go with wallets that support to set a personal node.
The contributors of ABCore are not liable for any cost or damage caused by the app including but not limited to data charges/penalties.
Acknowledgement
---------------
- Development
Lawrence Nahum
twitter.com/LarryBitcoin
- Graphic Content
Ottavio Fontolan
otta88.box (at) gmail (dot) com
- Testing & UX
Gabriele Domenichini
twitter.com/gabridome
- Community Manager
Timothy Redaelli
twitter.com/drizztbsd
timothy.redaelli (at) gmail (dot) com
Special thanks to the [Bitcoin Core dev team](https://bitcoincore.org/), the [Arch Linux](https://www.archlinux.org/) teams and to [Alessandro Polverini](https://github.com/Polve) for the [Java RPC client](https://github.com/Polve/JavaBitcoindRpcClient).

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More