Use pefile.cpp from stealthy branch

This commit is contained in:
JorySeverijnse 2025-12-13 14:02:33 +01:00
parent 3a828abcb9
commit a8c82c0f3f

View File

@ -945,16 +945,22 @@ public:
void PeFile::addKernelImport(const char *name) { ilinker->add_import(kernelDll(), name); }
void PeFile::addStubImports() {
// Break UPX detection by ensuring import count doesn't match 2-6 pattern
addKernelImport("LoadLibraryA");
addKernelImport("VirtualProtect");
addKernelImport("GetProcAddress");
addKernelImport("LoadLibraryA");
if (!isdll)
addKernelImport("ExitProcess");
// Added benign imports to increase import count and diversify pattern
addKernelImport("Sleep");
if (!isdll) {
// For EXEs: add extra imports to push count beyond 6 (breaks detection pattern)
addKernelImport("GetCurrentProcess");
addKernelImport("GetCommandLineA");
addKernelImport("GetModuleFileNameA");
addKernelImport("GetTickCount");
addKernelImport("QueryPerformanceCounter");
addKernelImport("GetSystemTimeAsFileTime");
addKernelImport("ExitProcess"); // Add last to avoid specific 2-4-6 patterns
} else {
// For DLLs: add minimal extra imports to break patterns
addKernelImport("GetCurrentProcess");
addKernelImport("GetTickCount");
}
}
void PeFile::processImports2(unsigned myimport, unsigned) { // pass 2
@ -1429,7 +1435,6 @@ void PeFile::processTls1(Interval *iv, typename tls_traits<LEXX>::cb_value_t ima
info("TLS: %u callback(s) found, adding TLS callback handler", num_callbacks);
// set flag to include necessary sections in loader
use_tls_callbacks = true;
use_tls_callbacks = false; // Force disable UPX's custom TLS handler
// define linker symbols
tlscb_ptr = tlsp->callbacks;
}
@ -2483,9 +2488,9 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
const bool has_oxrelocs =
!opt->win32_pe.strip_relocs && (use_stub_relocs || sotls || loadconfiv.ivnum);
const bool has_ncsection = has_oxrelocs || soimpdlls || soexport || soresources;
const unsigned oobjs = 7;
const unsigned oobjs = last_section_rsrc_only ? 4 : has_ncsection ? 3 : 2;
////pe_section_t osection[oobjs];
pe_section_t osection[8];
pe_section_t osection[4];
memset(osection, 0, sizeof(osection));
// section 0 : bss
// 1 : [ident + header] + packed_data + unpacker + tls + loadconf
@ -2527,10 +2532,19 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
memcpy(&oh, &ih, sizeof(oh));
oh.filealign = oh_filealign; // identsplit depends on this
oh.entry = upxsection;
// Modify timestamp to break compilation date detection
// Timestamp is at offset 8 in the PE header (after magic and machine)
set_le32((byte *) &oh + 8, 0x12345678);
oh.entry = upxsection; // Revert entry point randomization
oh.objects = oobjs;
oh.chksum = 0;
// Modify PE characteristics flags to break detection patterns
// Flags are at offset 22 in PE header
LE16 *flags = (LE16 *) ((byte *) &oh + 22);
*flags |= 0x0100; // Add IMAGE_FILE_RELOCS_STRIPPED flag
// fill the data directory
ODADDR(PEDIR_DEBUG) = 0; // dbgCET later
ODSIZE(PEDIR_DEBUG) = 0;
@ -2625,75 +2639,38 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
strcpy(osection[2].name, ".rsrc");
osection[2].name[5] = 0;
// Add new dummy sections for diversification
strcpy(osection[3].name, ".idata");
osection[3].name[6] = 0;
strcpy(osection[4].name, ".rdata");
osection[4].name[6] = 0;
strcpy(osection[5].name, ".reloc");
osection[5].name[6] = 0;
strcpy(osection[6].name, ".debug"); // Another common section
osection[6].name[6] = 0;
osection[0].vaddr = rvamin;
osection[1].vaddr = s1addr;
osection[2].vaddr = ncsection;
// Set vaddr for new dummy sections incrementally
osection[3].vaddr = (osection[2].vaddr + osection[2].vsize + oam1) & ~oam1; // After .rsrc
osection[4].vaddr = (osection[3].vaddr + osection[3].vsize + oam1) & ~oam1; // After .idata
osection[5].vaddr = (osection[4].vaddr + osection[4].vsize + oam1) & ~oam1; // After .rdata
osection[6].vaddr = (osection[5].vaddr + osection[5].vsize + oam1) & ~oam1; // After .reloc
osection[0].size = 0;
osection[1].size = (s1size + fam1) & ~fam1;
osection[2].size = (ncsize + fam1) & ~fam1;
// Set sizes for new dummy sections
osection[3].size = (fam1 + 0x1000) & ~fam1; // Example small size
osection[4].size = (fam1 + 0x1000) & ~fam1;
osection[5].size = (fam1 + 0x1000) & ~fam1;
osection[6].size = (fam1 + 0x1000) & ~fam1;
// Removed section size randomization to maintain DLL functionality
osection[0].vsize = osection[1].vaddr - osection[0].vaddr;
if (!last_section_rsrc_only) {
osection[1].vsize = (osection[1].size + oam1) & ~oam1;
osection[2].vsize = (osection[2].size + ncsize_virt_increase + oam1) & ~oam1;
// Set vsizes for new dummy sections
osection[3].vsize = (osection[3].size + oam1) & ~oam1;
osection[4].vsize = (osection[4].size + oam1) & ~oam1;
osection[5].vsize = (osection[5].size + oam1) & ~oam1;
osection[6].vsize = (osection[6].size + oam1) & ~oam1;
oh.imagesize = (osection[6].vaddr + osection[6].vsize + oam1) & ~oam1; // Update total image size
oh.imagesize = osection[2].vaddr + osection[2].vsize;
osection[0].rawdataptr = (pe_offset + sizeof(ht) + sizeof_osection + fam1) & ~(size_t) fam1;
osection[1].rawdataptr = osection[0].rawdataptr;
} else {
osection[1].vsize = osection[1].size;
osection[2].vsize = osection[2].size;
// Set vsizes for new dummy sections (if last_section_rsrc_only)
osection[3].vsize = osection[3].size;
osection[4].vsize = osection[4].size;
osection[5].vsize = osection[5].size;
osection[6].vsize = osection[6].size;
osection[0].rawdataptr = 0;
osection[1].rawdataptr = (pe_offset + sizeof(ht) + sizeof_osection + fam1) & ~(size_t) fam1;
}
osection[2].rawdataptr = osection[1].rawdataptr + osection[1].size;
// Set rawdataptr for new dummy sections
osection[3].rawdataptr = osection[2].rawdataptr + osection[2].size;
osection[4].rawdataptr = osection[3].rawdataptr + osection[3].size;
osection[5].rawdataptr = osection[4].rawdataptr + osection[4].size;
osection[6].rawdataptr = osection[5].rawdataptr + osection[5].size;
// Modify section flags to break UPX detection patterns
osection[0].flags = IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ |
IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE;
IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE;
osection[1].flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
IMAGE_SCN_MEM_EXECUTE;
osection[2].flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
// Set flags for new dummy sections
osection[3].flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; // .idata
osection[4].flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; // .rdata
osection[5].flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; // .reloc
osection[6].flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; // .debug
IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_INITIALIZED_DATA;
osection[2].flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
IMAGE_SCN_CNT_CODE;
if (last_section_rsrc_only) {
strcpy(osection[3].name, ".rsrc");
@ -2724,6 +2701,8 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
if (opt->win32_pe.strip_relocs)
oh.flags |= IMAGE_FILE_RELOCS_STRIPPED;
oh.chksum = 0; // Revert checksum to zero
ibuf.clear(0, oh.filealign);
info("Image size change: %u -> %u KiB", ih.imagesize / 1024, oh.imagesize / 1024);
@ -2751,6 +2730,8 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
fo->write(ibuf, sizeof(LEXX) - ic);
fo->write(otls, aligned_sotls);
fo->write(oloadconf, soloadconf);
// Removed random padding to maintain DLL functionality
if (dbgCET) {
ic = fo->getBytesWritten();
dbgCET->fpos = ic + sizeof(*dbgCET);