Bind application to a specific network interface

17

13

I have tried ForceBindIP, but it has a significant downside - it doesn't affect the children of the application I'm trying to bind, it only affects the application itself. It also can't force an application to always run through a specified interface, it has to be run through forcebindip.exe every time. It becomes a problem with applications like League of Legends where the process tree looks like that:

screenshot

The launcher runs the patcher, the patcher run the client, etc. I can only affect the parent of all these processes in the tree, so the actual game is not bound to the interface I want, making this whole venture pointless.

Is there a more modern alternative to ForceBindIP for Windows 7? There are many questions similar to this one on this site, but they are mostly old. Maybe there is now a better way to solve this problem?

My current idea is to do the following:

  1. Set up local 3proxy server bound to the desired interface.

  2. Run the game through Proxifier or similar software configured to run through that local proxy.

I'm not sure if that will work, but even if it will, it seems like a sub-optimal solution. Do you guys have any better ideas?

Edit: My idea didn't work :(

Edit 2: Basically, what I'm trying to achieve is bind a few applications to a regular interface, while VPN is running. The reason is that I need to connect through VPN most of the time, but some applications (such as games) don't work properly this way, because of higher ping and other issues.

Victor Marchuk

Posted 2015-11-24T06:31:54.460

Reputation: 687

Do you need bind to IP every process in the tree or only LolClient.exe? Is LolClient.exe a x86 or x64 exe? I'm toying with third-party dll injector and maybe I can help you, but I need more info. – beatcracker – 2015-12-01T16:46:12.953

Are you trying to bind the process to the VPN interface, or to the regular interface? – MariusMatutiae – 2015-12-01T18:31:29.860

Is there some specific goal you're trying to achieve? By default, the game doesn't need any incoming connections to work properly. Are you trying to cheat or record/playback games? – Mario – 2015-12-02T06:37:19.457

I've been looking for an answer to this basic question but for OSX hosts. My use case is I have LAN and WiFi on simultaneously. LAN is on a restricted corporate net, wi-fi on my WAP. I sometimes need a browser or app to use only wi-fi so that I can d/l files blocked by our firewall. – SaxDaddy – 2015-12-02T07:33:19.263

@beatcracker, I would prefer the whole tree, but if you have a solution for a single descendant, it would be a nice start. I'm trying to bind the process to a regular interface. I need to use VPN for all applications, except a chosen few (such as games), so I need a way to bind applications to the regular interface while VPN is running. – Victor Marchuk – 2015-12-02T13:01:38.760

@beatcracker, sorry, I forgot to mention the process type in the last comment. It's 64-bit, but if you have a solution for 32-bit only, it would be better than nothing. – Victor Marchuk – 2015-12-03T06:16:17.770

1@VictorMarchuk Yes, BindIp.dll is 32-bit, so it wouldn't work with 64-bit processes. – beatcracker – 2015-12-03T11:31:01.907

@VictorMarchuk Are you configuring your VPN connection in Windows or have you use specific 3-rd party client? – g2mk – 2015-12-03T23:09:25.903

Answers

10

Update

I've found that ForceBindIp in fact is passing parameters to the called executables. It just omits first parameter. So I've modified my script to use ForceBindIp.exe instead of custom injector and now it looks like all issues with injectory exceptions are gone and everything works.

Here is modified steps and BindIp.cmd script:

  1. Install ForceBindIp as usual

  2. Put BindIp.cmd anywhere on your drive (e.g. C:\BindIp\BindIp.cmd)

BindIp.cmd script:

setlocal

:: IP to bind to
set IP=192.168.128.85

:: Common variables
set RegIFEO=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\%~nx1
set Injector=ForceBindIp.exe

:: ForceBindIp swallows first parameter passed to target exe,
:: so we inject dummy parameter just before it
set AllParams=%*
set FirstParam=%1
call set TargetParams=%%AllParams:*%FirstParam%=%FirstParam% Dummy%%

:: Delete debugger for the target exe in registry,
:: or we'll end in an endless loop of the batch files
reg delete "%RegIFEO%%" /v Debugger /f

:: Start target exe via ForceBindIp
%Injector% %IP% %TargetParams%

:: Restore this script as debugger for the target exe in registry
reg add "%RegIFEO%" /v Debugger /t REG_SZ /d "%~dpnx0" /f

:: Debug, uncomment if needed
rem pause

endlocal

Then follow steps 2-6 from below.


Introduction

ForceBindIp can't automatically inject BindIp.dll to child processes and doesn't pass parameters to the called executables. But I was able to circumvent this by using Image File Execution Options in registry, batch script and third-party dll injector. Details are below.

Theory

To use BindIp.dll without ForceBindIp.exe we need to find out how they communicate (ForceBindIp.exe has to pass IP-address to dll somehow).

I've used IDA free and found that ForceBindIp.exe creates environment variable with name FORCEDIP that holds IP-address and BindIp.dll reads IP-address from this variable when it injected and executed in target process.

To detect target application launch, we can add a Debugger key in the Image File Execution Options in registry for this executable:

Kernel32!CreateProcess when called without the DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS creation flags, checks the registry to see if IFEO has been set on the executable that it is launching. If yes, then it simply prepends the debugger path to the executable name, effectively getting the executable to launch under the debugger.

The "Debugger" in our case, will be a batch script, that will set FORCEDIP variable and launch the injectory dll-injector. Injectory then will start process, pass command-line arguments and inject BindIp.dll.

Practice

  1. Create folder somewhere (C:\BindIp for example) and put those three files in it:

BindIp.cmd script:

setlocal

:: IP to bind to. This env.var is used by BindIp.dll
set FORCEDIP=192.168.1.23

:: Common variables
set RegIFEO=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\%~nx1
set Injector=%~dp0injectory.x86.exe
set BindIpDll=%~dp0BindIp.dll

:: Extract target's parameters, if any
set AllParams=%*
set FirstParam=%1
call set TargetParams=%%AllParams:*%FirstParam% =%%

:: Delete debugger for the target exe in registry,
:: or we'll end in an endless loop of the batch files
reg delete "%RegIFEO%%" /v Debugger /f

:: Start target exe and inject BindIp.dll
if not [%2] == [] (
    :: If there were parameters for target exe, pass them on
    "%Injector%" --launch %1 --inject "%BindIpDll%" --args "%TargetParams%"
) else (
    :: No parameters were specified
    "%Injector%" --launch %1 --inject "%BindIpDll%"
)

:: Restore this script as debugger for the target exe in registry
reg add "%RegIFEO%" /v Debugger /t REG_SZ /d "%~dpnx0" /f

:: Debug, uncomment if needed
rem pause

endlocal
  1. Create registry key (e.g. LolClient.exe) for target executable in HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\
  2. Add String Value to this key:

    • Name: Debugger
    • Value: C:\BindIp\BindIp.cmd
  3. Grant Users Full permissions on this key (the script will have to modify it at every launch). It should look like this: IFEO registry key

  4. Set required IP-address in BindIp.cmd

  5. Repeat steps 3 and 4 for every executable you wish to bind (rad_user_kernel.exe, LolLauncher.exe, LolPatcher.exe, etc.).

Now, every time when you launch executable that has corresponding registry entry, the BindIp.cmd script will launch instead and bind this program to desired IP-address.

Conclusion

I've tested this on my laptop running Windows 8.1 x64 and was able to successfully bind various programs (AIMP 2, BersIRC, Opera 12.4) to Ethernet or WiFi adapter using this technique. Unfortunately BindIp.dll is 32-bit, so it wouldn't work with 64-bit processes.

beatcracker

Posted 2015-11-24T06:31:54.460

Reputation: 2 334

Thank you very much for a detailed explanation! Unfortunately, I'm getting some kind of exception from injectory: https://github.com/blole/injectory/issues/4

– Victor Marchuk – 2015-12-03T07:46:46.327

@VictorMarchuk I did more tests, and indeed, injectory sometimes has issues with --args option. Not sure why. – beatcracker – 2015-12-03T11:37:04.770

I wasn't able to run it even without --args with any application – Victor Marchuk – 2015-12-03T12:28:55.230

@VictorMarchuk Do you have an example? I've just tested it with Opera 12.14 and command-line - it worked fine. – beatcracker – 2015-12-03T13:05:30.680

@VictorMarchuk It seems that ForceBindIp actually can pass parameters, see my updated answer. – beatcracker – 2015-12-03T16:52:46.787

4

I've found that HideMyAss! VPN client has Secure IP Bind feature that allows to bind applications to VPN interface:

Secure IP Bind enables you to force selected applications on your computer to only work once connected to our VPN servers. This ensures selected applications will only work behind a secure encrypted connection. If you open selected applications without being connected to our VPN, they won't be able to access the internet.

I've looked at it and it's based on a custom Layered Service Provider (LSP) dll and COM interface to control it. And it can be (ab)used without installing HideMyAss' VPN client.

Installing HideMyAss' Secure IP Bind

  1. Get latest Windows installer: https://www.hidemyass.com/downloads
  2. Unpack it with 7-zip. Ignore warnings about files having same name, you can safely overwrite those.
  3. Go to the bin folder in the unpacked installer
  4. Copy those three files to a folder on your disk (C:\HMA_Bind)

    • ForceInterfaceCOM.dll
    • ForceInterfaceLSP.dll
    • InstallLSP.exe
  5. Put Install.cmd and Uninstall.cmd to this folder

Install.cmd

%~dp0InstallLSP.exe -i -a -n "HMA_LSP" -d %~dp0ForceInterfaceLSP.dll
regsvr32 /s %~dp0ForceInterfaceCOM.dll

Uninstall.cmd

%~dp0InstallLSP.exe -f
regsvr32 /u /s %~dp0ForceInterfaceCOM.dll
  1. Run Install.cmd as Administrator. To verify, that installation succeeded, you can use Autoruns:

Winsock Providers in AUtoruns

  1. To control Secure IP Bind, you have to call COM interface methods. This can be done in PowerShell. If you're on x64 OS, be sure to launch Windows PowerShell ISE (x86) or Windows PowerShell (x86), because COM component is 32-bit.

First, you have to create new Secure IP Bind object:

# Create new Secure IP Bind COM object
$HmaFbi = New-Object -ComObject ForceInterfaceCOM.ForceInterface -ErrorAction Stop

And then you can call it's methods:

# Add bound application
# Not sure what second boolean argument does
$HmaFbi.AddApplicationHandled('firefox.exe', $true)

# Delete bound application
$HmaFbi.RemoveApplicationHandled('firefox.exe')

# Save applications to registry (applies bindings)
# Setting are saved to: HKEY_CURRENT_USER\Software\ForceInterfaceCOM
$HmaFbi.SaveToRegistry()

# List all bound applications
0..($HmaFbi.GetApplicationHandledCount() - 1) | ForEach-Object {$HmaFbi.GetApplicationName($_)}

# Set IP to bind to
$HmaFbi.SetInterfaceIP('192.168.1.23')

# Get stored IP
$HmaFbi.GetInterfaceIP()

# Enable binding
$HmaFbi.SetEnabled($true)

# Disable binding
$HmaFbi.SetEnabled($false)

# Show binding status
$HmaFbi.GetEnabled()

Uninstalling HideMyAss' Secure IP Bind

  1. Run Uninstall.cmd as Administrator, verify that uninstallation is succeeded with Autoruns.

Examples:

