diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FActivity.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Activity.java similarity index 57% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/app/FActivity.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/app/Activity.java index 3ee88b14..0ead8cad 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FActivity.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Activity.java @@ -4,14 +4,14 @@ import android.text.TextUtils; @SuppressWarnings({"rawtypes", "unchecked"}) -public class FActivity extends FComponent { +public class Activity extends Component { - public FPermission permission; + public Permission permission; - public FActivity(PackageParser.Activity activity) { + public Activity(PackageParser.Activity activity) { super(activity, activity.info); if (!TextUtils.isEmpty(activity.info.permission)) { - permission = new FPermission(activity.info.permission); + permission = new Permission(activity.info.permission); } } } diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FComponent.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Component.java similarity index 86% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/app/FComponent.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/app/Component.java index 21c6f240..dae5ec04 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FComponent.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Component.java @@ -11,15 +11,15 @@ import java.util.ArrayList; import java.util.List; -public class FComponent { +public class Component { public String name; public boolean exported; public boolean enabled; - public List intents; + public List intents; @SuppressLint("SwitchIntDef") - public FComponent(PackageParser.Component component, ComponentInfo info) { + public Component(PackageParser.Component component, ComponentInfo info) { PackageManager packageManager = Environment.getPackageManager(); ComponentName componentName = component.getComponentName(); @@ -43,7 +43,7 @@ public FComponent(PackageParser.Component component, ComponentInfo info) { if (component.intents != null && component.intents.size() > 0) { intents = new ArrayList<>(component.intents.size()); for (II intent : component.intents) { - intents.add(new FIntentFilter(intent)); + intents.add(new IntentFilter(intent)); } } } diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPathPermission.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPathPermission.java deleted file mode 100644 index f10d3de1..00000000 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPathPermission.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.ironman.framework.bean.app; - -import android.content.pm.PathPermission; - -public class FPathPermission extends FPatternMatcher { - - public FPermission readPermission; - public FPermission writePermission; - - public FPathPermission(PathPermission pathPermission) { - super(pathPermission); - readPermission = new FPermission(pathPermission.getReadPermission()); - writePermission = new FPermission(pathPermission.getWritePermission()); - } -} \ No newline at end of file diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FIntentFilter.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/IntentFilter.java similarity index 75% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/app/FIntentFilter.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/app/IntentFilter.java index 13696208..94be5a89 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FIntentFilter.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/IntentFilter.java @@ -1,24 +1,22 @@ package org.ironman.framework.bean.app; -import android.content.IntentFilter; import android.os.Build; -import android.os.PatternMatcher; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -public class FIntentFilter { +public class IntentFilter { public List actions; public List categories; public List dataSchemes; - public List dataSchemeSpecificParts; - public List dataAuthorities; - public List dataPaths; + public List dataSchemeSpecificParts; + public List dataAuthorities; + public List dataPaths; public List dataTypes; - public FIntentFilter(IntentFilter intent) { + public IntentFilter(android.content.IntentFilter intent) { if (intent.countActions() > 0) { actions = new ArrayList<>(intent.countActions()); Iterator it = intent.actionsIterator(); @@ -46,16 +44,16 @@ public FIntentFilter(IntentFilter intent) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (intent.countDataSchemeSpecificParts() > 0) { dataSchemeSpecificParts = new ArrayList<>(intent.countDataSchemeSpecificParts()); - Iterator it = intent.schemeSpecificPartsIterator(); + Iterator it = intent.schemeSpecificPartsIterator(); while (it.hasNext()) { - dataSchemeSpecificParts.add(new FPatternMatcher(it.next())); + dataSchemeSpecificParts.add(new PatternMatcher(it.next())); } } } if (intent.countDataAuthorities() > 0) { dataAuthorities = new ArrayList<>(intent.countDataAuthorities()); - Iterator it = intent.authoritiesIterator(); + Iterator it = intent.authoritiesIterator(); while (it.hasNext()) { dataAuthorities.add(new AuthorityEntry(it.next())); } @@ -63,9 +61,9 @@ public FIntentFilter(IntentFilter intent) { if (intent.countDataPaths() > 0) { dataPaths = new ArrayList<>(intent.countDataPaths()); - Iterator it = intent.pathsIterator(); + Iterator it = intent.pathsIterator(); while (it.hasNext()) { - dataPaths.add(new FPatternMatcher(it.next())); + dataPaths.add(new PatternMatcher(it.next())); } } @@ -84,7 +82,7 @@ public static class AuthorityEntry { public String host; public int port; - public AuthorityEntry(IntentFilter.AuthorityEntry authority) { + public AuthorityEntry(android.content.IntentFilter.AuthorityEntry authority) { host = authority.getHost(); port = authority.getPort(); } diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPackage.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Package.java similarity index 79% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPackage.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/app/Package.java index 03bc0ca5..5a118611 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPackage.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Package.java @@ -14,9 +14,9 @@ * Created by hu on 18-12-29. */ -public class FPackage { +public class Package { - private static final String TAG = FPackage.class.getSimpleName(); + private static final String TAG = Package.class.getSimpleName(); public String name; public String appName; @@ -30,18 +30,18 @@ public class FPackage { public boolean debuggable; public boolean allowBackup; - public List requestedPermissions; - public List permissions; - public List activities; - public List services; - public List receivers; - public List providers; + public List requestedPermissions; + public List permissions; + public List activities; + public List services; + public List receivers; + public List providers; - public FPackage(PackageInfo info) { + public Package(PackageInfo info) { this(info, true); } - public FPackage(PackageInfo info, boolean skipParse) { + public Package(PackageInfo info, boolean skipParse) { name = info.packageName; appName = PackageUtil.getApplicationName(info); userId = info.applicationInfo.uid; @@ -67,42 +67,42 @@ public FPackage(PackageInfo info, boolean skipParse) { if (pkg.requestedPermissions != null && pkg.requestedPermissions.size() > 0) { requestedPermissions = new ArrayList<>(pkg.requestedPermissions.size()); for (String permission : pkg.requestedPermissions) { - requestedPermissions.add(new FPermission(permission)); + requestedPermissions.add(new Permission(permission)); } } if (pkg.permissions != null && pkg.permissions.size() > 0) { permissions = new ArrayList<>(pkg.permissions.size()); for (PackageParser.Permission p : pkg.permissions) { - permissions.add(new FPermission(p.info.name)); + permissions.add(new Permission(p.info.name)); } } if (pkg.activities != null && pkg.activities.size() > 0) { activities = new ArrayList<>(pkg.activities.size()); for (PackageParser.Activity a : pkg.activities) { - activities.add(new FActivity(a)); + activities.add(new Activity(a)); } } if (pkg.services != null && pkg.services.size() > 0) { services = new ArrayList<>(pkg.services.size()); for (PackageParser.Service s : pkg.services) { - services.add(new FService(s)); + services.add(new Service(s)); } } if (pkg.receivers != null && pkg.receivers.size() > 0) { receivers = new ArrayList<>(pkg.receivers.size()); for (PackageParser.Activity r : pkg.receivers) { - receivers.add(new FReceiver(r)); + receivers.add(new Receiver(r)); } } if (pkg.providers != null && pkg.providers.size() > 0) { providers = new ArrayList<>(pkg.providers.size()); for (PackageParser.Provider p : pkg.providers) { - providers.add(new FProvider(p)); + providers.add(new Provider(p)); } } } diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/PathPermission.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/PathPermission.java new file mode 100644 index 00000000..62078b51 --- /dev/null +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/PathPermission.java @@ -0,0 +1,14 @@ +package org.ironman.framework.bean.app; + + +public class PathPermission extends PatternMatcher { + + public Permission readPermission; + public Permission writePermission; + + public PathPermission(android.content.pm.PathPermission pathPermission) { + super(pathPermission); + readPermission = new Permission(pathPermission.getReadPermission()); + writePermission = new Permission(pathPermission.getWritePermission()); + } +} \ No newline at end of file diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPatternMatcher.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/PatternMatcher.java similarity index 86% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPatternMatcher.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/app/PatternMatcher.java index 7d292e4d..7081701c 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPatternMatcher.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/PatternMatcher.java @@ -1,8 +1,6 @@ package org.ironman.framework.bean.app; -import android.os.PatternMatcher; - -public class FPatternMatcher { +public class PatternMatcher { public enum Type { literal, @@ -14,7 +12,7 @@ public enum Type { public String path; public Type type; - public FPatternMatcher(PatternMatcher patternMatcher) { + public PatternMatcher(android.os.PatternMatcher patternMatcher) { path = patternMatcher.getPath(); type = getType(patternMatcher.getType()); } diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPermission.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Permission.java similarity index 81% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPermission.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/app/Permission.java index 3df44123..8ca2a97c 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FPermission.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Permission.java @@ -4,7 +4,7 @@ import org.ironman.framework.util.PermissionUtil; -public class FPermission { +public class Permission { public enum Protection { dangerous, @@ -16,12 +16,12 @@ public enum Protection { public String name; public Protection protection; - public FPermission(String name) { + public Permission(String name) { this.name = name; this.protection = PermissionUtil.getProtection(name); } - public FPermission(PackageParser.Permission perm) { + public Permission(PackageParser.Permission perm) { this.name = perm.info.name; this.protection = PermissionUtil.getProtection(perm.info); } diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FProvider.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Provider.java similarity index 63% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/app/FProvider.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/app/Provider.java index 334b8f9f..2406b5cd 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FProvider.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Provider.java @@ -7,34 +7,34 @@ import java.util.List; @SuppressWarnings({"rawtypes", "unchecked"}) -public class FProvider extends FComponent { +public class Provider extends Component { public String authority; - public FPermission readPermission; - public FPermission writePermission; - public List uriPermissionPatterns; - public List pathPermissions; + public Permission readPermission; + public Permission writePermission; + public List uriPermissionPatterns; + public List pathPermissions; - public FProvider(PackageParser.Provider provider) { + public Provider(PackageParser.Provider provider) { super(provider, provider.info); authority = provider.info.authority; if (!TextUtils.isEmpty(provider.info.readPermission)) { - readPermission = new FPermission(provider.info.readPermission); + readPermission = new Permission(provider.info.readPermission); } if (!TextUtils.isEmpty(provider.info.writePermission)) { - writePermission = new FPermission(provider.info.writePermission); + writePermission = new Permission(provider.info.writePermission); } if (provider.info.uriPermissionPatterns != null) { uriPermissionPatterns = new ArrayList<>(provider.info.uriPermissionPatterns.length); for (android.os.PatternMatcher uriPermissionPattern : provider.info.uriPermissionPatterns) { - uriPermissionPatterns.add(new FPatternMatcher(uriPermissionPattern)); + uriPermissionPatterns.add(new PatternMatcher(uriPermissionPattern)); } } if (provider.info.pathPermissions != null) { pathPermissions = new ArrayList<>(provider.info.pathPermissions.length); for (android.content.pm.PathPermission pathPermission : provider.info.pathPermissions) { - pathPermissions.add(new FPathPermission(pathPermission)); + pathPermissions.add(new PathPermission(pathPermission)); } } } diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FReceiver.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Receiver.java similarity index 57% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/app/FReceiver.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/app/Receiver.java index 99639c47..a9743155 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FReceiver.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Receiver.java @@ -4,14 +4,14 @@ import android.text.TextUtils; @SuppressWarnings({"rawtypes", "unchecked"}) -public class FReceiver extends FComponent { +public class Receiver extends Component { - public FPermission permission; + public Permission permission; - public FReceiver(PackageParser.Activity receiver) { + public Receiver(PackageParser.Activity receiver) { super(receiver, receiver.info); if (!TextUtils.isEmpty(receiver.info.permission)) { - permission = new FPermission(receiver.info.permission); + permission = new Permission(receiver.info.permission); } } } diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FService.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Service.java similarity index 58% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/app/FService.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/app/Service.java index 668c6dca..96edd3b9 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/app/FService.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/app/Service.java @@ -4,14 +4,14 @@ import android.text.TextUtils; @SuppressWarnings({"rawtypes", "unchecked"}) -public class FService extends FComponent { +public class Service extends Component { - public FPermission permission; + public Permission permission; - public FService(PackageParser.Service service) { + public Service(PackageParser.Service service) { super(service, service.info); if (!TextUtils.isEmpty(service.info.permission)) { - permission = new FPermission(service.info.permission); + permission = new Permission(service.info.permission); } } } diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/net/FInetSocket.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/net/InetSocket.java similarity index 84% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/net/FInetSocket.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/net/InetSocket.java index d8d89884..421a7d54 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/net/FInetSocket.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/net/InetSocket.java @@ -1,6 +1,6 @@ package org.ironman.framework.bean.net; -public class FInetSocket extends FSocket { +public class InetSocket extends Socket { public String localAddress; public int localPort; diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/net/FSocket.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/net/Socket.java similarity index 86% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/net/FSocket.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/net/Socket.java index f259dcb4..a7b998d1 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/net/FSocket.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/net/Socket.java @@ -1,6 +1,6 @@ package org.ironman.framework.bean.net; -public class FSocket { +public class Socket { public String proto; public String state; public long inode; diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/net/FUnixSocket.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/net/UnixSocket.java similarity index 84% rename from agent/android/framework/src/main/java/org/ironman/framework/bean/net/FUnixSocket.java rename to agent/android/framework/src/main/java/org/ironman/framework/bean/net/UnixSocket.java index 6a4e39a2..e84c512d 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/bean/net/FUnixSocket.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/net/UnixSocket.java @@ -4,7 +4,7 @@ * Created by hu on 19-2-13. */ -public class FUnixSocket extends FSocket { +public class UnixSocket extends Socket { public long refCnt; public String flags; public String type; diff --git a/agent/android/framework/src/main/java/org/ironman/framework/bean/process/Process.java b/agent/android/framework/src/main/java/org/ironman/framework/bean/process/Process.java new file mode 100644 index 00000000..183cf223 --- /dev/null +++ b/agent/android/framework/src/main/java/org/ironman/framework/bean/process/Process.java @@ -0,0 +1,21 @@ +package org.ironman.framework.bean.process; + +public class Process { + public long pid; + public long uid; + public long gid; + public String state; + public String cmd; + public String name; + public long ppid; + public long pgid; + public long sid; + public long tty; + public long utime; + public long stime; + public long nice; + public long startTime; + public long vsz; + public long rss; + +} diff --git a/agent/android/framework/src/main/java/org/ironman/framework/util/NetworkUtil.java b/agent/android/framework/src/main/java/org/ironman/framework/util/NetworkUtil.java index 92291008..7bd50748 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/util/NetworkUtil.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/util/NetworkUtil.java @@ -3,9 +3,9 @@ import android.text.TextUtils; import org.ironman.framework.Const; -import org.ironman.framework.bean.net.FInetSocket; -import org.ironman.framework.bean.net.FSocket; -import org.ironman.framework.bean.net.FUnixSocket; +import org.ironman.framework.bean.net.InetSocket; +import org.ironman.framework.bean.net.Socket; +import org.ironman.framework.bean.net.UnixSocket; import java.io.File; import java.io.IOException; @@ -31,8 +31,8 @@ public class NetworkUtil { private static final String PROC_NET_RAW6 = "/proc/net/raw6"; private static final String PROC_NET_UNIX = "/proc/net/unix"; - public static List getTcpSockets() throws IOException { - List sockets = new ArrayList<>(); + public static List getTcpSockets() throws IOException { + List sockets = new ArrayList<>(); parse("tcp", PROC_NET_TCP, tcpParser, sockets); if (new File(PROC_NET_TCP6).exists()) { parse("tcp6", PROC_NET_TCP6, tcpParser, sockets); @@ -40,8 +40,8 @@ public static List getTcpSockets() throws IOException { return sockets; } - public static List getUdpSockets() throws IOException { - List sockets = new ArrayList<>(); + public static List getUdpSockets() throws IOException { + List sockets = new ArrayList<>(); parse("udp", PROC_NET_UDP, udpParser, sockets); if (new File(PROC_NET_UDP6).exists()) { parse("udp6", PROC_NET_UDP6, udpParser, sockets); @@ -49,8 +49,8 @@ public static List getUdpSockets() throws IOException { return sockets; } - public static List getRawSockets() throws IOException { - List sockets = new ArrayList<>(); + public static List getRawSockets() throws IOException { + List sockets = new ArrayList<>(); parse("raw", PROC_NET_RAW, rawParser, sockets); if (new File(PROC_NET_RAW6).exists()) { parse("raw6", PROC_NET_RAW6, rawParser, sockets); @@ -58,13 +58,13 @@ public static List getRawSockets() throws IOException { return sockets; } - public static List getUnixSockets() throws IOException { - List sockets = new ArrayList<>(); + public static List getUnixSockets() throws IOException { + List sockets = new ArrayList<>(); parse("unix", PROC_NET_UNIX, unixParser, sockets); return sockets; } - private static void parse(String proto, String path, Parser parser, List list) throws IOException { + private static void parse(String proto, String path, Parser parser, List list) throws IOException { String result = FileUtil.readString(path); String[] lines = result.split(Const.LINE_SEPARATOR); for (int i = 1; i < lines.length; i++) { @@ -94,11 +94,11 @@ private static InetAddress parseInetAddress(String address) throws Exception { } } - private interface Parser { + private interface Parser { T parse(String proto, String line) throws Exception; } - private static final Parser tcpParser = (proto, line) -> { + private static final Parser tcpParser = (proto, line) -> { String[] detail = line.split(" +"); if (detail.length < 10) { @@ -115,7 +115,7 @@ private interface Parser { int uid = CommonUtil.parseInt(detail[7], 0); long inode = CommonUtil.parseInt(detail[9], 0); - FInetSocket socket = new FInetSocket(); + InetSocket socket = new InetSocket(); socket.proto = proto; switch (state) { @@ -173,7 +173,7 @@ private interface Parser { return socket; }; - private static final Parser udpParser = (proto, line) -> { + private static final Parser udpParser = (proto, line) -> { String[] detail = line.split(" +"); if (detail.length < 10) { throw new Exception(); @@ -189,7 +189,7 @@ private interface Parser { int uid = CommonUtil.parseInt(detail[7], 0); long inode = CommonUtil.parseInt(detail[9], 0); - FInetSocket socket = new FInetSocket(); + InetSocket socket = new InetSocket(); socket.proto = proto; switch (state) { @@ -217,7 +217,7 @@ private interface Parser { return socket; }; - private static final Parser rawParser = (proto, line) -> { + private static final Parser rawParser = (proto, line) -> { String[] detail = line.split(" +"); if (detail.length < 10) { throw new Exception(); @@ -233,7 +233,7 @@ private interface Parser { int uid = CommonUtil.parseInt(detail[7], 0); long inode = CommonUtil.parseInt(detail[9], 0); - FInetSocket socket = new FInetSocket(); + InetSocket socket = new InetSocket(); socket.proto = proto; socket.state = String.valueOf(state); socket.localAddress = localAddress.getHostAddress(); @@ -249,7 +249,7 @@ private interface Parser { return socket; }; - private static final Parser unixParser = (proto, line) -> { + private static final Parser unixParser = (proto, line) -> { String[] detail = line.split(" +"); if (detail.length < 6) { throw new Exception(); @@ -263,7 +263,7 @@ private interface Parser { long inode = CommonUtil.parseLong(detail[6], 0); String path = detail.length > 7 ? detail[7] : null; - FUnixSocket socket = new FUnixSocket(); + UnixSocket socket = new UnixSocket(); if ((int) protocol == 0) { socket.proto = proto; } else { diff --git a/agent/android/framework/src/main/java/org/ironman/framework/util/PermissionUtil.java b/agent/android/framework/src/main/java/org/ironman/framework/util/PermissionUtil.java index 5af2d2fe..cb16241f 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/util/PermissionUtil.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/util/PermissionUtil.java @@ -5,7 +5,7 @@ import android.text.TextUtils; import org.ironman.framework.Environment; -import org.ironman.framework.bean.app.FPermission; +import org.ironman.framework.bean.app.Permission; /** * Created by hu on 18-12-17. @@ -15,7 +15,7 @@ public class PermissionUtil { private static final String TAG = PermissionUtil.class.getSimpleName(); - public static FPermission.Protection getProtection(String permission) { + public static Permission.Protection getProtection(String permission) { if (!TextUtils.isEmpty(permission)) { try { return getProtection(Environment.getPackageManager().getPermissionInfo(permission, -1)); @@ -23,21 +23,21 @@ public static FPermission.Protection getProtection(String permission) { LogUtil.printStackTrace(TAG, e, null); } } - return FPermission.Protection.normal; + return Permission.Protection.normal; } - public static FPermission.Protection getProtection(PermissionInfo permissionInfo) { + public static Permission.Protection getProtection(PermissionInfo permissionInfo) { switch (permissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) { case PermissionInfo.PROTECTION_DANGEROUS: - return FPermission.Protection.dangerous; + return Permission.Protection.dangerous; case PermissionInfo.PROTECTION_NORMAL: - return FPermission.Protection.normal; + return Permission.Protection.normal; case PermissionInfo.PROTECTION_SIGNATURE: - return FPermission.Protection.signature; + return Permission.Protection.signature; case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM: - return FPermission.Protection.signatureOrSystem; + return Permission.Protection.signatureOrSystem; default: - return FPermission.Protection.normal; + return Permission.Protection.normal; } } diff --git a/agent/android/framework/src/main/java/org/ironman/framework/util/ProcessUtil.java b/agent/android/framework/src/main/java/org/ironman/framework/util/ProcessUtil.java index 44bcca6c..7d38400c 100644 --- a/agent/android/framework/src/main/java/org/ironman/framework/util/ProcessUtil.java +++ b/agent/android/framework/src/main/java/org/ironman/framework/util/ProcessUtil.java @@ -1,6 +1,15 @@ package org.ironman.framework.util; +import org.ironman.framework.bean.process.Process; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class ProcessUtil { @@ -14,4 +23,93 @@ public static String getProcessName(int pid, String defaultValue) { return defaultValue; } } + + public static List getProcessList() { + List processList = new ArrayList<>(); + + File proc = new File("/proc/"); + File[] files = proc.listFiles((dir, name) -> name.matches("^\\d+$")); + if (files == null) { + return processList; + } + for (File dir : files) { + Process process = new Process(); + + process.pid = Integer.parseInt(dir.getName()); + + try { + BufferedReader reader = new BufferedReader(new FileReader(new File(dir, "stat"))); + String line; + + while ((line = reader.readLine()) != null) { + Pattern pattern = Pattern.compile("^(\\S+)\\s+\\((.+)\\)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(.*)$"); + Matcher matcher = pattern.matcher(line); + if (matcher.matches()) { + process.cmd = "[" + matcher.group(2) + "]"; + process.name = process.cmd; + process.state = matcher.group(3); + process.ppid = Long.parseLong(matcher.group(4)); + process.pgid = Long.parseLong(matcher.group(5)); + process.sid = Long.parseLong(matcher.group(6)); + process.tty = Long.parseLong(matcher.group(7)); + process.utime = Long.parseLong(matcher.group(8)); + process.stime = Long.parseLong(matcher.group(9)); + process.nice = Long.parseLong(matcher.group(12)); + process.startTime = Long.parseLong(matcher.group(13)); + process.vsz = Long.parseLong(matcher.group(14)); + process.rss = Long.parseLong(matcher.group(15)); + } + } + } catch (IOException e) { + // ignore + } + + try { + BufferedReader reader = new BufferedReader(new FileReader(new File(dir, "status"))); + String line; + + while ((line = reader.readLine()) != null) { + if (line.startsWith("Uid:")) { + process.uid = Long.parseLong(line.split("\\s+")[1]); + } else if (line.startsWith("Gid:")) { + process.gid = Long.parseLong(line.split("\\s+")[1]); + } + } + + reader.close(); + } catch (IOException e) { + // ignore + } + + try { + BufferedReader reader = new BufferedReader(new FileReader(new File(dir, "cmdline"))); + String line; + StringBuilder buffer = new StringBuilder(); + while ((line = reader.readLine()) != null) { + buffer.append(line); + } + + String cmdline = buffer.toString().trim().replace('\u0000', ' '); + if (cmdline.length() > 0) { + process.cmd = cmdline; + String[] args = cmdline.split(" +"); + if (args.length > 0) { + String name = args[0]; + int index = name.lastIndexOf("/"); + process.name = index >= 0 ? name.substring(index + 1) : name; + } + } + + reader.close(); + } catch (IOException e) { + // ignore + } + + processList.add(process); + + } + + return processList; + } + } diff --git a/agent/android/tools/src/main/java/android/tools/command/PackageCommand.java b/agent/android/tools/src/main/java/android/tools/command/PackageCommand.java index 10877b1d..32426800 100644 --- a/agent/android/tools/src/main/java/android/tools/command/PackageCommand.java +++ b/agent/android/tools/src/main/java/android/tools/command/PackageCommand.java @@ -6,7 +6,7 @@ import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; -import org.ironman.framework.bean.app.FPackage; +import org.ironman.framework.bean.app.Package; import org.ironman.framework.util.GsonUtil; import org.ironman.framework.util.PackageUtil; @@ -47,14 +47,14 @@ public void run() { packageInfos = PackageUtil.getInstalledPackages(); } - List packages = new ArrayList<>(packageInfos.size()); + List packages = new ArrayList<>(packageInfos.size()); for (PackageInfo packageInfo : packageInfos) { if (system && !PackageUtil.isSystemApp(packageInfo)) { // ignore } else if (nonSystem && PackageUtil.isSystemApp(packageInfo)) { // ignore } else { - packages.add(new FPackage(packageInfo, simple)); + packages.add(new Package(packageInfo, simple)); } } diff --git a/agent/android/tools/src/main/java/android/tools/command/ProcessCommand.java b/agent/android/tools/src/main/java/android/tools/command/ProcessCommand.java new file mode 100644 index 00000000..f8c76d8b --- /dev/null +++ b/agent/android/tools/src/main/java/android/tools/command/ProcessCommand.java @@ -0,0 +1,23 @@ +package android.tools.command; + +import android.tools.Output; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +import org.ironman.framework.util.GsonUtil; +import org.ironman.framework.util.ProcessUtil; + +@Parameters(commandNames = "process") +public class ProcessCommand extends Command { + + @Parameter(names = {"--list"}, order = 1, description = "List all processes") + private boolean list = false; + + @Override + public void run() { + if (list) { + Output.out.print(GsonUtil.toJson(ProcessUtil.getProcessList())); + } + } +} diff --git a/src/linktools/android/_adb.py b/src/linktools/android/_adb.py index 75364f81..fbd8eea9 100644 --- a/src/linktools/android/_adb.py +++ b/src/linktools/android/_adb.py @@ -31,7 +31,7 @@ import re from typing import Optional, Any, Generator -from ._struct import Package, UnixSocket, InetSocket +from ._struct import Package, UnixSocket, InetSocket, Process from .. import utils, environ from ..decorator import cached_property, cached_classproperty from ..device import BridgeError, Bridge, BaseDevice @@ -165,9 +165,10 @@ def shell(self, *args: [Any], privilege: bool = False, **kwargs) -> str: :param privilege: 是否以root权限运行 :return: adb输出结果 """ - args = ["shell", *args] \ + cmd = utils.list2cmdline([str(arg) for arg in args]) + args = ["shell", cmd] \ if not privilege or self.uid == 0 \ - else ["shell", "su", "-c", *args] + else ["shell", "su", "-c", cmd] return self.exec(*args, **kwargs) def sudo(self, *args: [Any], **kwargs) -> str: @@ -357,7 +358,7 @@ def is_file_exist(self, path: str, **kwargs) -> bool: :param path: 文件路径 :return: 是否存在 """ - args = ["[", "-a", path, "]", "&&", "echo", "-n ", "1"] + args = ["[", "-a", path, "]", "&&", "echo", "-n", "1"] out = self.shell(*args, **kwargs) return utils.bool(utils.int(out, default=0), default=False) @@ -465,16 +466,19 @@ def get_uid(self, package_name: str): :param package_name: 包名 :return: uid """ - info = self.get_package(package_name) + info = self.get_package(package_name, simple=True) return info.user_id if info else None - def get_package(self, package_name: str, **kwargs) -> Optional[Package]: + def get_package(self, package_name: str, simple: bool = None, **kwargs) -> Optional[Package]: """ 根据包名获取包信息 :param package_name: 包名 + :param simple: 只获取基本信息 :return: 包信息 """ args = ["package", "--packages", package_name] + if simple is True: + args.append("--simple") objs = json.loads(self.call_agent(*args, **kwargs)) return Package(objs[0]) if len(objs) > 0 else None @@ -557,6 +561,14 @@ def _get_sockets(self, type, command, **kwargs): result.append(type(obj)) return result + def get_processes(self, **kwargs) -> [Process]: + result = [] + agent_args = ["process", "--list"] + objs = json.loads(self.call_agent(*agent_args, **kwargs)) + for obj in objs: + result.append(Process(obj)) + return result + @classmethod def get_safe_path(cls, path: str) -> str: """ @@ -571,15 +583,6 @@ def get_safe_path(cls, path: str) -> str: return result temp = result - @classmethod - def get_safe_command(cls, seq: [str]) -> str: - """ - 用双引号把命令包起来 - :param seq: 原命令 - :return: 双引号包起来的命令 - """ - return utils.list2cmdline(seq) - @classmethod def get_storage_path(cls, *paths: [str]) -> str: """ diff --git a/src/linktools/android/_struct.py b/src/linktools/android/_struct.py index 6a30de2e..c2e4b7e5 100644 --- a/src/linktools/android/_struct.py +++ b/src/linktools/android/_struct.py @@ -165,8 +165,8 @@ class Package: def __init__(self, obj: dict): self.name = utils.get_item(obj, "name", type=str, default="") self.app_name = utils.get_item(obj, "appName", type=str, default="") - self.user_id = utils.get_item(obj, "userId", type=int, default="") - self.gids = utils.get_item(obj, "gids", type=str, default=[]) + self.user_id = utils.get_item(obj, "userId", type=int, default=0) + self.gids = utils.get_list_item(obj, "gids", type=int, default=[]) self.source_dir = utils.get_item(obj, "sourceDir", type=str, default="") self.version_code = utils.get_item(obj, "versionCode", type=str, default="") self.version_name = utils.get_item(obj, "versionName", type=str, default="") @@ -229,7 +229,7 @@ class Socket: def __init__(self, obj: dict): self.proto = utils.get_item(obj, "proto", type=str, default="") self.state = utils.get_item(obj, "state", type=str, default="") - self.inode = utils.get_item(obj, "inode", type=int, default="") + self.inode = utils.get_item(obj, "inode", type=int, default=0) self.listening = utils.get_item(obj, "listening", type=bool, default=False) def is_dangerous(self): @@ -241,19 +241,19 @@ class InetSocket(Socket): def __init__(self, obj: dict): super().__init__(obj) self.local_address = utils.get_item(obj, "localAddress", type=str, default="") - self.local_port = utils.get_item(obj, "localPort", type=int, default="") + self.local_port = utils.get_item(obj, "localPort", type=int, default=0) self.remote_address = utils.get_item(obj, "remoteAddress", type=str, default="") - self.remote_port = utils.get_item(obj, "remotePort", type=int, default="") - self.uid = utils.get_item(obj, "uid", type=int, default="") - self.transmit_queue = utils.get_item(obj, "transmitQueue", type=int, default="") - self.receive_queue = utils.get_item(obj, "receiveQueue", type=int, default="") + self.remote_port = utils.get_item(obj, "remotePort", type=int, default=0) + self.uid = utils.get_item(obj, "uid", type=int, default=0) + self.transmit_queue = utils.get_item(obj, "transmitQueue", type=int, default=0) + self.receive_queue = utils.get_item(obj, "receiveQueue", type=int, default=0) class UnixSocket(Socket): def __init__(self, obj: dict): super().__init__(obj) - self.ref_cnt = utils.get_item(obj, "refCnt", type=int, default="") + self.ref_cnt = utils.get_item(obj, "refCnt", type=int, default=0) self.flags = utils.get_item(obj, "flags", type=str, default="") self.type = utils.get_item(obj, "type", type=str, default=[]) self.path = utils.get_item(obj, "path", type=str, default="") @@ -262,3 +262,24 @@ def __init__(self, obj: dict): def is_dangerous(self): return super().is_dangerous() and (self.readable or self.writable) + + +class Process: + + def __init__(self, obj: dict): + self.pid = utils.get_item(obj, "pid", type=int, default=0) + self.uid = utils.get_item(obj, "uid", type=int, default=0) + self.gid = utils.get_item(obj, "gid", type=int, default=0) + self.state = utils.get_item(obj, "state", type=str, default="") + self.cmd = utils.get_item(obj, "cmd", type=str, default="") + self.name = utils.get_item(obj, "name", type=str, default="") + self.ppid = utils.get_item(obj, "ppid", type=int, default=0) + self.pgid = utils.get_item(obj, "pgid", type=int, default=0) + self.sid = utils.get_item(obj, "sid", type=int, default=0) + self.tty = utils.get_item(obj, "tty", type=int, default=0) + self.utime = utils.get_item(obj, "utime", type=int, default=0) + self.stime = utils.get_item(obj, "stime", type=int, default=0) + self.nice = utils.get_item(obj, "nice", type=int, default=0) + self.start_time = utils.get_item(obj, "startTime", type=int, default=0) + self.vsz = utils.get_item(obj, "vsz", type=int, default=0) + self.rss = utils.get_item(obj, "rss", type=int, default=0) diff --git a/src/linktools/assets/android-tools.apk b/src/linktools/assets/android-tools.apk index 1b94b7ba..0a85bf05 100644 Binary files a/src/linktools/assets/android-tools.apk and b/src/linktools/assets/android-tools.apk differ diff --git a/src/linktools/assets/android-tools.json b/src/linktools/assets/android-tools.json index ab810ba4..6e17932a 100644 --- a/src/linktools/assets/android-tools.json +++ b/src/linktools/assets/android-tools.json @@ -1,10 +1,10 @@ { "ANDROID_TOOL_BRIDGE_APK": { "name": "android-tools.apk", - "md5": "d7f62bda3865f5321614035dc1fc9af7", + "md5": "466c349cf14cb1cf4034b8274e84ca1f", "main": "android.tools.Main", - "size": 81735, - "time": "2022-11-19 12:54:33" + "size": 82895, + "time": "2023-05-03 15:42:45" }, "ANDROID_TOOL_FRIDA_SERVER": { "name": "frida-server-{version}-android-{abi}", diff --git a/src/linktools/frida/android.py b/src/linktools/frida/android.py index 59de1e8a..14e47350 100644 --- a/src/linktools/frida/android.py +++ b/src/linktools/frida/android.py @@ -34,7 +34,7 @@ def __init__(self, device: Device = None, local_port: int = 47042, remote_port: self._local_port = local_port self._remote_port = remote_port self._forward: Optional[Stoppable] = None - self._environ = self.Environ(self._device.abi, frida.__version__) + self._executable = self.Executable(self._device.abi, frida.__version__) self._server_prefix = "fs-ln-" self._server_name = f"{self._server_prefix}{utils.make_uuid()}" @@ -52,8 +52,8 @@ def remote_port(self): @classmethod def setup(cls, abis: [str] = ("arm", "arm64", "x86_64", "x86"), version: str = frida.__version__): for abi in abis: - env = cls.Environ(abi, version) - env.prepare() + exe = cls.Executable(abi, version) + exe.prepare() def _start(self): @@ -62,10 +62,10 @@ def _start(self): # 先下载frida server,然后把server推送到设备上 if not self._device.is_file_exist(remote_path): - self._environ.prepare() _logger.info(f"Push frida server to remote: {remote_path}") temp_path = self._device.get_storage_path("frida", remote_name) - self._device.push(self._environ.server_path, temp_path, log_output=True) + self._executable.prepare() + self._device.push(self._executable.path, temp_path, log_output=True) self._device.sudo("mv", temp_path, remote_path, log_output=True) self._device.sudo("chmod", "755", remote_path, log_output=True) @@ -79,12 +79,10 @@ def _start(self): # 接下来新开一个进程运行frida server,并且输出一下是否出错 self._device.sudo( - self._device.get_safe_command([ - self._server_path, - "-d", "fs-binaries", - "-l", f"0.0.0.0:{self._remote_port}", - "-D", "&" - ]), + self._server_path, + "-d", "fs-binaries", + "-l", f"0.0.0.0:{self._remote_port}", + "-D", "&", ignore_errors=True, log_output=True, ) @@ -96,7 +94,7 @@ def _stop(self): try: # 就算杀死adb进程,frida server也不一定真的结束了,所以kill一下frida server进程 process_name_lc = f"{self._server_prefix}*".lower() - for process in self.enumerate_processes(): + for process in self._device.get_processes(): if fnmatch.fnmatchcase(process.name.lower(), process_name_lc): _logger.debug(f"Find frida server process({process.name}:{process.pid}), kill it") self._device.sudo("kill", "-9", process.pid, ignore_errors=True) @@ -104,23 +102,23 @@ def _stop(self): # 把转发端口给移除了,不然会一直占用这个端口 self._forward.stop() - class Environ: + class Executable: def __init__(self, abi: str, version: str): cfg = environ.get_config("ANDROID_TOOL_FRIDA_SERVER", type=dict) cfg.update(version=version, abi=abi) - self.download_url = cfg["url"].format(**cfg) - self.server_name = cfg["name"].format(**cfg) - self.server_path = environ.get_data_path("frida", self.server_name, create_parent=True) + self.url = cfg["url"].format(**cfg) + self.name = cfg["name"].format(**cfg) + self.path = environ.get_data_path("frida", self.name, create_parent=True) def prepare(self): - if os.path.exists(self.server_path): + if os.path.exists(self.path): return _logger.info("Download frida server ...") - with utils.UrlFile(self.download_url) as file: - if os.path.exists(self.server_path): + with utils.UrlFile(self.url) as file: + if os.path.exists(self.path): return - with lzma.open(file.save(), "rb") as read, open(self.server_path, "wb") as write: + with lzma.open(file.save(), "rb") as read, open(self.path, "wb") as write: shutil.copyfileobj(read, write) file.clear() diff --git a/src/linktools/utils/_utils.py b/src/linktools/utils/_utils.py index 527c2a55..d899625c 100755 --- a/src/linktools/utils/_utils.py +++ b/src/linktools/utils/_utils.py @@ -35,7 +35,7 @@ import time import uuid from collections.abc import Iterable, Sized -from typing import Union, Callable, Optional, Type, Any, List, TypeVar +from typing import Union, Callable, Optional, Type, Any, List, TypeVar, Tuple, Set from urllib.request import urlopen _T = TypeVar("_T") @@ -263,7 +263,7 @@ def pop_item(obj: Any, *keys: Any, type: Type[_T] = None, default: _T = None) -> # 1noinspection PyShadowingBuiltins, PyUnresolvedReferences -def get_list_item(obj: Any, *keys: Any, type: Type[_T] = None, default: List[_T] = None) -> List[Optional[_T]]: +def get_list_item(obj: Any, *keys: Any, type: Type[_T] = None, default: List[_T] = None) -> Optional[List[_T]]: """ 获取子项(列表) :param obj: 对象 @@ -273,7 +273,7 @@ def get_list_item(obj: Any, *keys: Any, type: Type[_T] = None, default: List[_T] :return: 子项 """ objs = get_item(obj, *keys, default=None) - if objs is None or not isinstance(objs, Iterable): + if objs is None or not isinstance(objs, (Tuple, List, Set)): return default result = [] for obj in objs: