欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]逆向分析路由表相关函数(route.exe)

[原创]逆向分析路由表相关函数(route.exe)

好多年前弄的玩意了,放出来吧。


逆向了路由表相关操作的函数,包含win7 和 xp 平台,临时 和 永久路由表操作的API。

PS: 代码可能有资源泄漏等问题,只经过简单测试。


win 主要是操作 \\\\.\\Nsi (nsi.dll),xp 操作的是 \\\\.\\Tcp (iphlpapi.dll, mprapi.dll)


贴一下啊WIN7的代码,XP的见

#include "stdafx.h"

#include "NsiFunc.h"

#pragma comment(lib,"Iphlpapi.lib")

namespace ROUTEAPI

{

 

#ifndef HEAPMALLOC

#define HEAPMALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))

#endif

#ifndef HEAPFREE

#define HEAPFREE(x) HeapFree(GetProcessHeap(), 0, (x))

#endif

Route::Route()

{

	g_NsiAsyncDeviceHandle = INVALID_HANDLE_VALUE;

	g_NsiDeviceHandle = INVALID_HANDLE_VALUE;

	hNtdll = NULL;

	m_NtDeviceIoControlFile = NULL;

	m_NtWaitForSingleObject = NULL;

	m_RtlIpv4StringToAddressA = NULL;

	m_RtlIpv4StringToAddressW = NULL;

	m_RtlNtStatusToDosError = NULL;

}

Route::~Route()

{

}

DWORD Route::GetNtdllFuc()

{

	hNtdll = LoadLibrary(_T("ntdll.dll"));

	if (hNtdll == NULL)

	{

		return GetLastError();

	}

	m_NtDeviceIoControlFile = (NtDeviceIoControlFile)GetProcAddress(hNtdll,

		"NtDeviceIoControlFile");

	m_NtWaitForSingleObject = (NtWaitForSingleObject)GetProcAddress(hNtdll,

		"NtWaitForSingleObject");

	m_RtlNtStatusToDosError = (RtlNtStatusToDosError)GetProcAddress(hNtdll,

		"RtlNtStatusToDosError");

	m_RtlIpv4StringToAddressA = (RtlIpv4StringToAddressA)GetProcAddress(hNtdll,

		"RtlIpv4StringToAddressA");

	m_RtlIpv4StringToAddressW = (RtlIpv4StringToAddressW)GetProcAddress(hNtdll,

		"RtlIpv4StringToAddressW");

	if (!m_NtDeviceIoControlFile || !m_NtWaitForSingleObject || !m_RtlNtStatusToDosError

		||m_RtlIpv4StringToAddressA||m_RtlIpv4StringToAddressW)

	{

		FreeLibrary(hNtdll);

		return GetLastError();

	}

	return NO_ERROR;

}

DWORD  Route::Initialize()

{

	return GetNtdllFuc();

}

VOID Route::Clrear()

{

	//释放DLL

	if (hNtdll)

	{

		FreeLibrary(hNtdll);

	}

	hNtdll = NULL;

	m_NtDeviceIoControlFile = NULL;

	m_NtWaitForSingleObject = NULL;

	m_RtlIpv4StringToAddressA = NULL;

	m_RtlIpv4StringToAddressW = NULL;

	m_RtlNtStatusToDosError = NULL;

}

DWORD Route::NsiOpenDevice(BOOL bAsync)

{

	DWORD dwDesiredAccess;

	DWORD dwFlagsAndAttributes;

	volatile HANDLE * HandlePoint;

	HANDLE tempHandle;

	DWORD result;

	dwDesiredAccess = 0;

	dwFlagsAndAttributes = 0;

	result = 0;

	dwDesiredAccess = 0X100000;

	if (bAsync == TRUE)

	{

		HandlePoint = (volatile HANDLE *)&g_NsiAsyncDeviceHandle;

		dwFlagsAndAttributes =  FILE_FLAG_OVERLAPPED;

	}

	else

	{

		HandlePoint = (volatile HANDLE *)&g_NsiDeviceHandle;

	}

	if(*HandlePoint == INVALID_HANDLE_VALUE)

	{

		tempHandle = CreateFile(_T("\\\\.\\Nsi"),   

			                    dwDesiredAccess,

								FILE_SHARE_WRITE|FILE_SHARE_READ,

								NULL,OPEN_EXISTING,

								dwFlagsAndAttributes,

								NULL

								);

		if(tempHandle == INVALID_HANDLE_VALUE)

		{

			result = GetLastError();

		}

		else

		{

			if ( InterlockedCompareExchange((volatile LONG *)HandlePoint,(LONG) tempHandle, -1) != -1 )

				CloseHandle(tempHandle);

			result = 0;

		}

	}

	else

	{

		result =  0;

	}

	return result;

}

DWORD  Route:: NsiIoctl(DWORD dwIoControlCode, 

		 LPVOID lpInBuffer, 

		 DWORD nInBufferSize, 

		 LPVOID lpOutBuffer, 

		 DWORD * nOutBufferSize,

		 LPOVERLAPPED lpOverlapped

		 )

{

	DWORD result;

	DWORD dwOutBufferSize;

	HANDLE hevent = INVALID_HANDLE_VALUE;

	NTSTATUS m_ntsatus;

	IO_STATUS_BLOCK m_status_block;

	memset(&m_status_block,0,sizeof(m_status_block));

	result = NsiOpenDevice(TRUE);

	if (result)

	{

		return result;

	}

	dwOutBufferSize = * nOutBufferSize;

	if (lpOverlapped)

	{

		if (DeviceIoControl(

			   g_NsiAsyncDeviceHandle,

			   dwIoControlCode,

			   lpInBuffer,

			   nInBufferSize,

			   lpOutBuffer,

			   dwOutBufferSize,

			   nOutBufferSize,

			   lpOverlapped))

		{

			return NO_ERROR;

		}

		return GetLastError();

	}

	hevent = CreateEvent(NULL,FALSE,FALSE,NULL);

	if (hevent == NULL)

	{

		return GetLastError();

	}

	m_ntsatus = m_NtDeviceIoControlFile(

		                 g_NsiAsyncDeviceHandle,

						 hevent,

						 NULL,

						 NULL,

						 &m_status_block,

						 dwIoControlCode,

						 lpInBuffer,

						 nInBufferSize,

						 lpOutBuffer,

						 dwOutBufferSize

						 );

	if (m_ntsatus == STATUS_PENDING)

	{

		m_ntsatus = m_NtWaitForSingleObject(hevent,FALSE,0);

		if (m_ntsatus >= 0)

		{

			m_ntsatus = m_status_block.Status;

		}

	}

	CloseHandle(hevent);

	if (m_ntsatus >=0 && m_ntsatus != STATUS_MORE_ENTRIES)

	{

		* nOutBufferSize =  0;

		return NO_ERROR;

	}

	return m_RtlNtStatusToDosError(m_ntsatus& 0xC0000000);

}

DWORD Route:: Ipv4GetAddressA(

							   __in   PCSTR S,

							   __out  IN_ADDR* Addr

							   )

{

	if (m_RtlIpv4StringToAddressA(S,TRUE,(LPSTR *)&Addr,Addr) || *(BYTE *)Addr != 0 )

	{

		return ERROR_INVALID_PARAMETER;

	}

	else

	{

		return NO_ERROR;

	}

}

DWORD Route:: Ipv4GetAddressW(

								__in   PCWSTR S,

								__out  IN_ADDR* Addr

								)

{

	if (m_RtlIpv4StringToAddressW == NULL)

	{

		return GetLastError();

	}

	if (m_RtlIpv4StringToAddressW(S,TRUE,(LPWSTR *)&Addr,Addr) || *(BYTE *)Addr != 0 )

	{

		return ERROR_INVALID_PARAMETER;

	}

	else

	{

		return NO_ERROR;

	}

}

DWORD Route:: Ipv4GetPrefixA(

							   __in LPCSTR lpDestIpStr,

							   __out  IN_ADDR* Addr,

							   __out BYTE * PrefixLength

							   )

{

	DWORD dwResult;

	BYTE btemp;

	LPSTR lpdstIpstr_Copy;

	BYTE chPrefix;

	BYTE chTemp;

	PBYTE lpPoint ;

	dwResult = 0;

	chPrefix = 0;

	lpPoint = NULL;

	lpdstIpstr_Copy  = (LPSTR)lpDestIpStr;

	if (m_RtlIpv4StringToAddressA(lpDestIpStr,TRUE,&lpdstIpstr_Copy,Addr) < 0)

	{

		dwResult = ERROR_INVALID_PARAMETER;

		return dwResult;

	}

	btemp = *lpdstIpstr_Copy;

	lpdstIpstr_Copy ++;

	if (btemp != '/')

	{

		dwResult = ERROR_INVALID_PARAMETER;

		return dwResult;

	}

	for(;isdigit(*lpdstIpstr_Copy);lpdstIpstr_Copy++)  //计算输入的前缀

	{

		chPrefix = 10*chPrefix + *lpdstIpstr_Copy - 48;

		if (chPrefix>0xFF) //前缀使用CHAR 表示的,所以必然小于FF

		{

			dwResult = ERROR_INVALID_PARAMETER;

			return dwResult;

		}

	}

	if (*lpdstIpstr_Copy || chPrefix >0x20)  //在网络中,前缀最大只可能是32(0X20)

	{

		dwResult = ERROR_INVALID_PARAMETER;

		return dwResult;

	}

	else

	{

		chTemp = (chPrefix>>3)+1;

		lpPoint = (BYTE *)((BYTE *)Addr+chTemp);

		if (chTemp <4)

		{

			memset(lpPoint,0,sizeof(IN_ADDR)-chTemp);

		}

		chTemp = (chPrefix>>3);

		lpPoint = (BYTE *)((BYTE *)Addr + chTemp);

		(*lpPoint) &= -1<<(8-(chPrefix&7));

		*PrefixLength = chPrefix;

		return 0;

	}

} 

DWORD Route:: Ipv4GetPrefixW(

							 __in LPCWSTR lpDestIpStr,

							 __out  IN_ADDR* Addr,

							 __out BYTE * PrefixLength

							 )

{

	DWORD dwResult;

	WCHAR btemp;

	LPWSTR lpdstIpstr_Copy;

	BYTE chPrefix;

	BYTE chTemp;

	BYTE * lpPoint ;

	dwResult = 0;

	chPrefix = 0;

	lpPoint = NULL;

	lpdstIpstr_Copy  = (LPWSTR)lpDestIpStr;

	if (m_RtlIpv4StringToAddressW(lpDestIpStr,TRUE,&lpdstIpstr_Copy,Addr) < 0)

	{

		dwResult = ERROR_INVALID_PARAMETER;

		return dwResult;

	}

	btemp = *lpdstIpstr_Copy;

	lpdstIpstr_Copy ++;

	if (btemp != '/')

	{

		dwResult = ERROR_INVALID_PARAMETER;

		return dwResult;

	}

	for(;iswdigit (*lpdstIpstr_Copy);lpdstIpstr_Copy++)  //计算输入的前缀

	{

		chPrefix = 10*chPrefix + *lpdstIpstr_Copy - 48;

		if (chPrefix>0xFF) //前缀本来使用CHAR 表示的,因为结构体对齐,改为DWORD ,所以必然小于FF

		{

			dwResult = ERROR_INVALID_PARAMETER;

			return dwResult;

		}

	}

	if (*lpdstIpstr_Copy || chPrefix >0x20)  //在网络中,前缀最大只可能是32(0X20)

	{

		dwResult = ERROR_INVALID_PARAMETER;

		return dwResult;

	}

	else

	{

		chTemp = (chPrefix>>3)+1;

		lpPoint = (BYTE *)((BYTE *)Addr+chTemp);

		if (chTemp <4)

		{

			memset(lpPoint,0,sizeof(IN_ADDR)-chTemp);

		}

		chTemp = (chPrefix>>3);

		lpPoint = (BYTE *)((BYTE *)Addr + chTemp);

		(*lpPoint) &= -1<<(8-(chPrefix&7));

		*PrefixLength = chPrefix;

		return 0;

	}

} 

DWORD  Route::NsiSetAllParameters(DWORD dwStatic, 

						   DWORD dwActionCode, 

						   LPVOID NPI_MS_MODULEID, 

						   DWORD dwIoMainCode,  //一般为 16

						   LPVOID lpNetInfoBuffer,   

						   int SizeofNetInfoBuffer, 

						   LPVOID lpMetricBuffer, 

						   int SizeofMetricBuffer

						   )

{

   ADD_ROUTE_DEV m_route_dev;

   DWORD OutBufferSize;

  memset(&m_route_dev,0,sizeof(m_route_dev));

	m_route_dev.dwReserved1 = 0;

	m_route_dev.dwReserved2 = 0;

	m_route_dev.lpNpi = NPI_MS_MODULEID;

	m_route_dev.dwIoMainCode = 16;

	m_route_dev.dwStatic = dwStatic;

	m_route_dev.dwIoActionCode = dwActionCode;

	m_route_dev.lpdevinfo = (PROUTE_DEV_INFO)lpNetInfoBuffer;

	m_route_dev.ElementsSizeOfDev = SizeofNetInfoBuffer;

	m_route_dev.lpmertricinfo = (PROUTE_MERTRIC_INFO)lpMetricBuffer;

	m_route_dev.ElementsSizeOfMertric = SizeofMetricBuffer;

	OutBufferSize = sizeof(m_route_dev);

	return NsiIoctl(IOCTL_ROUTE_OPT_REQUEST,

		         &m_route_dev,

				 sizeof(m_route_dev),

				 &m_route_dev,

				 &OutBufferSize,

				 0

				 );

}

DWORD Route::NsiAllocateAndGetTable(DWORD dwStatic,

							 LPVOID NPI_MS_MODULEID,

							 DWORD dwIoMainCode,  //一般为 16

							 LPVOID* lpRouteInfoBuffer, //输入的指针,获得一个缓冲区,指向ROUTE_DEV_INFO结构体数组

							 DWORD ElementsSizeOfDev, //一个ROUTE_DEV_INFO的大小

							 LPVOID * lpMertricInfoBuffer, //输入的指针,获得一个缓冲区,指向ROUTE_MERTRIC_INFO结构体数组

							 DWORD ElementsSizeOfMertric, //一个ROUTE_MERTRIC_INFO结构的大小

							 LPVOID *lpUnknow1,

							 DWORD dwUnknow1,  //未知的结构体大小

							 LPVOID *lpUnknow2,

							 DWORD dwUnknow2,

							 DWORD *dwRouteSize, //路由信息的条数

							 DWORD dwReserved//未使用的位,保持0

							 )

{

	const DWORD dwZero = 0;

	DWORD dwResult;

	DWORD dwRouteInfoCount;

	DWORD dwTotalSizeOfDev = 0;

	LPVOID lpTemp_RouteInfo = NULL;

	DWORD dwTotalSizeOfMertric = 0;

	LPVOID lpTemp_MerterInfo = NULL;

	DWORD dwTotalSizeOfUnknow1 = 0;

	LPVOID lpTemp_Unknow1 = NULL;

	DWORD dwTotalSizeOfUnknow2 = 0;

	LPVOID lpTemp_Unknow2 = NULL;

	int i ;

	dwResult = 0;

	dwRouteInfoCount = 0;

	i = 0;

	for (;i<3;i++)

	{

		dwRouteInfoCount = 0;

		dwResult = NsiEnumerateObjectsAllParameters(

								dwStatic,

								1,

								NPI_MS_MODULEID,

								dwIoMainCode,

								dwZero,dwZero,

								dwZero,dwZero,

								dwZero,dwZero,

								dwZero,dwZero,

								&dwRouteInfoCount);

		if (dwResult !=0 && dwResult != ERROR_MORE_DATA)

		{

			return dwResult;

		}

		dwRouteInfoCount +=2;

		if (ElementsSizeOfDev > 0)

		{

			dwTotalSizeOfDev = ElementsSizeOfDev*dwRouteInfoCount;

			lpTemp_RouteInfo = (LPVOID)HEAPMALLOC(dwTotalSizeOfDev);

			if (lpTemp_RouteInfo == NULL)

			{

				return ERROR_NOT_ENOUGH_MEMORY;

			}

		}

		if (ElementsSizeOfMertric > 0)

		{

			dwTotalSizeOfMertric = ElementsSizeOfMertric*dwRouteInfoCount;

			lpTemp_MerterInfo = (LPVOID)HEAPMALLOC(dwTotalSizeOfMertric);

			if (lpTemp_MerterInfo == NULL)

			{

				NsiFreeTable(lpTemp_RouteInfo,lpMertricInfoBuffer,NULL,NULL);

				return ERROR_NOT_ENOUGH_MEMORY;

			}

			memset(lpTemp_MerterInfo,0,dwTotalSizeOfMertric);

		}

		if (dwUnknow1 >0)

		{

			dwTotalSizeOfUnknow1 = dwUnknow1*dwRouteInfoCount;

			lpTemp_Unknow1 = (LPVOID)HEAPMALLOC(dwTotalSizeOfUnknow1);

			if (lpTemp_Unknow1 == NULL)

			{

				NsiFreeTable(lpTemp_RouteInfo,lpMertricInfoBuffer,lpTemp_Unknow1,NULL);

				return ERROR_NOT_ENOUGH_MEMORY;

			}

		}

		if (dwUnknow2 >0)

		{

			dwTotalSizeOfUnknow2 = dwUnknow1*dwRouteInfoCount;

			lpTemp_Unknow2 = (LPVOID)HEAPMALLOC(dwTotalSizeOfUnknow2);

			if (lpTemp_Unknow2 == NULL)

			{

				NsiFreeTable(lpTemp_RouteInfo,lpMertricInfoBuffer,lpTemp_Unknow1,lpTemp_Unknow2);

				return ERROR_NOT_ENOUGH_MEMORY;

			}

		}

		dwResult = NsiEnumerateObjectsAllParameters(

			dwStatic,

			1,

			NPI_MS_MODULEID,

			dwIoMainCode,

			lpTemp_RouteInfo,ElementsSizeOfDev,

			lpTemp_MerterInfo,ElementsSizeOfMertric,

			lpTemp_Unknow1,dwUnknow1,

			lpTemp_Unknow2,dwUnknow2,

			&dwRouteInfoCount);

		if (dwResult != ERROR_MORE_DATA)

		{

			break;

		}

		NsiFreeTable(lpTemp_RouteInfo,lpMertricInfoBuffer,lpTemp_Unknow1,lpTemp_Unknow2);

		lpTemp_RouteInfo = NULL;

		lpTemp_MerterInfo = NULL;

		lpTemp_Unknow1 = NULL;

		lpTemp_Unknow2 = NULL;

	}	//end for

	if (dwResult !=0)

	{

		NsiFreeTable(lpTemp_RouteInfo,lpMertricInfoBuffer,lpTemp_Unknow1,lpTemp_Unknow2);

		return dwResult;

	}

	if (i == 3)

	{

		return STATUS_UNSUCCESSFUL;

	}

	else

	{

		*dwRouteSize = dwRouteInfoCount;

		if (lpTemp_RouteInfo != NULL)

		{

			*lpRouteInfoBuffer = lpTemp_RouteInfo;

		}

		if (lpTemp_MerterInfo != NULL)

		{

			*lpMertricInfoBuffer = lpTemp_MerterInfo;

		}

		if (lpTemp_Unknow1 != NULL)

		{

			*lpUnknow1 = lpTemp_Unknow1;

		}

		if (lpTemp_Unknow2 != NULL)

		{

			*lpUnknow2 = lpTemp_Unknow2;

		}

		dwResult = NO_ERROR;

	}

	return dwResult;

}

void  Route::NsiFreeTable(LPVOID lpRouteInfoBuffer,

						  LPVOID  lpMertricInfoBuffer,

						  LPVOID lpUnknow1,

						  LPVOID lpUnknow2

						  )

{

	if (lpRouteInfoBuffer)

	{

		HEAPFREE(lpRouteInfoBuffer);

	}

	if (lpMertricInfoBuffer)

	{

		HEAPFREE(lpMertricInfoBuffer);

	}

	if (lpUnknow1)

	{

		HEAPFREE(lpUnknow1);

	}

	if (lpUnknow2)

	{

		HEAPFREE(lpUnknow2);

	}

}

DWORD Route::NsiEnumerateObjectsAllParameters(

									   DWORD dwStatic,

									   DWORD dwUnknow0,  //默认是1

									   LPVOID NPI_MS_MODULEID,

									   DWORD dwIoMainCode,  //一般为 16

									   LPVOID lpRouteInfoBuffer, //输入的指针,获得一个缓冲区,指向ROUTE_DEV_INFO结构体数组

									   DWORD ElementsSizeOfDev, //一个ROUTE_DEV_INFO的大小

									   LPVOID lpMertricInfoBuffer, //输入的指针,获得一个缓冲区,指向ROUTE_MERTRIC_INFO结构体数组

									   DWORD ElementsSizeOfMertric, //一个ROUTE_MERTRIC_INFO结构的大小

									   LPVOID lpUnknow1,

									   DWORD dwUnknow1, //未知的结构体大小

									   LPVOID lpUnknow2,

									   DWORD dwUnknow2,

									   DWORD *dwRouteSize//路由信息的条数

									   )

{

	NSI_REQUEST_QUERY_INFORMATION nsi_buffer;

	DWORD dwResult;

	DWORD dwOutBufferSize;

	memset(&nsi_buffer,0,sizeof(nsi_buffer));

	nsi_buffer.lpNpi = NPI_MS_MODULEID;

	nsi_buffer.dwIoMainCode = dwIoMainCode;

	nsi_buffer.dwStatic = dwStatic;

	nsi_buffer.dwIoActionCode = dwUnknow0; // 估计用的ACTIONCODE 1的添加路由信息

	nsi_buffer.lpdevinfo = (PROUTE_DEV_INFO )lpRouteInfoBuffer;

	nsi_buffer.ElementsSizeOfDev = ElementsSizeOfDev;

	nsi_buffer.lpmertricinfo = (PROUTE_MERTRIC_INFO )lpMertricInfoBuffer;

	nsi_buffer.ElementsSizeOfMertric = ElementsSizeOfMertric;

	nsi_buffer.lpUnknow1 = lpUnknow1;

	nsi_buffer.dwUnknow1 = dwUnknow1;

	nsi_buffer.lpUnknow2 = lpUnknow2;

	nsi_buffer.dwUnknow2 = dwUnknow2;

	nsi_buffer.dwRouteSize = *dwRouteSize;

	dwOutBufferSize = sizeof(nsi_buffer);

	dwResult = NsiIoctl(IOCTL_ROUTE_ENUM_OBJECT,

				 &nsi_buffer,sizeof(nsi_buffer),

				 &nsi_buffer,&dwOutBufferSize,

				 0);

	*dwRouteSize = nsi_buffer.dwRouteSize;

	return dwResult;

}

DWORD  Route::_AddIpv4Route(IN_ADDR DestIp, 

					 BYTE MaskPrefix, 

					 NET_IFINDEX InterfaceIndex, 

					 IN_ADDR GateWay, 

					 int varMetric, 

					 DWORD dwStatic)

{

	DWORD dwResult;

	ULONG64 ulValue;

	ROUTE_DEV_INFO m_dev_buffer;

	ROUTE_MERTRIC_INFO m_mertric_buffer;

	NET_LUID  InterFaceLuid;

	InterFaceLuid.Value = 0;

	ulValue = 0;

	int test = sizeof(m_dev_buffer);

	memset(&m_dev_buffer,0,test);

	m_dev_buffer.dwIPv4Address = DestIp;

	m_dev_buffer.chMaskPrefix = MaskPrefix;

	m_dev_buffer.dwGateway = GateWay;

	if (InterfaceIndex)

	{

		dwResult = ConvertInterfaceIndexToLuid(InterfaceIndex,&(InterFaceLuid));

		if (dwResult)

		{

			return dwResult;

		}

	   ulValue = InterFaceLuid.Value;

	}

	m_dev_buffer.LuidValue1.Value = ulValue & 0X00000000FFFFFFFF ;

	m_dev_buffer.LuidValue2.Value = ulValue & 0X00000000FFFFFFFF ;

	test = sizeof(m_mertric_buffer);

	memset(&m_mertric_buffer,-1,sizeof(m_mertric_buffer));

	m_mertric_buffer.Mertric = varMetric;

	return NsiSetAllParameters(dwStatic,1,(LPVOID)NPI_MS_IPV4_MODULEID,16,&m_dev_buffer,sizeof(m_dev_buffer),&m_mertric_buffer,sizeof(m_mertric_buffer));

}

DWORD Route::AddIpv4RouteA(LPCSTR lpDestIpStr, 

			  LPCSTR lpMaskStr, 

			  LPCSTR lpGateWayStr, 

			  int MetricNum, 

			  BOOL bStatic, 

			  DWORD * StaticRet, 

			  NET_IFINDEX InterfaceIndex)

{

	DWORD dwResult;

	IN_ADDR AddrDestIp;

	IN_ADDR AddrGateWay;

	IN_ADDR AddMask;

	BYTE chMaskPrefix;

	dwResult = 0;

	chMaskPrefix = 0;

	dwResult = Ipv4GetPrefixA(lpDestIpStr,&AddrDestIp,&chMaskPrefix);

	if(dwResult == ERROR_INVALID_PARAMETER)

	{

		dwResult = Ipv4GetAddressA(lpDestIpStr,&AddrDestIp);

		if (dwResult)

		{

			dwResult = ERROR_INVALID_PARAMETER;

			return dwResult;

		}

		if (lpMaskStr)

		{

			dwResult = Ipv4GetAddressA(lpMaskStr,&AddMask);

			if (dwResult)

				return dwResult;

			else

			{

				dwResult = ConvertIpv4MaskToLength(AddMask.s_addr,(PUINT8)&chMaskPrefix);

				if (dwResult != NO_ERROR)

					return dwResult;

			}

		}

	}

	if (lpGateWayStr)

	{

	    dwResult = Ipv4GetAddressA(lpGateWayStr,&AddrGateWay);

		if (dwResult != NO_ERROR)

		   return dwResult;

	}// end

	dwResult = _AddIpv4Route(AddrDestIp,chMaskPrefix,InterfaceIndex,AddrGateWay,MetricNum,1);

	if(bStatic)

	{

		dwResult = _AddIpv4Route(AddrDestIp,chMaskPrefix,InterfaceIndex,AddrGateWay,MetricNum,0);

		if (StaticRet != NULL)

		{

			*StaticRet = dwResult;

		}

	}

	return dwResult;

}

DWORD Route::AddIpv4RouteW(LPCWSTR lpDestIpStr, 

					LPCWSTR lpMaskStr, 

					LPCWSTR lpGateWayStr, 

					int MetricNum, 

					BOOL bStatic, 

					DWORD * StaticRet, 

					NET_IFINDEX InterfaceIndex)

{

	DWORD dwResult;

	IN_ADDR AddrDestIp;

	IN_ADDR AddrGateWay;

	IN_ADDR AddMask;

	BYTE chMaskPrefix;

	dwResult = 0;

	chMaskPrefix = 0;

	dwResult = Ipv4GetPrefixW(lpDestIpStr,&AddrDestIp,&chMaskPrefix);

	if(dwResult == ERROR_INVALID_PARAMETER)

	{

		dwResult = Ipv4GetAddressW(lpDestIpStr,&AddrDestIp);

		if (dwResult)

		{

			dwResult = ERROR_INVALID_PARAMETER;

			return dwResult;

		}

		if (lpMaskStr)

		{

			dwResult = Ipv4GetAddressW(lpMaskStr,&AddMask);

			if (dwResult)

				return dwResult;

			else

			{

				dwResult = ConvertIpv4MaskToLength(AddMask.s_addr,(PUINT8)&chMaskPrefix);

				if (dwResult != NO_ERROR)

					return dwResult;

			}

		}

	}

	if (lpGateWayStr)

	{

		dwResult = Ipv4GetAddressW(lpGateWayStr,&AddrGateWay);

		if (dwResult != NO_ERROR)

			return dwResult;

	}// end

	dwResult = _AddIpv4Route(AddrDestIp,chMaskPrefix,InterfaceIndex,AddrGateWay,MetricNum,1);

	if(bStatic)

	{

		dwResult = _AddIpv4Route(AddrDestIp,chMaskPrefix,InterfaceIndex,AddrGateWay,MetricNum,0);

		if (StaticRet != NULL)

		{

			*StaticRet = dwResult;

		}

	}

	return dwResult;

}

DWORD Route::DeleteIpv4RouteA(LPCSTR lpDestIpStr, 

					   LPCSTR lpMaskStr, 

					   LPCSTR lpGateWayStr, 

					   BOOL bStatic,    //mustbe TRUE

					   NET_IFINDEX InterfaceIndex)

{

	LPCSTR lpDestIp_Copy;

	LPCSTR lpGateWay_Copy;

	DWORD dwResult;

	IN_ADDR AddrDestIp;

	IN_ADDR AddMask;

	IN_ADDR AddrGateWay;

	NET_LUID InterfaceLuid;

	BYTE chMaskPrefix;

	DWORD dwCount;

	AddMask.s_addr = 0;

	AddrDestIp.s_addr = 0;

	AddrGateWay.s_addr = 0;

	lpDestIp_Copy = lpDestIpStr;

	lpGateWay_Copy = lpGateWayStr;

	dwResult = 0;

	if (InterfaceIndex)

	{

		dwResult = ConvertInterfaceIndexToLuid(InterfaceIndex,&InterfaceLuid);

		if (dwResult)

		{

			return dwResult;

		}

	}

	if (!lpDestIpStr)

	{

		chMaskPrefix = -1;

	}

	else

	{

		dwResult = Ipv4GetPrefixA(lpDestIp_Copy,&AddrDestIp,&chMaskPrefix);

		if (dwResult == ERROR_INVALID_PARAMETER)

		{

			dwResult = Ipv4GetAddressA(lpDestIp_Copy,&AddrDestIp);

			if (dwResult)

			{

				return dwResult;

			}

			if (lpMaskStr)

			{

				dwResult = Ipv4GetAddressA(lpMaskStr,&AddMask);

				if (dwResult)

					return dwResult;

				else

				{

					dwResult = ConvertIpv4MaskToLength(AddMask.s_addr,(PUINT8)&chMaskPrefix);

					if (dwResult != NO_ERROR)

						return dwResult;

				}

			}

			else

			{

				chMaskPrefix = -1;

			}

		}

	}//end else

	if (lpGateWay_Copy)

	{

		dwResult = Ipv4GetAddressA(lpGateWay_Copy,&AddrGateWay);

		if (dwResult != NO_ERROR)

			return dwResult;

	}

	dwResult = _DeleteIpv4Route(AddrDestIp,chMaskPrefix,&InterfaceLuid,AddrGateWay,1,&dwCount);

	if(bStatic)

	{

		dwResult = _DeleteIpv4Route(AddrDestIp,chMaskPrefix,&InterfaceLuid,AddrGateWay,0,&dwCount);

	}

	if (lpDestIp_Copy)

	{

		if (dwResult)

		{

			return dwResult;

		}

		dwResult = (dwCount != 0 ? 0 : ERROR_NOT_FOUND);

		return dwResult;

	}

	else

		return NO_ERROR;

}

DWORD Route::DeleteIpv4RouteW(LPCWSTR lpDestIpStr, 

					   LPCWSTR lpMaskStr, 

					   LPCWSTR lpGateWayStr, 

					   BOOL bStatic,    //mustbe TRUE

					   NET_IFINDEX InterfaceIndex)

{

	LPCWSTR lpDestIp_Copy;

	LPCWSTR lpGateWay_Copy;

	DWORD dwResult;

	IN_ADDR AddrDestIp;

	IN_ADDR AddMask;

	IN_ADDR AddrGateWay;

	NET_LUID InterfaceLuid;

	BYTE chMaskPrefix;

	DWORD dwCount;

	AddMask.s_addr = 0;

	AddrDestIp.s_addr = 0;

	AddrGateWay.s_addr = 0;

	lpDestIp_Copy = lpDestIpStr;

	lpGateWay_Copy = lpGateWayStr;

	dwResult = 0;

	if (InterfaceIndex)

	{

		dwResult = ConvertInterfaceIndexToLuid(InterfaceIndex,&InterfaceLuid);

		if (dwResult)

		{

			return dwResult;

		}

	}

	if (!lpDestIpStr)

	{

		chMaskPrefix = -1;

	}

	else

	{

		dwResult = Ipv4GetPrefixW(lpDestIp_Copy,&AddrDestIp,&chMaskPrefix);

		if (dwResult == ERROR_INVALID_PARAMETER)

		{

			dwResult = Ipv4GetAddressW(lpDestIp_Copy,&AddrDestIp);

			if (dwResult)

			{

				return dwResult;

			}

			if (lpMaskStr)

			{

				dwResult = Ipv4GetAddressW(lpMaskStr,&AddMask);

				if (dwResult)

					return dwResult;

				else

				{

					dwResult = ConvertIpv4MaskToLength(AddMask.s_addr,(PUINT8)&chMaskPrefix);

					if (dwResult != NO_ERROR)

						return dwResult;

				}

			}

			else

			{

				chMaskPrefix = -1;

			}

		}

	}//end else

	if (lpGateWay_Copy)

	{

		dwResult = Ipv4GetAddressW(lpGateWay_Copy,&AddrGateWay);

		if (dwResult != NO_ERROR)

			return dwResult;

	}

	dwResult = _DeleteIpv4Route(AddrDestIp,chMaskPrefix,&InterfaceLuid,AddrGateWay,1,&dwCount);

	if(bStatic)

	{

		dwResult = _DeleteIpv4Route(AddrDestIp,chMaskPrefix,&InterfaceLuid,AddrGateWay,0,&dwCount);

	}

	if (lpDestIp_Copy)

	{

		if (dwResult)

		{

			return dwResult;

		}

		dwResult = (dwCount != 0 ? 0 : ERROR_NOT_FOUND);

		return dwResult;

	}

	else

		return NO_ERROR;

}

DWORD Route::_DeleteIpv4Route(IN_ADDR DestIp,

					   BYTE MaskPrefix, 

					   PNET_LUID pInterfaceLuid, 

					   IN_ADDR GateWay, 

					   DWORD dwStatic,

					   DWORD *dwCount

					   )

{

	DWORD dwResult = NO_ERROR;

	PROUTE_DEV_INFO pRouteInfo = NULL;

	DWORD dwRouteInfoCount = 0;

	BOOL bSetNsi = FALSE;

	PDWORD pdwTemp1;

	PDWORD pdwTemp2;

 	dwResult = NsiAllocateAndGetTable(

 						dwStatic,

 						(LPVOID)NPI_MS_IPV4_MODULEID,

 						16,

						(LPVOID*)&pRouteInfo,sizeof(ROUTE_DEV_INFO),

						0,0,0,0,0,0,&dwRouteInfoCount,0

 						);

	if (dwResult == NO_ERROR)

	{

		for (int i = 0;i<dwRouteInfoCount;i++)

		{

			if(DestIp.s_addr ==0 || pRouteInfo[i].dwIPv4Address.s_addr == DestIp.s_addr)

			{

				if (MaskPrefix == -1 || pRouteInfo[i].chMaskPrefix == MaskPrefix)

				{

					if (GateWay.s_addr == 0 || pRouteInfo[i].dwGateway.s_addr == GateWay.s_addr)

					{

						if (pInterfaceLuid != 0)

						{

							bSetNsi = TRUE;

						}

						else

						{

							pdwTemp1 =(PDWORD) pInterfaceLuid;

							pdwTemp2 = (PDWORD) (&pRouteInfo[i].LuidValue1);

							bSetNsi = (pdwTemp1[0] == pdwTemp2[0]);

							if (bSetNsi == FALSE)

							{

								bSetNsi = (pdwTemp1[1] == pdwTemp2[1]);

							}

						}

						if (bSetNsi == TRUE)

						{

							dwResult = NsiSetAllParameters(dwStatic,

											3,(LPVOID)NPI_MS_IPV4_MODULEID,

											16,&(pRouteInfo[i]),

											sizeof(ROUTE_DEV_INFO),

											NULL,0);

							if (dwResult == NO_ERROR && DestIp.s_addr != 0)

							{

								break;

								(*dwCount)++;

							}

						}

					}

				}

			}

		}

		NsiFreeTable(pRouteInfo,NULL,NULL,NULL);

	}

	return dwResult;

}

}//end of namespace routeapi


详细的代码看附件吧。





上传的附件 route_all.zip

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功