android ndk网络拦截,Android: 限定app可访问的网络 – 限制native进程

在Android应用程序中,我们可以通过ConnectivityManager.setProcessDefaultNetwork()来限制当前进程可访问的网络。对于native app,我们有没有办法对native进程进行限制呢?通过什么方法进行限制?

环境

Android系统版本:android-5.1.1_r15 @Nexus 4, 在项目中编译。

代码

一段很简单的代码,发起http请求:

int try_to_get_http_url(const char *hostname, const char *url)

{

int len;

char request[256], response[4096];

int fd = socket_network_client(hostname, 80, SOCK_STREAM);

if (fd < 0) {

printf("Failed to connect: %s, errno=%d(%s)\n", hostname, errno, strerror(errno));

return fd;

}

len = sprintf(request, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", url, hostname);

len = write(fd, request, len);

if (len <= 0) {

printf("Failed to send request: %s, errno=%d(%s)\n", request, errno, strerror(errno));

close(fd);

return len;

}

len = read(fd, response, sizeof(response) - 1);

if (len <= 0) {

printf("Failed to get response, errno=%d(%s)\n", errno, strerror(errno));

close(fd);

return len;

}

response[len] = '\0';

printf(response);

return close(fd);

}

int main(int argc, const char *argv[])

{

return try_to_get_http_url("brobwind.com", "/");

}

执行之后,可以从log中得到如下信息:

03-06 15:33:18.649 14917 14917 E hello-native: HTTP/1.1 301 Moved Permanently

03-06 15:33:18.649 14917 14917 E hello-native: Date: Sun, 06 Mar 2016 15:33:20 GMT

03-06 15:33:18.649 14917 14917 E hello-native: Server: Apache/2.4.7 (Ubuntu)

03-06 15:33:18.649 14917 14917 E hello-native: X-Powered-By: PHP/5.5.9-1ubuntu4.14

03-06 15:33:18.649 14917 14917 E hello-native: Location: http://www.brobwind.com/

03-06 15:33:18.649 14917 14917 E hello-native: Content-Length: 0

03-06 15:33:18.649 14917 14917 E hello-native: Content-Type: text/html; charset=UTF-8

试试这种方法,在JNI代码中去回调JAVA代码:

1. JNI相关代码:

#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \

var = env->GetMethodID(clazz, methodName, fieldDescriptor); \

LOG_FATAL_IF(! var, "Unable to find method" methodName);

static struct {

jobject thiz;

jmethodID nativeSetProcessNetwork;

} gNativeApplication;

extern "C" void Java_com_brobwind_brontv_v1_NativeApplication_nNativeSetup(JNIEnv *env, jclass clazz, jobject thiz)

{

gNativeApplication.thiz = env->NewGlobalRef(thiz);

GET_METHOD_ID(gNativeApplication.nativeSetProcessNetwork, clazz, "nativeSetProcessNetwork", "()V");

}

extern "C" void Java_com_brobwind_brontv_v1_NativeApplication_nSayHello(JNIEnv *env, jclass, jstring binDir)

{

pid_t pid;

char path[PATH_MAX];

ScopedUtfChars _binDir(env, binDir);

sprintf(path, "%s/hello-native", _binDir.c_str());

pid = fork();

if (pid == 0) { // Child process

env->CallVoidMethod(gNativeApplication.thiz, gNativeApplication.nativeSetProcessNetwork);

env->DeleteGlobalRef(gNativeApplication.thiz);

exit(execl(path, path, NULL));

}

}

2. JAVA相关代码:

public class NativeApplication extends Application {

private static final String TAG = "NativeApp";

static {

System.loadLibrary("native-jni");

}

@Override

public void onCreate() {

nNativeSetup(this);

final File binDir = new File(getApplicationInfo().dataDir, "/bin");

binDir.mkdir();

binDir.setReadable(true, false);

try {

File binName = new File(binDir, "hello-native");

binName.delete();

if (binName.exists() != true) {

AssetManager am = getAssets();

InputStream is = am.open("bin/armeabi-v7a/" + binName.getName());

FileUtils.copyToFile(is, binName);

FileUtils.setPermissions(binName, FileUtils.S_IRUSR | FileUtils.S_IXUSR, -1, -1);

}

} catch (IOException e) {

e.printStackTrace();

}

nSayHello(binDir.getPath());

}

public void nativeSetProcessNetwork() {

ConnectivityManager cm = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);

Network allNetworks[] = cm.getAllNetworks();

for (Network network : allNetworks) {

NetworkInfo info = cm.getNetworkInfo(network);

if (info.getType() == ConnectivityManager.TYPE_WIFI) {

// cm.bindProcessToNetwork(network);

boolean setOk = cm.setProcessDefaultNetwork(network);

if (!setOk) {

Log.e(TAG, " -> Failed to set process default network: " + network);

}

break;

}

}

}

private static native void nNativeSetup(NativeApplication thiz);

private static native void nSayHello(String binDir);

}

