www.pudn.com > mini_remote.zip > CmdShell.h


 
static VOID SessionReadShellThreadFn(LPVOID Param); 
static VOID SessionWriteShellThreadFn(LPVOID Param); 
//The CmdShell Class 
class CCmdShell   
{ 
public: 
	SOCKET m_socket; 
	HANDLE m_hPipe[2];//1 is Read Pipe,2 is Write Pipe 
 
	CCmdShell(){EnablePrivilege(SE_SHUTDOWN_NAME);} 
	virtual ~CCmdShell(){CleanUp();} 
 
	BOOL LetUsGo(SOCKET ClientSocket)//Let People Begin The Shell 
	{ 
		if (ClientSocket == INVALID_SOCKET) 
			return FALSE; 
		m_socket = ClientSocket; 
		StartCmdShell(); 
		return TRUE; 
	} 
private: 
	//1 is CmdProcess Handle,2 is ReadThread Handle,3 is WriteThread Handle 
	HANDLE HandleArray[3];	 
	//Start Cmd Shell 
	BOOL StartCmdShell() 
	{ 
		HANDLE ShellStdinPipe = NULL; 
		HANDLE ShellStdoutPipe = NULL; 
 
		SECURITY_ATTRIBUTES SA; 
		SA.nLength = sizeof(SA); 
		SA.lpSecurityDescriptor = NULL; 
		SA.bInheritHandle = TRUE; 
 
		if (!CreatePipe(&m_hPipe[0], &ShellStdoutPipe,&SA, 0)) 
		{ 
			CleanUp(); 
			if(ShellStdoutPipe != NULL)	CloseHandle(ShellStdoutPipe); 
			return FALSE; 
		} 
		if (!CreatePipe(&ShellStdinPipe, &m_hPipe[1],&SA, 0)) 
		{ 
			CleanUp(); 
			if(ShellStdoutPipe != NULL) CloseHandle(ShellStdoutPipe); 
			if(ShellStdinPipe != NULL) CloseHandle(ShellStdinPipe); 
			return FALSE; 
		} 
	 
		HandleArray[0] = CreateCmdProcess(ShellStdinPipe, ShellStdoutPipe); 
		CloseHandle(ShellStdinPipe); 
		CloseHandle(ShellStdoutPipe); 
 
		SECURITY_ATTRIBUTES SecurityAttributes; 
		SecurityAttributes.nLength = sizeof(SecurityAttributes); 
		SecurityAttributes.lpSecurityDescriptor = NULL; 
		SecurityAttributes.bInheritHandle = FALSE; 
		DWORD ThreadId; 
		HandleArray[1] = CreateThread(&SecurityAttributes, 0, (LPTHREAD_START_ROUTINE) SessionReadShellThreadFn, (LPVOID) this, 0, &ThreadId); 
		if (HandleArray[1] == NULL) 
		{ 
			CleanUp(); 
			return FALSE; 
		} 
 
		HandleArray[2] = CreateThread(&SecurityAttributes, 0, (LPTHREAD_START_ROUTINE) SessionWriteShellThreadFn, (LPVOID) this, 0, &ThreadId); 
		if (HandleArray[1] == NULL) 
		{ 
			CleanUp(); 
			return FALSE; 
		} 
 
		int i = WaitForMultipleObjects(3, HandleArray, FALSE, 0xffffffff); 
		switch (i) { 
			case WAIT_OBJECT_0 + 0: 
				TerminateThread(HandleArray[1], 0); 
			    TerminateThread(HandleArray[2], 0); 
				break; 
			case WAIT_OBJECT_0 + 1: 
				TerminateThread(HandleArray[2], 0); 
				TerminateProcess(HandleArray[0], 1); 
				break; 
			case WAIT_OBJECT_0 + 2: 
				TerminateThread(HandleArray[1], 0); 
				TerminateProcess(HandleArray[0], 1); 
				break; 
			default: 
				break; 
		} 
		CleanUp(); 
		return 0; 
	} 
	//Create The Cmd Process Function 
	HANDLE CreateCmdProcess(HANDLE ShellStdinPipeHandle, HANDLE ShellStdoutPipeHandle) 
	{ 
		PROCESS_INFORMATION ProcessInformation; 
		STARTUPINFO si; 
		HANDLE ProcessHandle = NULL; 
		char CmdShell[12]; 
	 
		si.cb = sizeof(STARTUPINFO); 
		si.lpReserved = NULL; 
		si.lpTitle = NULL; 
		si.lpDesktop = NULL; 
		si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0L; 
		si.wShowWindow = SW_HIDE; 
		si.lpReserved2 = NULL; 
		si.cbReserved2 = 0; 
		si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 
		si.hStdInput  = ShellStdinPipeHandle; 
		si.hStdOutput = ShellStdoutPipeHandle; 
		 
		DuplicateHandle(GetCurrentProcess(), ShellStdoutPipeHandle, GetCurrentProcess(), &si.hStdError, DUPLICATE_SAME_ACCESS, TRUE, 0); 
		if(GetOsVer()) 
			strcpy(CmdShell,"cmd.exe");// if nt 
		else 
			strcpy(CmdShell,"command.com");// if win9x 
		if (CreateProcess(NULL, CmdShell, NULL, NULL, TRUE, 0, NULL, NULL, &si, &ProcessInformation))  
		{ 
			ProcessHandle = ProcessInformation.hProcess; 
			CloseHandle(ProcessInformation.hThread); 
		} 
		return(ProcessHandle); 
	} 
	// get OS version Function 
	int GetOsVer() 
	{ 
		OSVERSIONINFO winfo; 
		winfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); 
		GetVersionEx(&winfo); 
		if(winfo.dwPlatformId==VER_PLATFORM_WIN32_NT) 
    		return 1; 
		else 
    		return 0; 
	} 
	//Clean All Up Function 
	void CleanUp() 
	{ 
		if(m_hPipe[0] != NULL) 
		{ 
			DisconnectNamedPipe(m_hPipe[0]); 
			CloseHandle(m_hPipe[0]); 
		} 
		if(m_hPipe[1] != NULL) 
		{ 
			DisconnectNamedPipe(m_hPipe[1]); 
			CloseHandle(m_hPipe[1]); 
		} 
		if(HandleArray[0] != NULL) CloseHandle(HandleArray[0]); 
		if(HandleArray[1] != NULL) CloseHandle(HandleArray[1]); 
		if(HandleArray[2] != NULL) CloseHandle(HandleArray[2]); 
	} 
	//Shutdown or restart the window 
	BOOL EnablePrivilege(LPTSTR privilege) 
	{ 
		int success; 
		HANDLE token; 
		LUID luid; 
		TOKEN_PRIVILEGES tokenprivileges; 
		success=OpenProcessToken(GetCurrentProcess(), 
			TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&token); 
		if (!success) return FALSE; 
		success=LookupPrivilegeValue(0,privilege,&luid); 
		if (!success) return FALSE; 
		tokenprivileges.PrivilegeCount=1; 
		tokenprivileges.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED; 
		tokenprivileges.Privileges[0].Luid=luid; 
		success=AdjustTokenPrivileges(token,false,&tokenprivileges,0,0,0); 
		if (!success)  
			return FALSE; 
		else 
			return TRUE; 
	} 
	// 
}; 
 
// handle piperead routine Function 
static VOID SessionReadShellThreadFn(LPVOID Param) 
{ 
	CCmdShell *cmdshell = (CCmdShell *) Param; 
    BYTE    Buffer[256]; 
    BYTE    Buffer2[256+30]; 
    DWORD   BytesRead; 
 
    while (PeekNamedPipe(cmdshell->m_hPipe[0], Buffer, sizeof(Buffer), &BytesRead, NULL, NULL)) { 
		DWORD BufferCnt, BytesToWrite; 
        BYTE PrevChar = 0; 
        if (BytesRead > 0) 
	    	ReadFile(cmdshell->m_hPipe[0], Buffer, sizeof(Buffer), &BytesRead, NULL); 
        else  
		{ 
  	    	Sleep(50); 
	    	continue; 
		} 
        for (BufferCnt = 0, BytesToWrite = 0; BufferCnt < BytesRead; BufferCnt++) { 
            if (Buffer[BufferCnt] == '\n' && PrevChar != '\r') 
                Buffer2[BytesToWrite++] = '\r'; 
            PrevChar = Buffer2[BytesToWrite++] = Buffer[BufferCnt]; 
        } 
 
        if (send(cmdshell->m_socket, (char*)Buffer2, BytesToWrite, 0) <= 0) 
            break; 
    } 
 
    if(GetLastError()!= ERROR_BROKEN_PIPE) {;} 
 
    ExitThread(0); 
} 
 
// handle pipewrite routine Function 
static VOID SessionWriteShellThreadFn(LPVOID Param) 
{ 
	CCmdShell *cmdshell = (CCmdShell *) Param; 
    BYTE    RecvBuffer[1]; 
    BYTE    Buffer[256]; 
    BYTE    EchoBuffer[5]; 
    DWORD   BytesWritten; 
    DWORD   BufferCnt, EchoCnt; 
    DWORD   TossCnt = 0; 
    BOOL    PrevWasFF = FALSE; 
 
    BufferCnt = 0; 
    while (recv(cmdshell->m_socket, (char*)RecvBuffer, sizeof(RecvBuffer), 0) != INVALID_SOCKET) { 
        EchoCnt = 0; 
        Buffer[BufferCnt++] = EchoBuffer[EchoCnt++] = RecvBuffer[0]; 
        if (RecvBuffer[0] == '\r') 
                Buffer[BufferCnt++] = EchoBuffer[EchoCnt++] = '\n'; 
		if (strnicmp((char*)Buffer, "exit\r\n", 6) == 0) {ExitThread(0);} 
		if (strnicmp((char*)Buffer, "restart\r\n", 9) == 0) 
		{ 
			ExitWindowsEx(EWX_REBOOT,0); 
			ExitThread(0); 
		} 
		if (strnicmp((char*)Buffer, "shutdown\r\n", 9) == 0) 
		{ 
			ExitWindowsEx(EWX_SHUTDOWN,0); 
			ExitThread(0); 
		} 
        if (RecvBuffer[0] == '\n' || RecvBuffer[0] == '\r')  
		{ 
            if (! WriteFile(cmdshell->m_hPipe[1], Buffer, BufferCnt, &BytesWritten, NULL)) break; 
            BufferCnt = 0; 
        } 
    } 
    ExitThread(0); 
}