Skip to content

Commit

Permalink
NPFInstall.exe supports renaming our loopback adapter to "NPcap Loopb…
Browse files Browse the repository at this point in the history
…ack Adapter" now, but this is not the network name, we need to find a way to rename the network in ncpa.cpl, because that name is used more often.
  • Loading branch information
hsluoyz committed Dec 29, 2015
1 parent 2009b38 commit 4eb04f1
Show file tree
Hide file tree
Showing 4 changed files with 304 additions and 5 deletions.
16 changes: 11 additions & 5 deletions packetWin7/NPFInstall/NPFInstall/LoopbackInstall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Module Name:
--*/

#include "LoopbackInstall.h"
#include "LoopbackRecord.h"

#include <shlobj.h>

Expand Down Expand Up @@ -69,7 +70,7 @@ void addDevID(int iDevID)
void addDevID(TCHAR strDevID[]) //DevID is in form like: "ROOT\\NET\\0008"
{
int iDevID;
_stscanf(strDevID, _T("ROOT\\NET\\%04d"), &iDevID);
_stscanf_s(strDevID, _T("ROOT\\NET\\%04d"), &iDevID);
addDevID(iDevID);
}

Expand All @@ -84,7 +85,7 @@ void addDevID_Pre(int iDevID)
void addDevID_Pre(TCHAR strDevID[]) //DevID is in form like: "ROOT\\NET\\0008"
{
int iDevID;
_stscanf(strDevID, _T("ROOT\\NET\\%04d"), &iDevID);
_stscanf_s(strDevID, _T("ROOT\\NET\\%04d"), &iDevID);
addDevID_Pre(iDevID);
}

Expand Down Expand Up @@ -1294,7 +1295,7 @@ BOOL GetConfigFilePath(char strConfigPath[])
{
return FALSE;
}
_splitpath(tmp, drive, dir, NULL, NULL);
_splitpath_s(tmp, drive, _MAX_DRIVE, dir, _MAX_DIR, NULL, 0, NULL, 0);
sprintf_s(strConfigPath, MAX_PATH + 30, "%s%sloopback.ini", drive, dir);
return TRUE;
}
Expand Down Expand Up @@ -1368,7 +1369,7 @@ int LoadDevIDFromFile()
{
return -1;
}
fscanf(fp, "%d", &iDevID);
fscanf_s(fp, "%d", &iDevID);
fclose(fp);
return iDevID;
}
Expand Down Expand Up @@ -1398,6 +1399,11 @@ BOOL InstallLoopbackAdapter()
return FALSE;
}

if (!RecordLoopbackDevice(iNPcapAdapterID))
{
return FALSE;
}

if (!SaveDevIDToFile(iNPcapAdapterID))
{
return FALSE;
Expand All @@ -1419,4 +1425,4 @@ BOOL UninstallLoopbackAdapter()
}

return TRUE;
}
}
267 changes: 267 additions & 0 deletions packetWin7/NPFInstall/NPFInstall/LoopbackRecord.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
/*++
Copyright (c) Nmap.org. All rights reserved.
Module Name:
LoopbackRecord.cpp
Abstract:
This is used for enumerating our "NPcap Loopback Adapter" using NetCfg API, if found, we changed its name from "Ethernet X" to "NPcap Loopback Adapter".
Also, we need to make a flag in registry to let the NPcap driver know that "this adapter is ours", so send the loopback traffic to it.
--*/

#include <Netcfgx.h>

#include <iostream>
#include <atlbase.h> // CComPtr
#include <devguid.h> // GUID_DEVCLASS_NET, ...

#include "LoopbackRecord.h"

#define NPCAP_LOOPBACK_ADAPTER_NAME L"NPcap Loopback Adapter"
#define NPCAP_LOOPBACK_APP_NAME L"NPCAP_Loopback"

int g_NPcapAdapterID = -1;

// RAII helper class
class COM
{
public:
COM();
~COM();
};

COM::COM()
{
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

if(!SUCCEEDED(hr))
{
printf("ERROR: CoInitializeEx() failed. Error code: 0x%08x\n", hr);
}
}

COM::~COM()
{
CoUninitialize();
}

