2013-01-13 1 views
3

C#에서 선택한 프로세스의 나가는 패킷을 읽을 수 있습니까? 그렇다면 어떤 API를 사용해야합니까? 미리 감사드립니다. 선택한 프로세스에서 나가는 패킷 읽기

+0

[faq]와 [ask]를 두 번 읽으십시오. –

+0

http : //www.codeproject를 확인하십시오.com/Articles/2614/Testing-TCP-and-UDP 소켓 서버 -C-and-NET 사용 –

답변

0

TPL 데이터 흐름을 사용하여이를 수행 할 수 있습니다.

1

물론 프로세스에 "청취자"가있는 경우에만 가능합니다. 그렇지 않으면 스니퍼를 만들어야합니다 : 실행 파일 디버깅, 소켓 전송 버퍼의 오프셋 찾기 및 판독기 연결. 방화벽과 같은 응용 프로그램을 통해 쉽게 할 수 있습니다.

2

WireShark 또는 Winsock 패킷 편집기과 비슷한 작업을 수행한다고 가정합니다.

짧은 대답은 아니요입니다. 기능이 내장 된 네임 스페이스 또는 어셈블리가 없습니다.

길게 대답은 예입니다. 그러나 손을 조금 더러워야합니다.C++ DLL을 '스파이'프로세스에 삽입해야 할 가능성이 높습니다. 그러나이 C#을 통해 인터페이스하고 인터페이스를 . NET으로 만들 수 있습니다.

bool InitialzeHook() 
{ 
    // TODO: Patch the Import Address Table (IAT) to overwrite 
    //  the address of Winsock's send/recv functions 
    //  with your SpySend/SpyRecv ones instead. 
} 

bool UninitializeHook() 
{ 
    // TODO: Restore the Import Address Table (IAT) to the way you found it. 
} 

// This function will be called instead of Winsock's recv function once hooked. 
int SpySend(SOCKET s, const char *buf, int len, int flags) 
{ 
    // TODO: Do something with the data to be sent, like logging it. 

    // Call the real Winsock send function. 
    int numberOfBytesSent = send(s, buf, len, flags); 

    // Return back to the calling process. 
    return numberOfBytesSent; 
} 

// This function will be called instead of Winsock's recv function once hooked. 
int SpyRecv(SOCKET s, char *buf, int len, int flags) 
{ 
    // Call the real Winsock recv function to get the data. 
    int numberOfBytesReceived = recv(s, buf, len, flags); 

    // TODO: Do something with the received data, like logging it. 

    // Return back to the calling process. 
    return numberOfBytesReceived; 
} 

이 모두의 가장 어려운 부분은 가져 오기 주소 테이블을 패치 할 수있는 기능입니다 :

첫 번째 단계는 몇 수출에게 필요한 것 C++ DLL를 생성하는 것 (IAT). 그것을 트래버스하고 그 안에 함수 가져 오기를 찾는 방법에 대한 다양한 리소스가 있습니다. 팁 :Winsockordinal (이름이 아님)으로 패치해야합니다.

Inside the Windows PE Format (Part 2)C++ Code Example을 확인하십시오.

일단 완료했다면 DLL을 대상 프로세스에 삽입해야합니다. 여기에 (내 머리 위로 떨어져) 할 수있는 C++ 사이비 코드는 다음과 같습니다

// Get the target window handle (if you don't have the process ID handy). 
HWND hWnd = FindWindowA(NULL, "Your Target Window Name"); 

// Get the process ID from the target window handle. 
DWORD processId = 0; 
DWORD threadId = GetWindowThreadProcessId(hWnd, &processId); 

// Open the process for reading/writing memory. 
DWORD accessFlags = PROCESS_VM_OPERATION | 
        PROCESS_VM_READ | 
        PROCESS_VM_WRITE | 
        PROCESS_QUERY_INFORMATION; 

HANDLE hProcess = OpenProcess(accessFlags, false, processId); 

// Get the base address for Kernel32.dll (always the same for each process). 
HMODULE hKernel32 = GetModuleHandleA("kernel32"); 

// Get the address of LoadLibraryA (always the same for each process). 
DWORD loadLibraryAddr = GetProcAddress(hKernel32, "LoadLibraryA"); 

// Allocate some space in the remote process and write the library string to it. 
LPVOID libraryNameBuffer = VirtualAllocEx(hProcess, NULL, 256, 
              MEM_COMMIT | MEM_RESERVE, 
              PAGE_EXECUTE_READWRITE); 

LPCSTR libraryName = L"MySpyLibrary.dll\0"; 
DWORD numberOfBytesWritten = 0; 
BOOL writeResult = WriteProcessMemory(hProcess, libraryNameBuffer, 
               (LPCVOID)libraryName, 
               strlen(libraryName) + 1, 
               &numberOfBytesWritten); 

// Create a thread in the remote process, using LoadLibraryA as the procedure, 
// and the parameter is the library name we just wrote to the remote process. 
DWORD remoteThreadId = 0; 
HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, 
              (LPTHREAD_START_ROUTINE)loadLibraryAddr, 
              libraryNameBuffer, 
              0, &remotThreadId); 

// Wait for our thread to complete and get the exit code (which is the return value). 
DWORD loadedLibraryAddr = 0; 
BOOL waitResult = WaitForSingleObject(hRemoteThread, INFINITE); 
BOOL exitResult = GetExitCodeThread(hRemoteThread, &loadedLibraryAddr); 

// TODO: Check that it was loaded properly 
// if(lodadedLibraryAddr == NULL) { ... } 

// Cleanup our loose ends here. 
VirtualFreeEx(hProcess, libraryNameBuffer, 256, MEM_RELEASE); 
CloseHandle(hRemoteThread); 
CloseHandle(hProcess); 

당신은 C 번호 플랫폼을 통해 같은 일이 생각 (PInvoke를)를 호출 할 수 있습니다. 데이터를 기록하고 C# 모니터링 프로그램으로 다시 전송하는 방법은 귀하에게 달려 있습니다. 프로세스 간 통신Named Pipes, NamedPipeClientStream, C#과 같이 사용할 수 있습니다.

그러나 이것은 유용 할 것이고 아름다운 부분은 거의 모든 프로그램에서 작동한다는 것입니다. 이 같은 기술은 모든 유형의 스니핑에 적용 할 수 있습니다. Winsock이 아닙니다.

관련 문제