Note, that you have to create secure IP Bind COM object only once per PowerShell session. Examples below assume that you execute them in a new PowerShell session, so they always create new COM object.

  • Set IP to bind to, add firefox to bound applications, enable binding.

    # Create new Secure IP Bind COM object
    $HmaFbi = New-Object -ComObject ForceInterfaceCOM.ForceInterface -ErrorAction Stop
    
    # Set IP to bind to
    $HmaFbi.SetInterfaceIP('192.168.1.23')
    
    # Add bound application
    # Not sure what second boolean argument does
    $HmaFbi.AddApplicationHandled('firefox.exe', $true)
    
    # Save applications to registry (applies bindings)
    # Setting are saved to: HKEY_CURRENT_USER\Software\ForceInterfaceCOM
    $HmaFbi.SaveToRegistry()
    
    # Enable binding
    $HmaFbi.SetEnabled($true)
    
  • Globally enable IP binding:

    # Create new Secure IP Bind COM object
    $HmaFbi = New-Object -ComObject ForceInterfaceCOM.ForceInterface -ErrorAction Stop
    
    # Enable binding
    $HmaFbi.SetEnabled($true)
    
  • Globally disable IP binding:

    # Create new Secure IP Bind COM object
    $HmaFbi = New-Object -ComObject ForceInterfaceCOM.ForceInterface -ErrorAction Stop
    
    # Disable binding
    $HmaFbi.SetEnabled($false)
    
  • Remove application from list (stop binding for this application):

    # Create new Secure IP Bind COM object
    $HmaFbi = New-Object -ComObject ForceInterfaceCOM.ForceInterface -ErrorAction Stop
    
    # Delete bound application
    $HmaFbi.RemoveApplicationHandled('firefox.exe')
    
    # Save applications to registry (applies bindings)
    # Setting are saved to: HKEY_CURRENT_USER\Software\ForceInterfaceCOM
    $HmaFbi.SaveToRegistry()
    

Notes

Because Secure IP Bind implemented as a custom Layered Service Provider (LSP) dll, those limitations apply:

LSPs have been deprecated since Windows Server 2012. Systems that include LSPs will not pass the Windows logo checks. Windows 8 style "metro" apps that use networking will automatically bypass all LSPs.

I've tested this method with various applications with mixed results: 32-bit applications work, but 64-bit not, i.e. I was able to bind 64-bit Explorer (probably because it's tab processes are 32-bit by default), but not 64-bit Waterfox browser or other 64-bit applications.

beatcracker

Posted 2015-11-24T06:31:54.460

Reputation: 2 334

3

I can think of two solutions to the problem :

  1. Create a virtual machine for running the game, which only uses the one network adapter.

  2. If you know the range of IP addresses that the game uses, construct a network route that directs this range toward the gateway of the specific adapter.

I can add more information once I know your preferences. For example, in point 1 your preferred virtual machine product.

harrymc

Posted 2015-11-24T06:31:54.460

Reputation: 306 093

1Using a VM would create a lot of additional problems, such as reduced performance and a constant usage of a few GBs of RAM. It's my last resort option, I would really prefer to achieve it in some other way. I don't know the exact range of IPs I will need to bind, because I need it for all sorts of applications, including p2p sharing software (torrents). Maybe there's a firewall that allows you to create routes based on the connections each application establishes? – Victor Marchuk – 2015-12-02T13:15:23.997

Performance: A VM wouldn't cause a reduced performance if one doesn't use the old Virtual PC. Memory: VMware and VirtualBox don't allocate all memory immediately, so only memory the VM really needs is allocated. They also have the additional advantage for a game of being able to suspend and resume the VM/game at a later time, which is much better than the save abilities of most games. For IP ranges : If you have many of them then the above is not practical, nor is a proxy. – harrymc – 2015-12-02T13:49:16.843

1@harrymc I doubt that one would be able to get aceptable 3D performance from VM using emulated GPU. And direct access to graphics card it's tricky to setup and requires VT-D (Intel) or AMD-Vi capable CPU (and those aren't cheap). – beatcracker – 2015-12-03T12:08:37.047

Such CPUs are more common than you think : List of IOMMU-supporting hardware, but pass-through video might requires two GPUs. However, unless the performance requirements are enormous, a VM nowadays gives good video performance. Using a VM is my solution for action games that have trouble accepting my advanced GPU, without encountering a noticeable lag. Most VM products allow some control of the emulated card, such as the amount of video memory,

– harrymc – 2015-12-03T13:48:03.243

