Skip to content

Commit

Permalink
Merge branch 'main' of github.com:trustedsec/COFFLoader into trusteds…
Browse files Browse the repository at this point in the history
…ec-main
  • Loading branch information
rkervella committed Jan 16, 2023
2 parents bff2abf + f34623d commit 88227eb
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 58 deletions.
154 changes: 106 additions & 48 deletions COFFLoader.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,10 @@
#define PREPENDSYMBOLVALUE "__imp__"
#endif

unsigned char *unhexlify(unsigned char *value, int *outlen)
{
unsigned char *retval = NULL;
char byteval[3] = {0};
int counter = 0;
unsigned char* unhexlify(unsigned char* value, int *outlen) {
unsigned char* retval = NULL;
char byteval[3] = { 0 };
unsigned int counter = 0;
int counter2 = 0;
char character = 0;
if (value == NULL)
Expand All @@ -60,7 +59,7 @@ unsigned char *unhexlify(unsigned char *value, int *outlen)
for (counter = 0; counter < strlen((char *)value); counter += 2)
{
memcpy(byteval, value + counter, 2);
character = strtol(byteval, NULL, 16);
character = (char)strtol(byteval, NULL, 16);
memcpy(retval + counter2, &character, 1);
counter2++;
}
Expand All @@ -77,9 +76,9 @@ unsigned char *getContents(char *filepath, uint32_t *outsize)
{
FILE *fin = NULL;
uint32_t fsize = 0;
uint32_t readsize = 0;
unsigned char *buffer = NULL;
unsigned char *tempbuffer = NULL;
size_t readsize = 0;
unsigned char* buffer = NULL;
unsigned char* tempbuffer = NULL;

fin = fopen(filepath, "rb");
if (fin == NULL)
Expand Down Expand Up @@ -110,6 +109,10 @@ unsigned char *getContents(char *filepath, uint32_t *outsize)
return buffer;
}

static BOOL starts_with(const char* string, const char* substring) {
return strncmp(string, substring, strlen(substring)) == 0;
}

/* Helper function to process a symbol string, determine what function and
* library its from, and return the right function pointer. Will need to
* implement in the loading of the beacon internal functions, or any other
Expand All @@ -125,23 +128,19 @@ void *process_symbol(char *symbolstring)
HMODULE llHandle = NULL;
#endif

memcpy(localcopy, symbolstring, strlen(symbolstring));
if (strncmp(symbolstring, PREPENDSYMBOLVALUE "Beacon", strlen(PREPENDSYMBOLVALUE "Beacon")) == 0 || strncmp(symbolstring, PREPENDSYMBOLVALUE "toWideChar", strlen(PREPENDSYMBOLVALUE "toWideChar")) == 0 ||
strncmp(symbolstring, PREPENDSYMBOLVALUE "GetProcAddress", strlen(PREPENDSYMBOLVALUE "GetProcAddress")) == 0 || strncmp(symbolstring, PREPENDSYMBOLVALUE "LoadLibraryA", strlen(PREPENDSYMBOLVALUE "LoadLibraryA")) == 0 ||
strncmp(symbolstring, PREPENDSYMBOLVALUE "GetModuleHandleA", strlen(PREPENDSYMBOLVALUE "GetModuleHandleA")) == 0 || strncmp(symbolstring, PREPENDSYMBOLVALUE "FreeLibrary", strlen(PREPENDSYMBOLVALUE "FreeLibrary")) == 0)
{
strncpy(localcopy, symbolstring, sizeof(localcopy) - 1);
if (starts_with(symbolstring, PREPENDSYMBOLVALUE"Beacon") || starts_with(symbolstring, PREPENDSYMBOLVALUE"toWideChar") ||
starts_with(symbolstring, PREPENDSYMBOLVALUE"GetProcAddress") || starts_with(symbolstring, PREPENDSYMBOLVALUE"LoadLibraryA") ||
starts_with(symbolstring, PREPENDSYMBOLVALUE"GetModuleHandleA") || starts_with(symbolstring, PREPENDSYMBOLVALUE"FreeLibrary")) {
localfunc = symbolstring + strlen(PREPENDSYMBOLVALUE);
DEBUG_PRINT("\t\tInternalFunction: %s\n", localfunc);
/* TODO: Get internal symbol here and set to functionaddress, then
* return the pointer to the internal function*/
#if defined(_WIN32)
for (tempcounter = 0; tempcounter < 29; tempcounter++)
{
if (InternalFunctions[tempcounter][0] != NULL)
{
if (strcmp(localfunc, (char *)(InternalFunctions[tempcounter][0])) == 0)
{
functionaddress = (void *)InternalFunctions[tempcounter][1];
for (tempcounter = 0; tempcounter < 29; tempcounter++) {
if (InternalFunctions[tempcounter][0] != NULL) {
if (starts_with(localfunc, (char*)(InternalFunctions[tempcounter][0]))) {
functionaddress = (void*)InternalFunctions[tempcounter][1];
return functionaddress;
}
}
Expand Down Expand Up @@ -218,14 +217,14 @@ int RunCOFF(char *functionname, unsigned char *coff_data, uint32_t filesize, uns
int retcode = 0;
int counter = 0;
int reloccount = 0;
int tempcounter = 0;
unsigned int tempcounter = 0;
uint32_t symptr = 0;
long unsigned int old_prot = 0;
uint32_t protect = 0;
uint32_t protect_index = 0;
#ifdef _WIN32
void *funcptrlocation = NULL;
int32_t offsetvalue = 0;
void* funcptrlocation = NULL;
size_t offsetvalue = 0;
#endif
char *entryfuncname = functionname;
#if defined(__x86_64__) || defined(_WIN64)
Expand Down Expand Up @@ -358,9 +357,8 @@ int RunCOFF(char *functionname, unsigned char *coff_data, uint32_t filesize, uns
retcode = 1;
goto cleanup;
}
offsetvalue = ((char *)(sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1] + offsetvalue) - (char *)(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4));
DEBUG_PRINT("\tOffsetValue : 0x%0X\n", offsetvalue);
DEBUG_PRINT("\t\tSetting 0x%X to %X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue);
offsetvalue = ((char*)(sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1] + offsetvalue) - (char*)(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4));
DEBUG_PRINT("\tSetting 0x%p to OffsetValue: 0x%X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, offsetvalue);
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));
}
/* This is Type == 4 relocation code, needed to make global variables to work correctly */
Expand All @@ -375,21 +373,35 @@ int RunCOFF(char *functionname, unsigned char *coff_data, uint32_t filesize, uns
goto cleanup;
}
offsetvalue += (sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1] - (sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4));
DEBUG_PRINT("\t\tRelative address: 0x%X\n", offsetvalue);
offsetvalue += coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].Value;
DEBUG_PRINT("\t\tSetting 0x%p to relative address: 0x%X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, offsetvalue);
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));
}
else
{
DEBUG_PRINT("No code for relocation type: %d\n", coff_reloc_ptr->Type);
}
#else
/* This is Type == IMAGE_REL_I386_DIR32 relocation code */
memcpy(&offsetvalue, sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, sizeof(int32_t));
DEBUG_PRINT("\tReadin OffsetValue : 0x%0X\n", offsetvalue);
offsetvalue = (uint32_t)(sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1]) + offsetvalue;
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));
#endif // WIN64 statement close
#endif // WIN32 statement close
/* This is Type == IMAGE_REL_I386_DIR32 relocation code */
if (coff_reloc_ptr->Type == IMAGE_REL_I386_DIR32){
memcpy(&offsetvalue, sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, sizeof(int32_t));
DEBUG_PRINT("\tReadin OffsetValue : 0x%0X\n", offsetvalue);
offsetvalue = (uint32_t)(sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1]) + offsetvalue;
offsetvalue += coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].Value;
DEBUG_PRINT("\tSetting 0x%p to: 0x%X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, offsetvalue);
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));
}
else if (coff_reloc_ptr->Type == IMAGE_REL_I386_REL32){
memcpy(&offsetvalue, sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, sizeof(int32_t));
DEBUG_PRINT("\tReadin OffsetValue : 0x%0X\n", offsetvalue);
offsetvalue += (sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1] - (sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4));
offsetvalue += coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].Value;
DEBUG_PRINT("\tSetting 0x%p to relative address: 0x%X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, offsetvalue);
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));

}
#endif //WIN64 statement close
#endif //WIN32 statement close
}
else
{
Expand All @@ -400,16 +412,22 @@ int RunCOFF(char *functionname, unsigned char *coff_data, uint32_t filesize, uns

/* This is the code to handle functions themselves, so using a makeshift Global Offset Table for it */
#ifdef _WIN32
funcptrlocation = process_symbol(((char *)(coff_sym_ptr + coff_header_ptr->NumberOfSymbols)) + symptr);
if (funcptrlocation == NULL)
{
funcptrlocation = process_symbol(((char*)(coff_sym_ptr + coff_header_ptr->NumberOfSymbols)) + symptr);
if (funcptrlocation == NULL && coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber == 0) {
DEBUG_PRINT("Failed to resolve symbol\n");
retcode = 1;
goto cleanup;
}
#ifdef _WIN64
if (coff_reloc_ptr->Type == IMAGE_REL_AMD64_REL32 && funcptrlocation != NULL)
{
if (coff_reloc_ptr->Type == IMAGE_REL_AMD64_ADDR64) {
memcpy(&longoffsetvalue, sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, sizeof(uint64_t));
DEBUG_PRINT("\tReadin longOffsetValue : 0x%llX\n", longoffsetvalue);
longoffsetvalue = (uint64_t)(sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1] + (uint64_t)longoffsetvalue);
DEBUG_PRINT("\tModified longOffsetValue : 0x%llX Base Address: %p\n", longoffsetvalue, sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1]);
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &longoffsetvalue, sizeof(uint64_t));
}

else if (coff_reloc_ptr->Type == IMAGE_REL_AMD64_REL32 && funcptrlocation != NULL) {
/* This is Type == 4 relocation code */
DEBUG_PRINT("Doing function relocation\n");
if (((functionMapping + (functionMappingCount * 8)) - (sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4)) > 0xffffffff)
Expand All @@ -420,7 +438,7 @@ int RunCOFF(char *functionname, unsigned char *coff_data, uint32_t filesize, uns
}
memcpy(functionMapping + (functionMappingCount * 8), &funcptrlocation, sizeof(uint64_t));
offsetvalue = (int32_t)((functionMapping + (functionMappingCount * 8)) - (sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4));
DEBUG_PRINT("\t\tRelative address : 0x%x\n", offsetvalue);
DEBUG_PRINT("\t\tSetting 0x%p to relative address: 0x%X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, offsetvalue);
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));
functionMappingCount++;
}
Expand All @@ -435,21 +453,61 @@ int RunCOFF(char *functionname, unsigned char *coff_data, uint32_t filesize, uns
retcode = 1;
goto cleanup;
}
DEBUG_PRINT("\t\tReferenced Section: 0x%X\n", sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1] + offsetvalue);
DEBUG_PRINT("\t\tReadin offset value: 0x%X\n", offsetvalue);
DEBUG_PRINT("\t\tVirtualAddressOffset: 0x%X\n", (sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4));
offsetvalue += (sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1] - (sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4));
DEBUG_PRINT("\t\tRelative address: 0x%X\n", offsetvalue);
offsetvalue += coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].Value;
DEBUG_PRINT("\t\tSetting 0x%p to relative address: 0x%X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, offsetvalue);
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));
}
else if (coff_reloc_ptr->Type == IMAGE_REL_AMD64_ADDR32NB) {
memcpy(&offsetvalue, sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, sizeof(int32_t));
DEBUG_PRINT("\tReadin OffsetValue : 0x%0X\n", offsetvalue);
DEBUG_PRINT("\t\tReferenced Section: 0x%X\n", sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1] + offsetvalue);
DEBUG_PRINT("\t\tEnd of Relocation Bytes: 0x%X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4);
if (((char*)(sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1] + offsetvalue) - (char*)(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4)) > 0xffffffff) {
DEBUG_PRINT("Relocations > 4 gigs away, exiting\n");
retcode = 1;
goto cleanup;
}
offsetvalue = ((char*)(sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1] + offsetvalue) - (char*)(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4));
DEBUG_PRINT("\tSetting 0x%p to OffsetValue: 0x%X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, offsetvalue);
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));
}
else
{
DEBUG_PRINT("No code for relocation type: %d\n", coff_reloc_ptr->Type);
}
#else
/* This is Type == IMAGE_REL_I386_DIR32 relocation code */
memcpy(functionMapping + (functionMappingCount * 4), &funcptrlocation, sizeof(uint32_t));
offsetvalue = (int32_t)(functionMapping + (functionMappingCount * 4));
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));
functionMappingCount++;
if (coff_reloc_ptr->Type == IMAGE_REL_I386_DIR32 && funcptrlocation != NULL){
/* This is Type == IMAGE_REL_I386_DIR32 relocation code */
memcpy(functionMapping + (functionMappingCount * 4), &funcptrlocation, sizeof(uint32_t));
offsetvalue = (int32_t)(functionMapping + (functionMappingCount * 4));
DEBUG_PRINT("\tSetting 0x%p to virtual address: 0x%X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, offsetvalue);
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));
functionMappingCount++;
}
else if (coff_reloc_ptr->Type == IMAGE_REL_I386_DIR32) {
memcpy(&offsetvalue, sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, sizeof(int32_t));
DEBUG_PRINT("\tReadin OffsetValue : 0x%0X\n", offsetvalue);
offsetvalue = (uint32_t)(sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1]) + offsetvalue;
offsetvalue += coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].Value;
DEBUG_PRINT("\tSetting 0x%p to virtual address: 0x%X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, offsetvalue);
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));
}
else if (coff_reloc_ptr->Type == IMAGE_REL_I386_REL32){
memcpy(&offsetvalue, sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, sizeof(int32_t));
DEBUG_PRINT("\tReadin OffsetValue : 0x%0X\n", offsetvalue);
offsetvalue += (sectionMapping[coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].SectionNumber - 1] - (sectionMapping[counter] + coff_reloc_ptr->VirtualAddress + 4));
offsetvalue += coff_sym_ptr[coff_reloc_ptr->SymbolTableIndex].Value;
DEBUG_PRINT("\tSetting 0x%p to relative address: 0x%X\n", sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, offsetvalue);
memcpy(sectionMapping[counter] + coff_reloc_ptr->VirtualAddress, &offsetvalue, sizeof(uint32_t));

}
else {
DEBUG_PRINT("No code for relocation type: %d\n", coff_reloc_ptr->Type);
}
#endif
#endif
}
Expand Down Expand Up @@ -522,7 +580,7 @@ int RunCOFF(char *functionname, unsigned char *coff_data, uint32_t filesize, uns
#ifdef _WIN32
/* So for some reason VS 2017 doesn't like this, but char* casting works, so just going to do that */
#ifdef _MSC_VER
foo = (char *)(sectionMapping[coff_sym_ptr[tempcounter].SectionNumber - 1] + coff_sym_ptr[tempcounter].Value);
foo = (void(__cdecl*)(char*, unsigned long))(sectionMapping[coff_sym_ptr[tempcounter].SectionNumber - 1] + coff_sym_ptr[tempcounter].Value);
#else
foo = (void (*)(char *, unsigned long))(sectionMapping[coff_sym_ptr[tempcounter].SectionNumber - 1] + coff_sym_ptr[tempcounter].Value);
#endif
Expand Down
17 changes: 7 additions & 10 deletions beacon_compatibility.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,19 +291,15 @@ void BeaconGetSpawnTo(BOOL x86, char* buffer, int length) {
}
if (x86) {
tempBufferPath = "C:\\Windows\\"X86PATH"\\"DEFAULTPROCESSNAME;
if (strlen(tempBufferPath) > length) {
return;
}
memcpy(buffer, tempBufferPath, strlen(tempBufferPath));
}
else {
tempBufferPath = "C:\\Windows\\"X64PATH"\\"DEFAULTPROCESSNAME;
if (strlen(tempBufferPath) > length) {
return;
}
memcpy(buffer, tempBufferPath, strlen(tempBufferPath));
}

if ((int)strlen(tempBufferPath) > length) {
return;
}
memcpy(buffer, tempBufferPath, strlen(tempBufferPath));
return;
}

Expand Down Expand Up @@ -335,8 +331,9 @@ void BeaconCleanupProcess(PROCESS_INFORMATION* pInfo) {
}

BOOL toWideChar(char* src, wchar_t* dst, int max) {
/* Leaving this to be implemented by people needing/wanting it */
return FALSE;
if (max < sizeof(wchar_t))
return FALSE;
return MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, src, -1, dst, max / sizeof(wchar_t));
}

char* BeaconGetOutputData(int *outsize) {
Expand Down

0 comments on commit 88227eb

Please sign in to comment.