看来这种方法不可行:

03-06 16:24:24.331 17117 17117 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xb3fcf038 in tid 17117 (bwind.brontv.v1)

03-06 16:24:24.433 187 187 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

03-06 16:24:24.433 187 187 I DEBUG : Build fingerprint: 'Android/aosp_mako/mako:5.1.1/LMY48T/rwchen03041349:userdebug/test-keys'

03-06 16:24:24.433 187 187 I DEBUG : Revision: '11'

03-06 16:24:24.433 187 187 I DEBUG : ABI: 'arm'

03-06 16:24:24.433 558 674 W NativeCrashListener: Couldn't find ProcessRecord for pid 17117

03-06 16:24:24.433 187 187 I DEBUG : pid: 17117, tid: 17117, name: bwind.brontv.v1 >>> com.brobwind.brontv.v1 <<<

03-06 16:24:24.433 187 187 E DEBUG : AM write failure (32 / Broken pipe)

03-06 16:24:24.433 187 187 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb3fcf038

03-06 16:24:24.444 187 187 I DEBUG : r0 00000000 r1 00000000 r2 00000000 r3 00000000

03-06 16:24:24.444 187 187 I DEBUG : r4 00000010 r5 00000001 r6 b7f2dd50 r7 b3fcf038

03-06 16:24:24.444 187 187 I DEBUG : r8 b3fcf028 r9 b7f2d980 sl b6e31255 fp 00007205

03-06 16:24:24.444 187 187 I DEBUG : ip b6dadd7c sp be8cfb40 lr b6da603c pc b6e3444e cpsr 800b0030

03-06 16:24:24.445 187 187 I DEBUG :

03-06 16:24:24.445 187 187 I DEBUG : backtrace:

03-06 16:24:24.445 187 187 I DEBUG : #00 pc 0002244e /system/lib/libbinder.so (android::Parcel::ipcSetDataReference(unsigned char const*, unsigned int, unsigned int const*, unsigned int, void (*)(android::Parcel*, unsigned char const*, unsigned int, unsigned int const*, unsigned int, void*), void*)+61)

03-06 16:24:24.445 187 187 I DEBUG : #01 pc 0001fa3f /system/lib/libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*)+206)

03-06 16:24:24.445 187 187 I DEBUG : #02 pc 0001fb3d /system/lib/libbinder.so (android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+124)

03-06 16:24:24.445 187 187 I DEBUG : #03 pc 0001ad23 /system/lib/libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+30)

03-06 16:24:24.445 187 187 I DEBUG : #04 pc 000877bf /system/lib/libandroid_runtime.so

03-06 16:24:24.445 187 187 I DEBUG : #05 pc 00c1221d /data/dalvik-cache/arm/system@framework@boot.oat

我们再回看一下ConnectivityManager.setProcessDefaultNetwork()做了些什么:->@

public static boolean setProcessDefaultNetwork(Network network) {

int netId = (network == null) ? NETID_UNSET : network.netId;

if (netId == NetworkUtils.getNetworkBoundToProcess()) {

return true;

}

if (NetworkUtils.bindProcessToNetwork(netId)) {

// Set HTTP proxy system properties to match network.

// TODO: Deprecate this static method and replace it with a non-static version.

Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy());

// Must flush DNS cache as new network may have different DNS resolutions.

InetAddress.clearDnsCache();

// Must flush socket pool as idle sockets will be bound to previous network and may

// cause subsequent fetches to be performed on old network.

NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();

return true;

} else {

return false;

}

}

1. netId: 这个好办

2. NetworkUtils.bindProcessToNetwork(): 这个方法实际上直接调用的是native的setNetworkForProcess()这个也没问题

3. Proxy.setHttpProxySystemProperty(): 这个可以先暂时不管

4. InetAddress.clearDnsCache():  貌似也可以不管

=== 待续 ===

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值