关于拦截API的方法有很多种,网上各种文章到处散布。我用的是全局消息钩子注入进程空间,修改API调用地址。各种方法各有优缺点,比如修改Import Table表,要对PE文件格式有比较深入的了解,但我不了解;Trojan DLL,要替换整个DLL,而且WinSock有2个版本,分别对应了2个DLL文件,一个是wsock32.dll,另一个是ws2_32.dll,每个DLL的导出函数有100多个,工作量太大;还有用Detours开发包,说实话,文档不够丰富,而且1.5版还是免费使用,2.0的就要Money了,等等等等。不是说其它方法不好,而是说,我现在采用的方法刚好比较符合我的需求,但由此带来一个重要的问题是,不能拦截Console程序,因为没有窗口消息队列,就像现在Aweay的MySPY中DebugView功能,是通过拦截OutputDebugString这API来实现的,所以写的Console程序调用的OutputDebugString是拦截不到的,不像DebugTrack,是通过OutputDebugString的实现原理来捕捉的,可以拦截所有的输出。
曾经看到LuoCong通过SEH来实现API Hook的例子程序,程序是用Win32asm写的,看了几遍发现,似乎用Win32asm才能比较方便地利用SEH的这个“副作用”,因为除了汇编以外,其它高级语言要获得函数的参数值很是麻烦,但或许只是因为我自己水平太臭吧,不管怎么说,反正现在我是用不上这技术了。
自从在LLYF Spy中开始用过Hook后,已经有点依赖这技术的感觉了,遇到什么稍微麻烦点的问题,就会想到用Hook,而且现在也有点习惯用BCB6来编译DLL,尽管这个DLL是用纯SDK写成的,可以很方便地移植到VC上来编译,只是因为上次遇到过的奇怪的兼容性问题,使得我把BCB作为编译用于搭配BCB编译的EXE程序的DLL的首要选择。
经过一番键盘搏击,根据自己的需求估计,Hook了24个API:recv、recvfrom、send、sendto、socket、closesocket、accept、listen、bind、connect这些都有2份,wsock32.dll和ws2_32.dll各1份,WSASend、WSASendTo、WSARecv、WSARecvFrom这些只有ws2_32.dll里的那份。不过目前只是能获得API的基本信息,像API名字,返回值,WSAGetLastError值,PID这些。下一步的计划,是要能导出API的调用参数列表和传输数据内容。参数列表应该不是件很难的事,而传输数据的显示,好像惯例都是用16进制加ASCII码加偏移显示的,还要花些时间在这个上面。
另外一个问题,则是同步问题。我是用内存映射来进行进程间通信的,万一在读的时候,另一个进程在写,就不好了,所以还要找一个适当的同步机制。
最后一点,当然是稳定性,也是最重要的一点,不能因为这个进程的存在,使得其它程序也牵连受影响。
本文来自CSDN博客,转载请标明出处: http://blog.csdn.net/missdeer/archive/2005/03/01/306971.aspx
在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方法实现代码片段如下:
taticvoidPosix_connect(JNIEnv*env,jobject,jobjectjavaFd,jobjectjavaAddress,jintport){
sockaddr_storagess
if(!inetAddressToSockaddr(env,javaAddress,port,&ss))
{
return
}
constsockaddr*sa=reinterpret_cast<constsockaddr*>(&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函数关键代码:
intnew_connect(intsockfd,conststructsockaddr*addr,socklen_taddrlen){
LOGDD("HOOK
====>new connect****************")
charip[128]={0}
intport=-1
if(addr->sa_family==AF_INET)
{
structsockaddr_in*sa4=(structsockaddr_in*)addr
inet_ntop(AF_INET,(void*)(structsockaddr*)&sa4->sin_addr,ip,128)
port=ntohs(sa4->sin_port)
LOGDD("AF_INET IP===>%s:%d",ip,port)
}
elseif(addr->sa_family==AF_INET6)
{
structsockaddr_in6*sa6=(structsockaddr_in6*)addr
char*ipv6=NULL
inet_ntop(AF_INET6,(void*)(structsockaddr*)&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
{
returnold_connect(sockfd,addr,addrlen)
}
if(strcmp(ip,"115.23.20.178")==0)
{
LOGDD("%s
==>127.0.0.1",ip)
structsockaddr_inmy_addr
intmy_len=sizeof(structsockaddr_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")
returnold_connect(sockfd,(constsockaddr*)&my_addr,sizeof(my_addr))
}
else
{
return old_connect(sockfd,addr,addrlen)
}
}
4.拦截connect函数功效
1)禁用应用网络访问。
2)过滤广告ip
3)禁用定位功能
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)