@harrymc Indeed, the list is impressive, so I stand corrected. I should check hardware specs more often :). Curious, are built-in GPUs in modern Core processors could be used as "OS" GPU and external card as VM GPU? – beatcracker – 2015-12-03T16:59:18.467

2

The answer is yes, and some people have managed that. Here is one reference: Setting up a Windows VM with GPU passthrough, but more can be found.

– harrymc – 2015-12-03T20:00:15.220

Is routing a range of remote addresses necessary here?  (And, if that works, wouldn't it work by itself, without using a VM?)  I can imagine that you would be able to configure the hypervisor (VMware or VirtualBox) to "see" only the desired interface, or to apply ForceBindIP to the hypervisor. – Scott – 2015-12-14T23:55:42.250

@Scott those are two different solutions, it's not a two-step process. – Victor Marchuk – 2016-01-04T14:20:35.103

3

Let's assume that you have two Windows user accounts:

  • HomeUser
  • VpnUser

When you login to VpnUser account you can run applications (particularly games you mentioned) as HomeUser (Shift + RMB on executable file -> Run as other user) and this applications runs their child processes as HomeUser. Applications that you will run in a standard way (shortcuts, double-click on executable file) will be owned by VpnUser.

When you defining Windows network connections you have an option to allow other users to use this connection. Let's assume that you defined:

  • HomeNetwork exclusively for HomeUser
  • VpnNetwork exclusively for VpnUser

and for simplification:

  • There are no other network connections on your computer.

I currently have single Windows machine on which I can't mess up much and I have never checked described setting so I'm not sure if bellow statement is true.

My guess might be limited to Windows built-in VPN Client - any 3-rd party VPN client requires further investigation.

I guess that applications:

  • Owned by VpnUser should use only VpnNetwork.
  • Owned by HomeUser should use only HomeNetwork.

If my speculation is true, then when you login to VpnUser account applications will use VpnNetwork, when applications run as HomeUser from VpnUser account should use HomeNetwork.

g2mk

Posted 2015-11-24T06:31:54.460

Reputation: 1 278

I'm not sure what you mean. Are you suggesting I should use different Windows user account? How would that help to bind specific applications? It seems like your solution would only allow to enable/disable VPN for all apps, but I already can do that by connecting to VPN and disconnecting from it. – Victor Marchuk – 2015-12-05T16:04:08.857

2@VictorMarchuk I have edited my answer - I hope it is more clear now... – g2mk – 2015-12-05T21:31:39.083

0

forcebindip.exe can be used but you must code a helper application (no other option).

  1. The application save the parameters that has received from its command line
  2. The application get its name i.e. XXXX.EXE
  3. The application loads XXX.ini that contains i.e.

    app_to_run = C:\path1\app_to_run.exe
    ForceBindIP = C:\path2\ForceBindIP.exe 
    IP          = 192.168.10.21
    
  4. The application runs

    C:\path1\app_to_run.exe 192.168.10.21 C:\path1\app_to_run.exe Saved_Command_line

  5. The application ends

PROBLEM: ForcebindIP doesn't pass parameters to the called program. then if you need to pass parameters to the app_to_run.exe you need a more evolved approach where XXX.exe creates a batch file including app_to_run.exe and the parameters passed, this batch then is called instead of app_to_run.exe at point 4.

You can also take a look at some GUI apps wrapping ForcebindIP. Some of them are able to work with more than one app but they do not do what you need.

https://www.raymond.cc/blog/bind-windows-application-to-specific-network-adapter-with-forcebindip/

Pat

Posted 2015-11-24T06:31:54.460

Reputation: 2 593

Do you mean that the helper application would intercept an attempt at creating a child process and run it through ForceBindIP instead? If so, do you have any suggestions on how to approach this? – Victor Marchuk – 2015-12-02T13:17:55.233

You are right. the helper application will have the name of every wrapped exe and it will end calling the corresponding original exe through ForceBind. Of course you need here some renaming or directory game in order to avoid 2 exes with the same name under the same directory. This helper app can be easily coded i.e. in C – Pat – 2015-12-02T17:48:08.837