Working DNS resolution in eSIM Frida mocking

This commit is contained in:
Adam Gastineau 2025-08-09 07:27:15 -07:00
parent 6d21cf44f1
commit 8c8eb3b672
4 changed files with 45 additions and 10 deletions

View File

@ -1,7 +1,9 @@
package com.penumbraos.bridge_system.provider
import android.util.Log
import com.penumbraos.bridge.IDnsProvider
import okhttp3.Dns
import java.net.InetAddress
class DnsProvider(private val resolver: Dns) : IDnsProvider.Stub() {
override fun lookup(hostname: String): String? {
@ -9,7 +11,7 @@ class DnsProvider(private val resolver: Dns) : IDnsProvider.Stub() {
return if (results.isEmpty()) {
null
} else {
results[0].hostAddress
(results[0] as InetAddress?)?.hostAddress
}
}
}

View File

@ -18,6 +18,12 @@ class OkHttpDnsResolver : Dns {
private val resolver = SimpleResolver("1.1.1.1")
override fun lookup(hostname: String): List<InetAddress> {
if (hostname.matches(Regex("^\\d+\\.\\d+\\.\\d+\\.\\d+$"))) {
val parts = hostname.split(".")
val bytes = parts.map { it.toInt().toByte() }.toByteArray()
return listOf(InetAddress.getByAddress(bytes))
}
val resolvedIpString = try {
val lookup = Lookup(hostname, Type.A)
lookup.setResolver(resolver)

View File

@ -2,30 +2,54 @@ import { log } from "../utils/logging";
let dnsProvider: any = null;
// Track getDns calls to prevent infinite recursion
let insideDnsCall = false;
export const setupNetworkHooks = (): void => {
try {
const InetAddress = Java.use("java.net.InetAddress");
const getDns = (hostname: string): string => {
// TODO: Something about this is incorrect
return dnsProvider.lookup
if (insideDnsCall) {
log(`Skipping ${hostname} fetch due to inside DNS call`);
return hostname;
}
insideDnsCall = true;
const result = dnsProvider.lookup
.overload("java.lang.String")
.call(dnsProvider, hostname);
insideDnsCall = false;
return result;
};
const hookDnsMethod = (method: any) => {
const hookDnsMethod = (method: any, isList: boolean) => {
const original = method.implementation;
method.implementation = function (hostname: string) {
if (dnsProvider) {
const resolvedHostname = getDns(hostname);
if (isIpAddress(resolvedHostname)) {
log(`Creating InetAddress directly for IP ${resolvedHostname}`);
const parts = resolvedHostname.split(".");
const bytes = Java.array(
"byte",
parts.map((p) => parseInt(p))
);
const result = InetAddress.getByAddress
.overload("[B")
.call(InetAddress, bytes);
return isList
? Java.array("java.net.InetAddress", [result])
: result;
}
return original.call(this, resolvedHostname);
}
return original.call(this, hostname);
};
};
hookDnsMethod(InetAddress.getByName.overload("java.lang.String"));
hookDnsMethod(InetAddress.getAllByName.overload("java.lang.String"));
hookDnsMethod(InetAddress.getByName.overload("java.lang.String"), false);
hookDnsMethod(InetAddress.getAllByName.overload("java.lang.String"), true);
} catch (err) {
log(`[Frida] Network hook error: ${err}`);
}
@ -34,3 +58,8 @@ export const setupNetworkHooks = (): void => {
export const setDnsProvider = (provider: any): void => {
dnsProvider = provider;
};
const isIpAddress = (str: string): boolean => {
const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
return ipv4Regex.test(str);
};

View File

@ -5,6 +5,7 @@ declare const Java: {
ClassFactory: {
get(loader: any): any;
};
array(type: any, value: unknown[]): any;
use(className: string): any;
cast(obj: any, cls: any): any;
scheduleOnMainThread(fn: () => void): void;
@ -15,10 +16,7 @@ declare const Memory: {
};
declare const Module: {
getExportByName(
moduleName: string | null,
exportName: string
): NativePointer;
getExportByName(moduleName: string | null, exportName: string): NativePointer;
};
declare const NativeFunction: new (