Android connect函数hook

Home / Android MrLee 2015-7-15 3272

u=331957141,1260236691&fm=58


在android系统中,可以使用iptables控制单个应用网络访问。在google code上有一个开源项目-droidwall就是基于iptables实现的。除了iptables可以实现控制单个应用网络访问外,还可以通过拦截应用中的connect函数,达到控制应用访问网络的目的。下面从几个方面分析android应用中connect调用流程为例来实现拦截connect实现网络禁用和ip过滤。(以下分析基于4.2源码)
1.android中网络访问流程
1)android系统中访问网络可以通过Socket.java、URL.java、HttpPost.java、HttpGet.java等关键类来访问网络资源。通过代码追踪,这些类访问网络资源最终需要通过native方式,调用linux系统下的socket函数访问网络。在android4.2源码中,java层访问网络得native方法定义在源码路径libcore/luni/src/main/java/libcore/io/Posix.java中(4.0之前的网络系统、文件系统的native方法是独立分开得,4.0之后组织在Posix.java中)。如下是Posix.java中的代码片段:
public final class Posix implements Os 
{
    Posix() { }
    public native FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException;
    public native boolean access(String path, int mode) throws ErrnoException;
    public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
    ......
    //对应linux下的connect系统调用
    public native void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;

2)Posix.java中的native方法实现源码路径libcore/luni/src/main/native/libcore_io_Posix.cpp文件中,native connect方法实现代码片段如下:
static void Posix_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) 
{
    sockaddr_storage ss;
    if (!inetAddressToSockaddr(env, javaAddress, port, &ss)) 
    {
        return;
    }
    const sockaddr* sa = reinterpret_cast(&ss);
    (void) NET_FAILURE_RETRY(env, int, connect, javaFd, sa, sizeof(sockaddr_storage));
}

有上代码可知,java层connect最终功能由linux系统connect函数实现。
2.so注入
so注入可以参考古河大哥牛逼的libInject,本站有实例。
3.拦截connect库编写
在connect中,获取传入的参数ip地址,根据需要把需要禁用的ip地址改为127.0.01.以下是我测试的拦截connect函数关键代码:
int new_connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
{
	LOGDD("HOOK ====>new connect****************");
	char ip[128]={0};
	int port=-1;
	if(addr->sa_family==AF_INET)
	{
		struct sockaddr_in *sa4=(struct sockaddr_in*)addr;
		inet_ntop(AF_INET,(void*)(struct sockaddr*)&sa4->sin_addr,ip,128);
		port=ntohs(sa4->sin_port);
		LOGDD("AF_INET  IP===>%s:%d",ip,port);
	}
	else if(addr->sa_family==AF_INET6)
	{
		struct sockaddr_in6 *sa6=(struct sockaddr_in6*)addr;
		char *ipv6=NULL;
		inet_ntop(AF_INET6,(void*)(struct sockaddr*)&sa6->sin6_addr,ip,128);
		ipv6=strstr(ip,"f:");
		if(NULL!=ipv6)
		{
			strcpy(ip,ipv6+2);
		}
		port=ntohs(sa6->sin6_port);
		LOGDD("af_inet6 IP===>%s:%d",ip,port);
	}
	else
	{
		return old_connect(sockfd,addr,addrlen);
	}
	if(strcmp(ip,"115.23.20.178")==0)
	{
		LOGDD("%s ==>127.0.0.1",ip);
		struct sockaddr_in my_addr;
		int my_len=sizeof(struct sockaddr_in);
		bzero(&my_addr,sizeof(my_addr));
		my_addr.sin_family=AF_INET;
		my_addr.sin_port=htons(80);
		my_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
		return old_connect(sockfd,(const sockaddr*)&my_addr,sizeof(my_addr));
	}
	else
	{
		return  old_connect(sockfd,addr,addrlen);
	}
}

4.拦截connect函数功效
1)禁用应用网络访问。 2)过滤广告ip 3)禁用定位功能
以上仅个人见解,各位大牛多多指教。
转载自 Android connect函数hook | 神乎

本文链接:https://www.it72.com/3710.htm

推荐阅读
最新回复 (0)
返回