View Full Version : Need Help for Unpacking UPX ( header changed! )
ian.anindya
06-08-2010, 10:26 AM
I have program that packed using UPX. But all the files header been changed, modify UPX0,UPX1, UPX2 and UPX! is not success, type upx -d I have got checksum error.
link here : http://www.megaupload.com/?d=QZHM997W
How to restore header?
Any guidance how to unpacked it? I have tried to find tutorial about UPX but all refer to use ollyDBG that not supported with ARM.
Kindly need your Help, Master in here...
Thanks,
Why are you so sure it is UPX?
If PE Explorer won't unpack it then it ain't UPX packed.
Git
ian.anindya
06-09-2010, 11:03 AM
Hi Git,
Thanks for your response.
Yes, I'm sure that file is packed using UPX. When you open on ultraedit then you will find UPX2 and information packer that UPX 3.04 version.
Before, I can use AFAIK with UPX0, UPX1, UPX2 and UPX! then type UPX -d papago.exe --> success to unpack. But with this new method ( I Think Header has been change ) then AFAIK Method cannot unpack it. Must be restoring UPX header. ( see pic when opening on ultraedit).
http://www.4shared.com/photo/mknIS5Vw/UPX.html
What I need is how to restore UPX Header so I can use AFAIK method to unpacking that file.
Thanks,
Ian
Test it with PEID and see what it says. If PEID reports it as UPX then open it with PE Explorer and use Save As from the menu to save the unpacked exe.
Git
ian.anindya
06-11-2010, 04:09 PM
Hi Git,
I need tutorial for this this :
This file Which I can confirm it only packed with UPX program, Not other.
This file which after packed by UPX, the Image header has been modified; The UPX version, file type, compress method, compress alder32, uncompress alder32, Compress size, uncompress size, origin size, filter ID and Link checksum, all been modified to Zero.
Most probably, the UPX program will not be recognize the file header and reject to unpack it directly by upx -d.
Download UPX Source code to understand how the upx work, then will know how to recover the image header.
Unpacked file from helpfully member :http://www.mediafire.com/?zaokiym5gwo
Source code UPX : http://hotfile.com/dl/48320417/f4dabee/UPX_SoureCode.rar.html
Anyone here can help to make tutorial for it?
Thanks,
Ian
shikigami
06-14-2010, 01:58 PM
Googling manual UPX unpacking returns a few good tuts including UPX packed files with altered headers.
robin1044
06-15-2010, 04:54 AM
@shikigami : UPX is not a commercial Packer and not aimed for protection, it is just a packer
you can just download from
http://upx.sourceforge.net/#downloadupx
and use to pack or unpack:
packing example: UPX notepad.exe
un-packing example: UPX -d notepad.exe
@ian.anindya : not every packer with UPX0, UPX1 section names is UPX!
ian.anindya
06-15-2010, 05:33 PM
@Hi shikigami,
All tut for unpack UPX on google recommended using ollydbg then that exe for ARM and ollyDBG cannot handle ARM proc.
@robin,
I'm sure that file is packed using UPX. Then after that they change all info of UPX version, header, compress and uncompress elder, checksum, manually to zero.
I don't understand C language to understand how UPX work. If you understand that please mind to share....with manually restore header info and checksum we can use : UPX -d filename.exe again to unpack it.
Hi,
Member that successful unpack it using this script but I don't know what should we do with this script.
1. Should we put/write this script in *.cpp file inside UPX source code than re-compile again source code with below script inside.
2. What *.cpp file name that we must put in/write in?
3. For compiling source code what software we use? Cygwin?
script ====>>
/************************************************** ***********************
// simple checksum for the header itself (since version 10)
************************************************** ************************/
static unsigned char get_packheader_checksum(const upx_bytep buf, int len)
{
assert(get_le32(buf) == UPX_MAGIC_LE32);
//printf("1 %d\n", len);
buf += 4;
len -= 4;
unsigned c = 0;
while (len-- > 0)
c += *buf++;
c %= 251;
//printf("2 %d\n", c);
return (unsigned char) c;
}
/************************************************** ***********************
//
************************************************** ************************/
int PackHeader::getPackHeaderSize() const
{
if (format < 0 || version < 0)
throwInternalError("getPackHeaderSize";
int n = 0;
if (version <= 3)
n = 24;
else if (version <= 9)
{
if (format == UPX_F_DOS_COM || format == UPX_F_DOS_SYS)
n = 20;
else if (format == UPX_F_DOS_EXE || format == UPX_F_DOS_EXEH)
n = 25;
else
n = 28;
}
else
{
if (format == UPX_F_DOS_COM || format == UPX_F_DOS_SYS)
n = 22;
else if (format == UPX_F_DOS_EXE || format == UPX_F_DOS_EXEH)
n = 27;
else
n = 32;
}
if (n < 20)
throwCantUnpack("unknown header version";
return n;
}
/************************************************** ***********************
// see stub/header.ash
************************************************** ************************/
void PackHeader::putPackHeader(upx_bytep p)
{
assert(get_le32(p) == UPX_MAGIC_LE32);
if (get_le32(p+4) != UPX_MAGIC2_LE32)
{
//fprintf(stderr, "MAGIC2_LE32: %x %x\n", get_le32(p+4), UPX_MAGIC2_LE32);
throwBadLoader();
}
int size = 0;
int old_chksum = 0;
// the new variable length header
if (format < 128)
{
if (format == UPX_F_DOS_COM || format == UPX_F_DOS_SYS)
{
size = 22;
old_chksum = get_packheader_checksum(p, size - 1);
set_le16(p+16,u_len);
set_le16(p+18,c_len);
p[20] = (unsigned char) filter;
}
else if (format == UPX_F_DOS_EXE)
{
size = 27;
old_chksum = get_packheader_checksum(p, size - 1);
set_le24(p+16,u_len);
set_le24(p+19,c_len);
set_le24(p+22,u_file_size);
p[25] = (unsigned char) filter;
}
else if (format == UPX_F_DOS_EXEH)
{
throwInternalError("invalid format";
}
else
{
size = 32;
old_chksum = get_packheader_checksum(p, size - 1);
set_le32(p+16,u_len);
set_le32(p+20,c_len);
set_le32(p+24,u_file_size);
p[28] = (unsigned char) filter;
p[29] = (unsigned char) filter_cto;
assert(n_mru == 0 || (n_mru >= 2 && n_mru <= 256));
p[30] = (unsigned char) (n_mru ? n_mru - 1 : 0);
}
set_le32(p+8,u_adler);
set_le32(p+12,c_adler);
}
else
{
size = 32;
old_chksum = get_packheader_checksum(p, size - 1);
set_be32(p+8,u_len);
set_be32(p+12,c_len);
set_be32(p+16,u_adler);
set_be32(p+20,c_adler);
set_be32(p+24,u_file_size);
p[28] = (unsigned char) filter;
p[29] = (unsigned char) filter_cto;
assert(n_mru == 0 || (n_mru >= 2 && n_mru <= 256));
p[30] = (unsigned char) (n_mru ? n_mru - 1 : 0);
}
p[4] = (unsigned char) version;
p[5] = (unsigned char) format;
p[6] = (unsigned char) method;
p[7] = (unsigned char) level;
// header_checksum
assert(size == getPackHeaderSize());
// check old header_checksum
if (p[size - 1] != 0)
{
if (p[size - 1] != old_chksum)
{
//printf("old_checksum: %d %d\n", p[size - 1], old_chksum);
throwBadLoader();
}
}
// store new header_checksum
p[size - 1] = get_packheader_checksum(p, size - 1);
}
/************************************************** ***********************
//
************************************************** ************************/
bool PackHeader::fillPackHeader(const upx_bytep buf, int blen)
{
int boff = find_le32(buf, blen, UPX_MAGIC_LE32);
if (boff < 0)
return false;
if (boff + 8 <= 0 || boff + 8 > blen)
throwCantUnpack("header corrupted 1";
const upx_bytep p = buf + boff;
version = p[4];
format = p[5];
method = p[6];
level = p[7];
filter_cto = 0;
const int size = getPackHeaderSize();
if (boff + size <= 0 || boff + size > blen)
throwCantUnpack("header corrupted 2";
//
// decode the new variable length header
//
int off_filter = 0;
if (format < 128)
{
u_adler = get_le32(p+8);
c_adler = get_le32(p+12);
if (format == UPX_F_DOS_COM || format == UPX_F_DOS_SYS)
{
u_len = get_le16(p+16);
c_len = get_le16(p+18);
u_file_size = u_len;
off_filter = 20;
}
else if (format == UPX_F_DOS_EXE || format == UPX_F_DOS_EXEH)
{
u_len = get_le24(p+16);
c_len = get_le24(p+19);
u_file_size = get_le24(p+22);
off_filter = 25;
}
else
{
u_len = get_le32(p+16);
c_len = get_le32(p+20);
u_file_size = get_le32(p+24);
off_filter = 28;
filter_cto = p[29];
n_mru = p[30] ? 1 + p[30] : 0;
}
}
else
{
u_len = get_be32(p+8);
c_len = get_be32(p+12);
u_adler = get_be32(p+16);
c_adler = get_be32(p+20);
u_file_size = get_be32(p+24);
off_filter = 28;
filter_cto = p[29];
n_mru = p[30] ? 1 + p[30] : 0;
}
if (version >= 10)
filter = p[off_filter];
else if ((level & 128) == 0)
filter = 0;
else
{
// convert old flags to new filter id
level &= 127;
if (format == UPX_F_DOS_COM || format == UPX_F_DOS_SYS)
filter = 0x06;
else
filter = 0x26;
}
level &= 15;
//
// now some checks
//
if (version == 0xff)
throwCantUnpack("cannot unpack UPX ";
// check header_checksum
if (version > 9)
if (p[size - 1] != get_packheader_checksum(p, size - 1))
throwCantUnpack("header corrupted 3");
//
// success
//
this->buf_offset = boff;
return true;
}
vBulletin® v3.6.4, Copyright ©2000-2015, Jelsoft Enterprises Ltd.