Skip to content

Commit e464b09

Browse files
committed
2 parents c73dc7e + 9959f05 commit e464b09

16 files changed

+865
-20
lines changed

AndroidManifest.png

128 KB
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package qilin.android;
2+
3+
import qilin.android.manifest.IManifestHandler;
4+
import qilin.android.manifest.ProcessManifest;
5+
import qilin.core.PTAScene;
6+
import soot.SootClass;
7+
8+
import java.io.File;
9+
import java.io.IOException;
10+
import java.util.HashSet;
11+
import java.util.Set;
12+
13+
public class AndroidManifestParser {
14+
15+
protected IManifestHandler manifest = null;
16+
17+
protected Set<SootClass> entrypoints = new HashSet<>();
18+
19+
public Set<SootClass> parseAppAndResourcesAndReturnEntryPoints(String APP_PATH) throws IOException {
20+
parseAppResources(APP_PATH);
21+
return entrypoints;
22+
}
23+
24+
25+
public void parseAppResources(String APP_PATH) throws IOException {
26+
manifest = createManifestParser(new File(APP_PATH));
27+
Set<String> entryPoints = manifest.getEntryPointClasses();
28+
entrypoints = new HashSet<>(entryPoints.size());
29+
for (String className : entryPoints) {
30+
SootClass sc = PTAScene.v().createSootClassUnsafe(className);
31+
if (sc != null)
32+
entrypoints.add(sc);
33+
}
34+
}
35+
36+
private IManifestHandler createManifestParser(File file) throws IOException {
37+
return new ProcessManifest(file);
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package qilin.android.axml;
2+
3+
public class AXmlAttribute<T> {
4+
5+
public AXmlAttribute(String name, int resourceId, int type, T value) {
6+
this.name = name;
7+
this.resourceId = resourceId;
8+
this.type = type;
9+
this.value = value;
10+
}
11+
12+
/**
13+
* The attribute's name.
14+
*/
15+
protected String name;
16+
17+
/**
18+
* The attribute's type
19+
*/
20+
protected int type;
21+
22+
/**
23+
* The attribute's value.
24+
*/
25+
protected T value;
26+
27+
/**
28+
* The attribute's resource id
29+
*/
30+
protected int resourceId;
31+
32+
33+
/**
34+
* Returns the name of this attribute.
35+
*
36+
* @return the attribute's name.
37+
*/
38+
public String getName() {
39+
return this.name;
40+
}
41+
42+
/**
43+
* Returns the value of this attribute.
44+
*
45+
* @return the attribute's value.
46+
*/
47+
public T getValue() {
48+
return this.value;
49+
}
50+
51+
@Override
52+
public String toString() {
53+
return this.name + "=\"" + this.value + "\"";
54+
}
55+
56+
@Override
57+
public int hashCode() {
58+
final int prime = 31;
59+
int result = 1;
60+
result = prime * result + ((name == null) ? 0 : name.hashCode());
61+
result = prime * result + resourceId;
62+
result = prime * result + type;
63+
result = prime * result + ((value == null) ? 0 : value.hashCode());
64+
return result;
65+
}
66+
67+
@Override
68+
public boolean equals(Object obj) {
69+
if (this == obj)
70+
return true;
71+
if (obj == null)
72+
return false;
73+
if (getClass() != obj.getClass())
74+
return false;
75+
AXmlAttribute<?> other = (AXmlAttribute<?>) obj;
76+
if (name == null) {
77+
if (other.name != null)
78+
return false;
79+
} else if (!name.equals(other.name))
80+
return false;
81+
if (resourceId != other.resourceId)
82+
return false;
83+
if (type != other.type)
84+
return false;
85+
if (value == null) {
86+
if (other.value != null)
87+
return false;
88+
} else if (!value.equals(other.value))
89+
return false;
90+
return true;
91+
}
92+
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package qilin.android.axml;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
public class AXmlDocument {
7+
8+
/**
9+
* The root node of the document
10+
*/
11+
private AXmlNode rootNode;
12+
13+
/**
14+
* The namespaces registered on this element.
15+
*/
16+
Map<String, AXmlNamespace> namespaces = null;
17+
18+
/**
19+
* Adds a namespace that is defined in this node.
20+
*
21+
* @param ns The namespace defined in this node.
22+
*/
23+
public void addNamespace(AXmlNamespace ns) {
24+
// Do not add the default namespace
25+
if (ns.getUri() == null || ns.getUri().isEmpty())
26+
return;
27+
28+
if (this.namespaces == null)
29+
this.namespaces = new HashMap<>();
30+
this.namespaces.put(ns.getPrefix(), ns);
31+
}
32+
33+
/**
34+
* Sets the root node of this document
35+
*
36+
* @param rootNode The new root node of this document
37+
*/
38+
public void setRootNode(AXmlNode rootNode) {
39+
this.rootNode = rootNode;
40+
}
41+
42+
/**
43+
* Gets the root node of this Android XML document
44+
*
45+
* @return The root node of this Android XML document
46+
*/
47+
public AXmlNode getRootNode() {
48+
return this.rootNode;
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package qilin.android.axml;
2+
3+
import java.io.BufferedInputStream;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
/**
10+
* {@link AXmlHandler} provides functionality to parse a byte compressed android xml file and access all nodes.
11+
*
12+
* @author Palaniappan Muthuraman
13+
*/
14+
public class AXmlHandler {
15+
16+
/**
17+
* Contains the byte compressed xml which was parsed by this {@link AXmlHandler}.
18+
*/
19+
protected byte[] xml;
20+
21+
/**
22+
* The parser used for actually reading out the binary XML file
23+
*/
24+
protected final IBinaryXmlParser parser;
25+
26+
/**
27+
* Returns a list containing all nodes of the xml document which have the given tag.
28+
*
29+
* @param tag the tag being search for
30+
* @return list pointing on all nodes which have the given tag.
31+
*/
32+
public List<AXmlNode> getNodesWithTag(String tag) {
33+
return parser.getNodesWithTag(tag);
34+
}
35+
36+
public AXmlHandler(InputStream aXmlIs, IBinaryXmlParser parser) throws IOException {
37+
// wrap the InputStream within a BufferedInputStream
38+
// to have mark() and reset() methods
39+
BufferedInputStream buffer = new BufferedInputStream(aXmlIs);
40+
41+
// read xml one time for writing the output later on
42+
{
43+
List<byte[]> chunks = new ArrayList<>();
44+
int bytesRead = 0;
45+
while (aXmlIs.available() > 0) {
46+
byte[] nextChunk = new byte[aXmlIs.available()];
47+
int chunkSize = buffer.read(nextChunk);
48+
if (chunkSize < 0)
49+
break;
50+
chunks.add(nextChunk);
51+
bytesRead += chunkSize;
52+
}
53+
54+
// Create the full array
55+
this.xml = new byte[bytesRead];
56+
int bytesCopied = 0;
57+
for (byte[] chunk : chunks) {
58+
int toCopy = Math.min(chunk.length, bytesRead - bytesCopied);
59+
System.arraycopy(chunk, 0, this.xml, bytesCopied, toCopy);
60+
bytesCopied += toCopy;
61+
}
62+
}
63+
64+
parser.parseFile(this.xml);
65+
this.parser = parser;
66+
}
67+
68+
/**
69+
* Returns the Android xml document.
70+
*
71+
* @return the Android xml document
72+
*/
73+
public AXmlDocument getDocument() {
74+
return parser.getDocument();
75+
}
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package qilin.android.axml;
2+
3+
/**
4+
* Represents a namesapce in an Android XML document.
5+
*
6+
* @author Steven Arzt
7+
*/
8+
public class AXmlNamespace {
9+
10+
protected String prefix;
11+
12+
protected String uri;
13+
14+
protected int line;
15+
16+
/**
17+
* Creates a new namespace definition for Android xml documents
18+
* @param prefix The prefix to be used when referring to this namespace
19+
* @param uri The uri uniquely identifying the namespace
20+
* @param line The line in which the namespace was defined
21+
*/
22+
public AXmlNamespace(String prefix, String uri, int line) {
23+
super();
24+
this.prefix = prefix;
25+
this.uri = uri;
26+
this.line = line;
27+
}
28+
29+
/**
30+
* Gets the prefix to be used when referring to this namespace
31+
* @return The prefix to be used when referring to this namespace
32+
*/
33+
public String getPrefix() {
34+
return this.prefix;
35+
}
36+
37+
/**
38+
* Gets the uri uniquely identifying the namespace
39+
* @return The uri uniquely identifying the namespace
40+
*/
41+
public String getUri() {
42+
return this.uri;
43+
}
44+
45+
}

0 commit comments

Comments
 (0)