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);
}