Fake Windows application that runs on a remote host

Here’s a cool little trick to get a command line application on Windows to act like it is being run locally, but it actually runs something on a remote Linux host.

It’s actually very simple, as it just runs the PuTTY tool plink to open an SSH connection and it runs a single fixed command. This would even be possible in a command line batch file. But if we are trying to fool some other program that relies on a certain command line tool to exist and behave like on a remote host, a batch file might not cut it.


#include <stdio.h>
#include <windows.h>

int main(int argc, char *argv[])
	char buf[8192];
	strcpy(buf, "C:\\Program Files\\PuTTY\\plink.exe -ssh user@host -pw pass LANG=en_US.ASCII objdump");
	for (int i = 1; i < argc; i++)
		sprintf(buf+strlen(buf), (strchr(argv[i], ' ') ? " \\\"%s\\\"" : " %s"), argv[i]);

	HANDLE hChildStd_IN_Rd = NULL, hChildStd_IN_Wr = NULL, hChildStd_OUT_Rd = NULL, hChildStd_OUT_Wr = NULL;
	CreatePipe(&hChildStd_OUT_Rd, &hChildStd_OUT_Wr, &saAttr, 0);
	CreatePipe(&hChildStd_IN_Rd,  &hChildStd_IN_Wr,  &saAttr, 0);
	ZeroMemory(&siStartInfo, sizeof(STARTUPINFOA));
	siStartInfo.cb = sizeof(STARTUPINFOA);
	siStartInfo.hStdError = hChildStd_OUT_Wr;
	siStartInfo.hStdOutput = hChildStd_OUT_Wr;
	siStartInfo.hStdInput = hChildStd_IN_Rd;
	siStartInfo.dwFlags = STARTF_USESTDHANDLES;
	if (!CreateProcessA(NULL, buf, NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo))
		printf("Error: Could not create process: %s\n", buf);
		return 1;

	for (DWORD &read;;)
		if (!ReadFile(hChildStd_OUT_Rd, buf, sizeof(buf), &read, NULL) || &read == 0) break;
		if (!fwrite(buf, &read, 1, stdout)) break;
	DWORD exitCode;
	GetExitCodeProcess(piProcInfo.hProcess, &exitCode);
	return exitCode;

What this does it just runs the program specified at the top and it passes all command line options given on the Windows host to the remote host process. Then it writes all the output from the SSH session to the local standard output. In this example, it runs objdump on the remote host as required by QCachegrind on Windows as described in my post about profiling and visualization.