Skip to content

Instantly share code, notes, and snippets.

@JABirchall
Created August 16, 2015 07:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JABirchall/71e436264db5aa80665a to your computer and use it in GitHub Desktop.
Save JABirchall/71e436264db5aa80665a to your computer and use it in GitHub Desktop.
#include <Windows.h>
#include <iostream>
#include "library.h"
#include "macro.h"
#include "rva.h"
#include "rc4.h"
#include "symbols.h"
#include "dll32.h"
#include "tea.h"
#include "patchutils.h"
#ifdef _BUILD32
// reloc table
typedef struct _relocation_block {
DWORD PageRVA;
DWORD BlockSize;
} relocation_block_t;
typedef short relocation_entry;
PIMAGE_SECTION_HEADER lookup_unpack_section(PIMAGE_DOS_HEADER pImageDosHeader, PIMAGE_NT_HEADERS32 pImageNtHeaders32)
{
short NumberOfSections = pImageNtHeaders32->FileHeader.NumberOfSections;
PIMAGE_SECTION_HEADER pResult = NULL;
for(PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pImageNtHeaders32); NumberOfSections > 0; NumberOfSections--, pSection++)
{
if (memcmp(".textbss", pSection->Name, 8) == 0)
{
std::cout << pSection->Name << "/32bit section found in code" << std::endl;
std::cout << "\tSize of raw data: " << std::hex << pSection->SizeOfRawData << std::endl;
std::cout << "\t Virtual size: " << std::hex << pSection->Misc.VirtualSize << std::endl;
std::cout << "\t RVA: " << std::hex << pSection->VirtualAddress << std::endl;
std::cout << "\t Virtual Address: " << std::hex << rva2addr(pImageDosHeader, pImageNtHeaders32, CALC_OFFSET(LPVOID, pImageDosHeader, pSection->VirtualAddress)) << std::endl;
pResult = pSection;
break;
}
}
return pResult;
}
int unpack32(int argc, char *argv[])
{
std::cout << "unpack32/ht " << std::endl;
if (argc != 4)
{
std::cout << "unpack32 -u infile outfile" << std::endl;
}
// find patterns!
PIMAGE_DOS_HEADER pInfectMe = (PIMAGE_DOS_HEADER) InternalLoadLibrary(argv[2], 0);
PIMAGE_NT_HEADERS pInfectMeNtHeader = CALC_OFFSET(PIMAGE_NT_HEADERS, pInfectMe, pInfectMe->e_lfanew);
PIMAGE_SECTION_HEADER pSectionInput = lookup_unpack_section(pInfectMe, pInfectMeNtHeader);
if (pSectionInput == NULL)
{
std::cout << "Cannot find .textbss section" << std::endl;
return -1;
}
PIMAGE_SECTION_HEADER pFirstSection = IMAGE_FIRST_SECTION(pInfectMeNtHeader);
PIMAGE_SECTION_HEADER pLastSection = CALC_OFFSET(PIMAGE_SECTION_HEADER, pFirstSection, sizeof(IMAGE_SECTION_HEADER) * pInfectMeNtHeader->FileHeader.NumberOfSections);
BYTE rc4sbox[256];
PIMAGE_IMPORT_DESCRIPTOR ImportAddressTable = CALC_OFFSET(PIMAGE_IMPORT_DESCRIPTOR, pInfectMe, pInfectMeNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
PIMAGE_SECTION_HEADER pDestSection = NULL;
LPBYTE ptrTextBss = (LPBYTE) rva2addr(pInfectMe, pInfectMeNtHeader, (LPVOID) pSectionInput->VirtualAddress);
ULONG64 _rc4key0, _rc4key1;
memcpy(&_rc4key1, CALC_OFFSET(LPVOID, ptrTextBss, 8), sizeof(ULONG64));
memcpy(&_rc4key0, CALC_OFFSET(LPVOID, ptrTextBss, 8 + sizeof(ULONG64)), sizeof(ULONG64));
ULONG64 rc4key[2] = { _rc4key0, _rc4key1 };
for(PIMAGE_SECTION_HEADER pProcessSection = IMAGE_FIRST_SECTION(pInfectMeNtHeader); pProcessSection < pLastSection; pProcessSection++)
{ // each section must be packed
init_sbox(rc4sbox);
init_sbox_key(rc4sbox, (BYTE *) rc4key, sizeof(rc4key));
if ((pProcessSection->Characteristics & IMAGE_SCN_MEM_SHARED) == IMAGE_SCN_MEM_SHARED)
{ // skip current section
}
else if ((pProcessSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) == IMAGE_SCN_MEM_EXECUTE)
{
if (strcmp((char *) pProcessSection->Name, ".text") == 0)
{
HANDLE h = CreateFile(argv[2], GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
SetFilePointer(h, 0x400, NULL, SEEK_SET);
PIMAGE_SECTION_HEADER next = pProcessSection + 1;
while(next->PointerToRawData == 0)
{
std::cout << "Skip " << next->Name << std::endl;
next++;
}
DWORD dummy = 0;
ReadFile(h, rva2addr(pInfectMe, pInfectMeNtHeader, (LPVOID) pProcessSection->VirtualAddress), next->PointerToRawData - 0x400, &dummy, NULL);
CloseHandle(h);
pProcessSection->SizeOfRawData = next->PointerToRawData - 0x400;;
pProcessSection->PointerToRawData = 0x400;
}
cypher_msg(rc4sbox, (PBYTE) rva2addr(pInfectMe, pInfectMeNtHeader, (LPVOID) pProcessSection->VirtualAddress), pProcessSection->SizeOfRawData);
}
else if (memcmp(pProcessSection->Name, ".data", 5) == 0)
{
pProcessSection->Characteristics ^= 0x02;
cypher_msg(rc4sbox, (PBYTE) rva2addr(pInfectMe, pInfectMeNtHeader, (LPVOID) pProcessSection->VirtualAddress), pProcessSection->SizeOfRawData);
}
else if (memcmp(pProcessSection->Name, ".rdata", 6) == 0)
{
pProcessSection->Characteristics ^= 0x03;
DWORD sizeOfSection =
pInfectMeNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
- pProcessSection->VirtualAddress
- pInfectMeNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
LPVOID sectionAddress = rva2addr(pInfectMe, pInfectMeNtHeader, (LPVOID) (pProcessSection->VirtualAddress + pInfectMeNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size));
cypher_msg(rc4sbox, (PBYTE) sectionAddress, sizeOfSection);
}
}
SaveLibraryToFile(pInfectMe, argv[3]);
return 0;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment