modify resources of an exe

Конфигурация по умолчанию в exe файле, ее изменение и сохранение в ресурсе типа RT_RCDATA, всё официальными функциями BeginUpdateResource, UpdateResource, EndUpdateResource, без хакерства.
	path = GetCommandLine();
	path = path.Mid(1); // убираем "
	path = path.Left(path.ReverseFind('\\'));
	path += L"\\server.exe";

	try {
		// проверяем наличие экзешника, в моем случае должен лежать в одном каталоге с патчилкой
		CFileException* e = new CFileException();
		CFile cfile;
		if (!cfile.Open(path, CFile::modeReadWrite, e))
		{
			throw e;
		}
		cfile.Close();

		LPBYTE bomPos = 0;
		// загрузка ресурса
		HMODULE hLibrary = 0;
		HRSRC hResource = 0;
		HGLOBAL hResourceLoaded = 0;
		DWORD  resourceSize = 0;
		LPBYTE lpBuffer = 0;
		hLibrary = LoadLibrary(path);
		if (NULL != hLibrary)
		{
			hResource = FindResource(hLibrary, MAKEINTRESOURCE(paramsResId), RT_RCDATA); // !!! paramsResId == 139 ИД ресурса в экзешнике
			if (NULL != hResource)
			{
				hResourceLoaded = LoadResource(hLibrary, hResource);
				resourceSize = SizeofResource(hLibrary, hResource);
				if (NULL != hResourceLoaded)
				{
					lpBuffer = (LPBYTE)LockResource(hResourceLoaded);
					bomPos = new BYTE[resourceSize];
					memcpy_s(bomPos, resourceSize, lpBuffer, resourceSize);
				}
			}
			FreeLibrary(hLibrary);
		}

		if (bomPos == 0) {
			AfxThrowArchiveException(CArchiveException::endOfFile, _T("signature"));
		}

		// попытка загрузить ранее записанные параметры		
		int sizeOfParams = (int)*(bomPos + bomSize);
		if (sizeOfParams > 0 && sizeOfParams < 800) {
			BYTE kk[] = { 'q', 10, 'e', 7, 'a', 'z', 'Q' };
			encryptDecrypt((BYTE*)(bomPos + bomSize + sizeof(0)), sizeOfParams, kk, sizeof(kk));
			int realLength = wcslen((TCHAR*)(bomPos + bomSize + sizeof(0)));
			TCHAR* decryptData = (TCHAR*)(bomPos + bomSize + sizeof(0));
			if (realLength > 2 && decryptData[0] == _T('Z') && decryptData[1] == _T('A')) { // проверяем на ZA, значит всё раскодировалось
				decryptData += 2; // пропустим ZA
				TCHAR* s_ssh_host = 0, *s_ssh_port = 0, *s_ssh_user = 0, *s_ssh_pwd = 0, *s_ssh_add = 0;
				s_ssh_host = decryptData;
				s_ssh_port = _tcschr(s_ssh_host, _T('\t')) + 1;
				if (s_ssh_port)
					s_ssh_user = _tcschr(s_ssh_port, _T('\t')) + 1;
				if (s_ssh_user)
					s_ssh_pwd = _tcschr(s_ssh_user, _T('\t')) + 1;
				if (s_ssh_pwd)
					s_ssh_add = _tcschr(s_ssh_pwd, _T('\t')) + 1;
				if (s_ssh_port)
					*(s_ssh_port - 1) = 0;
				if (s_ssh_user)
					*(s_ssh_user - 1) = 0;
				if (s_ssh_pwd)
					*(s_ssh_pwd - 1) = 0;
				if (s_ssh_add)
					*(s_ssh_add - 1) = 0;
			
				//
			}
		}
		delete[] bomPos;
	CString s_ssh_host;
	ssh_host.GetWindowText(s_ssh_host);
	CString s_ssh_port;
	ssh_port.GetWindowText(s_ssh_port);
	CString s_ssh_user;
	ssh_user.GetWindowText(s_ssh_user);
	CString s_ssh_pwd;
	ssh_pwd.GetWindowText(s_ssh_pwd);
	CString s_ssh_add;
	ssh_add.GetWindowText(s_ssh_add);
	CString s_full;
	s_full.Format(_T("ZA%s\t%s\t%s\t%s\t%s\0"), s_ssh_host.GetBuffer(), s_ssh_port.GetBuffer(), s_ssh_user.GetBuffer(), s_ssh_pwd.GetBuffer(), s_ssh_add.GetBuffer());

	HANDLE hResource;
	hResource = BeginUpdateResource(path, FALSE);
	if (NULL != hResource)
	{
		int sizeOfParams = (s_full.GetLength() + 1) * sizeof(_T('\0'));
		if (sizeOfParams > 700) {
			::AfxMessageBox(_T("Only 700 bytes allowed for writing."));
			FreeResource(hResource);
			return;
		}
		LPBYTE lpBuffer = new BYTE[bomSize + sizeof(0) + sizeOfParams];
		memcpy(lpBuffer, bom, bomSize);
		memcpy(lpBuffer + bomSize, &sizeOfParams, sizeof(0));
		memcpy(lpBuffer + bomSize + sizeof(0), (BYTE*)s_full.GetBuffer(), sizeOfParams);
		
		BYTE kk[] = { 'q', 10, 'e', 7, 'a', 'z', 'Q' };
		encryptDecrypt(lpBuffer + bomSize + sizeof(0), sizeOfParams, kk, sizeof(kk));
		
		if (UpdateResource(hResource,
			RT_RCDATA,
			MAKEINTRESOURCE(paramsResId),
			0,
			(LPVOID)lpBuffer,
			bomSize + sizeof(0) + sizeOfParams) != FALSE)
		{
			EndUpdateResource(hResource, FALSE);
		}
		delete[] lpBuffer;
	}

ssh over https proxy

Очередной раз из разряда, «век живи, век учись» или «если бы мы читали документацию».
Проброс портов с помощью PUTTY и туда и обратно и все это через корпоративный прокси сервер (TMG, NAT закрыт совсем).
Благо прокси разрешает Basic авторизацию, PUTTY только с ней и может, иначе было бы сложнее.
Wireshark По умолчанию в Threat Management Gateway для туннелирования с использованием HTTP метода CONNECT открыты всего два порта:
By default on TMG/ISA, the following tunnel ranges are configured:
NNTP (single port): 563
ssl (single port): 443
Воспользуемся портом 563 (443 у меня занят) и поднимем SSH сервер во вне (в моем случае проброс на домашнем роутере в одну из виртуалок)
Не забываем на SSH сервере разрешить AllowTcpForwarding yes и GatewayPorts yes
putty putty putty
По какой-то причине PUTTY принимает только 127.0.0.1 при обратном пробросе, пришлось воспользоваться помощью администратора
netsh interface portproxy add v4tov4 listenport=3393 listenaddress=0.0.0.0 connectport=3389 connectaddress=10.19.80.152
netsh interface portproxy add v4tov4 listenport=3397 listenaddress=0.0.0.0 connectport=80 connectaddress=10.19.80.76

Итого, с рабочего доступна RDP домашнего, с домашнего, RDP одного из серверов и веб-сервер из корпоративной сети.