// RAII helper class
class NetCfg
{
CComPtr<INetCfg> m_pINetCfg;
CComPtr<INetCfgLock> m_pLock;

public:
NetCfg();
~NetCfg();

// Displays all network adapters, clients, transport protocols and services.
// For each client, transport protocol and service (network features)
// shows adpater(s) they are bound to.
BOOL GetNetworkConfiguration();
};

NetCfg::NetCfg() : m_pINetCfg(0)
{
HRESULT hr = S_OK;

hr = m_pINetCfg.CoCreateInstance(CLSID_CNetCfg);

if(!SUCCEEDED(hr))
{
printf("ERROR: CoCreateInstance() failed. Error code: 0x%08x\n", hr);
throw 1;
}

hr = m_pINetCfg.QueryInterface(&m_pLock);

if (!SUCCEEDED(hr))
{
printf("QueryInterface(INetCfgLock) 0x%08x\n", hr);
throw 2;
}

// Note that this call can block.
hr = m_pLock->AcquireWriteLock(INFINITE, NPCAP_LOOPBACK_APP_NAME, NULL);
if (!SUCCEEDED(hr))
{
printf("INetCfgLock::AcquireWriteLock 0x%08x\n", hr);
throw 3;
}

hr = m_pINetCfg->Initialize(NULL);

if(!SUCCEEDED(hr))
{
printf("ERROR: Initialize() failed. Error code: 0x%08x\n", hr);
throw 4;
}
}

NetCfg::~NetCfg()
{
HRESULT hr = S_OK;

if(m_pINetCfg)
{
hr = m_pINetCfg->Uninitialize();
if(!SUCCEEDED(hr))
{
printf("ERROR: Uninitialize() failed. Error code: 0x%08x\n", hr);
}

hr = m_pLock->ReleaseWriteLock();
if (!SUCCEEDED(hr))
{
printf("INetCfgLock::ReleaseWriteLock 0x%08x\n", hr);
}
}
}

BOOL EnumerateComponents(CComPtr<INetCfg>& pINetCfg, const GUID* pguidClass)
{
/* cout << "\n\nEnumerating " << GUID2Str(pguidClass) << " class:\n" << endl;*/

// IEnumNetCfgComponent provides methods that enumerate the INetCfgComponent interfaces
// for network components of a particular type installed on the operating system.
// Types of network components include network cards, protocols, services, and clients.
CComPtr<IEnumNetCfgComponent> pIEnumNetCfgComponent;

// get enumeration containing network components of the provided class (GUID)
HRESULT hr = pINetCfg->EnumComponents(pguidClass, &pIEnumNetCfgComponent);

if(!SUCCEEDED(hr))
{
printf("ERROR: Failed to get IEnumNetCfgComponent interface pointer\n");
throw 1;
}

// INetCfgComponent interface provides methods that control and retrieve
// information about a network component.
CComPtr<INetCfgComponent> pINetCfgComponent;

unsigned int nIndex = 1;
BOOL bFound = FALSE;
BOOL bFailed = FALSE;
// retrieve the next specified number of INetCfgComponent interfaces in the enumeration sequence.
while(pIEnumNetCfgComponent->Next(1, &pINetCfgComponent, 0) == S_OK)
{
/* cout << GUID2Desc(pguidClass) << " "<< nIndex++ << ":\n";*/

// LPWSTR pszDisplayName = NULL;
// pINetCfgComponent->GetDisplayName(&pszDisplayName);
// wcout << L"\tDisplay name: " << wstring(pszDisplayName) << L'\n';
// CoTaskMemFree(pszDisplayName);

LPWSTR pszBindName = NULL;
pINetCfgComponent->GetBindName(&pszBindName);
// wcout << L"\tBind name: " << wstring(pszBindName) << L'\n';
CoTaskMemFree(pszBindName);

// DWORD dwCharacteristics = 0;
// pINetCfgComponent->GetCharacteristics(&dwCharacteristics);
// cout << "\tCharacteristics: " << dwCharacteristics << '\n';
//
// GUID guid;
// pINetCfgComponent->GetClassGuid(&guid);
// cout << "\tClass GUID: " << guid.Data1 << '-' << guid.Data2 << '-'
// << guid.Data3 << '-' << (unsigned int) guid.Data4 << '\n';
//
// ULONG ulDeviceStatus = 0;
// pINetCfgComponent->GetDeviceStatus(&ulDeviceStatus);
// cout << "\tDevice Status: " << ulDeviceStatus << '\n';
//
// LPWSTR pszHelpText = NULL;
// pINetCfgComponent->GetHelpText(&pszHelpText);
// wcout << L"\tHelp Text: " << wstring(pszHelpText) << L'\n';
// CoTaskMemFree(pszHelpText);
//
// LPWSTR pszID = NULL;
// pINetCfgComponent->GetId(&pszID);
// wcout << L"\tID: " << wstring(pszID) << L'\n';
// CoTaskMemFree(pszID);
//
// pINetCfgComponent->GetInstanceGuid(&guid);
// cout << "\tInstance GUID: " << guid.Data1 << '-' << guid.Data2 << '-'
// << guid.Data3 << '-' << (unsigned int) guid.Data4 << '\n';

LPWSTR pszPndDevNodeId = NULL;
pINetCfgComponent->GetPnpDevNodeId(&pszPndDevNodeId);
// wcout << L"\tPNP Device Node ID: " << wstring(pszPndDevNodeId) << L'\n';

int iDevID = getIntDevID(pszPndDevNodeId);
if (g_NPcapAdapterID == iDevID)
{
bFound = TRUE;

hr = pINetCfgComponent->SetDisplayName(NPCAP_LOOPBACK_ADAPTER_NAME);

if (hr != S_OK)
{
bFailed = TRUE;
}
else
{
AddFlagToLoopbackDevice();
}
}

CoTaskMemFree(pszPndDevNodeId);
pINetCfgComponent.Release();

if (bFound)
{
return TRUE;
}
if (bFailed)
{
return FALSE;
}
}

return FALSE;
}

