mirror of
https://github.com/M66B/NetGuard.git
synced 2025-01-03 13:54:09 +00:00
Native get uid
This commit is contained in:
parent
d4b7b93a55
commit
064c3d4d4b
4 changed files with 104 additions and 103 deletions
|
@ -98,7 +98,6 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/objectFiles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard-rules" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
|
|
4
app/proguard-rules.pro
vendored
4
app/proguard-rules.pro
vendored
|
@ -23,9 +23,9 @@
|
|||
#NetGuard
|
||||
-keepnames class eu.faircode.netguard.** { *; }
|
||||
|
||||
# logPacket(int version, String saddr, int sport, String daddr, int dport, int protocol, String flags)
|
||||
# logPacket(int version, String saddr, int sport, String daddr, int dport, int protocol, String flags, int uid)
|
||||
-keep class eu.faircode.netguard.SinkholeService {
|
||||
void logPacket(int, java.lang.String, int, java.lang.String, int, int, java.lang.String);
|
||||
void logPacket(int, java.lang.String, int, java.lang.String, int, int, java.lang.String, int);
|
||||
}
|
||||
|
||||
#Support library
|
||||
|
|
|
@ -61,19 +61,15 @@ import android.util.Log;
|
|||
import android.util.TypedValue;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
@ -724,7 +720,7 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
receiveThread.start();
|
||||
}
|
||||
|
||||
private void logPacket(int version, String saddr, int sport, String daddr, int dport, int protocol, String flags) {
|
||||
private void logPacket(int version, String saddr, int sport, String daddr, int dport, int protocol, String flags, int uid) {
|
||||
try {
|
||||
int connection;
|
||||
if (last_connected)
|
||||
|
@ -735,19 +731,6 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
else
|
||||
connection = 0;
|
||||
|
||||
int tries = 0;
|
||||
int uid = getUid(version, InetAddress.getByName(saddr), sport, protocol);
|
||||
while (uid < 0 && tries < 10) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
tries++;
|
||||
uid = getUid(version, InetAddress.getByName(saddr), sport, protocol);
|
||||
if (uid >= 0)
|
||||
Log.w(TAG, "Uid found after try=" + tries);
|
||||
}
|
||||
|
||||
new DatabaseHelper(SinkholeService.this).insertLog(
|
||||
version,
|
||||
daddr,
|
||||
|
@ -762,51 +745,6 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
}
|
||||
}
|
||||
|
||||
public int getUid(int version, InetAddress source, int sport, int protocol) {
|
||||
StringBuilder addr = new StringBuilder();
|
||||
byte[] b = source.getAddress();
|
||||
for (int i = b.length - 1; i >= 0; i--)
|
||||
addr.append(String.format("%02X", b[i]));
|
||||
|
||||
String port = String.format("%04X", sport);
|
||||
|
||||
int uid = -1;
|
||||
if (version == 4) {
|
||||
uid = scanUid("0000000000000000FFFF0000" + addr.toString() + ":" + port, protocol == 6 ? "/proc/net/tcp6" : "/proc/net/udp6");
|
||||
if (uid < 0)
|
||||
uid = scanUid(addr.toString() + ":" + port, protocol == 6 ? "/proc/net/tcp" : "/proc/net/udp");
|
||||
if (uid < 0 && protocol == 17)
|
||||
uid = scanUid("00000000:" + port, "/proc/net/udp");
|
||||
} else
|
||||
uid = scanUid(addr.toString() + ":" + port, protocol == 6 ? "/proc/net/tcp6" : "/proc/net/udp6");
|
||||
|
||||
return uid;
|
||||
}
|
||||
|
||||
private static int scanUid(String addr, String name) {
|
||||
File file = new File(name);
|
||||
Scanner scanner = null;
|
||||
try {
|
||||
scanner = new Scanner(file);
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine().trim();
|
||||
if (line.startsWith("sl"))
|
||||
continue;
|
||||
|
||||
String[] field = line.split("\\s+");
|
||||
if (addr.equals(field[1]))
|
||||
return Integer.parseInt(field[7]);
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
} finally {
|
||||
if (scanner != null)
|
||||
scanner.close();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void stopReceiving() {
|
||||
if (receiveThread != null)
|
||||
receiveThread.interrupt();
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include <jni.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <malloc.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <android/log.h>
|
||||
#include <arpa/inet.h>
|
||||
|
@ -15,7 +14,7 @@
|
|||
|
||||
void decode(JNIEnv *env, jobject instance, jbyte *, int);
|
||||
|
||||
void scanproc6(const char *);
|
||||
int getUid(int protocol, int version, const char *psaddr, int psport);
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_eu_faircode_netguard_SinkholeService_jni_1init(JNIEnv *env, jobject instance) {
|
||||
|
@ -26,21 +25,18 @@ JNIEXPORT void JNICALL
|
|||
Java_eu_faircode_netguard_SinkholeService_jni_1decode(JNIEnv *env, jobject instance,
|
||||
jbyteArray buffer_, jint length) {
|
||||
jbyte *buffer = (*env)->GetByteArrayElements(env, buffer_, NULL);
|
||||
|
||||
decode(env, instance, buffer, length);
|
||||
|
||||
(*env)->ReleaseByteArrayElements(env, buffer_, buffer, 0);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_eu_faircode_netguard_SinkholeService_jni_1receive(JNIEnv *env, jobject instance, jint fd) {
|
||||
int len;
|
||||
jbyte *buffer = malloc(MAXPKT);
|
||||
jbyte buffer[MAXPKT];
|
||||
while (1) {
|
||||
len = read(fd, buffer, MAXPKT);
|
||||
len = read(fd, buffer, sizeof(buffer));
|
||||
if (len < 0) {
|
||||
__android_log_print(ANDROID_LOG_WARN, TAG, "Receive error %d", len);
|
||||
free(buffer);
|
||||
return;
|
||||
|
||||
} else if (len > 0)
|
||||
|
@ -52,16 +48,18 @@ Java_eu_faircode_netguard_SinkholeService_jni_1receive(JNIEnv *env, jobject inst
|
|||
}
|
||||
|
||||
void decode(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
|
||||
jbyte protocol = -1;
|
||||
jbyte protocol;
|
||||
char source[40];
|
||||
char dest[40];
|
||||
char flags[10];
|
||||
int flen = 0;
|
||||
void *payload = NULL;
|
||||
jbyte *payload;
|
||||
|
||||
// Get protocol, addresses & payload
|
||||
jbyte version = (*buffer) >> 4;
|
||||
if (version == 4) {
|
||||
struct iphdr *ip4hdr = buffer;
|
||||
|
||||
protocol = ip4hdr->protocol;
|
||||
inet_ntop(AF_INET, &ip4hdr->saddr, source, sizeof(source));
|
||||
inet_ntop(AF_INET, &ip4hdr->daddr, dest, sizeof(dest));
|
||||
|
@ -69,10 +67,11 @@ void decode(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
|
|||
jbyte optlen = 0;
|
||||
if (ip4hdr->ihl > 5)
|
||||
optlen = buffer[20];
|
||||
payload = buffer + 20 * sizeof(jbyte) + optlen;
|
||||
payload = buffer + (20 + optlen) * sizeof(jbyte);
|
||||
}
|
||||
else if (version == 6) {
|
||||
struct ip6_hdr *ip6hdr = buffer;
|
||||
|
||||
protocol = ip6hdr->ip6_nxt;
|
||||
inet_ntop(AF_INET6, &ip6hdr->ip6_src, source, sizeof(source));
|
||||
inet_ntop(AF_INET6, &ip6hdr->ip6_dst, dest, sizeof(dest));
|
||||
|
@ -81,16 +80,18 @@ void decode(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
|
|||
}
|
||||
else {
|
||||
__android_log_print(ANDROID_LOG_WARN, TAG, "Unknown version %d", version);
|
||||
*source = 0;
|
||||
*dest = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get ports & flags
|
||||
int sport = -1;
|
||||
int dport = -1;
|
||||
if (protocol == IPPROTO_TCP) {
|
||||
struct tcphdr *tcp = payload;
|
||||
|
||||
sport = ntohs(tcp->source);
|
||||
dport = ntohs(tcp->dest);
|
||||
|
||||
if (tcp->syn)
|
||||
flags[flen++] = 'S';
|
||||
if (tcp->ack)
|
||||
|
@ -103,6 +104,7 @@ void decode(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
|
|||
flags[flen++] = 'R';
|
||||
} else if (protocol == IPPROTO_UDP) {
|
||||
struct udphdr *udp = payload;
|
||||
|
||||
sport = ntohs(udp->source);
|
||||
dport = ntohs(udp->dest);
|
||||
}
|
||||
|
@ -111,40 +113,102 @@ void decode(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
|
|||
|
||||
__android_log_print(ANDROID_LOG_INFO, TAG, "Packet v%d %s/%d -> %s/%d proto %d flags %s",
|
||||
version, source, sport, dest, dport, protocol, flags);
|
||||
//scanproc6("/proc/net/tcp6");
|
||||
|
||||
// Get uid
|
||||
int uid = -1;
|
||||
if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP) {
|
||||
// Sleep 10 ms
|
||||
struct timespec tim, tim2;
|
||||
tim.tv_sec = 0;
|
||||
tim.tv_nsec = 10000000L;
|
||||
nanosleep(&tim, &tim2);
|
||||
|
||||
// Lookup uid
|
||||
uid = getUid(protocol, version, source, sport);
|
||||
if (uid < 0 && version == 4) {
|
||||
int8_t addr128[16];
|
||||
char source6[40];
|
||||
|
||||
memset(addr128, 0, 10);
|
||||
addr128[10] = 0xFF;
|
||||
addr128[11] = 0xFF;
|
||||
|
||||
inet_pton(AF_INET, source, addr128 + 12);
|
||||
inet_ntop(AF_INET6, &addr128, source6, sizeof(source6));
|
||||
uid = getUid(protocol, 6, source6, sport);
|
||||
}
|
||||
}
|
||||
|
||||
// Call back
|
||||
jclass cls = (*env)->GetObjectClass(env, instance);
|
||||
jmethodID mid = (*env)->GetMethodID(env, cls, "logPacket",
|
||||
"(ILjava/lang/String;ILjava/lang/String;IILjava/lang/String;)V");
|
||||
"(ILjava/lang/String;ILjava/lang/String;IILjava/lang/String;I)V");
|
||||
if (mid != 0) {
|
||||
jstring jsource = (*env)->NewStringUTF(env, source);
|
||||
jstring jdest = (*env)->NewStringUTF(env, dest);
|
||||
jstring jflags = (*env)->NewStringUTF(env, flags);
|
||||
(*env)->CallVoidMethod(env, instance, mid,
|
||||
version, jsource, sport, jdest, dport, protocol, jflags);
|
||||
version, jsource, sport, jdest, dport, protocol, jflags, uid);
|
||||
(*env)->DeleteLocalRef(env, jsource);
|
||||
(*env)->DeleteLocalRef(env, jdest);
|
||||
(*env)->DeleteLocalRef(env, jflags);
|
||||
}
|
||||
}
|
||||
|
||||
void scanproc6(const char *file) {
|
||||
char line[500];
|
||||
struct in6_addr *saddr = malloc(sizeof(struct in6_addr));
|
||||
char source[40];
|
||||
int sport;
|
||||
int uid;
|
||||
FILE *fd = fopen(file, "r");
|
||||
if (fd != NULL) {
|
||||
int i = 0;
|
||||
while (fgets(line, 500, fd) != NULL) {
|
||||
if (i++) {
|
||||
sscanf(line,
|
||||
"%*d: %8X%8X%8X%8X:%X %*X:%*X %*X %*lX:%*lX %*X:%*X %*X %d %*d %*ld ",
|
||||
saddr, ((void *) saddr) + 4, ((void *) saddr) + 8, ((void *) saddr) + 12,
|
||||
&sport, &uid);
|
||||
inet_ntop(AF_INET6, saddr, source, sizeof(source));
|
||||
__android_log_print(ANDROID_LOG_INFO, TAG, "proc %s/%d %d", source, sport, uid);
|
||||
}
|
||||
}
|
||||
fclose(fd);
|
||||
int getUid(int protocol, int version, const char *saddr, int sport) {
|
||||
char line[250];
|
||||
int fields;
|
||||
int32_t addr32;
|
||||
int8_t addr128[16];
|
||||
char addr[40];
|
||||
int port;
|
||||
int uid = -1;
|
||||
|
||||
// Get proc file name
|
||||
char *fn = NULL;
|
||||
if (protocol == IPPROTO_TCP)
|
||||
fn = (version == 4 ? "/proc/net/tcp" : "/proc/net/tcp6");
|
||||
else if (protocol == IPPROTO_UDP)
|
||||
fn = (version == 4 ? "/proc/net/udp" : "/proc/net/udp6");
|
||||
else
|
||||
return -1;
|
||||
|
||||
// Open proc file
|
||||
FILE *fd = fopen(fn, "r");
|
||||
if (fd == NULL) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "Error opening %s", fn);
|
||||
return -1;
|
||||
}
|
||||
free(saddr);
|
||||
|
||||
// Scan proc file
|
||||
int i = 0;
|
||||
while (fgets(line, sizeof(line), fd) != NULL) {
|
||||
if (i++) {
|
||||
if (version == 4)
|
||||
fields = sscanf(line,
|
||||
"%*d: %X:%X %*X:%*X %*X %*lX:%*lX %*X:%*X %*X %d %*d %*ld ",
|
||||
&addr32, &port, &uid);
|
||||
else
|
||||
fields = sscanf(line,
|
||||
"%*d: %8X%8X%8X%8X:%X %*X:%*X %*X %*lX:%*lX %*X:%*X %*X %d %*d %*ld ",
|
||||
addr128, addr128 + 4, addr128 + 8, addr128 + 12, &port, &uid);
|
||||
|
||||
if (fields < 3) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "Invalid field #%d: %s", fields, line);
|
||||
break;
|
||||
}
|
||||
|
||||
if (version == 4)
|
||||
inet_ntop(AF_INET, &addr32, addr, sizeof(addr));
|
||||
else
|
||||
inet_ntop(AF_INET6, addr128, addr, sizeof(addr));
|
||||
|
||||
if (port == sport && strcmp(addr, saddr) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
|
||||
return uid;
|
||||
}
|
Loading…
Reference in a new issue