String dllFileName = "C:\\Program Files (x86)\\TRH\\bin\\GuiControls.dll"; Assembly assembly = Assembly.LoadFrom(dllFileName); var resources = assembly.GetManifestResourceNames(); foreach (string resourceName in resources) { var stream = assembly.GetManifestResourceStream(resourceName); var rawFile = new byte[stream.Length]; stream.Read(rawFile, 0, (int)stream.Length); using (var fs = new FileStream(resourceName, FileMode.Create)) { fs.Write(rawFile, 0, (int)stream.Length); } }
Рубрика: Разное
mailto send attachment
отправить вложение невозможно (нет такого в rfc), а значит сохраняем и создаем «ссылку-пароль» на это вложение
https://www.rfc-editor.org/rfc/rfc2368
Event.isTrusted and simulate mouse click
The HTMLElement.click() method simulates a mouse click on an element.
The isTrusted read-only property of the Event interface is a boolean value that is true when the event was generated by a user action, and false when the event was created or modified by a script or dispatched via EventTarget.dispatchEvent().
«Вечная светодиодная лампа»
У 25-ватной колпак с бортиками, держится очень крепко, пришлось ножом подковырнуть. Остальные легко отрываются руками, туда-сюда качнул и готово.
Подогревать плату нечем, в наличии только паяльник, потому небольшой лайфхак, чуток заливаю оловом контакты резистора, дабы жало грело сразу двух сторон.
modify resources of an exe
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; }
basic authentication in Squid
/etc/squid/squid.conf
.... auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/.htpasswd acl authenticated proxy_auth REQUIRED http_access allow authenticated .... # And finally deny all other access to this proxy http_access deny all ....
ssh over https proxy
Проброс портов с помощью PUTTY и туда и обратно и все это через корпоративный прокси сервер (TMG, NAT закрыт совсем).
Благо прокси разрешает Basic авторизацию, PUTTY только с ней и может, иначе было бы сложнее.
По умолчанию в Threat Management Gateway для туннелирования с использованием HTTP метода CONNECT открыты всего два порта:
Воспользуемся портом 563 (443 у меня занят) и поднимем SSH сервер во вне (в моем случае проброс на домашнем роутере в одну из виртуалок)By default on TMG/ISA, the following tunnel ranges are configured: NNTP (single port): 563 ssl (single port): 443
Не забываем на SSH сервере разрешить AllowTcpForwarding yes и GatewayPorts yes
По какой-то причине 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 одного из серверов и веб-сервер из корпоративной сети.
C++ include SQLite
1. Navigate to https://www.sqlite.org/download.html and download latest `amalgamation` source version of SQLite. 2. Extract all the files into your project directory, or your include path, or separate path that you will add/added as include path in your project properties. 3. Run `Developer Command Prompt for VS ****` which is usually available at `Start -> Programs -> Visual Studio **** -> Visual Studio Tools`. 4. Navigate with command prompt to that directory where we extracted our SQLite. 5. Run next command to compile: `cl /c /EHsc sqlite3.c` 6. Run next command to create static library: `lib sqlite3.obj` 7. Open properties of your project and add `sqlite3.lib` to `Linker -> Input -> Additional Dependencies`. Now you ready to include and use `sqlite3.h` in your project.
Простой сервис родительского контроля (simple service parental control)
По просьбе трудящихся наваял небольшой сервис, выполняет выход из сеанса пользователя (log off) или его отключение (disconnect) в определенное время с временной блокировкой учетной записи, если необходимо. Периодичность проверки попадания в график 1 минута.
Действия по блокировке или отключению учетки применяются только если сессия активна. Учетной запись разблокируется при условиях: учетная запись присутствует в графике, она заблокирована, и в этот момент не попадает в график по отключению. (раз в минуту)
Версия 1.3 — добавлена возможность отключения записи графика. У отключенных текст подкрашен серым.
UPD 09.10.2020 Версия 1.4 — добавлена группировка записей графика и множественное выделение и выключение/включение записей.
chado.zipНеобходимо настроить график отключений, установить и запустить сервис. Данные графика сохраняются в SQLite. После изменения графика необходим перезапуск сервиса, так как сервисом данные считываются только один раз, при запуске. Сервис и GUI-приложение один и тот же бинарный файл, при установке сервиса приложение не копируется, сервис запускается с места нахождения chado.exe
Для disconnect и log off используются WTSDisconnectSession и WTSLogoffSession
for (auto& user : theApp.DBUsers) { if (user.userName.Compare(userName) == 0 && user.dayOfWeek == dayOfWeek && curentSeconds >= user.allowedFrom && curentSeconds <= user.allowedTo ) { if (user.disconnect == 0) { WTSDisconnectSession(WTS_CURRENT_SERVER_HANDLE, pInfos[i].SessionId, FALSE); theApp.log.WriteString((date.Format(L"%Y-%m-%d %T") + L" disconnect: " + user.userName + L"\r\n").GetString()); } else { WTSLogoffSession(WTS_CURRENT_SERVER_HANDLE, pInfos[i].SessionId, FALSE); theApp.log.WriteString((date.Format(L"%Y-%m-%d %T") + L" logoff: " + user.userName + L"\r\n").GetString()); } if (user.lock == 0) { theApp.unlockAccount(user.userName.GetString(), 1); } } }
Для блокировки/разблокировки учетной записи: NetUserGetInfo и NetUserSetInfo
if (!lock && (ui4->usri4_flags & UF_ACCOUNTDISABLE) == UF_ACCOUNTDISABLE) { ui.usri1008_flags = ui4->usri4_flags ^ UF_ACCOUNTDISABLE; need = 2; } if (lock && (ui4->usri4_flags & UF_ACCOUNTDISABLE) != UF_ACCOUNTDISABLE) { ui.usri1008_flags = ui4->usri4_flags | UF_ACCOUNTDISABLE; need = 1; } // Call the NetUserSetInfo function // to disable the account, specifying level 1008. if (need) { nStatus = NetUserSetInfo(NULL, username, 1008, (LPBYTE)&ui, NULL); // Display the result of the call. if (nStatus == NERR_Success) { #ifdef _DEBUG theApp.log.WriteString((date.Format(L"%Y-%m-%d %T") + (need == 1 ? L" lock " : L" unlock ") + L"account: " + username + L"\r\n").GetString()); #endif } else { theApp.log.WriteString((date.Format(L"%Y-%m-%d %T") + L" error lock/unlock account: " + username + L"\r\n").GetString()); } }