Windows/Unix* 系统都支持为一个网卡绑定多个IP地址,但是通常操作系统会根据路由表自动选择IP地址,应用程序使用哪个IP地址用户无法主动控制。本文分别讲解在Linux和Windows下为应用程序绑定指定IP地址的方法。
关于Windows如何选择IP地址可以参考这篇文章:《Source IP address selection on a Multi-Homed Windows Computer》
一、 如何让Linux下的程序指定使用的IP地址
英文原文:《BINDING APPLICATIONS TO A SPECIFIC IP》
作者Daniel Ryde采用了LD_PRELOAD进行HACK,为应用程序注入一个动态库bind.so,这个动态库中对bind和connect函数加钩子,程序建立socket连接前绑定指定的本地IP地址。
使用方法:
Hessian:bind/ $ BIND_ADDR="192.168.8.9" LD_PRELOAD=./bind.so YOUR_PROGRAME
程序源码可从这里下载
编译方法:
Hessian:bind/ $ gcc -nostartfiles -fpic -shared bind.c -o bind.so -ldl -D_GNU_SOURCE Hessian:bind/ $ strip bind.so
二、 如何让Windows下的程序指定使用的IP地址
在Windows实现这个功能要相对麻烦一些,博主没有找到十分简单的办法,找了很久才发现这个高大上的东西——ForceBindIP - Bind any Windows application to a specific interface。
程序原理就不翻译了,反正也没源码,不过大体跟linux版本的实现是差不多的,不过这边还多挂了WSA函数的钩子,覆盖的更完全。因为只会注入目标程序,如果网络访问是目标程序fork出去的进程发起的则不会受影响。
ForceBindIP works in two stages - the loader, ForceBindIP.exe will load the target application in a suspended state. It will then inject a DLL (BindIP.dll) which loads WS2_32.DLL into memory and intercepts the bind(), connect(), sendto(), WSAConnect() and WSASendTo() functions, redirecting them to code in the DLL which verifies which interface they will be bound to and if not the one specified, (re)binds the socket. Once the function intercepts are complete, the target application is resumed. Note that some applications with anti-debugger / injection techniques may not work correctly when an injected DLL is present; for the vast majority of applications though this technique should work fine.
作者声明支持的系统版本有:Windows NT/2000/XP/2003.
作者测试过可用的软件: DC++, uTorrent, Quake II, Quake III, Diablo II, StarCraft, Internet Explorer, Mozilla Firefox, Google Earth, Infantry, Real Player, Unreal Tournament 2004 (requires -i), Outlook 2000 (requires -i).
不可用的软件: GetRight (anti-debugger / forking techniques), WinCVS (forks cvs.exe)
博主测试过在Windows7上无法正常工作。搜狗浏览器也不知道是什么原因没有效果。
使用方法:
ForceBindIP 1.2.3.4 c:\full\path\to\app.exe
还可以通过网卡GUID进行绑定,GUID可以从注册表中找到[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces]
ForceBindIP {4FA65F75-7A5F-4BCA-A3A2-59824B2F5CA0} c:\path\to\app.exe
如果遇到程序崩溃或者什么意外情况可以尝试-i参数,这会让ForceBindIP等待目标程序进入它的消息循环后再注入DLL。
ForceBindIP -i 1.2.3.4 c:\full\path\to\app.exe