#include
#include "MemoryModule.h"
#include "nt.h"
#define SIZE (4096 / sizeof(char*))
typedef struct
{
void* headers;
unsigned char *codeBase;
void* modules;
int numModules;
BOOL initialized;
BOOL isDLL;
BOOL isRelocated;
void* loadLibrary;
void* getProcAddress;
void* freeLibrary;
void *userdata;
void* exeEntry;
DWORD pageSize;
int *CustomArgc;
char *** CustomArgv;
int *CustomWArgc;
wchar_t *** CustomWArgv;
} MEMORYMODULE, *PMEMORYMODULE;
HMODULE hVirtualModule = NULL;
char sVirtualModuleName[128];
char* strndup(char const* name, size_t len)
{
char *s = (char*)malloc(len + 1);
if (s != NULL)
{
memcpy(s, name, len);
s[len] = 0;
}
return s;
}
wchar_t* wcsndup(wchar_t* name, size_t len)
{
wchar_t *s = (wchar_t*)malloc((len + 1) * sizeof(wchar_t));
if (s != NULL)
{
memcpy(s, name, len*sizeof(wchar_t));
s[len] = 0;
}
return s;
}
int aadd(char* name)
{
char** _new;
if ((__argc % SIZE) == 0)
{
if (__argv == NULL)
_new = (char**)malloc(sizeof(char*) * (1 + SIZE));
else
_new = (char**)realloc(__argv, sizeof(char*) * (__argc + 1 + SIZE));
if (_new == NULL)
return -1;
__argv = _new;
}
__argv[__argc++] = name;
__argv[__argc] = NULL;
return 0;
}
int wadd(wchar_t* name)
{
wchar_t** _new;
if ((__argc % SIZE) == 0)
{
if (__wargv == NULL)
_new = (wchar_t**)malloc(sizeof(wchar_t*) * (1 + SIZE));
else
_new = (wchar_t**)realloc(__wargv, sizeof(wchar_t*) * (__argc + 1 + SIZE));
if (_new == NULL)
return -1;
__wargv = _new;
}
__wargv[__argc++] = name;
__wargv[__argc] = NULL;
return 0;
}
int aexpand(char* name, int expand_wildcards)
{
char* s;
WIN32_FIND_DATAA fd;
HANDLE hFile;
BOOLEAN first = TRUE;
char buffer[256];
uintptr_t pos;
if (expand_wildcards && (s = strpbrk(name, "*?")))
{
hFile = FindFirstFileA(name, &fd);
if (hFile != INVALID_HANDLE_VALUE)
{
while(s != name && *s != '/' && *s != '\\')
s--;
pos = s - name;
if (*s == '/' || *s == '\\')
pos++;
strncpy(buffer, name, pos);
do
{
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
strcpy(&buffer[pos], fd.cFileName);
if (aadd(_strdup(buffer)) < 0)
{
FindClose(hFile);
return -1;
}
first = FALSE;
}
}
while(FindNextFileA(hFile, &fd));
FindClose(hFile);
}
}
if (first)
{
if (aadd(name) < 0)
return -1;
}
else
free(name);
return 0;
}
int wexpand(wchar_t* name, int expand_wildcards)
{
wchar_t* s;
WIN32_FIND_DATAW fd;
HANDLE hFile;
BOOLEAN first = TRUE;
wchar_t buffer[256];
uintptr_t pos;
if (expand_wildcards && (s = wcspbrk(name, L"*?")))
{
hFile = FindFirstFileW(name, &fd);
if (hFile != INVALID_HANDLE_VALUE)
{
while(s != name && *s != L'/' && *s != L'\\')
s--;
pos = s - name;
if (*s == L'/' || *s == L'\\')
pos++;
wcsncpy(buffer, name, pos);
do
{
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
wcscpy(&buffer[pos], fd.cFileName);
if (wadd(_wcsdup(buffer)) < 0)
{
FindClose(hFile);
return -1;
}
first = FALSE;
}
}
while(FindNextFileW(hFile, &fd));
FindClose(hFile);
}
}
if (first)
{
if (wadd(name) < 0)
return -1;
}
else
free(name);
return 0;
}
void __getmainargs(int* argc, char*** argv, char*** env, int expand_wildcards, int* new_mode, char* _acmdln)
{
int i, afterlastspace, ignorespace, doexpand;
size_t len;
char* aNewCmdln;
/* missing threading init */
i = 0;
afterlastspace = 0;
ignorespace = 0;
doexpand = expand_wildcards;
if (__argv && _environ)
{
*argv = __argv;
*env = _environ;
*argc = __argc;
return;
}
__argc = 0;
len = strlen(_acmdln);
/* Allocate a temporary buffer to be used instead of the original _acmdln parameter. */
aNewCmdln = strndup(_acmdln, len);
while (aNewCmdln[i])
{
if (aNewCmdln[i] == '"')
{
if(ignorespace)
{
ignorespace = 0;
}
else
{
ignorespace = 1;
doexpand = 0;
}
memmove(aNewCmdln + i, aNewCmdln + i + 1, len - i);
len--;
continue;
}
if (aNewCmdln[i] == ' ' && !ignorespace)
{
aexpand(strndup(aNewCmdln + afterlastspace, i - afterlastspace), doexpand);
i++;
while (aNewCmdln[i] == ' ')
i++;
afterlastspace=i;
doexpand = expand_wildcards;
}
else
{
i++;
}
}
if (aNewCmdln[afterlastspace] != 0)
{
aexpand(strndup(aNewCmdln + afterlastspace, i - afterlastspace), doexpand);
}
/* Free the temporary buffer. */
free(aNewCmdln);
HeapValidate(GetProcessHeap(), 0, NULL);
*argc = __argc;
if (__argv == NULL)
{
__argv = (char**)malloc(sizeof(char*));
__argv[0] = 0;
}
*argv = __argv;
*env = _environ;
_pgmptr = _strdup(__argv[0]);
}
void __wgetmainargs(int* argc, wchar_t*** wargv, wchar_t*** wenv,
int expand_wildcards, int* new_mode, wchar_t*_wcmdln)
{
int i, afterlastspace, ignorespace, doexpand;
size_t len;
wchar_t* wNewCmdln;
/* missing threading init */
i = 0;
afterlastspace = 0;
ignorespace = 0;
doexpand = expand_wildcards;
if (__wargv && _wenviron)
{
*wargv = __wargv;
*wenv = _wenviron;
*argc = __argc;
return;
}
__argc = 0;
len = wcslen(_wcmdln);
/* Allocate a temporary buffer to be used instead of the original _wcmdln parameter. */
wNewCmdln = wcsndup(_wcmdln, len);
while (wNewCmdln[i])
{
if (wNewCmdln[i] == L'"')
{
if(ignorespace)
{
ignorespace = 0;
}
else
{
ignorespace = 1;
doexpand = 0;
}
memmove(wNewCmdln + i, wNewCmdln + i + 1, (len - i) * sizeof(wchar_t));
len--;
continue;
}
if (wNewCmdln[i] == L' ' && !ignorespace)
{
wexpand(wcsndup(wNewCmdln + afterlastspace, i - afterlastspace), doexpand);
i++;
while (wNewCmdln[i] == L' ')
i++;
afterlastspace=i;
doexpand = expand_wildcards;
}
else
{
i++;
}
}
if (wNewCmdln[afterlastspace] != 0)
{
wexpand(wcsndup(wNewCmdln + afterlastspace, i - afterlastspace), doexpand);
}
/* Free the temporary buffer. */
free(wNewCmdln);
HeapValidate(GetProcessHeap(), 0, NULL);
*argc = __argc;
if (__wargv == NULL)
{
__wargv = (wchar_t**)malloc(sizeof(wchar_t*));
__wargv[0] = 0;
}
*wargv = __wargv;
*wenv = _wenviron;
_wpgmptr = _wcsdup(__wargv[0]);
}
BOOL __stdcall Virtual_GetModuleHandleEx(DWORD dwFlags, void* pModuleName, HMODULE *hModuleRet)
{
if(pModuleName == NULL)
{
*hModuleRet = NULL;
return true;
}
return GetModuleHandleEx(dwFlags, (LPCWSTR)pModuleName, hModuleRet);
}
HMODULE __stdcall Virtual_GetModuleHandle(void* pModuleName)
{
if(pModuleName == NULL) return hVirtualModule;
return GetModuleHandle((LPCWSTR)pModuleName);
}
char* __stdcall Virtual_GetCommandLineA()
{
PEB32 *tPeb = (PEB32*)GetThreadPEB();
RTL_USER_PROCESS_PARAMETERS_MEMMODULE *ProcessParams = (RTL_USER_PROCESS_PARAMETERS_MEMMODULE*)tPeb->ProcessParameters;
if(ProcessParams->ExSign != 0xFFFFACAC)
{
return GetCommandLineA();
}
return GetCommandLineA(); //
}
wchar_t* __stdcall Virtual_GetCommandLineW()
{
PEB32 *tPeb = (PEB32*)GetThreadPEB();
RTL_USER_PROCESS_PARAMETERS_MEMMODULE *ProcessParams = (RTL_USER_PROCESS_PARAMETERS_MEMMODULE*)tPeb->ProcessParameters;
if(ProcessParams->ExSign != 0xFFFFACAC)
{
return GetCommandLineW();
}
return GetCommandLineW(); //
}
int Virtual_getmainargs(int * _Argc, char *** _Argv, char *** _Env, int _DoWildCard, void * _StartInfo) // msvcrt
{
PEB32 *tPeb = (PEB32*)GetThreadPEB();
RTL_USER_PROCESS_PARAMETERS_MEMMODULE *ProcessParams = (RTL_USER_PROCESS_PARAMETERS_MEMMODULE*)tPeb->ProcessParameters;
if(ProcessParams->ExSign != 0xFFFFACAC)
{
__getmainargs(_Argc, _Argv, _Env, _DoWildCard, (int*)_StartInfo, GetCommandLineA());
return 0;
}
char* cLine = new char[ProcessParams->CommandLine.MaximumLength];
memset(cLine, 0x00, ProcessParams->CommandLine.MaximumLength);
WideCharToMultiByte(CP_UTF8, 0, ProcessParams->CommandLine.Buffer, lstrlenW(ProcessParams->CommandLine.Buffer), cLine, ProcessParams->CommandLine.MaximumLength, NULL, NULL);
__getmainargs(_Argc, _Argv, _Env, _DoWildCard, (int*)_StartInfo, cLine);
MEMORYMODULE *hMemoryModule = (MEMORYMODULE*)ProcessParams->MemModule;
hMemoryModule->CustomArgc = (int*)_Argc;
hMemoryModule->CustomArgv = (char***)_Argv;
return 0;
}
int Virtual_wgetmainargs(int *_Argc, wchar_t ***_Argv, wchar_t ***_Env, int _DoWildCard, void * _StartInfo) // msvcrt
{
PEB32 *tPeb = (PEB32*)GetThreadPEB();
RTL_USER_PROCESS_PARAMETERS_MEMMODULE *ProcessParams = (RTL_USER_PROCESS_PARAMETERS_MEMMODULE*)tPeb->ProcessParameters;
if(ProcessParams->ExSign != 0xFFFFACAC)
{
__wgetmainargs(_Argc, _Argv, _Env, _DoWildCard, (int*)_StartInfo, GetCommandLineW());
return 0;
}
__wgetmainargs(_Argc, _Argv, _Env, _DoWildCard, (int*)_StartInfo, ProcessParams->CommandLine.Buffer);
MEMORYMODULE *hMemoryModule = (MEMORYMODULE*)ProcessParams->MemModule;
hMemoryModule->CustomWArgc = (int*)_Argc;
hMemoryModule->CustomWArgv = (wchar_t***)_Argv;
return 0;
}