BOOL NetCfg::GetNetworkConfiguration()
{
// get enumeration containing GUID_DEVCLASS_NET class of network components
return EnumerateComponents(m_pINetCfg, &GUID_DEVCLASS_NET);
}

int getIntDevID(TCHAR strDevID[]) //DevID is in form like: "ROOT\\NET\\0008"
{
int iDevID;
_stscanf_s(strDevID, _T("ROOT\\NET\\%04d"), &iDevID);
return iDevID;
}

BOOL AddFlagToLoopbackDevice()
{
return TRUE;
}

BOOL RecordLoopbackDevice(int iNPcapAdapterID)
{
g_NPcapAdapterID = iNPcapAdapterID;

try
{
COM com;
NetCfg netCfg;
if (!netCfg.GetNetworkConfiguration())
{
return FALSE;
}
}
catch(...)
{
printf("ERROR: main() caught exception\n");
return FALSE;
}

return TRUE;
}
18 changes: 18 additions & 0 deletions packetWin7/NPFInstall/NPFInstall/LoopbackRecord.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*++
Copyright (c) Nmap.org. All rights reserved.
Module Name:
LoopbackRecord.h
Abstract:
This is used for enumerating our "NPcap Loopback Adapter" using NetCfg API, if found, we changed its name from "Ethernet X" to "NPcap Loopback Adapter".
Also, we need to make a flag in registry to let the NPcap driver know that "this adapter is ours", so send the loopback traffic to it.
--*/

int getIntDevID(TCHAR strDevID[]);
BOOL AddFlagToLoopbackDevice();
BOOL RecordLoopbackDevice(int iNPcapAdapterID);
8 changes: 8 additions & 0 deletions packetWin7/NPFInstall/NPFInstall/NPFInstall.vcproj
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@
RelativePath=".\LoopbackInstall.cpp"
>
</File>
<File
RelativePath=".\LoopbackRecord.cpp"
>
</File>
<File
RelativePath="..\..\Dll\netcfgapi.cpp"
>
Expand All @@ -360,6 +364,10 @@
RelativePath=".\LoopbackInstall.h"
>
</File>
<File
RelativePath=".\LoopbackRecord.h"
>
</File>
<File
RelativePath=".\msg.h"
>
Expand Down

0 comments on commit 4eb04f1

Please sign in to comment.