Created
August 16, 2015 07:45
-
-
Save JABirchall/71e436264db5aa80665a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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