mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
src: clang-format more files; cleanups; NFCI
This commit is contained in:
parent
510505a85c
commit
9da4f7a6dc
|
@ -74,13 +74,16 @@ endif
|
|||
# automatically format some C++ source code files
|
||||
ifeq ($(shell uname),Linux)
|
||||
CLANG_FORMAT_FILES += bele.h bele_policy.h
|
||||
CLANG_FORMAT_FILES += c_file.cpp c_init.cpp c_none.cpp c_screen.cpp
|
||||
CLANG_FORMAT_FILES += compress_lzma.cpp compress_ucl.cpp compress_zlib.cpp
|
||||
CLANG_FORMAT_FILES += except.cpp except.h
|
||||
CLANG_FORMAT_FILES += file.cpp file.h
|
||||
CLANG_FORMAT_FILES += file.cpp file.h lefile.cpp lefile.h
|
||||
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h
|
||||
CLANG_FORMAT_FILES += main.cpp options.cpp options.h packer.cpp packer.h
|
||||
CLANG_FORMAT_FILES += p_armpe.cpp p_armpe.h
|
||||
CLANG_FORMAT_FILES += p_com.cpp p_com.h p_djgpp2.cpp p_djgpp2.h p_exe.cpp p_exe.h p_ps1.cpp p_ps1.h
|
||||
CLANG_FORMAT_FILES += p_sys.cpp p_sys.h p_tmt.cpp p_tmt.h p_tos.cpp p_tos.h p_wcle.cpp p_wcle.h
|
||||
CLANG_FORMAT_FILES += p_w32pe.h p_w64pep.h
|
||||
CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h
|
||||
CLANG_FORMAT_FILES += ui.cpp ui.h work.cpp
|
||||
CLANG_FORMAT_FILES += $(wildcard util/[a-ln-z]*.[ch]* util/mem*.[ch]*)
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#if (USE_CONSOLE)
|
||||
|
@ -34,58 +33,41 @@
|
|||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int init(FILE *f, int o, int now)
|
||||
{
|
||||
static int init(FILE *f, int o, int now) {
|
||||
UNUSED(f);
|
||||
UNUSED(o);
|
||||
UNUSED(now);
|
||||
return CON_FILE;
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
UNUSED(f);
|
||||
UNUSED(fg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void print0(FILE *f, const char *s)
|
||||
{
|
||||
static void print0(FILE *f, const char *s) {
|
||||
#if 1
|
||||
fputs(s,f);
|
||||
fputs(s, f);
|
||||
#else
|
||||
/* filter out all ANSI sequences */
|
||||
int c;
|
||||
while ((c = *s++) != 0)
|
||||
{
|
||||
if (c == '\033' && *s == ']')
|
||||
{
|
||||
while ((c = *s++) != 0) {
|
||||
if (c == '\033' && *s == ']') {
|
||||
while (*s && *s != 'm')
|
||||
s++;
|
||||
}
|
||||
else
|
||||
fputc(c,f);
|
||||
} else
|
||||
fputc(c, f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
static bool intro(FILE *f) {
|
||||
UNUSED(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
console_t console_file =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
print0,
|
||||
intro
|
||||
};
|
||||
console_t console_file = {init, set_fg, print0, intro};
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
FILE *con_term = nullptr;
|
||||
|
@ -36,19 +35,17 @@ FILE *con_term = nullptr;
|
|||
//
|
||||
**************************************************************************/
|
||||
|
||||
static console_t * const me = &console_init;
|
||||
console_t * con = &console_init;
|
||||
static console_t *const me = &console_init;
|
||||
console_t *con = &console_init;
|
||||
|
||||
int con_mode = CON_INIT;
|
||||
|
||||
|
||||
static void try_init(console_t *c, FILE *f)
|
||||
{
|
||||
static void try_init(console_t *c, FILE *f) {
|
||||
int k;
|
||||
|
||||
assert(c);
|
||||
assert(c->init);
|
||||
k = c->init(f,opt->console,con_mode);
|
||||
k = c->init(f, opt->console, con_mode);
|
||||
if (k == CON_INIT)
|
||||
return;
|
||||
#if 0
|
||||
|
@ -56,8 +53,7 @@ static void try_init(console_t *c, FILE *f)
|
|||
if (k != opt->console)
|
||||
return;
|
||||
#endif
|
||||
if (k > con_mode)
|
||||
{
|
||||
if (k > con_mode) {
|
||||
con_mode = k;
|
||||
con = c;
|
||||
con->init = nullptr;
|
||||
|
@ -70,41 +66,37 @@ static void try_init(console_t *c, FILE *f)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int do_init(FILE *f)
|
||||
{
|
||||
static int do_init(FILE *f) {
|
||||
assert(con_mode == CON_INIT);
|
||||
|
||||
try_init(&console_none,f);
|
||||
try_init(&console_none, f);
|
||||
assert(con != me);
|
||||
assert(con == &console_none);
|
||||
if (opt->console == CON_NONE || opt->to_stdout)
|
||||
return con_mode;
|
||||
try_init(&console_file,f);
|
||||
try_init(&console_file, f);
|
||||
if (!acc_isatty(STDIN_FILENO) || !acc_isatty(STDOUT_FILENO) || !acc_isatty(STDERR_FILENO))
|
||||
return con_mode;
|
||||
|
||||
#if (USE_ANSI)
|
||||
try_init(&console_ansi_mono,f);
|
||||
try_init(&console_ansi_color,f);
|
||||
try_init(&console_ansi_mono, f);
|
||||
try_init(&console_ansi_color, f);
|
||||
#endif
|
||||
#if (USE_SCREEN)
|
||||
try_init(&console_screen,f);
|
||||
try_init(&console_screen, f);
|
||||
#endif
|
||||
#if (USE_AALIB)
|
||||
try_init(&console_aalib,f);
|
||||
try_init(&console_aalib, f);
|
||||
#endif
|
||||
|
||||
return con_mode;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int init(FILE *f, int o, int now)
|
||||
{
|
||||
static int init(FILE *f, int o, int now) {
|
||||
if (con != me)
|
||||
return con_mode;
|
||||
assert(o == -1);
|
||||
|
@ -114,47 +106,34 @@ static int init(FILE *f, int o, int now)
|
|||
return do_init(f);
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
if (con == me)
|
||||
init(f,-1,-1);
|
||||
init(f, -1, -1);
|
||||
assert(con != me);
|
||||
return con->set_fg(f,fg);
|
||||
return con->set_fg(f, fg);
|
||||
}
|
||||
|
||||
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
static bool intro(FILE *f) {
|
||||
if (con == me)
|
||||
init(f,-1,-1);
|
||||
init(f, -1, -1);
|
||||
assert(con != me);
|
||||
return con->intro(f);
|
||||
}
|
||||
|
||||
console_t console_init = {init, set_fg, nullptr, intro};
|
||||
|
||||
console_t console_init =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
nullptr,
|
||||
intro
|
||||
};
|
||||
|
||||
|
||||
void con_fprintf(FILE *f, const char *format, ...)
|
||||
{
|
||||
void con_fprintf(FILE *f, const char *format, ...) {
|
||||
va_list args;
|
||||
char buf[80*25];
|
||||
char buf[80 * 25];
|
||||
|
||||
va_start(args, format);
|
||||
upx_safe_vsnprintf(buf, sizeof(buf), format,args);
|
||||
upx_safe_vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
|
||||
if (con == me)
|
||||
init(f,-1,-1);
|
||||
init(f, -1, -1);
|
||||
assert(con != me);
|
||||
con->print0(f,buf);
|
||||
con->print0(f, buf);
|
||||
}
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#if (USE_CONSOLE)
|
||||
|
@ -34,44 +33,30 @@
|
|||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int init(FILE *f, int o, int now)
|
||||
{
|
||||
static int init(FILE *f, int o, int now) {
|
||||
UNUSED(f);
|
||||
UNUSED(o);
|
||||
UNUSED(now);
|
||||
return CON_NONE;
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
UNUSED(f);
|
||||
UNUSED(fg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void print0(FILE *f, const char *s)
|
||||
{
|
||||
static void print0(FILE *f, const char *s) {
|
||||
UNUSED(f);
|
||||
UNUSED(s);
|
||||
}
|
||||
|
||||
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
static bool intro(FILE *f) {
|
||||
UNUSED(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
console_t console_none =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
print0,
|
||||
intro
|
||||
};
|
||||
console_t console_none = {init, set_fg, print0, intro};
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
||||
|
|
143
src/c_screen.cpp
143
src/c_screen.cpp
|
@ -25,7 +25,6 @@
|
|||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#if (USE_SCREEN)
|
||||
|
@ -35,16 +34,14 @@
|
|||
#define mask_fg 0x0f
|
||||
#define mask_bg 0xf0
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int do_init(screen_t *s, int fd)
|
||||
{
|
||||
static int do_init(screen_t *s, int fd) {
|
||||
int fg, bg;
|
||||
|
||||
if (s->init(s,fd) != 0)
|
||||
if (s->init(s, fd) != 0)
|
||||
return -1;
|
||||
|
||||
if (s->getCols(s) < 80 || s->getCols(s) > 256)
|
||||
|
@ -59,39 +56,32 @@ static int do_init(screen_t *s, int fd)
|
|||
if (fg == (bg >> 4))
|
||||
return -1;
|
||||
if (bg != BG_BLACK)
|
||||
if (!s->isMono(s))
|
||||
{
|
||||
/* return 0; */ /* we could emulate ANSI mono */
|
||||
if (!s->isMono(s)) {
|
||||
/* return 0; */ /* we could emulate ANSI mono */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static screen_t *do_construct(screen_t *s, int fd)
|
||||
{
|
||||
static screen_t *do_construct(screen_t *s, int fd) {
|
||||
if (!s)
|
||||
return nullptr;
|
||||
if (do_init(s,fd) != 0)
|
||||
{
|
||||
if (do_init(s, fd) != 0) {
|
||||
s->destroy(s);
|
||||
return nullptr;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static screen_t *screen = nullptr;
|
||||
|
||||
static void __acc_cdecl_atexit do_destroy(void)
|
||||
{
|
||||
if (screen)
|
||||
{
|
||||
static void __acc_cdecl_atexit do_destroy(void) {
|
||||
if (screen) {
|
||||
if (screen->atExit)
|
||||
screen->atExit();
|
||||
screen->destroy(screen);
|
||||
|
@ -99,16 +89,13 @@ static void __acc_cdecl_atexit do_destroy(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int mode = -1;
|
||||
static int init_fg = -1;
|
||||
static int init_bg = -1;
|
||||
static int cur_fg = -1;
|
||||
static int cur_bg = -1;
|
||||
|
||||
|
||||
static int init(FILE *f, int o, int now)
|
||||
{
|
||||
static int init(FILE *f, int o, int now) {
|
||||
int fd = fileno(f);
|
||||
int n;
|
||||
|
||||
|
@ -117,30 +104,30 @@ static int init(FILE *f, int o, int now)
|
|||
|
||||
if (o == CON_SCREEN)
|
||||
n = CON_SCREEN;
|
||||
else if (o == CON_INIT) /* use by default */
|
||||
else if (o == CON_INIT) /* use by default */
|
||||
n = CON_SCREEN;
|
||||
else if (o == CON_ANSI_COLOR) /* can emulate ANSI color */
|
||||
else if (o == CON_ANSI_COLOR) /* can emulate ANSI color */
|
||||
n = CON_ANSI_COLOR;
|
||||
else if (o == CON_ANSI_MONO) /* can emulate ANSI mono */
|
||||
else if (o == CON_ANSI_MONO) /* can emulate ANSI mono */
|
||||
n = CON_ANSI_MONO;
|
||||
else
|
||||
return CON_INIT;
|
||||
|
||||
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_djgpp2_construct(),fd);
|
||||
screen = do_construct(screen_djgpp2_construct(), fd);
|
||||
#endif
|
||||
#if (USE_SCREEN_WIN32)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_win32_construct(),fd);
|
||||
screen = do_construct(screen_win32_construct(), fd);
|
||||
#endif
|
||||
#if (USE_SCREEN_VCSA)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_vcsa_construct(),fd);
|
||||
screen = do_construct(screen_vcsa_construct(), fd);
|
||||
#endif
|
||||
#if (USE_SCREEN_CURSES)
|
||||
if (!screen && o == CON_SCREEN)
|
||||
screen = do_construct(screen_curses_construct(),fd);
|
||||
screen = do_construct(screen_curses_construct(), fd);
|
||||
#endif
|
||||
if (!screen)
|
||||
return CON_INIT;
|
||||
|
@ -155,19 +142,16 @@ static int init(FILE *f, int o, int now)
|
|||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
const int last_fg = cur_fg;
|
||||
int f1 = fg & mask_fg;
|
||||
int f2 = init_fg & mask_fg;
|
||||
|
||||
UNUSED(f);
|
||||
cur_fg = fg;
|
||||
if (screen->isMono(screen))
|
||||
{
|
||||
if (screen->isMono(screen)) {
|
||||
const int b = (init_bg & mask_bg) >> 4;
|
||||
if (fg == -1) /* restore startup fg */
|
||||
if (fg == -1) /* restore startup fg */
|
||||
f1 = f2;
|
||||
else if (b == 0)
|
||||
f1 = (f2 <= 8) ? 15 : 8;
|
||||
|
@ -175,19 +159,15 @@ static int set_fg(FILE *f, int fg)
|
|||
f1 = (f2 == 0) ? 15 : 0;
|
||||
else
|
||||
f1 = (f2 == 0) ? 8 : 0;
|
||||
}
|
||||
else if (con_mode == CON_ANSI_MONO && f1 != f2)
|
||||
{
|
||||
} else if (con_mode == CON_ANSI_MONO && f1 != f2) {
|
||||
f1 = f2 ^ 0x08;
|
||||
}
|
||||
|
||||
screen->setFg(screen,f1 & mask_fg);
|
||||
screen->setFg(screen, f1 & mask_fg);
|
||||
return last_fg;
|
||||
}
|
||||
|
||||
|
||||
static void print0(FILE *f, const char *ss)
|
||||
{
|
||||
static void print0(FILE *f, const char *ss) {
|
||||
int cx, cy;
|
||||
int old_cx = 0, old_cy = 0;
|
||||
const int sx = screen->getCols(screen);
|
||||
|
@ -199,57 +179,47 @@ static void print0(FILE *f, const char *ss)
|
|||
// scrollUp() under Win32 is *extremely* slow.
|
||||
UNUSED(f);
|
||||
|
||||
screen->getCursor(screen,&old_cx,&old_cy);
|
||||
cx = old_cx; cy = old_cy;
|
||||
screen->getCursor(screen, &old_cx, &old_cy);
|
||||
cx = old_cx;
|
||||
cy = old_cy;
|
||||
|
||||
for (pass = 0; pass < 2; pass++)
|
||||
{
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
const char *s = ss;
|
||||
// char buffer for pass 2
|
||||
char p[256+1];
|
||||
char p[256 + 1];
|
||||
int pi = 0, px = 0, py = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
// walk over whitespace
|
||||
for (;;)
|
||||
{
|
||||
if (*s == '\n')
|
||||
{
|
||||
for (;;) {
|
||||
if (*s == '\n') {
|
||||
cx = 0;
|
||||
cy++;
|
||||
}
|
||||
else if (*s == '\r')
|
||||
{
|
||||
} else if (*s == '\r') {
|
||||
cx = 0;
|
||||
if (pass > 0 && cy < sy)
|
||||
screen->clearLine(screen,cy);
|
||||
}
|
||||
else
|
||||
screen->clearLine(screen, cy);
|
||||
} else
|
||||
break;
|
||||
s++;
|
||||
}
|
||||
// adjust cursor
|
||||
if (cx >= sx)
|
||||
{
|
||||
if (cx >= sx) {
|
||||
cx = 0;
|
||||
cy++;
|
||||
}
|
||||
if (pass > 0)
|
||||
{
|
||||
if (pass > 0) {
|
||||
// check if we should print something
|
||||
if (pi > 0 && (*s == 0 || py != cy))
|
||||
{
|
||||
if (pi > 0 && (*s == 0 || py != cy)) {
|
||||
p[pi] = 0;
|
||||
screen->putString(screen,p,px,py);
|
||||
screen->putString(screen, p, px, py);
|
||||
pi = 0;
|
||||
}
|
||||
// check if we should scroll even more (this can happen
|
||||
// if the string is longer than sy lines)
|
||||
if (cy >= sy)
|
||||
{
|
||||
if (cy >= sy) {
|
||||
int scroll_y = cy - sy + 1;
|
||||
screen->scrollUp(screen,scroll_y);
|
||||
screen->scrollUp(screen, scroll_y);
|
||||
cy -= scroll_y;
|
||||
if (cy < 0)
|
||||
cy = 0;
|
||||
|
@ -258,11 +228,9 @@ static void print0(FILE *f, const char *ss)
|
|||
// done ?
|
||||
if (*s == 0)
|
||||
break;
|
||||
if (pass > 0)
|
||||
{
|
||||
if (pass > 0) {
|
||||
// store current char
|
||||
if (pi == 0)
|
||||
{
|
||||
if (pi == 0) {
|
||||
px = cx;
|
||||
py = cy;
|
||||
}
|
||||
|
@ -273,47 +241,34 @@ static void print0(FILE *f, const char *ss)
|
|||
s++;
|
||||
}
|
||||
|
||||
if (pass == 0)
|
||||
{
|
||||
if (pass == 0) {
|
||||
// end of pass 1 - scroll up, restore cursor
|
||||
if (cy >= sy)
|
||||
{
|
||||
if (cy >= sy) {
|
||||
int scroll_y = cy - sy + 1;
|
||||
screen->scrollUp(screen,scroll_y);
|
||||
screen->scrollUp(screen, scroll_y);
|
||||
cy = old_cy - scroll_y;
|
||||
if (cy < 0)
|
||||
cy = 0;
|
||||
}
|
||||
else
|
||||
} else
|
||||
cy = old_cy;
|
||||
cx = old_cx;
|
||||
}
|
||||
}
|
||||
|
||||
screen->setCursor(screen,cx,cy);
|
||||
screen->setCursor(screen, cx, cy);
|
||||
screen->refresh(screen);
|
||||
}
|
||||
|
||||
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
static bool intro(FILE *f) {
|
||||
UNUSED(f);
|
||||
#if (USE_FRAMES)
|
||||
if (screen->intro)
|
||||
return screen->intro(screen,screen_show_frames);
|
||||
return screen->intro(screen, screen_show_frames);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
console_t console_screen =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
print0,
|
||||
intro
|
||||
};
|
||||
|
||||
console_t console_screen = {init, set_fg, print0, intro};
|
||||
|
||||
#endif /* USE_SCREEN */
|
||||
|
||||
|
|
327
src/lefile.cpp
327
src/lefile.cpp
|
@ -25,285 +25,226 @@
|
|||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "util/membuffer.h"
|
||||
#include "lefile.h"
|
||||
|
||||
|
||||
LeFile::LeFile(InputFile *f) :
|
||||
fif(f), fof(nullptr),
|
||||
le_offset(0), exe_offset(0)
|
||||
{
|
||||
LeFile::LeFile(InputFile *f) : fif(f), fof(nullptr), le_offset(0), exe_offset(0) {
|
||||
COMPILE_TIME_ASSERT(sizeof(le_header_t) == 196)
|
||||
COMPILE_TIME_ASSERT(sizeof(le_object_table_entry_t) == 24)
|
||||
COMPILE_TIME_ASSERT(sizeof(le_pagemap_entry_t) == 4)
|
||||
memset(&ih,0,sizeof ih);
|
||||
memset(&oh,0,sizeof oh);
|
||||
iobject_table = oobject_table = nullptr;
|
||||
ifpage_table = ofpage_table = nullptr;
|
||||
ipm_entries = opm_entries = nullptr;
|
||||
ires_names = ores_names = nullptr;
|
||||
ifixups = ofixups = nullptr;
|
||||
inonres_names = ononres_names = nullptr;
|
||||
ientries = oentries = nullptr;
|
||||
memset(&ih, 0, sizeof ih);
|
||||
memset(&oh, 0, sizeof oh);
|
||||
}
|
||||
|
||||
|
||||
LeFile::~LeFile()
|
||||
{
|
||||
delete [] iobject_table;
|
||||
delete [] oobject_table;
|
||||
delete [] ifpage_table;
|
||||
delete [] ofpage_table;
|
||||
delete [] ipm_entries;
|
||||
delete [] opm_entries;
|
||||
delete [] ires_names;
|
||||
delete [] ores_names;
|
||||
delete [] ifixups;
|
||||
delete [] ofixups;
|
||||
delete [] inonres_names;
|
||||
delete [] ononres_names;
|
||||
delete [] ientries;
|
||||
delete [] oentries;
|
||||
LeFile::~LeFile() {
|
||||
delete[] iobject_table;
|
||||
delete[] oobject_table;
|
||||
delete[] ifpage_table;
|
||||
delete[] ofpage_table;
|
||||
delete[] ipm_entries;
|
||||
delete[] opm_entries;
|
||||
delete[] ires_names;
|
||||
delete[] ores_names;
|
||||
delete[] ifixups;
|
||||
delete[] ofixups;
|
||||
delete[] inonres_names;
|
||||
delete[] ononres_names;
|
||||
delete[] ientries;
|
||||
delete[] oentries;
|
||||
}
|
||||
|
||||
|
||||
#define objects ih.object_table_entries
|
||||
#define pages ih.memory_pages
|
||||
#define mps ih.memory_page_size
|
||||
#define pages ih.memory_pages
|
||||
#define mps ih.memory_page_size
|
||||
|
||||
|
||||
void LeFile::readObjectTable()
|
||||
{
|
||||
void LeFile::readObjectTable() {
|
||||
soobject_table = objects;
|
||||
iobject_table = New(le_object_table_entry_t, soobject_table);
|
||||
fif->seek(le_offset + ih.object_table_offset,SEEK_SET);
|
||||
fif->readx(iobject_table,sizeof(*iobject_table)*objects);
|
||||
fif->seek(le_offset + ih.object_table_offset, SEEK_SET);
|
||||
fif->readx(iobject_table, sizeof(*iobject_table) * objects);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeObjectTable()
|
||||
{
|
||||
void LeFile::writeObjectTable() {
|
||||
if (fof && oobject_table)
|
||||
fof->write(oobject_table,sizeof(*iobject_table)*soobject_table);
|
||||
fof->write(oobject_table, sizeof(*iobject_table) * soobject_table);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::readPageMap()
|
||||
{
|
||||
void LeFile::readPageMap() {
|
||||
sopm_entries = pages;
|
||||
ipm_entries = New(le_pagemap_entry_t, sopm_entries);
|
||||
fif->seek(le_offset + ih.object_pagemap_offset,SEEK_SET);
|
||||
fif->readx(ipm_entries,sizeof(*ipm_entries)*pages);
|
||||
fif->seek(le_offset + ih.object_pagemap_offset, SEEK_SET);
|
||||
fif->readx(ipm_entries, sizeof(*ipm_entries) * pages);
|
||||
|
||||
for (unsigned ic = 0; ic < pages; ic++)
|
||||
if ((ipm_entries[ic].type & 0xC0) != 0 && (ipm_entries[ic].type & 0xC0) != 0xC0)
|
||||
throwCantPack("unexpected value in page map table");
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writePageMap()
|
||||
{
|
||||
void LeFile::writePageMap() {
|
||||
if (fof && opm_entries)
|
||||
fof->write(opm_entries,sizeof(*ipm_entries)*sopm_entries);
|
||||
fof->write(opm_entries, sizeof(*ipm_entries) * sopm_entries);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::readResidentNames()
|
||||
{
|
||||
void LeFile::readResidentNames() {
|
||||
sores_names = ih.entry_table_offset - ih.resident_names_offset;
|
||||
ires_names = New(upx_byte, sores_names);
|
||||
fif->seek(le_offset+ih.resident_names_offset,SEEK_SET);
|
||||
fif->readx(ires_names,sores_names);
|
||||
fif->seek(le_offset + ih.resident_names_offset, SEEK_SET);
|
||||
fif->readx(ires_names, sores_names);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeResidentNames()
|
||||
{
|
||||
void LeFile::writeResidentNames() {
|
||||
if (fof && ores_names)
|
||||
fof->write(ores_names,sores_names);
|
||||
fof->write(ores_names, sores_names);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::readEntryTable()
|
||||
{
|
||||
void LeFile::readEntryTable() {
|
||||
soentries = ih.fixup_page_table_offset - ih.entry_table_offset;
|
||||
fif->seek(le_offset + ih.entry_table_offset,SEEK_SET);
|
||||
fif->seek(le_offset + ih.entry_table_offset, SEEK_SET);
|
||||
ientries = New(upx_byte, soentries);
|
||||
fif->readx(ientries,soentries);
|
||||
fif->readx(ientries, soentries);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeEntryTable()
|
||||
{
|
||||
void LeFile::writeEntryTable() {
|
||||
if (fof && oentries)
|
||||
fof->write(oentries,soentries);
|
||||
fof->write(oentries, soentries);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::readFixupPageTable()
|
||||
{
|
||||
sofpage_table = 1+pages;
|
||||
void LeFile::readFixupPageTable() {
|
||||
sofpage_table = 1 + pages;
|
||||
ifpage_table = New(unsigned, sofpage_table);
|
||||
fif->seek(le_offset + ih.fixup_page_table_offset,SEEK_SET);
|
||||
fif->readx(ifpage_table,4*sofpage_table);
|
||||
fif->seek(le_offset + ih.fixup_page_table_offset, SEEK_SET);
|
||||
fif->readx(ifpage_table, 4 * sofpage_table);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeFixupPageTable()
|
||||
{
|
||||
void LeFile::writeFixupPageTable() {
|
||||
if (fof && ofpage_table)
|
||||
fof->write(ofpage_table,4*sofpage_table);
|
||||
fof->write(ofpage_table, 4 * sofpage_table);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::readFixups()
|
||||
{
|
||||
sofixups = get_le32(ifpage_table+pages)-get_le32(ifpage_table);
|
||||
void LeFile::readFixups() {
|
||||
sofixups = get_le32(ifpage_table + pages) - get_le32(ifpage_table);
|
||||
ifixups = New(upx_byte, sofixups);
|
||||
fif->seek(le_offset + ih.fixup_record_table_offset,SEEK_SET);
|
||||
fif->readx(ifixups,sofixups);
|
||||
fif->seek(le_offset + ih.fixup_record_table_offset, SEEK_SET);
|
||||
fif->readx(ifixups, sofixups);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeFixups()
|
||||
{
|
||||
void LeFile::writeFixups() {
|
||||
if (fof && ofixups)
|
||||
fof->write(ofixups,sofixups);
|
||||
fof->write(ofixups, sofixups);
|
||||
}
|
||||
|
||||
|
||||
unsigned LeFile::getImageSize() const
|
||||
{
|
||||
unsigned LeFile::getImageSize() const {
|
||||
unsigned n = 0;
|
||||
if (ih.memory_pages > 0)
|
||||
{
|
||||
if (ih.memory_pages > 0) {
|
||||
n = (ih.memory_pages - 1) * ih.memory_page_size;
|
||||
n += ih.bytes_on_last_page;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void LeFile::readImage()
|
||||
{
|
||||
soimage = pages*mps;
|
||||
void LeFile::readImage() {
|
||||
soimage = pages * mps;
|
||||
mb_iimage.alloc(soimage);
|
||||
mb_iimage.clear();
|
||||
iimage = mb_iimage;
|
||||
|
||||
unsigned ic,jc;
|
||||
for (ic = jc = 0; ic < pages; ic++)
|
||||
{
|
||||
if ((ipm_entries[ic].type & 0xC0) == 0)
|
||||
{
|
||||
unsigned ic, jc;
|
||||
for (ic = jc = 0; ic < pages; ic++) {
|
||||
if ((ipm_entries[ic].type & 0xC0) == 0) {
|
||||
fif->seek(ih.data_pages_offset + exe_offset +
|
||||
(ipm_entries[ic].m*0x100 + ipm_entries[ic].l-1) * mps,SEEK_SET);
|
||||
auto bytes = ic != pages-1 ? mps : ih.bytes_on_last_page;
|
||||
fif->readx(raw_bytes(iimage+jc, bytes), bytes);
|
||||
(ipm_entries[ic].m * 0x100 + ipm_entries[ic].l - 1) * mps,
|
||||
SEEK_SET);
|
||||
auto bytes = ic != pages - 1 ? mps : ih.bytes_on_last_page;
|
||||
fif->readx(raw_bytes(iimage + jc, bytes), bytes);
|
||||
}
|
||||
jc += mps;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeImage()
|
||||
{
|
||||
void LeFile::writeImage() {
|
||||
if (fof && oimage != nullptr)
|
||||
fof->write(raw_bytes(oimage, soimage), soimage);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::readNonResidentNames()
|
||||
{
|
||||
if (ih.non_resident_name_table_length)
|
||||
{
|
||||
void LeFile::readNonResidentNames() {
|
||||
if (ih.non_resident_name_table_length) {
|
||||
sononres_names = ih.non_resident_name_table_length;
|
||||
inonres_names = New(upx_byte, sononres_names);
|
||||
fif->seek(exe_offset+ih.non_resident_name_table_offset,SEEK_SET);
|
||||
fif->readx(inonres_names,sononres_names);
|
||||
fif->seek(exe_offset + ih.non_resident_name_table_offset, SEEK_SET);
|
||||
fif->readx(inonres_names, sononres_names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeNonResidentNames()
|
||||
{
|
||||
void LeFile::writeNonResidentNames() {
|
||||
if (fof && ononres_names)
|
||||
fof->write(ononres_names,sononres_names);
|
||||
fof->write(ononres_names, sononres_names);
|
||||
}
|
||||
|
||||
|
||||
bool LeFile::readFileHeader()
|
||||
{
|
||||
#define H(x) get_le16(header+2*(x))
|
||||
bool LeFile::readFileHeader() {
|
||||
#define H(x) get_le16(header + 2 * (x))
|
||||
upx_byte header[0x40];
|
||||
le_offset = exe_offset = 0;
|
||||
int ic;
|
||||
|
||||
for (ic = 0; ic < 20; ic++)
|
||||
{
|
||||
fif->seek(le_offset,SEEK_SET);
|
||||
fif->readx(header,sizeof(header));
|
||||
for (ic = 0; ic < 20; ic++) {
|
||||
fif->seek(le_offset, SEEK_SET);
|
||||
fif->readx(header, sizeof(header));
|
||||
|
||||
if (memcmp(header,"MZ",2) == 0) // normal dos exe
|
||||
if (memcmp(header, "MZ", 2) == 0) // normal dos exe
|
||||
{
|
||||
exe_offset = le_offset;
|
||||
if (H(0x18/2) >= 0x40
|
||||
&& memcmp(header+0x19,"TIPPACH",7)) // new format exe
|
||||
le_offset += H(0x3c/2)+H(0x3e/2)*65536;
|
||||
else
|
||||
{
|
||||
le_offset += H(2)*512+H(1);
|
||||
if (H(0x18 / 2) >= 0x40 && memcmp(header + 0x19, "TIPPACH", 7)) // new format exe
|
||||
le_offset += H(0x3c / 2) + H(0x3e / 2) * 65536;
|
||||
else {
|
||||
le_offset += H(2) * 512 + H(1);
|
||||
if (H(1))
|
||||
le_offset -= 512;
|
||||
else if (H(2) == 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (memcmp(header,"BW",2) == 0) // used in dos4gw.exe
|
||||
le_offset += H(2)*512+H(1);
|
||||
else if (memcmp(header,"LE",2) == 0)
|
||||
} else if (memcmp(header, "BW", 2) == 0) // used in dos4gw.exe
|
||||
le_offset += H(2) * 512 + H(1);
|
||||
else if (memcmp(header, "LE", 2) == 0)
|
||||
break;
|
||||
else if (memcmp(header,"PMW1",4) == 0)
|
||||
else if (memcmp(header, "PMW1", 4) == 0)
|
||||
throwCantPack("already packed with PMWLITE");
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if (ic == 20)
|
||||
return false;
|
||||
fif->seek(le_offset,SEEK_SET);
|
||||
fif->readx(&ih,sizeof(ih));
|
||||
fif->seek(le_offset, SEEK_SET);
|
||||
fif->readx(&ih, sizeof(ih));
|
||||
return true;
|
||||
#undef H
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeFile(OutputFile *f, bool le)
|
||||
{
|
||||
void LeFile::writeFile(OutputFile *f, bool le) {
|
||||
fof = f;
|
||||
memcpy (&oh,&ih,(char*)&oh.memory_pages-(char*)&oh); // copy some members of the orig. header
|
||||
memcpy(&oh, &ih,
|
||||
(char *) &oh.memory_pages - (char *) &oh); // copy some members of the orig. header
|
||||
oh.memory_page_size = mps;
|
||||
oh.object_table_offset = sizeof(oh);
|
||||
oh.object_table_entries = soobject_table;
|
||||
oh.object_pagemap_offset = oh.object_table_offset + soobject_table*sizeof(*iobject_table);
|
||||
oh.resident_names_offset = oh.object_pagemap_offset + sopm_entries*sizeof(*ipm_entries);
|
||||
oh.object_pagemap_offset = oh.object_table_offset + soobject_table * sizeof(*iobject_table);
|
||||
oh.resident_names_offset = oh.object_pagemap_offset + sopm_entries * sizeof(*ipm_entries);
|
||||
oh.entry_table_offset = oh.resident_names_offset + sores_names;
|
||||
oh.fixup_page_table_offset = oh.entry_table_offset + soentries;
|
||||
oh.fixup_record_table_offset = oh.fixup_page_table_offset + sofpage_table*4;
|
||||
oh.fixup_record_table_offset = oh.fixup_page_table_offset + sofpage_table * 4;
|
||||
oh.imported_modules_name_table_offset = oh.fixup_record_table_offset + sofixups - FIXUP_EXTRA;
|
||||
oh.imported_procedures_name_table_offset = oh.imported_modules_name_table_offset;
|
||||
oh.data_pages_offset = oh.fixup_record_table_offset + sofixups + (le ? 0 : le_offset-exe_offset);
|
||||
if (ih.non_resident_name_table_length)
|
||||
{
|
||||
oh.data_pages_offset =
|
||||
oh.fixup_record_table_offset + sofixups + (le ? 0 : le_offset - exe_offset);
|
||||
if (ih.non_resident_name_table_length) {
|
||||
oh.non_resident_name_table_offset = oh.data_pages_offset + soimage;
|
||||
oh.non_resident_name_table_length = sononres_names;
|
||||
}
|
||||
oh.fixup_size = sofixups + 4*sofpage_table;
|
||||
oh.fixup_size = sofixups + 4 * sofpage_table;
|
||||
oh.loader_size = oh.fixup_size + oh.fixup_page_table_offset - sizeof(oh);
|
||||
|
||||
fof->write(&oh,sizeof(oh));
|
||||
fof->write(&oh, sizeof(oh));
|
||||
writeObjectTable();
|
||||
writePageMap();
|
||||
writeResidentNames();
|
||||
|
@ -314,57 +255,53 @@ void LeFile::writeFile(OutputFile *f, bool le)
|
|||
writeNonResidentNames();
|
||||
}
|
||||
|
||||
|
||||
void LeFile::countFixups(unsigned *counts) const
|
||||
{
|
||||
void LeFile::countFixups(unsigned *counts) const {
|
||||
const unsigned o = objects;
|
||||
memset(counts,0,sizeof(unsigned)*(o+2));
|
||||
memset(counts, 0, sizeof(unsigned) * (o + 2));
|
||||
// counts[0..objects-1] - # of 32-bit offset relocations in for that objects
|
||||
// counts[objects] - # of selector fixups
|
||||
// counts[objects+1] - # of self-relative fixups
|
||||
|
||||
const upx_byte *fix = ifixups;
|
||||
const unsigned sfixups = get_le32(ifpage_table+pages);
|
||||
const unsigned sfixups = get_le32(ifpage_table + pages);
|
||||
unsigned ll;
|
||||
|
||||
while ((unsigned)(fix - ifixups) < sfixups)
|
||||
{
|
||||
while (ptr_udiff_bytes(fix, ifixups) < sfixups) {
|
||||
if ((fix[1] & ~0x10) != 0)
|
||||
throwCantPack("unsupported fixup record");
|
||||
switch (*fix)
|
||||
{
|
||||
case 2: // selector fixup
|
||||
counts[o] += 9;
|
||||
fix += 5;
|
||||
break;
|
||||
case 0x12: // alias selector
|
||||
throwCantPack("16-bit selector alias fixup not yet supported");
|
||||
case 5: // 16-bit offset
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
case 6: // 16:32 pointer
|
||||
counts[o] += 9;
|
||||
// fall through
|
||||
case 7: // 32-bit offset
|
||||
counts[fix[4]-1] += 4;
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
case 0x27: // 32-bit offset list
|
||||
ll = fix[2];
|
||||
counts[fix[3]-1] += ll*4;
|
||||
fix += (fix[1] & 0x10) ? 6 : 4;
|
||||
fix += ll*2;
|
||||
break;
|
||||
case 8: // 32-bit self relative fixup
|
||||
counts[o+1] += 4;
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
default:
|
||||
throwCantPack("unsupported fixup record");
|
||||
switch (*fix) {
|
||||
case 2: // selector fixup
|
||||
counts[o] += 9;
|
||||
fix += 5;
|
||||
break;
|
||||
case 0x12: // alias selector
|
||||
throwCantPack("16-bit selector alias fixup not yet supported");
|
||||
case 5: // 16-bit offset
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
case 6: // 16:32 pointer
|
||||
counts[o] += 9;
|
||||
// fall through
|
||||
case 7: // 32-bit offset
|
||||
counts[fix[4] - 1] += 4;
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
case 0x27: // 32-bit offset list
|
||||
ll = fix[2];
|
||||
counts[fix[3] - 1] += ll * 4;
|
||||
fix += (fix[1] & 0x10) ? 6 : 4;
|
||||
fix += ll * 2;
|
||||
break;
|
||||
case 8: // 32-bit self relative fixup
|
||||
counts[o + 1] += 4;
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
default:
|
||||
throwCantPack("unsupported fixup record");
|
||||
}
|
||||
}
|
||||
counts[o]++; // extra space for 'ret'
|
||||
counts[o+1] += 4; // extra space for 0xFFFFFFFF
|
||||
counts[o]++; // extra space for 'ret'
|
||||
counts[o + 1] += 4; // extra space for 0xFFFFFFFF
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
|
216
src/lefile.h
216
src/lefile.h
|
@ -25,20 +25,18 @@
|
|||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_LEFILE_H
|
||||
#define __UPX_LEFILE_H 1
|
||||
#pragma once
|
||||
#ifndef UPX_LEFILE_H__
|
||||
#define UPX_LEFILE_H__ 1
|
||||
|
||||
class InputFile;
|
||||
class OutputFile;
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
class LeFile
|
||||
{
|
||||
class LeFile {
|
||||
protected:
|
||||
LeFile(InputFile *);
|
||||
virtual ~LeFile();
|
||||
|
@ -49,161 +47,170 @@ protected:
|
|||
protected:
|
||||
enum { FIXUP_EXTRA = 3 };
|
||||
|
||||
__packed_struct(le_header_t)
|
||||
struct alignas(1) le_header_t {
|
||||
// 0x00
|
||||
char _[2]; // signature: 'LE' || 'LX'
|
||||
char byte_order; // 0 little endian
|
||||
char word_order; // 0 little endian
|
||||
LE32 exe_format_level; // 0
|
||||
LE16 cpu_type; // 1->286..4->586
|
||||
LE16 target_os; // 1->OS2
|
||||
char _0[4]; // module_version = 0
|
||||
char _[2]; // signature: 'LE' || 'LX'
|
||||
char byte_order; // 0 little endian
|
||||
char word_order; // 0 little endian
|
||||
LE32 exe_format_level; // 0
|
||||
LE16 cpu_type; // 1->286..4->586
|
||||
LE16 target_os; // 1->OS2
|
||||
char _0[4]; // module_version = 0
|
||||
// 0x10
|
||||
LE32 module_type; // 0x200->compatible with PM windowing
|
||||
LE32 memory_pages;
|
||||
LE32 init_cs_object;
|
||||
LE32 init_eip_offset;
|
||||
LE32 module_type; // 0x200->compatible with PM windowing
|
||||
LE32 memory_pages;
|
||||
LE32 init_cs_object;
|
||||
LE32 init_eip_offset;
|
||||
// 0x20
|
||||
LE32 init_ss_object;
|
||||
LE32 init_esp_offset;
|
||||
LE32 memory_page_size;
|
||||
LE32 bytes_on_last_page;
|
||||
LE32 init_ss_object;
|
||||
LE32 init_esp_offset;
|
||||
LE32 memory_page_size;
|
||||
LE32 bytes_on_last_page;
|
||||
// 0x30
|
||||
LE32 fixup_size;
|
||||
char _1[4]; // fixup_checksum = 0
|
||||
LE32 loader_size;
|
||||
char _2[4]; // loader_checksum = 0
|
||||
LE32 fixup_size;
|
||||
char _1[4]; // fixup_checksum = 0
|
||||
LE32 loader_size;
|
||||
char _2[4]; // loader_checksum = 0
|
||||
// 0x40
|
||||
LE32 object_table_offset;
|
||||
LE32 object_table_entries;
|
||||
LE32 object_pagemap_offset;
|
||||
LE32 object_iterate_data_map_offset;
|
||||
LE32 object_table_offset;
|
||||
LE32 object_table_entries;
|
||||
LE32 object_pagemap_offset;
|
||||
LE32 object_iterate_data_map_offset;
|
||||
// 0x50
|
||||
char _3[4]; // resource_offset
|
||||
LE32 resource_entries;
|
||||
LE32 resident_names_offset;
|
||||
LE32 entry_table_offset;
|
||||
char _3[4]; // resource_offset
|
||||
LE32 resource_entries;
|
||||
LE32 resident_names_offset;
|
||||
LE32 entry_table_offset;
|
||||
// 0x60
|
||||
char _4[4]; // module_directives_table_offset = 0
|
||||
LE32 module_directives_entries;
|
||||
LE32 fixup_page_table_offset;
|
||||
LE32 fixup_record_table_offset;
|
||||
char _4[4]; // module_directives_table_offset = 0
|
||||
LE32 module_directives_entries;
|
||||
LE32 fixup_page_table_offset;
|
||||
LE32 fixup_record_table_offset;
|
||||
// 0x70
|
||||
LE32 imported_modules_name_table_offset;
|
||||
LE32 imported_modules_count;
|
||||
LE32 imported_procedures_name_table_offset;
|
||||
char _5[4]; // per_page_checksum_table_offset = 0
|
||||
LE32 imported_modules_name_table_offset;
|
||||
LE32 imported_modules_count;
|
||||
LE32 imported_procedures_name_table_offset;
|
||||
char _5[4]; // per_page_checksum_table_offset = 0
|
||||
// 0x80
|
||||
LE32 data_pages_offset;
|
||||
char _6[4]; // preload_page_count = 0
|
||||
LE32 non_resident_name_table_offset;
|
||||
LE32 non_resident_name_table_length;
|
||||
LE32 data_pages_offset;
|
||||
char _6[4]; // preload_page_count = 0
|
||||
LE32 non_resident_name_table_offset;
|
||||
LE32 non_resident_name_table_length;
|
||||
// 0x90
|
||||
char _7[4]; //non_resident_names_checksum
|
||||
LE32 automatic_data_object;
|
||||
char _7[4]; // non_resident_names_checksum
|
||||
LE32 automatic_data_object;
|
||||
#if 1
|
||||
char _8[44];
|
||||
char _8[44];
|
||||
#else
|
||||
LE32 debug_info_offset;
|
||||
LE32 debug_info_length;
|
||||
LE32 debug_info_offset;
|
||||
LE32 debug_info_length;
|
||||
// 0xA0
|
||||
LE32 preload_instance_pages;
|
||||
LE32 demand_instance_pages;
|
||||
LE32 extra_heap_alloc;
|
||||
char reserved[12];
|
||||
LE32 versioninfo;
|
||||
LE32 unknown;
|
||||
LE32 preload_instance_pages;
|
||||
LE32 demand_instance_pages;
|
||||
LE32 extra_heap_alloc;
|
||||
char reserved[12];
|
||||
LE32 versioninfo;
|
||||
LE32 unknown;
|
||||
// 0xC0
|
||||
LE16 device_id;
|
||||
LE16 ddk_version;
|
||||
LE16 device_id;
|
||||
LE16 ddk_version;
|
||||
#endif
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
__packed_struct(le_object_table_entry_t)
|
||||
LE32 virtual_size;
|
||||
LE32 base_address;
|
||||
LE32 flags;
|
||||
LE32 pagemap_index;
|
||||
LE32 npages;
|
||||
LE32 reserved;
|
||||
__packed_struct_end()
|
||||
struct alignas(1) le_object_table_entry_t {
|
||||
LE32 virtual_size;
|
||||
LE32 base_address;
|
||||
LE32 flags;
|
||||
LE32 pagemap_index;
|
||||
LE32 npages;
|
||||
LE32 reserved;
|
||||
};
|
||||
|
||||
__packed_struct(le_pagemap_entry_t)
|
||||
struct alignas(1) le_pagemap_entry_t {
|
||||
unsigned char h;
|
||||
unsigned char m;
|
||||
unsigned char l;
|
||||
unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
|
||||
__packed_struct_end()
|
||||
unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
|
||||
};
|
||||
|
||||
virtual void readObjectTable();
|
||||
virtual void writeObjectTable();
|
||||
//virtual void encodeObjectTable(){oobject_table = iobject_table; iobject_table = nullptr;}
|
||||
//virtual void decodeObjectTable(){encodeObjectTable();}
|
||||
// virtual void encodeObjectTable(){oobject_table = iobject_table; iobject_table = nullptr;}
|
||||
// virtual void decodeObjectTable(){encodeObjectTable();}
|
||||
|
||||
virtual void readFixupPageTable();
|
||||
virtual void writeFixupPageTable();
|
||||
//virtual void encodeFixupPageTable(){ofpage_table = ifpage_table; ifpage_table = nullptr;}
|
||||
//virtual void decodeFixupPageTable(){encodeFixupPageTable();}
|
||||
// virtual void encodeFixupPageTable(){ofpage_table = ifpage_table; ifpage_table = nullptr;}
|
||||
// virtual void decodeFixupPageTable(){encodeFixupPageTable();}
|
||||
|
||||
virtual void readPageMap();
|
||||
virtual void writePageMap();
|
||||
virtual void encodePageMap(){opm_entries = ipm_entries; ipm_entries = nullptr;}
|
||||
virtual void decodePageMap(){encodePageMap();}
|
||||
virtual void encodePageMap() {
|
||||
opm_entries = ipm_entries;
|
||||
ipm_entries = nullptr;
|
||||
}
|
||||
virtual void decodePageMap() { encodePageMap(); }
|
||||
|
||||
virtual void readResidentNames();
|
||||
virtual void writeResidentNames();
|
||||
virtual void encodeResidentNames(){ores_names = ires_names; ires_names = nullptr;}
|
||||
virtual void decodeResidentNames(){encodeResidentNames();}
|
||||
virtual void encodeResidentNames() {
|
||||
ores_names = ires_names;
|
||||
ires_names = nullptr;
|
||||
}
|
||||
virtual void decodeResidentNames() { encodeResidentNames(); }
|
||||
|
||||
virtual void readNonResidentNames();
|
||||
virtual void writeNonResidentNames();
|
||||
virtual void encodeNonResidentNames(){ononres_names = inonres_names; inonres_names = nullptr;}
|
||||
virtual void decodeNonResidentNames(){encodeNonResidentNames();}
|
||||
virtual void encodeNonResidentNames() {
|
||||
ononres_names = inonres_names;
|
||||
inonres_names = nullptr;
|
||||
}
|
||||
virtual void decodeNonResidentNames() { encodeNonResidentNames(); }
|
||||
|
||||
virtual void readEntryTable();
|
||||
virtual void writeEntryTable();
|
||||
//virtual void encodeEntryTable(){oentries = ientries; ientries = nullptr;}
|
||||
//virtual void decodeEntryTable(){encodeEntryTable();}
|
||||
// virtual void encodeEntryTable(){oentries = ientries; ientries = nullptr;}
|
||||
// virtual void decodeEntryTable(){encodeEntryTable();}
|
||||
|
||||
virtual void readFixups();
|
||||
virtual void writeFixups();
|
||||
//virtual void encodeFixups(){ofixups = ifixups; ifixups = nullptr;}
|
||||
//virtual void decodeFixups(){encodeFixups();}
|
||||
// virtual void encodeFixups(){ofixups = ifixups; ifixups = nullptr;}
|
||||
// virtual void decodeFixups(){encodeFixups();}
|
||||
|
||||
virtual void readImage();
|
||||
virtual void writeImage();
|
||||
//virtual void encodeImage(){oimage = iimage; iimage = nullptr;}
|
||||
//virtual void decodeImage(){encodeImage();}
|
||||
// virtual void encodeImage(){oimage = iimage; iimage = nullptr;}
|
||||
// virtual void decodeImage(){encodeImage();}
|
||||
|
||||
void countFixups(unsigned *) const;
|
||||
unsigned getImageSize() const;
|
||||
|
||||
InputFile *fif;
|
||||
OutputFile *fof;
|
||||
InputFile *fif = nullptr;
|
||||
OutputFile *fof = nullptr;
|
||||
unsigned le_offset;
|
||||
unsigned exe_offset;
|
||||
|
||||
le_header_t ih;
|
||||
le_header_t oh;
|
||||
|
||||
le_object_table_entry_t *iobject_table;
|
||||
le_object_table_entry_t *oobject_table;
|
||||
unsigned *ifpage_table;
|
||||
unsigned *ofpage_table;
|
||||
le_pagemap_entry_t *ipm_entries;
|
||||
le_pagemap_entry_t *opm_entries;
|
||||
upx_byte *ires_names;
|
||||
upx_byte *ores_names;
|
||||
upx_byte *ifixups;
|
||||
upx_byte *ofixups;
|
||||
upx_byte *inonres_names;
|
||||
upx_byte *ononres_names;
|
||||
le_object_table_entry_t *iobject_table = nullptr;
|
||||
le_object_table_entry_t *oobject_table = nullptr;
|
||||
unsigned *ifpage_table = nullptr;
|
||||
unsigned *ofpage_table = nullptr;
|
||||
le_pagemap_entry_t *ipm_entries = nullptr;
|
||||
le_pagemap_entry_t *opm_entries = nullptr;
|
||||
upx_byte *ires_names = nullptr;
|
||||
upx_byte *ores_names = nullptr;
|
||||
upx_byte *ifixups = nullptr;
|
||||
upx_byte *ofixups = nullptr;
|
||||
upx_byte *inonres_names = nullptr;
|
||||
upx_byte *ononres_names = nullptr;
|
||||
MemBuffer mb_iimage;
|
||||
SPAN_0(upx_byte) iimage = nullptr;
|
||||
MemBuffer mb_oimage;
|
||||
SPAN_0(upx_byte) oimage = nullptr;
|
||||
upx_byte *ientries;
|
||||
upx_byte *oentries;
|
||||
upx_byte *ientries = nullptr;
|
||||
upx_byte *oentries = nullptr;
|
||||
|
||||
unsigned soobject_table;
|
||||
unsigned sofpage_table;
|
||||
|
@ -217,10 +224,9 @@ protected:
|
|||
private:
|
||||
// disable copy and assignment
|
||||
LeFile(const LeFile &) = delete;
|
||||
LeFile& operator= (const LeFile &) = delete;
|
||||
LeFile &operator=(const LeFile &) = delete;
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
|
128
src/p_armpe.cpp
128
src/p_armpe.cpp
|
@ -25,7 +25,6 @@
|
|||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "filter.h"
|
||||
|
@ -34,55 +33,45 @@
|
|||
#include "p_armpe.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||
#include "stub/arm.v4a-wince.pe.h"
|
||||
static const
|
||||
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||
#include "stub/arm.v4t-wince.pe.h"
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
PackArmPe::PackArmPe(InputFile *f) : super(f)
|
||||
{
|
||||
use_thumb_stub = false;
|
||||
}
|
||||
PackArmPe::PackArmPe(InputFile *f) : super(f) {}
|
||||
|
||||
PackArmPe::~PackArmPe() {}
|
||||
|
||||
PackArmPe::~PackArmPe()
|
||||
{}
|
||||
|
||||
|
||||
const int *PackArmPe::getCompressionMethods(int method, int level) const
|
||||
{
|
||||
static const int m_all[] = { M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END };
|
||||
static const int m_lzma[] = { M_LZMA, M_END };
|
||||
static const int m_nrv2b[] = { M_NRV2B_8, M_END };
|
||||
static const int m_nrv2e[] = { M_NRV2E_8, M_END };
|
||||
const int *PackArmPe::getCompressionMethods(int method, int level) const {
|
||||
static const int m_all[] = {M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END};
|
||||
static const int m_lzma[] = {M_LZMA, M_END};
|
||||
static const int m_nrv2b[] = {M_NRV2B_8, M_END};
|
||||
static const int m_nrv2e[] = {M_NRV2E_8, M_END};
|
||||
|
||||
if (!use_thumb_stub)
|
||||
return getDefaultCompressionMethods_8(method, level);
|
||||
|
||||
if (method == M_ALL) return m_all;
|
||||
if (M_IS_LZMA(method)) return m_lzma;
|
||||
if (M_IS_NRV2B(method)) return m_nrv2b;
|
||||
if (M_IS_NRV2E(method)) return m_nrv2e;
|
||||
if (method == M_ALL)
|
||||
return m_all;
|
||||
if (M_IS_LZMA(method))
|
||||
return m_lzma;
|
||||
if (M_IS_NRV2B(method))
|
||||
return m_nrv2b;
|
||||
if (M_IS_NRV2E(method))
|
||||
return m_nrv2e;
|
||||
return m_nrv2e;
|
||||
}
|
||||
|
||||
|
||||
const int *PackArmPe::getFilters() const
|
||||
{
|
||||
static const int filters[] = { 0x50, FT_END };
|
||||
const int *PackArmPe::getFilters() const {
|
||||
static const int filters[] = {0x50, FT_END};
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
||||
Linker* PackArmPe::newLinker() const
|
||||
{
|
||||
return new ElfLinkerArmLE;
|
||||
}
|
||||
|
||||
Linker *PackArmPe::newLinker() const { return new ElfLinkerArmLE; }
|
||||
|
||||
/*************************************************************************
|
||||
// import handling
|
||||
|
@ -93,17 +82,14 @@ void PackArmPe::processImports2(unsigned myimport, unsigned iat_off) // pass 2
|
|||
PeFile::processImports2(myimport, iat_off);
|
||||
|
||||
// adjust import data
|
||||
for (import_desc *im = (import_desc*) oimpdlls; im->dllname; im++)
|
||||
{
|
||||
for (import_desc *im = (import_desc *) oimpdlls; im->dllname; im++) {
|
||||
im->oft = im->iat;
|
||||
bool is_coredll = strcasecmp(kernelDll(), (char*) oimpdlls +
|
||||
im->dllname - myimport) == 0;
|
||||
bool is_coredll = strcasecmp(kernelDll(), oimpdlls + (im->dllname - myimport)) == 0;
|
||||
im->iat = is_coredll ? iat_off : iat_off + 12;
|
||||
}
|
||||
}
|
||||
|
||||
void PackArmPe::addStubImports()
|
||||
{
|
||||
void PackArmPe::addStubImports() {
|
||||
// the order of procedure names below should match the
|
||||
// assumptions of the assembly stubs
|
||||
// WARNING! these names are sorted alphanumerically by the ImportLinker
|
||||
|
@ -114,20 +100,18 @@ void PackArmPe::addStubImports()
|
|||
|
||||
void PackArmPe::processTls(Interval *) // pass 1
|
||||
{
|
||||
if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS),4u)) == 0)
|
||||
if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS), 4u)) == 0)
|
||||
return;
|
||||
|
||||
// never should happen on wince
|
||||
throwCantPack("Static TLS entries found. Send a report please.");
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// pack
|
||||
**************************************************************************/
|
||||
|
||||
bool PackArmPe::canPack()
|
||||
{
|
||||
bool PackArmPe::canPack() {
|
||||
if (!readFileHeader() || (ih.cpu != 0x1c0 && ih.cpu != 0x1c2))
|
||||
return false;
|
||||
use_thumb_stub |= ih.cpu == 0x1c2 || (ih.entry & 1) == 1;
|
||||
|
@ -135,9 +119,7 @@ bool PackArmPe::canPack()
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PackArmPe::buildLoader(const Filter *ft)
|
||||
{
|
||||
void PackArmPe::buildLoader(const Filter *ft) {
|
||||
const unsigned char *loader = use_thumb_stub ? stub_arm_v4t_wince_pe : stub_arm_v4a_wince_pe;
|
||||
unsigned size = use_thumb_stub ? sizeof(stub_arm_v4t_wince_pe) : sizeof(stub_arm_v4a_wince_pe);
|
||||
|
||||
|
@ -157,7 +139,6 @@ void PackArmPe::buildLoader(const Filter *ft)
|
|||
else if (M_IS_LZMA(ph.method))
|
||||
addLoader("+40C,CallLZMA", nullptr);
|
||||
|
||||
|
||||
if (ft->id == 0x50)
|
||||
addLoader("+40C,Unfilter_0x50", nullptr);
|
||||
|
||||
|
@ -179,48 +160,38 @@ void PackArmPe::buildLoader(const Filter *ft)
|
|||
addLoader("IDENTSTR,UPX1HEAD", nullptr);
|
||||
}
|
||||
|
||||
bool PackArmPe::handleForceOption()
|
||||
{
|
||||
return (ih.cpu != 0x1c0 && ih.cpu != 0x1c2)
|
||||
|| (ih.opthdrsize != 0xe0)
|
||||
|| ((ih.flags & EXECUTABLE) == 0)
|
||||
|| (ih.entry == 0 /*&& !isdll*/)
|
||||
|| (ih.ddirsentries != 16)
|
||||
// || IDSIZE(PEDIR_EXCEPTION) // is this used on arm?
|
||||
// || IDSIZE(PEDIR_COPYRIGHT)
|
||||
;
|
||||
bool PackArmPe::handleForceOption() {
|
||||
return (ih.cpu != 0x1c0 && ih.cpu != 0x1c2) || (ih.opthdrsize != 0xe0) ||
|
||||
((ih.flags & EXECUTABLE) == 0) || (ih.entry == 0 /*&& !isdll*/) ||
|
||||
(ih.ddirsentries != 16);
|
||||
// || IDSIZE(PEDIR_EXCEPTION) // is this used on arm?
|
||||
// || IDSIZE(PEDIR_COPYRIGHT)
|
||||
}
|
||||
|
||||
void PackArmPe::callCompressWithFilters(Filter &ft, int filter_strategy, unsigned ih_codebase)
|
||||
{
|
||||
void PackArmPe::callCompressWithFilters(Filter &ft, int filter_strategy, unsigned ih_codebase) {
|
||||
// limit stack size needed for runtime decompression
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
upx_compress_config_t cconf;
|
||||
cconf.reset();
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||
compressWithFilters(&ft, 2048, &cconf, filter_strategy,
|
||||
ih_codebase, rvamin, 0, nullptr, 0);
|
||||
compressWithFilters(&ft, 2048, &cconf, filter_strategy, ih_codebase, rvamin, 0, nullptr, 0);
|
||||
}
|
||||
|
||||
void PackArmPe::addNewRelocations(Reloc &rel, unsigned upxsection)
|
||||
{
|
||||
static const char* symbols_to_relocate[] = {
|
||||
"ONAM", "BIMP", "BREL", "FIBE", "FIBS", "ENTR", "DST0", "SRC0"
|
||||
};
|
||||
for (unsigned s2r = 0; s2r < TABLESIZE(symbols_to_relocate); s2r++)
|
||||
{
|
||||
void PackArmPe::addNewRelocations(Reloc &rel, unsigned upxsection) {
|
||||
static const char *const symbols_to_relocate[] = {"ONAM", "BIMP", "BREL", "FIBE",
|
||||
"FIBS", "ENTR", "DST0", "SRC0"};
|
||||
for (unsigned s2r = 0; s2r < TABLESIZE(symbols_to_relocate); s2r++) {
|
||||
unsigned off = linker->getSymbolOffset(symbols_to_relocate[s2r]);
|
||||
if (off != 0xdeaddead)
|
||||
rel.add(off + upxsection, 3);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned PackArmPe::getProcessImportParam(unsigned upxsection)
|
||||
{
|
||||
unsigned PackArmPe::getProcessImportParam(unsigned upxsection) {
|
||||
return linker->getSymbolOffset("IATT") + upxsection;
|
||||
}
|
||||
|
||||
void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned,
|
||||
unsigned ic, unsigned s1addr)
|
||||
{
|
||||
void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned, unsigned ic,
|
||||
unsigned s1addr) {
|
||||
const unsigned onam = ncsection + soxrelocs + ih.imagebase;
|
||||
linker->defineSymbol("start_of_dll_names", onam);
|
||||
linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports);
|
||||
|
@ -235,19 +206,14 @@ void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned,
|
|||
defineDecompressorSymbols();
|
||||
}
|
||||
|
||||
void PackArmPe::setOhDataBase(const pe_section_t *osection)
|
||||
{
|
||||
oh.database = osection[2].vaddr;
|
||||
}
|
||||
void PackArmPe::setOhDataBase(const pe_section_t *osection) { oh.database = osection[2].vaddr; }
|
||||
|
||||
void PackArmPe::setOhHeaderSize(const pe_section_t *osection)
|
||||
{
|
||||
void PackArmPe::setOhHeaderSize(const pe_section_t *osection) {
|
||||
oh.headersize = osection[1].rawdataptr;
|
||||
}
|
||||
|
||||
void PackArmPe::pack(OutputFile *fo)
|
||||
{
|
||||
super::pack0(fo, (1u<<IMAGE_SUBSYSTEM_WINDOWS_CE_GUI), 0x10000, true);
|
||||
void PackArmPe::pack(OutputFile *fo) {
|
||||
super::pack0(fo, (1u << IMAGE_SUBSYSTEM_WINDOWS_CE_GUI), 0x10000, true);
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
|
|
@ -25,17 +25,15 @@
|
|||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_ARMPE_H
|
||||
#define __UPX_P_ARMPE_H 1
|
||||
|
||||
#pragma once
|
||||
#ifndef UPX_P_ARMPE_H__
|
||||
#define UPX_P_ARMPE_H__ 1
|
||||
|
||||
/*************************************************************************
|
||||
// arm/pe
|
||||
**************************************************************************/
|
||||
|
||||
class PackArmPe : public PeFile32
|
||||
{
|
||||
class PackArmPe final : public PeFile32 {
|
||||
typedef PeFile32 super;
|
||||
|
||||
public:
|
||||
|
@ -51,9 +49,8 @@ public:
|
|||
virtual bool handleForceOption() override;
|
||||
virtual void callCompressWithFilters(Filter &, int filter_strategy,
|
||||
unsigned ih_codebase) override;
|
||||
virtual void defineSymbols(unsigned ncsection, unsigned upxsection,
|
||||
unsigned sizeof_oh, unsigned isize_isplit,
|
||||
unsigned s1addr) override;
|
||||
virtual void defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh,
|
||||
unsigned isize_isplit, unsigned s1addr) override;
|
||||
virtual void addNewRelocations(Reloc &, unsigned upxsection) override;
|
||||
virtual unsigned getProcessImportParam(unsigned upxsection) override;
|
||||
virtual void setOhDataBase(const pe_section_t *osection) override;
|
||||
|
@ -64,7 +61,7 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft) override;
|
||||
virtual Linker* newLinker() const override;
|
||||
virtual Linker *newLinker() const override;
|
||||
|
||||
virtual const char *kernelDll() const override { return "COREDLL.dll"; }
|
||||
virtual void processImports2(unsigned, unsigned) override;
|
||||
|
@ -72,10 +69,9 @@ protected:
|
|||
|
||||
virtual void processTls(Interval *) override;
|
||||
|
||||
bool use_thumb_stub;
|
||||
bool use_thumb_stub = false;
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
|
|
@ -64,14 +64,15 @@ protected:
|
|||
unsigned adam_offset;
|
||||
int big_relocs;
|
||||
|
||||
struct tmt_header_t {
|
||||
struct alignas(1) tmt_header_t {
|
||||
char _[16]; // signature,linkerversion,minversion,exesize,imagestart
|
||||
LE32 imagesize;
|
||||
char __[4]; // initial memory
|
||||
LE32 entry;
|
||||
char ___[12]; // esp,numfixups,flags
|
||||
LE32 relocsize;
|
||||
} ih, oh;
|
||||
};
|
||||
tmt_header_t ih, oh;
|
||||
};
|
||||
|
||||
#endif /* already included */
|
||||
|
|
|
@ -25,17 +25,15 @@
|
|||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_W32PE_H
|
||||
#define __UPX_P_W32PE_H 1
|
||||
|
||||
#pragma once
|
||||
#ifndef UPX_P_W32PE_H__
|
||||
#define UPX_P_W32PE_H__ 1
|
||||
|
||||
/*************************************************************************
|
||||
// w32/pe
|
||||
**************************************************************************/
|
||||
|
||||
class PackW32Pe : public PeFile32
|
||||
{
|
||||
class PackW32Pe final : public PeFile32 {
|
||||
typedef PeFile32 super;
|
||||
|
||||
public:
|
||||
|
@ -48,9 +46,8 @@ public:
|
|||
virtual const int *getFilters() const override;
|
||||
|
||||
virtual bool handleForceOption() override;
|
||||
virtual void defineSymbols(unsigned ncsection, unsigned upxsection,
|
||||
unsigned sizeof_oh, unsigned isize_isplit,
|
||||
unsigned s1addr) override;
|
||||
virtual void defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh,
|
||||
unsigned isize_isplit, unsigned s1addr) override;
|
||||
virtual void addNewRelocations(Reloc &, unsigned upxsection) override;
|
||||
virtual void setOhDataBase(const pe_section_t *osection) override;
|
||||
virtual void setOhHeaderSize(const pe_section_t *osection) override;
|
||||
|
@ -62,10 +59,9 @@ protected:
|
|||
virtual int readFileHeader() override;
|
||||
|
||||
virtual void buildLoader(const Filter *ft) override;
|
||||
virtual Linker* newLinker() const override;
|
||||
virtual Linker *newLinker() const override;
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
|
|
@ -25,16 +25,15 @@
|
|||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_W64PEP_H
|
||||
#define __UPX_P_W64PEP_H 1
|
||||
#pragma once
|
||||
#ifndef UPX_P_W64PEP_H__
|
||||
#define UPX_P_W64PEP_H__ 1
|
||||
|
||||
/*************************************************************************
|
||||
// w64/pep
|
||||
**************************************************************************/
|
||||
|
||||
class PackW64Pep : public PeFile64
|
||||
{
|
||||
class PackW64Pep final : public PeFile64 {
|
||||
typedef PeFile64 super;
|
||||
|
||||
public:
|
||||
|
@ -47,9 +46,8 @@ public:
|
|||
virtual const int *getFilters() const override;
|
||||
|
||||
virtual bool handleForceOption() override;
|
||||
virtual void defineSymbols(unsigned ncsection, unsigned upxsection,
|
||||
unsigned sizeof_oh, unsigned isize_isplit,
|
||||
unsigned s1addr) override;
|
||||
virtual void defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh,
|
||||
unsigned isize_isplit, unsigned s1addr) override;
|
||||
virtual void setOhDataBase(const pe_section_t *) override {}
|
||||
virtual void setOhHeaderSize(const pe_section_t *osection) override;
|
||||
virtual void pack(OutputFile *fo) override;
|
||||
|
@ -58,10 +56,9 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft) override;
|
||||
virtual Linker* newLinker() const override;
|
||||
virtual Linker *newLinker() const override;
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
|
|
@ -223,7 +223,8 @@ void PackWcle::encodeFixupPageTable() {
|
|||
}
|
||||
|
||||
void PackWcle::encodeFixups() {
|
||||
ofixups = New(upx_byte, sofixups = 1 * 7 + FIXUP_EXTRA);
|
||||
sofixups = 1 * 7 + FIXUP_EXTRA;
|
||||
ofixups = New(upx_byte, sofixups);
|
||||
memset(ofixups, 0, sofixups);
|
||||
ofixups[0] = 7;
|
||||
set_le16(ofixups + 2, (LE_STUB_EDI + neweip) & (mps - 1));
|
||||
|
@ -257,7 +258,7 @@ void PackWcle::preprocessFixups() {
|
|||
|
||||
upx_byte *fix = ifixups;
|
||||
for (ic = jc = 0; ic < pages; ic++) {
|
||||
while ((unsigned) (fix - ifixups) < get_le32(ifpage_table + ic + 1)) {
|
||||
while (ptr_udiff_bytes(fix, ifixups) < get_le32(ifpage_table + (ic + 1))) {
|
||||
const int fixp2 = get_le16_signed(fix + 2);
|
||||
unsigned value;
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ bool PeFile::testUnpackVersion(int version) const
|
|||
|
||||
int PeFile::readFileHeader()
|
||||
{
|
||||
__packed_struct(exe_header_t)
|
||||
struct alignas(1) exe_header_t {
|
||||
LE16 mz;
|
||||
LE16 m512;
|
||||
LE16 p512;
|
||||
|
@ -156,7 +156,7 @@ int PeFile::readFileHeader()
|
|||
LE16 relocoffs;
|
||||
char __[34];
|
||||
LE32 nexepos;
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 64)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(exe_header_t)
|
||||
|
@ -290,10 +290,10 @@ void PeFile::Interval::dump() const
|
|||
// relocation handling
|
||||
**************************************************************************/
|
||||
|
||||
__packed_struct(PeFile::Reloc::reloc)
|
||||
struct alignas(1) PeFile::Reloc::reloc {
|
||||
LE32 pagestart;
|
||||
LE32 size;
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
void PeFile::Reloc::newRelocPos(void *p)
|
||||
{
|
||||
|
@ -958,7 +958,7 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1
|
|||
unsigned const skip2 = (im->oft ? im->oft : im->iat);
|
||||
dlls[ic].lookupt = (LEXX*)ibuf.subref("bad dll lookupt %#x", skip2, sizeof(LEXX));
|
||||
dlls[ic].original_position = ic;
|
||||
dlls[ic].isk32 = strcasecmp(kernelDll(), (const char*)dlls[ic].name) == 0;
|
||||
dlls[ic].isk32 = strcasecmp(kernelDll(), dlls[ic].name) == 0;
|
||||
|
||||
soimport += strlen(dlls[ic].name) + 1 + 4;
|
||||
|
||||
|
@ -1000,7 +1000,7 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1
|
|||
// for kernel32.dll we need to put all the imported
|
||||
// ordinals into the output import table, as on
|
||||
// some versions of windows GetProcAddress does not resolve them
|
||||
if (strcasecmp((const char*)idlls[ic]->name, "kernel32.dll"))
|
||||
if (strcasecmp(idlls[ic]->name, "kernel32.dll"))
|
||||
continue;
|
||||
if (idlls[ic]->ordinal)
|
||||
for (LEXX *tarr = idlls[ic]->lookupt; *tarr; tarr++)
|
||||
|
@ -1284,13 +1284,13 @@ void PeFile::processExports(Export *xport,unsigned newoffs) // pass2
|
|||
template <>
|
||||
struct PeFile::tls_traits<LE32>
|
||||
{
|
||||
__packed_struct(tls)
|
||||
struct alignas(1) tls {
|
||||
LE32 datastart; // VA tls init data start
|
||||
LE32 dataend; // VA tls init data end
|
||||
LE32 tlsindex; // VA tls index
|
||||
LE32 callbacks; // VA tls callbacks
|
||||
char _[8]; // zero init, characteristics
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
static const unsigned sotls = 24;
|
||||
static const unsigned cb_size = 4;
|
||||
|
@ -1302,13 +1302,13 @@ struct PeFile::tls_traits<LE32>
|
|||
template <>
|
||||
struct PeFile::tls_traits<LE64>
|
||||
{
|
||||
__packed_struct(tls)
|
||||
struct alignas(1) tls {
|
||||
LE64 datastart; // VA tls init data start
|
||||
LE64 dataend; // VA tls init data end
|
||||
LE64 tlsindex; // VA tls index
|
||||
LE64 callbacks; // VA tls callbacks
|
||||
char _[8]; // zero init, characteristics
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
static const unsigned sotls = 40;
|
||||
static const unsigned cb_size = 8;
|
||||
|
@ -1520,12 +1520,12 @@ void PeFile::processLoadConf(Reloc *rel, const Interval *iv,
|
|||
// resource handling
|
||||
**************************************************************************/
|
||||
|
||||
__packed_struct(PeFile::Resource::res_dir_entry)
|
||||
struct alignas(1) PeFile::Resource::res_dir_entry {
|
||||
LE32 tnl; // Type | Name | Language id - depending on level
|
||||
LE32 child;
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
__packed_struct(PeFile::Resource::res_dir)
|
||||
struct alignas(1) PeFile::Resource::res_dir {
|
||||
char _[12]; // flags, timedate, version
|
||||
LE16 namedentr;
|
||||
LE16 identr;
|
||||
|
@ -1534,13 +1534,13 @@ __packed_struct(PeFile::Resource::res_dir)
|
|||
res_dir_entry entries[1];
|
||||
// it's usually safe to assume that every res_dir contains
|
||||
// at least one res_dir_entry - check() complains otherwise
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
__packed_struct(PeFile::Resource::res_data)
|
||||
struct alignas(1) PeFile::Resource::res_data {
|
||||
LE32 offset;
|
||||
LE32 size;
|
||||
char _[8]; // codepage, reserved
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
struct PeFile::Resource::upx_rnode
|
||||
{
|
||||
|
@ -2100,12 +2100,12 @@ unsigned PeFile::stripDebug(unsigned overlaystart)
|
|||
if (IDADDR(PEDIR_DEBUG) == 0)
|
||||
return overlaystart;
|
||||
|
||||
__packed_struct(debug_dir_t)
|
||||
struct alignas(1) debug_dir_t {
|
||||
char _[16]; // flags, time/date, version, type
|
||||
LE32 size;
|
||||
char __[4]; // rva
|
||||
LE32 fpos;
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(debug_dir_t) == 28)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(debug_dir_t)
|
||||
|
|
24
src/pefile.h
24
src/pefile.h
|
@ -179,26 +179,26 @@ protected:
|
|||
unsigned crelocs; // rva of preprocessed fixups
|
||||
int big_relocs;
|
||||
|
||||
__packed_struct(ddirs_t)
|
||||
struct alignas(1) ddirs_t {
|
||||
LE32 vaddr;
|
||||
LE32 size;
|
||||
__packed_struct_end()
|
||||
};
|
||||
ddirs_t *iddirs;
|
||||
ddirs_t *oddirs;
|
||||
|
||||
__packed_struct(import_desc)
|
||||
struct alignas(1) import_desc {
|
||||
LE32 oft; // orig first thunk
|
||||
char _[8];
|
||||
LE32 dllname;
|
||||
LE32 iat; // import address table
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
LE32 &IDSIZE(unsigned x);
|
||||
LE32 &IDADDR(unsigned x);
|
||||
LE32 &ODSIZE(unsigned x);
|
||||
LE32 &ODADDR(unsigned x);
|
||||
|
||||
__packed_struct(pe_section_t)
|
||||
struct alignas(1) pe_section_t {
|
||||
char name[8];
|
||||
LE32 vsize;
|
||||
LE32 vaddr;
|
||||
|
@ -206,7 +206,7 @@ protected:
|
|||
LE32 rawdataptr;
|
||||
char _[12];
|
||||
LE32 flags;
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
MemBuffer mb_isection;
|
||||
pe_section_t *isection;
|
||||
|
@ -420,7 +420,7 @@ protected:
|
|||
|
||||
class Export : private noncopyable
|
||||
{
|
||||
__packed_struct(export_dir_t)
|
||||
struct alignas(1) export_dir_t {
|
||||
char _[12]; // flags, timedate, version
|
||||
LE32 name;
|
||||
char __[4]; // ordinal base
|
||||
|
@ -429,7 +429,7 @@ protected:
|
|||
LE32 addrtable;
|
||||
LE32 nameptrtable;
|
||||
LE32 ordinaltable;
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
export_dir_t edir;
|
||||
char *ename;
|
||||
|
@ -470,7 +470,7 @@ protected:
|
|||
virtual void processTls(Interval *) override;
|
||||
virtual void processTls(Reloc *, const Interval *, unsigned) override;
|
||||
|
||||
__packed_struct(pe_header_t)
|
||||
struct alignas(1) pe_header_t {
|
||||
// 0x0
|
||||
char _[4]; // pemagic
|
||||
LE16 cpu;
|
||||
|
@ -507,7 +507,7 @@ protected:
|
|||
LE32 ddirsentries; // usually 16
|
||||
|
||||
ddirs_t ddirs[16];
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
pe_header_t ih, oh;
|
||||
};
|
||||
|
@ -532,7 +532,7 @@ protected:
|
|||
virtual void processTls(Interval *) override;
|
||||
virtual void processTls(Reloc *, const Interval *, unsigned) override;
|
||||
|
||||
__packed_struct(pe_header_t)
|
||||
struct alignas(1) pe_header_t {
|
||||
// 0x0
|
||||
char _[4]; // pemagic
|
||||
LE16 cpu;
|
||||
|
@ -569,7 +569,7 @@ protected:
|
|||
LE32 ddirsentries; // usually 16
|
||||
|
||||
ddirs_t ddirs[16];
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
pe_header_t ih, oh;
|
||||
};
|
||||
|
|
|
@ -60,17 +60,25 @@ upx_rsize_t upx_safe_strlen(const char *);
|
|||
#define strlen upx_safe_strlen
|
||||
|
||||
/*************************************************************************
|
||||
// some unsigned char string support functions
|
||||
// some unsigned char string support functions to avoid casts
|
||||
**************************************************************************/
|
||||
|
||||
inline unsigned char *strcpy(unsigned char *s1, const unsigned char *s2) {
|
||||
return (unsigned char *) strcpy((char *) s1, (const char *) s2);
|
||||
}
|
||||
|
||||
inline int strcmp(const unsigned char *s1, const char *s2) { return strcmp((const char *) s1, s2); }
|
||||
inline int strcmp(const char *s1, const unsigned char *s2) { return strcmp(s1, (const char *) s2); }
|
||||
inline int strcmp(const unsigned char *s1, const unsigned char *s2) {
|
||||
return strcmp((const char *) s1, (const char *) s2);
|
||||
}
|
||||
|
||||
inline int strcasecmp(const unsigned char *s1, const char *s2) {
|
||||
return strcasecmp((const char *) s1, s2);
|
||||
}
|
||||
inline int strcasecmp(const char *s1, const unsigned char *s2) {
|
||||
return strcasecmp(s1, (const char *) s2);
|
||||
}
|
||||
inline int strcasecmp(const unsigned char *s1, const unsigned char *s2) {
|
||||
return strcasecmp((const char *) s1, (const char *) s2);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user