看雪论坛

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

netsd 2017-3-13 835

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


逆向了路由表相关操作的函数,包含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


详细的代码看附件吧。





最新回复 (6)
linhanshi 2017-3-13
2
support!
uvbs 2017-3-13
3
赞一个
水木之 2017-3-14
4
厉害了,可以自己做router了
值得怀疑 2017-3-15
5
支持 搞完整他·· 支持 win10吗·?
netsd 2017-3-16
6
值得怀疑 支持 搞完整他··[em_1] 支持 win10吗·?
这个没试过,你拿WIN7的去试试,应该差不多。
halou 5天前
7
棋牌辅助透视联系我603580196 重谢
返回



©2000-2017 看雪学院 | Based on Xiuno BBS | 知道创宇带宽支持 | 微信公众号:ikanxue
Time: 0.009, SQL: 7 / 京ICP备10040895号-17