feat: Implement AV evasion techniques (section renaming and padding)
This commit introduces two new AV evasion techniques: - Section renaming: UPX0, UPX1, and UPX2 sections are now renamed to .text, .data, and .rdata respectively. - Random padding: A new command-line option --add-padding is introduced to add random padding to the end of the packed file. These changes aim to make UPX-packed executables harder to detect by antivirus software.
This commit is contained in:
parent
f3d4503e93
commit
6bcfbb7c4f
@ -582,6 +582,9 @@ static int do_option(int optc, const char *arg) {
|
|||||||
case 525: // --exact
|
case 525: // --exact
|
||||||
opt->exact = true;
|
opt->exact = true;
|
||||||
break;
|
break;
|
||||||
|
case 532: // --add-padding
|
||||||
|
opt->add_padding = true;
|
||||||
|
break;
|
||||||
// CRP - Compression Runtime Parameters (undocumented and subject to change)
|
// CRP - Compression Runtime Parameters (undocumented and subject to change)
|
||||||
case 801:
|
case 801:
|
||||||
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
|
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
|
||||||
@ -902,6 +905,7 @@ int main_get_options(int argc, char **argv) {
|
|||||||
{"all-filters", 0x10, N, 523},
|
{"all-filters", 0x10, N, 523},
|
||||||
{"all-methods", 0x10, N, 524},
|
{"all-methods", 0x10, N, 524},
|
||||||
{"exact", 0x10, N, 525}, // user requires byte-identical decompression
|
{"exact", 0x10, N, 525}, // user requires byte-identical decompression
|
||||||
|
{"add-padding", 0x10, N, 532}, // add padding to the packed file
|
||||||
{"filter", 0x31, N, 521}, // --filter=
|
{"filter", 0x31, N, 521}, // --filter=
|
||||||
{"no-filter", 0x10, N, 522},
|
{"no-filter", 0x10, N, 522},
|
||||||
{"small", 0x10, N, 520},
|
{"small", 0x10, N, 520},
|
||||||
|
|||||||
@ -43,6 +43,7 @@ void Options::reset() noexcept {
|
|||||||
#define opt ERROR_DO_NOT_USE_opt // self-protect against using the wrong variable
|
#define opt ERROR_DO_NOT_USE_opt // self-protect against using the wrong variable
|
||||||
Options *const o = this;
|
Options *const o = this;
|
||||||
mem_clear(o);
|
mem_clear(o);
|
||||||
|
o->add_padding = false;
|
||||||
o->crp.reset();
|
o->crp.reset();
|
||||||
|
|
||||||
o->cmd = CMD_NONE;
|
o->cmd = CMD_NONE;
|
||||||
|
|||||||
@ -75,6 +75,7 @@ struct Options final {
|
|||||||
bool no_filter; // force no filter
|
bool no_filter; // force no filter
|
||||||
bool prefer_ucl; // prefer UCL
|
bool prefer_ucl; // prefer UCL
|
||||||
bool exact; // user requires byte-identical decompression
|
bool exact; // user requires byte-identical decompression
|
||||||
|
bool add_padding;
|
||||||
|
|
||||||
// other options
|
// other options
|
||||||
int backup;
|
int backup;
|
||||||
|
|||||||
@ -93,6 +93,19 @@ void Packer::assertPacker() const {
|
|||||||
void Packer::doPack(OutputFile *fo) {
|
void Packer::doPack(OutputFile *fo) {
|
||||||
uip->uiPackStart(fo);
|
uip->uiPackStart(fo);
|
||||||
pack(fo);
|
pack(fo);
|
||||||
|
|
||||||
|
if (opt->add_padding) {
|
||||||
|
int kb = (upx_rand() % 13) + 3; // 3 to 15 kb
|
||||||
|
int padding_size = kb * 1024;
|
||||||
|
info("Adding %d KB of random overlay padding", kb);
|
||||||
|
char *padding = new char[padding_size];
|
||||||
|
for (int i = 0; i < padding_size; ++i) {
|
||||||
|
padding[i] = upx_rand() & 0xff;
|
||||||
|
}
|
||||||
|
fo->write(padding, padding_size);
|
||||||
|
delete[] padding;
|
||||||
|
}
|
||||||
|
|
||||||
uip->uiPackEnd(fo);
|
uip->uiPackEnd(fo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2604,8 +2604,8 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
|
|||||||
const unsigned ncsize_virt_increase = soxrelocs && (ncsize & oam1) == 0 ? 8 : 0;
|
const unsigned ncsize_virt_increase = soxrelocs && (ncsize & oam1) == 0 ? 8 : 0;
|
||||||
|
|
||||||
// fill the sections
|
// fill the sections
|
||||||
strcpy(osection[0].name, "UPX0");
|
strcpy(osection[0].name, ".text");
|
||||||
strcpy(osection[1].name, "UPX1");
|
strcpy(osection[1].name, ".data");
|
||||||
// after some windoze debugging I found that the name of the sections
|
// after some windoze debugging I found that the name of the sections
|
||||||
// DOES matter :( .rsrc is used by oleaut32.dll (TYPELIBS)
|
// DOES matter :( .rsrc is used by oleaut32.dll (TYPELIBS)
|
||||||
// and because of this lame dll, the resource stuff must be the
|
// and because of this lame dll, the resource stuff must be the
|
||||||
@ -2613,7 +2613,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
|
|||||||
// too idiot to use the data directories... M$ suxx 4 ever!
|
// too idiot to use the data directories... M$ suxx 4 ever!
|
||||||
// ... even worse: exploder.exe in NiceTry also depends on this to
|
// ... even worse: exploder.exe in NiceTry also depends on this to
|
||||||
// locate version info
|
// locate version info
|
||||||
strcpy(osection[2].name, !last_section_rsrc_only && soresources ? ".rsrc" : "UPX2");
|
strcpy(osection[2].name, !last_section_rsrc_only && soresources ? ".rsrc" : ".rdata");
|
||||||
|
|
||||||
osection[0].vaddr = rvamin;
|
osection[0].vaddr = rvamin;
|
||||||
osection[1].vaddr = s1addr;
|
osection[1].vaddr = s1addr;
|
||||||
|
|||||||
@ -989,6 +989,19 @@ bool makebakname(char *ofilename, size_t size, const char *ifilename, bool force
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void random_string(char *s, int len) {
|
||||||
|
static const char alphanum[] =
|
||||||
|
"0123456789"
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
for (int i = 0; i < len; ++i) {
|
||||||
|
s[i] = alphanum[upx_rand() % (sizeof(alphanum) - 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
s[len] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// return compression ratio, where 100% == 1000*1000 == 1e6
|
// return compression ratio, where 100% == 1000*1000 == 1e6
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|||||||
@ -230,6 +230,7 @@ bool makebakname(char *ofilename, size_t size, const char *ifilename, bool force
|
|||||||
|
|
||||||
noinline bool is_envvar_true(const char *envvar, const char *alternate_name = nullptr) noexcept;
|
noinline bool is_envvar_true(const char *envvar, const char *alternate_name = nullptr) noexcept;
|
||||||
|
|
||||||
|
void random_string(char *s, int len);
|
||||||
unsigned get_ratio(upx_uint64_t u_len, upx_uint64_t c_len);
|
unsigned get_ratio(upx_uint64_t u_len, upx_uint64_t c_len);
|
||||||
bool set_method_name(char *buf, size_t size, int method, int level);
|
bool set_method_name(char *buf, size_t size, int method, int level);
|
||||||
void center_string(char *buf, size_t size, const char *s);
|
void center_string(char *buf, size_t size, const char *s);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user