Hello,
I compiled this file in my android phone. (not cross compiled, just compiled in phone and no header fix)
and I packed this executable file with upx3.91, but It doesn't work in Phone.
I attached 2 files(original and packed files)
Please check it.
thanks.
How does it not work? What are the symptoms, error messages, etc.? Which version of Android? Which CPU chip, or model of phone?
just no reponse. no error messages.
source)
int main()
{
printf("hello.c");
return 0;
}
pack)
root@android:/sdcard # ./pack_excutable
127|root@android:/sdcard #
original)
root@android:/sdcard # ./org_excutable
hello.c
root@android:/sdcard #
My Phone Spec :
Device : SHV-E160S (Samsung Galaxy Note)
CPU : Qualcomm APQ8060 45 nm ARMv7 1.2-1.7 Ghz Dual-core Scorpion L2
OS Version : 4.0.4 (Ice Cream Sandwich)
Last edit: sonh 2013-10-07
In https://android.googlesource.com/platform/ndk/+/48cdce8c044f6e7d11aa2b5eb97635c922e0bc58/sources/android/crazy_linker/src/crazy_linker_rdebug.cpp which has a 2013 copyright date, I see
That code assumes that /proc/self/exe exists and points to the right place. Those assumptions are not necessarily true. Some other process could unlink the path after it was execve() but before the readlink(). In the case of upx, the file corresponding to the current process image does not reside at any path in the filesystem. There is no such file. The compressed file has been decompressed into the address space. There is no page of the compressed file that still is mapped into the address space, so the operating system erases the link /proc/self/exe. [Note that somewhere there should be a log file with the results of the LOG_ERRNO.]
On other platforms one page of the compressed file is kept mapped so that /proc/self/exe still exists as a hint (for the directory name, etc.) On ARM there is no place to put (keep) that one page. Below 0x8000 is forbidden to mmap() or execve(), and any other page would interfere with the address space that the app expects.
The upx runtime decompression stub remembers the original value of readlink("/proc/self/exe", ...) in the environment variable " " (three spaces), so getenv(" ") will return it.
If /proc/self/exe is the reason for "does not work on phone" then please talk to the purveyors of whatever software believes that /proc/self/exe should exist and have certain properties.
Please try the attached output from upx. It is android_org compressed with a stub that turns some gymnastics in order to keep the symlink /proc/self/exe from disappearing. (The code changes to upx have been committed to the tip of the source repository https://www.pysol.org:4443/hg/upx.hg )
So /proc/self/exe will be available, but its contents will be the compressed file. This is of no use to any code that does not understand upx compression! The only useful information conveyed by the link text of /proc/self/exe is the path (the directory), and indirectly the owner, permissions, etc.; but all of that has no direct impact on executing the file. If /system/bin/linker really wants to get information about the current image in memory, then it must look at the Elf32_auxv vector which appears just beyond the array of environment variable pointers. Consult /usr/include/elf.h and AT_PHDR etc.
thanks for kindly and fast reply.
I tested the attached file and It still doesn't work.
root@android:/sdcard # ./proc-self-exe_pack
127|root@android:/sdcard #
It displays same result. and I don't know why it displays "127". (also same)
I have a raspberry pi and compiled and packed with upx.
then I run this packed file, there is no problems. (in raspberry, gcc (Debian 4.6.3))
and I compiled "gcc -O0 -static" in raspberry pi and do upx it.
then I tested it in android phone with this packed file, and it successfully works.
root@android:/sdcard # ./rasp_static_original
compiled by raspberry pi
root@android:/sdcard #
root@android:/sdcard # ./rasp_static_upx
compiled by raspberry pi
root@android:/sdcard #
and I compiled my another project sources and run it,
but It doesn't perfectly work. (some functions doesn't work.)
i think that there is something different between arm and android-arm, so it's impossible to perfectly run in android-arm.
Last edit: sonh 2013-10-07
I have tested UPX with many phones during a few days.
Please check out attach picture.
Fix UPX means ELF Packed File made by your newest svn files.
In case of 2.6.32.9 kernel version, One phone do run but another phone doesn't run.
I guess that Manufacturers compile kernel with their own's options.
I want to work on all phones Without modifying the kernel.
What should I do?
Last edit: sonh 2013-10-17
Thank you for testing all those phones! But what is the key to the entries in the columns Rooting, fix UPX, org UPX? Does "X" mean "it works", or "it does NOT work"? I assume that "O" means the opposite of "X". Ultimately I need access to a phone or tablet that works as far as loading apps and running them, but does NOT work for running apps that have been compressed by UPX. I do not need or want to send or receive calls, just load+debug+run apps. I'm in the US, so I suppose one way is to buy a phone/tablet from eBay. Alternately, if you could run 'strace' or equivalent (traces system calls), or run an app under a debugger such as gdb and print the pc and register contents, then that might provide enough clues as to what is going on. In particular, compare strace of a compressed app where UPX works (on some particular phone or tablet) versus strace where UPX fails (on some other particular phone or tablet.)
thanks for the your guides.
I compiled upx with your the newest SVN files. (https://www.pysol.org:4443/hg/upx.hg)
"fix UPX" means that. (packed elf file with fix upx)
"org UPX" means "packed elf file" with official page's upx 3.91 file.
"rooting" means rooting phone (su privilege)
yes, "O" means working well. and "X" means the opposite of "O"
and already I tried debugging with gdb.
but there's no /proc/[pid]/exe, so gdb can't find informations.
./gdb --pid 17266
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copyi
and "show warranty" for details.
This GDB was configured as "arm-linux".
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/.
Attaching to process 17266
/proc/17266/exe: No such file or directory.
(gdb)
I checked /proc/[pid]/maps, and there's no file path.
00008000-0000b000 r-xp 00000000 00:00 0
0000c000-0000d000 r-xp 00000000 00:00 0
0000d000-0000e000 rwxp 00000000 00:00 0
of course, I tested packed file in phone which does work UPX.
I used ln command to make link, but i can't link for the /proc/[pid]/exe.
is there no way using gdb?
and I sorted the sheet into kernal version, and include 2 phone.
Please check out attach picture. i assume that maybe upper kernel can run upx
Last edit: sonh 2013-10-18
Looking at the sort.png picture, it seems to me that kernel version >= 3.0.31 works, while <= 3.0.15 fails. (Version numbers don't sort properly as strings unless they have the same number of digits in each component. "3.0.8" as a string is after "3.0.31" because "8" > "3", but as a version number 3.0.8 precedes 3.0.31)
I have added some debug code to android_upx_dbg which writes to stderr (file descriptor 2). This is crude but will give some indication of how much did work before the failure. I don't know where output for stderr goes, but perhaps it goes to a console or log file. Example output:
and here the 0177 exit is because /system/bin/ld cannot be found on my sheevaplug test platform.
Running with strace shows:
I have tested the attached file in my working and no working phones
in working phone)
shell access and kernel 3.4.0
shell@android:/data/local/tmp $ ./gdb ./android_upx_dbg
./gdb ./android_upx_dbg
gdb) r
Starting program: /data/local/tmp/android_upx_dbg
00000001>
00000000 00000000 be886b00 00000000 00000000 00000000 00000000 00000000 00000000
00000008 00000000 00000000 00000000 00000000 00000000 00000000 00009c20 00000001
00000010 be886b00 00000000 be886b20 be886b42 be886b4d be886b5e be886b86 be886b99
00000002>
00000000 00020000 00002bfc 00000007 00000032 ffffffff 00000000 00000000 000000c0
00000008 00000000 00008000 00009e9c 00009f78 00009bfc 00000022 00009c6c 00020000
00000010 00002bfc 00020000 00000000 00000022 00000001 be886b00 00000000 be886b20
00000003>
00000000 00009f84 000006ea 00021ea4 be8869b4 00018000 00021db0 2afffffb 000f0002
00000008 e3a0201e 00001b70 0002008c 00009f78 00009bfc 00021ea4 00009cf0 00000003
00000010 00021ea4 00020000 00002bfc 00000a1c 00000000 00000022 00000001 be886b00
compiled at Android phone
Program exited normally.
(gdb) quit
quit
shell@android:/data/local/tmp $ ls /system/bin/ld
ls /system/bin/ld
/system/bin/ld: No such file or directory
(but it have /system/bin/linker)
i don't know how work in upx ELF without /system/bin/ld
in not working phone)
root access and kernel 3.0.08
./gdb ./android_upx_dbg
gdb) r
Starting program: /data/local/tmp/android_upx_dbg
00000001>
00000000 00000000 beadabc5 00000000 00000000 00000000 00000000 00000000 00000000
00000008 00000000 00000000 00000000 00000000 00000000 00000000 00009c20 00000001
00000010 beadabc5 00000000 beadabe5 beadac07 beadac1a beadac3d beadac56 beadac61
00000002>
00000000 00020000 00002bfc 00000007 00000032 ffffffff 00000000 00000000 000000c0
00000008 00000000 00008000 00009e9c 00009f78 00009bfc 00000022 00009c6c 00020000
00000010 00002bfc 00020000 00000000 00000022 00000001 beadabc5 00000000 beadabe5
00000003>
00000000 00009f84 000006ea 00021ea4 beadaa94 00018000 00021db0 2afffffb 000f0002
00000008 e3a0201e 00001b70 0002008c 00009f78 00009bfc 00021ea4 00009cf0 00000003
00000010 00021ea4 00020000 00002bfc 00000a1c 00000000 00000022 00000001 beadabc5
Program exited with code 0177.
(gdb) quit
quit
root@android:/data/local/tmp # ls /system/bin/ld
ls /system/bin/ld
/system/bin/ld: No such file or directory
it shows 0177 error
(but it have /system/bin/linker)
Last edit: sonh 2013-10-21
adding strace testing results:
strace doesn't work well in phones
working phone)
shell@android:/data/local/tmp # ./strace ./android_upx_dbg
./strace ./android_upx_dbg
execve("./android_upx_dbg", ["./android_upx_dbg"], [/ 30 vars /]) = 0
syscall: unknown syscall trap 0x00000022
packed upx works well, but strace shows 0x22 error.
not working phone)
root@android:/data/local/tmp # ./strace ./android_upx_dbg
./strace ./android_upx_dbg
execve("./android_upx_dbg", ["./android_upx_dbg"], [/ 26 vars /]) = 0
syscall: unknown syscall trap 0x00000022
it shows same results.
but,
then i can check log.
please add getchar() at the source file before printf("compiled .....");
example)
void main()
{
// write debug info
getchar();
// printf("compiled android phone);
}
in working phone with my source (no debug info, i dont know how to make it)
shell@android:/data/local/tmp $ ./packed_upx
(getchar() waiting...)
Hello world!
and run anthoer console,
shell@android:/data/local/tmp $ ps packed_upx
USER PID PPID VSIZE RSS WCHAN PC NAME
shell 24468 24403 1252 924 c03912c4 401c7a1c S ./packed_upx
shell@android:/data/local/tmp $ ./strace -p 24468
./strace -p 24468
Process 24468 attached - interrupt to quit <---- press [enter] in running process.. it goes well
read(0, "\n", 1024) = 1
mprotect(0x402e1000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x402e1000, 4096, PROT_READ) = 0
futex(0x4020473c, 0x81 / FUTEX_??? /, 2147483647) = 0
mprotect(0x402e1000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x402e1000, 4096, PROT_READ) = 0
munmap(0x402e1000, 4096) = 0
exit_group(33161641) = ?
Process 24468 detached
shell@android:/data/local/tmp $
Last edit: sonh 2013-10-21
OK, please try another attached executable android_upx_dbg2. The good output looks like:
thanks for the reply.
i tested the new attach file.
working phone)
shell@android:/data/local/tmp $ ./android_upx_dbg2
./android_upx_dbg2
00000001>
00000000 00000000 befc9b3c 00000000 00000000 00000000 00000000 00000000 00000000
00000008 00000000 00000000 00000000 00000000 00000000 00000000 00009c20 00000001
00000010 befc9b3c 00000000 befc9b4f befc9b64 befc9b8c befc9bb2 befc9bdc befc9c19
00000002>
00000000 00020000 00002bfc 00000007 00000032 ffffffff 00000000 00000000 000000c0
00000008 00000000 00008000 00009e9c 00009f78 00009bfc 00000022 00009c6c 00020000
00000010 00002bfc 00020000 00000000 00000022 00000001 befc9b3c 00000000 befc9b4f
00000003>
00000000 00009f84 00000a84 00021ea4 befc9a04 00018000 00021db0 2afffffb 000f0002
00000008 e3a0201e 00001b70 0002008c 00009f78 00009bfc 00021ea4 00009cf0 00000003
00000010 00021ea4 00020000 00002bfc 00000fb8 00000000 00000022 00000001 befc9b3c
upx_main av=0xbefc3f70 szc=0x1b70 f_dec=0x21db0 f_unf=0x22068 xo=0xbefc34b
c(0x134 0xbefc34d4) xi=0xbefc34c4(0xa3 0x2008c) dynbase=0x0
unpackExtent in=0xbefc34c4(0xa3 0x2008c) out=0xbefc34bc(0x134 0xbefc34d4) 0x21
db0 0x0
xread 0xbefc34c4(0xa3 0x2008c) 0xbefc344c 0xc
auxv_up 0xbefc3f70 0x5 0x8
auxv_up 0xbefc3f70 0x4 0x20
auxv_up 0xbefc3f70 0x3 0x8034
xfind_pages 0x10 0xbefc3508 8 0xbefc3448
do_xmap fdi=0x21db0 ehdr=0xbefc34d4 xi=0xbefc34c4(0x1b70 0x2008c) av=0xbefc3
f70 p_reloc=0xbefc3494 f_unf=0x22068
auxv_up 0xbefc3f70 0x3 0x8034
unpackExtent in=0xbefc34c4(0x1b70 0x2008c) out=0xbefc3440(0x1b48 0x8000) 0x21d
b0 0x22068
xread 0xbefc34c4(0x1b70 0x2008c) 0xbefc33e8 0xc
xread 0xbefc34c4(0x1acd 0x2012f) 0xbefc33e8 0xc
xread 0xbefc34c4(0x1ac1 0x2013b) 0x8134 0x1a14
make_hatch 0xbefc3568 0x0 0xef000000
auxv_up 0xbefc3f70 0x0 0x9b48
unpackExtent in=0xbefc34c4(0xad 0x21b4f) out=0xbefc3440(0x16c 0x11b48) 0x21db0
0x0
xread 0xbefc34c4(0xad 0x21b4f) 0xbefc33e8 0xc
make_hatch 0xbefc3588 0x0 0xef000000
auxv_up 0xbefc3f70 0x9 0x8548
xfind_pages 0x0 0xbefc3508 7 0xbefc3448
do_xmap fdi=0x3 ehdr=0xbefc34d4 xi=0x0(0x0 0x0) av=0xbefc3f70 p_reloc=0xbef
c3494 f_unf=0x0
auxv_up 0xbefc3f70 0x7 0x40042000
00000004>
00000000 00020000 00002bfc befc4000 00009b48 ef000000 e1a0f00e 00022068 00000134
00000008 befc34d4 000000a3 0002008c 00000000 00001b70 40045700 0002200c 00000001
00000010 befc9b3c 00000000 befc9b4f befc9b64 befc9b8c befc9bb2 befc9bdc befc9c19
compiled at Android phone
shell@android:/data/local/tmp $
not working phone)
root@android:/data/local/tmp # ./android_upx_dbg2
./android_upx_dbg2
00000001>
00000000 00000000 bec66c00 00000000 00000000 00000000 00000000 00000000 00000000
00000008 00000000 00000000 00000000 00000000 00000000 00000000 00009c20 00000001
00000010 bec66c00 00000000 bec66c13 bec66c28 bec66c3b bec66c5e bec66c77 bec66c91
00000002>
00000000 00020000 00002bfc 00000007 00000032 ffffffff 00000000 00000000 000000c0
00000008 00000000 00008000 00009e9c 00009f78 00009bfc 00000022 00009c6c 00020000
00000010 00002bfc 00020000 00000000 00000022 00000001 bec66c00 00000000 bec66c13
00000003>
00000000 00009f84 00000a84 00021ea4 bec66ad4 00018000 00021db0 2afffffb 000f0002
00000008 e3a0201e 00001b70 0002008c 00009f78 00009bfc 00021ea4 00009cf0 00000003
00000010 00021ea4 00020000 00002bfc 00000fb8 00000000 00000022 00000001 bec66c00
upx_main av=0xbec5ff70 szc=0x1b70 f_dec=0x21db0 f_unf=0x22068 xo=0xbec5f4c
c(0x134 0xbec5f4e4) xi=0xbec5f4d4(0xa3 0x2008c) dynbase=0x0
unpackExtent in=0xbec5f4d4(0xa3 0x2008c) out=0xbec5f4cc(0x134 0xbec5f4e4) 0x21
db0 0x0
xread 0xbec5f4d4(0xa3 0x2008c) 0xbec5f45c 0xc
auxv_up 0xbec5ff70 0x5 0x8
auxv_up 0xbec5ff70 0x4 0x20
auxv_up 0xbec5ff70 0x3 0x8034
xfind_pages 0x10 0xbec5f518 8 0xbec5f458
do_xmap fdi=0x21db0 ehdr=0xbec5f4e4 xi=0xbec5f4d4(0x1b70 0x2008c) av=0xbec5f
f70 p_reloc=0xbec5f4a4 f_unf=0x22068
auxv_up 0xbec5ff70 0x3 0x8034
unpackExtent in=0xbec5f4d4(0x1b70 0x2008c) out=0xbec5f450(0x1b48 0x8000) 0x21d
b0 0x22068
xread 0xbec5f4d4(0x1b70 0x2008c) 0xbec5f3f8 0xc
xread 0xbec5f4d4(0x1acd 0x2012f) 0xbec5f3f8 0xc
xread 0xbec5f4d4(0x1ac1 0x2013b) 0x8134 0x1a14
make_hatch 0xbec5f578 0x0 0xef000000
auxv_up 0xbec5ff70 0x0 0x9b48
unpackExtent in=0xbec5f4d4(0xad 0x21b4f) out=0xbec5f450(0x16c 0x11b48) 0x21db0
0x0
xread 0xbec5f4d4(0xad 0x21b4f) 0xbec5f3f8 0xc
make_hatch 0xbec5f598 0x0 0xef000000
auxv_up 0xbec5ff70 0x9 0x8548
xfind_pages 0x10 0xbec5f518 5 0xbec5f458
do_xmap fdi=0x3 ehdr=0xbec5f4e4 xi=0x0(0x0 0x0) av=0xbec5ff70 p_reloc=0xbec
5f4a4 f_unf=0x0
127|root@android:/data/local/tmp #
please check out these results.
thanks
Last edit: sonh 2013-10-21
Thank you. The problem is related to the contents of /system/bin/linker. Please run "readelf --headers /system/bin/linker" and copy+paste the results for both a working phone and a non-working phone. Also if possible, please gzip a copy of /system/bin/linker from the non-working phone, and attach that compressed copy to this bug report.
The key difference is:
which is part of mapping in the PT_INTERP /system/bin/linker.
Here is android_upx_dbg3 which contains a "read(0, &junk, 1);" so that you can attach the process with strace, then type <Enter>.
i attached files that result in readelf.
not working linker shows fixed addr. (i guess)
not working attach
strace shows error in not working phone
write(2, " ", 1) = 1
write(2, "p", 1) = 1
write(2, "", 1) = 1
write(2, "r", 1) = 1
write(2, "e", 1) = 1
write(2, "l", 1) = 1
write(2, "o", 1) = 1
write(2, "c", 1) = 1
write(2, "=", 1) = 1
write(2, "0xbe9ff4a4", 10) = 10
write(2, " ", 1) = 1
write(2, " ", 1) = 1
write(2, "f", 1) = 1
write(2, "", 1) = 1
write(2, "u", 1) = 1
write(2, "n", 1) = 1
write(2, "f", 1) = 1
write(2, "=", 1) = 1
write(2, "0x0", 3) = 3
write(2, "\n", 1) = 1
mmap2(NULL, 0, PROT_READ, MAP_PRIVATE|MAP_FIXED, 3, 0) = -1 EINVAL (Invalid argument)
exit(127) = ?
Process 26729 detached
in the case working phone,
write(2, " ", 1) = 1
write(2, "p", 1) = 1
write(2, "", 1) = 1
write(2, "r", 1) = 1
write(2, "e", 1) = 1
write(2, "l", 1) = 1
write(2, "o", 1) = 1
write(2, "c", 1) = 1
write(2, "=", 1) = 1
write(2, "0xbe97b494", 10) = 10
write(2, " ", 1) = 1
write(2, " ", 1) = 1
write(2, "f", 1) = 1
write(2, "", 1) = 1
write(2, "u", 1) = 1
write(2, "n", 1) = 1
write(2, "f", 1) = 1
write(2, "=", 1) = 1
write(2, "0x0", 3) = 3
write(2, "\n", 1) = 1
mmap2(0x40098000, 75472, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0
0098000
mmap2(0x400ab000, 4976, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x12)
0x400ab000
mmap2(0x400ad000, 63752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONY
mmap func works well
Last edit: sonh 2013-10-21
Thank you for running readelf and the strace. The problem is in the first LOAD (which is really PT_LOAD) of /system/bin/linker as reported in not_working.txt:
The VirtAddr of the first PT_LOAD is 0, and the operating system does not allow that from mmap (which shows up as "mmap(NULL," in the strace.) On the other hand, the MemSiz is 0, so the range is empty; and the Offset of 0xd4 is not congruent to VirtAddr of 0 modulo the Align of 0x1000. So the first PT_LOAD is somewhat incorrectly formed.
Atttached is android_upx_dbg4 with contains a test to skip any PT_LOAD which has 0==MemSiz. This might be enough to avoid trouble.
Thanks for the reply.
finally working successfully!
is it possible to use upx that i just fix packed elf file?
Last edit: sonh 2013-10-21
It is good to hear that android_upx_dbg4 worked! Thank you for working with me to find the problem and the fix.
No, it is not possible to edit an already-packed file. Instead, get the new source for upx from https://www.pysol.org:4443/hg/upx.hg , build it, then compress the original file using the newly-built upx.
Fixed in source.