📄 cping.cpp
字号:
CRouteTime rt(E_NtDeviceIoControlFileSend);
NTSTATUS NtStatus = s_pTrampoline_NtDeviceIoControlFile(FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
IoControlCode,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength);
if (NtStatus == STATUS_PENDING) {
LARGE_INTEGER li;
li.QuadPart = INFINITE;
s_pTrampoline_NtWaitForSingleObject(Event, FALSE, &li);
NtStatus = IoStatusBlock->Status;
}
return NtStatus;
}
else if (IoControlCode == IO_CONTROL_AFD_RECV_DATAGRAM ||
IoControlCode == IO_CONTROL_AFD_RECV) {
CRouteTime rt(E_NtDeviceIoControlFileRecv);
return s_pTrampoline_NtDeviceIoControlFile(FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
IoControlCode,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength);
}
else {
CRouteTime rt(E_NtDeviceIoControlFile);
if (rt.Routed()) {
printf("IoControlCode: %08lx\n", IoControlCode);
__asm int 3;
}
return s_pTrampoline_NtDeviceIoControlFile(FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
IoControlCode,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength);
}
}
static RPC_STATUS RPC_ENTRY Detour_I_RpcGetBuffer(RPC_MESSAGE * Message)
{
CRouteTime rt(E_I_RpcGetBuffer);
return Trampoline_I_RpcGetBuffer(Message);
}
static RPC_STATUS RPC_ENTRY Detour_I_RpcSendReceive(RPC_MESSAGE * Message)
{
CRouteTime rt(E_I_RpcSendReceive);
return Trampoline_I_RpcSendReceive(Message);
}
static RPC_STATUS RPC_ENTRY Detour_I_RpcFreeBuffer(RPC_MESSAGE * Message)
{
CRouteTime rt(E_I_RpcFreeBuffer);
return Trampoline_I_RpcFreeBuffer(Message);
}
static RPC_STATUS RPC_ENTRY Detour_I_RpcSend(PRPC_MESSAGE Message)
{
CRouteTime rt(E_I_RpcSend);
return Trampoline_I_RpcSend(Message);
}
static RPC_STATUS RPC_ENTRY Detour_I_RpcReceive(PRPC_MESSAGE Message, unsigned int Size)
{
CRouteTime rt(E_I_RpcReceive);
return Trampoline_I_RpcReceive(Message, Size);
}
static RPC_STATUS RPC_ENTRY Detour_I_RpcFreePipeBuffer(RPC_MESSAGE * Message)
{
CRouteTime rt(E_I_RpcFreePipeBuffer);
return Trampoline_I_RpcFreePipeBuffer(Message);
}
static RPC_STATUS RPC_ENTRY Detour_I_RpcReallocPipeBuffer(PRPC_MESSAGE Message,
unsigned int NewSize)
{
CRouteTime rt(E_I_RpcReallocPipeBuffer);
return Trampoline_I_RpcReallocPipeBuffer(Message, NewSize);
}
static void RPC_ENTRY Detour_I_RpcRequestMutex(I_RPC_MUTEX * Mutex)
{
CRouteTime rt(E_I_RpcRequestMutex);
Trampoline_I_RpcRequestMutex(Mutex);
}
static void RPC_ENTRY Detour_I_RpcClearMutex(I_RPC_MUTEX Mutex)
{
CRouteTime rt(E_I_RpcClearMutex);
Trampoline_I_RpcClearMutex(Mutex);
}
static void * RPC_ENTRY Detour_I_RpcAllocate(unsigned int Size)
{
CRouteTime rt(E_I_RpcAllocate);
return Trampoline_I_RpcAllocate(Size);
}
static void RPC_ENTRY Detour_I_RpcFree(void * Object)
{
CRouteTime rt(E_I_RpcFree);
Trampoline_I_RpcFree(Object);
}
static void RPC_ENTRY Detour_I_RpcPauseExecution(unsigned long Milliseconds)
{
CRouteTime rt(E_I_RpcPauseExecution);
Trampoline_I_RpcPauseExecution(Milliseconds);
}
static RPC_STATUS RPC_ENTRY Detour_I_RpcMonitorAssociation(RPC_BINDING_HANDLE Handle,
PRPC_RUNDOWN RundownRoutine,
void * Context)
{
CRouteTime rt(E_I_RpcMonitorAssociation);
return Trampoline_I_RpcMonitorAssociation(Handle, RundownRoutine, Context);
}
static RPC_STATUS RPC_ENTRY Detour_I_RpcStopMonitorAssociation(RPC_BINDING_HANDLE Handle)
{
CRouteTime rt(E_I_RpcStopMonitorAssociation);
return Trampoline_I_RpcStopMonitorAssociation(Handle);
}
static STDMETHODIMP Detour_IPing_Ping(IPing *pip)
{
HRESULT hr;
InterlockedIncrement(&s_nInCall);
{
CRouteTime rt(E_Proxy);
hr = pip->Ping();
}
InterlockedDecrement(&s_nInCall);
return hr;
}
static STDMETHODIMP Detour_IPing_PingToServer(IPing *pip, LPSTR pszString)
{
HRESULT hr;
InterlockedIncrement(&s_nInCall);
{
CRouteTime rt(E_Proxy);
hr = pip->PingToServer(pszString);
}
InterlockedDecrement(&s_nInCall);
return hr;
}
static STDMETHODIMP Detour_IPing_PingToClient(IPing *pip, LPSTR *ppszString)
{
HRESULT hr;
InterlockedIncrement(&s_nInCall);
{
CRouteTime rt(E_Proxy);
hr = pip->PingToClient(ppszString);
}
InterlockedDecrement(&s_nInCall);
return hr;
}
static STDMETHODIMP Detour_IPing_PingToClientSize(IPing *pip, ULONG cbOut)
{
return pip->PingToClientSize(cbOut);
}
//////////////////////////////////////////////////////////////////////////////
//
HRESULT RerouteEntryPoints(VOID)
{
s_pNtWaitForSingleObject
= ((NTSTATUS (NTAPI *)(HANDLE,
BOOLEAN,
PLARGE_INTEGER))
DetourFindFunction("ntdll.dll", "NtWaitForSingleObject"));
s_pTrampoline_NtWaitForSingleObject
= ((NTSTATUS (NTAPI *)(HANDLE,
BOOLEAN,
PLARGE_INTEGER))
DetourFunction((PBYTE)s_pNtWaitForSingleObject,
(PBYTE)Detour_NtWaitForSingleObject));
s_pNtDeviceIoControlFile
= ((NTSTATUS (NTAPI *)(HANDLE,
HANDLE,
PIO_APC_ROUTINE,
PVOID,
PIO_STATUS_BLOCK,
ULONG,
PVOID,
ULONG,
PVOID,
ULONG))
DetourFindFunction("ntdll.dll", "NtDeviceIoControlFile"));
s_pTrampoline_NtDeviceIoControlFile
= ((NTSTATUS (NTAPI *)(HANDLE,
HANDLE,
PIO_APC_ROUTINE,
PVOID,
PIO_STATUS_BLOCK,
ULONG,
PVOID,
ULONG,
PVOID,
ULONG))
DetourFunction((PBYTE)s_pNtDeviceIoControlFile,
(PBYTE)Detour_NtDeviceIoControlFile));
DetourFunctionWithTrampoline((PBYTE)Trampoline_Sleep,
(PBYTE)Detour_Sleep);
DetourFunctionWithTrampoline((PBYTE)Trampoline_send,
(PBYTE)Detour_send);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcGetBuffer,
(PBYTE)Detour_I_RpcGetBuffer);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcSendReceive,
(PBYTE)Detour_I_RpcSendReceive);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcFreeBuffer,
(PBYTE)Detour_I_RpcFreeBuffer);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcSend,
(PBYTE)Detour_I_RpcSend);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcReceive,
(PBYTE)Detour_I_RpcReceive);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcFreePipeBuffer,
(PBYTE)Detour_I_RpcFreePipeBuffer);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcReallocPipeBuffer,
(PBYTE)Detour_I_RpcReallocPipeBuffer);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcRequestMutex,
(PBYTE)Detour_I_RpcRequestMutex);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcClearMutex,
(PBYTE)Detour_I_RpcClearMutex);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcAllocate,
(PBYTE)Detour_I_RpcAllocate);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcFree,
(PBYTE)Detour_I_RpcFree);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcPauseExecution,
(PBYTE)Detour_I_RpcPauseExecution);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcMonitorAssociation,
(PBYTE)Detour_I_RpcMonitorAssociation);
DetourFunctionWithTrampoline((PBYTE)Trampoline_I_RpcStopMonitorAssociation,
(PBYTE)Detour_I_RpcStopMonitorAssociation);
return 0;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////// Classes.
class CNetPingFactory : public IClassFactory
{
public:
CNetPingFactory();
~CNetPingFactory();
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IClassFactory
STDMETHODIMP CreateInstance(LPUNKNOWN punkOuter, REFIID iid, void **ppv);
STDMETHODIMP LockServer(BOOL fLock);
public:
static HRESULT InitSystem(VOID);
static HRESULT FiniSystem(VOID);
static HRESULT InitObject(VOID);
static HRESULT FiniObject(VOID);
static HRESULT Lock(BOOL fLock);
static HRESULT Wait(VOID);
private:
LONG m_cRef;
static HANDLE s_hevtDone;
static LONG s_nObjects;
static LONG s_nLocks;
};
class CNetPingObject : public IPing
{
public:
CNetPingObject();
~CNetPingObject();
// IUnknown
STDMETHODIMP QueryInterface(REFIID iid, void **ppv);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IPing
STDMETHODIMP Ping();
STDMETHODIMP PingToServer(LPSTR pszString);
STDMETHODIMP PingToClient(LPSTR *ppszString);
STDMETHODIMP PingToClientSize(ULONG cbOut);
private:
LONG m_cRef;
ULONG m_cbLast;
ULONG m_cbOut;
};
/////////////////////////////////////////////////////////////////////// GUIDs.
DEFINE_GUID(CLSID_NetPingObject,
0xdecdbeed, 0xd1ac, 0x11d1, 0x96, 0xbc, 0x00, 0xaa, 0x00, 0x57, 0x3f, 0xb0);
/////////////////////////////////////////////////////////// Initialize String.
//
void InitializeString(LPSTR pszString, LONG cbSize)
{
ASSERT(cbSize >= 1);
while (cbSize-- > 1) {
*pszString++ = '+';
}
*pszString = '\0';
}
BOOL GetKeyValue(HKEY hRootKey, PWCHAR pwzKey, PWCHAR pwzValueName, PWCHAR pwzValue,
DWORD cbValue)
{
HKEY hKey;
WCHAR wzKey[256];
wcscpy(wzKey, pwzKey);
if (RegOpenKeyEx(hRootKey, wzKey, 0, KEY_READ, &hKey) != NO_ERROR) {
abort:
pwzValue[0] = '\0';
return FALSE;
}
DWORD nType = 0;
cbValue -= sizeof(WCHAR);
if (RegQueryValueEx(hKey, pwzValueName, 0, &nType, (PBYTE)pwzValue, &cbValue)
!= NO_ERROR || nType != REG_SZ) {
RegCloseKey(hKey);
goto abort;
}
RegCloseKey(hKey);
cbValue /= sizeof(WCHAR);
pwzValue[cbValue] = L'\0';
return TRUE;
}
static BOOLEAN SetKeyAndValue(HKEY hRootKey,
PWCHAR pszKey, PWCHAR pszSubkey,
PWCHAR pszValueName, PWCHAR pszValue)
{
HKEY hKey;
WCHAR szKey[256];
wcscpy(szKey, pszKey);
if (pszSubkey != NULL) {
wcscat(szKey, L"\\");
wcscat(szKey, pszSubkey);
}
if (RegCreateKeyEx(hRootKey, szKey, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS) {
return FALSE;
}
if (pszValue != NULL) {
RegSetValueEx(hKey, pszValueName, 0, REG_SZ,
(BYTE *)pszValue, wcssize(pszValue));
}
RegCloseKey(hKey);
return TRUE;
}
static BOOLEAN SetKeyAndValue(HKEY hRootKey,
PWCHAR pszKey, PWCHAR pszSubkey,
PWCHAR pszValueName,
PBYTE pbData, ULONG cbData)
{
HKEY hKey;
WCHAR szKey[256];
wcscpy(szKey, pszKey);
if (pszSubkey != NULL) {
wcscat(szKey, L"\\");
wcscat(szKey, pszSubkey);
}
if (RegCreateKeyEx(hRootKey, szKey, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS) {
return FALSE;
}
if (pbData != NULL) {
RegSetValueEx(hKey, pszValueName, 0, REG_BINARY, pbData, cbData);
}
RegCloseKey(hKey);
return TRUE;
}
static void Register(void)
{
WCHAR wzModule[256];
WCHAR wzName[256];
WCHAR wzValue[256];
WCHAR wzClass[48];
WCHAR wzKey[256];
PWCHAR pwz;
BYTE rgEveryone[] = {
0x01,0x00,0x04,0x80,0x34,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x14,0x00,0x00,0x00,0x02,0x00,0x20,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x18,0x00,
0x01,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x05,0x00,0x00,0x00,0x00,0x00,0x05,0x15,0x00,0x00,0x00,
0xa0,0x65,0xcf,0x7e,0x78,0x4b,0x9b,0x5f,0xe7,0x7c,0x87,0x70,0x32,0x7f,0x00,0x00,
0x01,0x05,0x00,0x00,0x00,0x00,0x00,0x05,0x15,0x00,0x00,0x00,0xa0,0x65,0xcf,0x7e,
0x78,0x4b,0x9b,0x5f,0xe7,0x7c,0x87,0x70,0x32,0x7f,0x00,0x00
};
GetModuleFileName(NULL, wzModule, sizeof(wzModule)/sizeof(WCHAR));
if ((pwz = wcsrchr(wzModule, '\\')) != NULL) {
wcscpy(wzName, pwz + 1);
}
else if ((pwz = wcsrchr(wzModule, ':')) != NULL) {
wcscpy(wzName, pwz + 1);
}
else {
wcscpy(wzName, wzModule);
}
// printf("Server: %ls / %ls\n", wzModule, wzName);
StringFromGUID2(CLSID_NetPingObject, wzClass, arrayof(wzClass));
// printf(" Class: %ls\n", wzClass);
wcscpy(wzKey, L"CLSID\\");
wcscat(wzKey, wzClass);
SetKeyAndValue(HKEY_CLASSES_ROOT, wzKey, NULL, NULL, L"COM Ping Network Server");
wsprintf(wzValue, L"%ls /s", wzModule);
SetKeyAndValue(HKEY_CLASSES_ROOT, wzKey, L"LocalServer32", NULL, wzValue);
SetKeyAndValue(HKEY_CLASSES_ROOT, wzKey, L"LaunchPermission", NULL, L"Y");
SetKeyAndValue(HKEY_CLASSES_ROOT, wzKey, NULL, L"AppID", wzClass);
wcscpy(wzKey, L"AppID\\");
wcscat(wzKey, wzClass);
SetKeyAndValue(HKEY_CLASSES_ROOT, wzKey, NULL, NULL, L"COM Ping Network Server");
SetKeyAndValue(HKEY_CLASSES_ROOT, wzKey, NULL, L"RunAs", L"Interactive User");
SetKeyAndValue(HKEY_CLASSES_ROOT, wzKey, NULL, L"AccessPermission",
rgEveryone, sizeof(rgEveryone));
wcscpy(wzKey, L"AppID\\");
wcscat(wzKey, wzName);
SetKeyAndValue(HKEY_CLASSES_ROOT, wzKey, NULL, L"AppID", wzClass);
/////////////////////////////////////////////////// Register Proxy & Stub.
//
HRESULT hr = iping_DllRegisterServer();
if (FAILED(hr)) {
CheckResult(hr, "IPing_DllRegisterServer");
}
//////////////////////////////////////////////// Register Processor Speed.
//
DWORD cycles = 0;
wcscpy(wzKey, L"Software\\Microsoft\\galenh\\ProcessorCycles");
if (GetKeyValue(HKEY_LOCAL_MACHINE, wzKey, NULL, wzValue, sizeof(wzValue))) {
cycles = _wtoi(wzValue);
printf("[Recorded Cycles/Second: %ld]\n", cycles);
}
if (cycles < 10000) {
LONGLONG llBeg;
LONGLONG llEnd;
printf("[Calibrating Processors...]\r"); fflush(stdout);
LARGE_INTEGER liBeg;
LARGE_INTEGER liEnd;
LARGE_INTEGER liBrk;
LARGE_INTEGER liFrq;
QueryPerformanceFrequency(&liFrq);
QueryPerformanceCounter(&liBeg);
PingLoadCycleCount(llBeg);
liBrk.QuadPart = liBeg.QuadPart + liFrq.QuadPart * 5;
do {
QueryPerformanceCounter(&liEnd);
PingLoadCycleCount(llEnd);
} while (liEnd.QuadPart < liBrk.QuadPart);
double secs = (double)(liEnd.QuadPart - liBeg.QuadPart) / (double)liFrq.QuadPart;
double clks = (double)(llEnd - llBeg);
double cycs = clks / secs;
cycles = (DWORD)cycs;
printf("[Measured Cycles/Second: %ld] \n", cycles);
swprintf(wzValue, L"%d", cycles);
SetKeyAndValue(HKEY_LOCAL_MACHINE, wzKey, NULL, NULL, wzValue);
}
}
void Unregister(void)
{
///////////////////////////////////////////////// Unregister Proxy & Stub.
//
HRESULT hr = iping_DllUnregisterServer();
if (FAILED(hr)) {
CheckResult(hr, "IPing_DllUnregisterServer");
}
}
//////////////////////////////////////////////////////////////////////////////
//
HRESULT GetClockInfo(LONGLONG *pllCyclesPerSecond)
{
WCHAR wzKey[512];
WCHAR wzValue[128];
LONG cbValue;
////////////////////////////////////////////////////////// Check Registry.
cbValue = sizeof(wzValue);
wcscpy(wzKey, L"Software\\Microsoft\\galenh\\ProcessorCycles");
if (RegQueryValue(HKEY_LOCAL_MACHINE, wzKey, wzValue, &cbValue) == NO_ERROR) {
*pllCyclesPerSecond = _wtoi(wzValue);
return S_OK;
}
*pllCyclesPerSecond = 1000000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -