HyperDbg/hyperdbg/script-engine/code/script_include.c

199 lines
4.2 KiB
C

/**
* @file script_include.c
* @author M.H. Gholamrezaei (mh@hyperdbg.org)
*
* @brief Include file path resolution and parsing routines
* @details
* @version 0.1
* @date 2020-10-22
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
#include "script_include.h"
/**
* @brief Trims leading whitespace from a string in-place
*
* @param Str the string to left-trim
* @return VOID
*/
static VOID
Ltrim(char * Str)
{
char * P = Str;
while (*P && isspace((unsigned char)*P))
P++;
if (P != Str)
memmove(Str, P, strlen(P) + 1);
}
/**
* @brief Trims trailing whitespace from a string in-place
*
* @param Str the string to right-trim
* @return VOID
*/
static VOID
Rtrim(char * Str)
{
char * End = Str + strlen(Str);
while (End > Str && isspace((unsigned char)End[-1]))
End--;
*End = '\0';
}
/**
* @brief Trims leading and trailing whitespace from a string in-place
*
* @param Str the string to trim
* @return VOID
*/
static VOID
Trim(char * Str)
{
Ltrim(Str);
Rtrim(Str);
}
/**
* @brief Inserts a string into another string at a given index
*
* @param Str the original string (will be reallocated)
* @param InputIdx the index at which to insert
* @param Buf the string to insert
* @return char * the new string, or the original on allocation failure
*/
char *
InsertStrNew(char * Str, int InputIdx, const char * Buf)
{
SIZE_T LenStr = strlen(Str);
SIZE_T LenBuf = strlen(Buf);
if (InputIdx < 0 || (SIZE_T)InputIdx > LenStr)
return Str;
char * NewStr = (char *)realloc(Str, LenStr + LenBuf + 1);
if (!NewStr)
return Str;
memmove(NewStr + InputIdx + LenBuf,
NewStr + InputIdx,
LenStr - InputIdx + 1);
memcpy(NewStr + InputIdx, Buf, LenBuf);
return NewStr;
}
/**
* @brief Checks whether a file path is absolute
*
* @param Path the file path to check
* @return BOOLEAN TRUE if the path is absolute, FALSE otherwise
*/
BOOLEAN
IsAbsolutePath(const char * Path)
{
if (!Path || !Path[0])
return FALSE;
if (strlen(Path) >= 3 &&
((Path[1] == ':' && (Path[2] == '\\' || Path[2] == '/'))))
return TRUE;
return FALSE;
}
/**
* @brief Resolves an include file path to a full absolute path
*
* @param IncludeFilePath the include file path (relative or absolute)
* @param OutPath the buffer to receive the resolved path
* @return VOID
*/
VOID
ResolveIncludePath(const char * IncludeFilePath, char * OutPath)
{
if (IsAbsolutePath(IncludeFilePath))
{
strncpy(OutPath, IncludeFilePath, MAX_PATH_LEN - 1);
OutPath[MAX_PATH_LEN - 1] = '\0';
return;
}
CHAR ExeDir[MAX_PATH_LEN];
GetModuleFileNameA(NULL, ExeDir, MAX_PATH_LEN);
char * P = strrchr(ExeDir, '\\');
if (P)
*P = '\0';
snprintf(
OutPath,
MAX_PATH_LEN,
"%s\\%s",
ExeDir,
IncludeFilePath);
}
/**
* @brief Checks whether a file exists at the given path
*
* @param Path the file path to check
* @return BOOLEAN TRUE if the file exists, FALSE otherwise
*/
BOOLEAN
FileExists(const char * Path)
{
DWORD Attr = GetFileAttributesA(Path);
if (Attr == INVALID_FILE_ATTRIBUTES)
return FALSE;
if (Attr & FILE_ATTRIBUTE_DIRECTORY)
return FALSE;
return TRUE;
}
/**
* @brief Reads and parses an include file into a buffer
*
* @param IncludeFile the path to the include file
* @param Buffer pointer to receive the allocated file content buffer
* @return BOOLEAN TRUE if the file was parsed successfully, FALSE otherwise
*/
BOOLEAN
ParseIncludeFile(char * IncludeFile, char ** Buffer)
{
FILE * Fp = fopen(IncludeFile, "r");
fseek(Fp, 0, SEEK_END);
LONG Size = ftell(Fp);
rewind(Fp);
*Buffer = calloc(Size + 1, 1);
fread(*Buffer, 1, Size, Fp);
(*Buffer)[Size] = '\0';
Trim(*Buffer);
SIZE_T Len = strlen(*Buffer);
if ((*Buffer)[0] == '?' &&
(*Buffer)[1] == ' ' &&
(*Buffer)[2] == '{' &&
(*Buffer)[Len - 1] == '}')
{
memmove(
*Buffer,
*Buffer + 3,
Len - 3 + 1);
(*Buffer)[strlen(*Buffer) - 1] = '\0';
return TRUE;
}
return FALSE;
}