Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIPS is broken in 3.96 #342

Closed
bol-van opened this issue Feb 3, 2020 · 12 comments
Closed

MIPS is broken in 3.96 #342

bol-van opened this issue Feb 3, 2020 · 12 comments
Milestone

Comments

@bol-van
Copy link

bol-van commented Feb 3, 2020

What's the problem (or question)?

Static musl executable packed by UPX 3.96 hangs on MIPS32 MSB router D-link DIR-825 B2
Program should output some strings in response to -h command. It outputs nothing , no response.
It works fine if packed by UPX 3.95

What should have happened?

It should run

How can we reproduce the issue?

Make simple hello-world C program, compile it for MIPS, pack with upx 3.96, run on mips device

Please tell us details about your environment.

  • UPX version used (upx --version): 3.96
  • Host Operating System and version: Wi64, linux amd 64
  • Host CPU architecture: amd64
  • Target Operating System and version: linux openwrt kernel 4.14.82
  • Target CPU architecture: mips32r2-msb
@cnsilvan
Copy link

cnsilvan commented Feb 3, 2020

same here

@jreiser
Copy link
Collaborator

jreiser commented Feb 3, 2020

You must upload ("Attach files by ...") an actual executable that experiences the problem. Compress the upload using zip, gzip, or .tgz so that Github can save space.

@bol-van
Copy link
Author

bol-van commented Feb 3, 2020

If you wish..
but you can take any system file (/bin/ls)

hw.zip

Also, to note. It eats 100% cpu core

@jreiser
Copy link
Collaborator

jreiser commented Feb 3, 2020

@bol-van Thank you. It saves debugging time to start with something that is known to fail. I don't have MIPS32 MSB router D-link DIR-825 B2 to choose a file.

@bol-van
Copy link
Author

bol-van commented Feb 3, 2020

Anyway you need at least qemu mips system running linux. Can take ls from there

@jreiser
Copy link
Collaborator

jreiser commented Feb 9, 2020

This environment worked enough for debugging the upx stub. There is no ls in sight.

sudo apt-get install qemu-user gdb-multiarch g++-5-mips-linux-gnu
qemu-mips -L /usr/mips-linux-gnu -g 1234 -- /path/to/my_executable &
gdb-multiarch /path/to/my_executable
(gdb) target remote :1234

jreiser added a commit that referenced this issue Feb 9, 2020
#342
#339
	modified:   src/stub/src/include/linux.h
   consequences:
	modified:   .github/travis_testsuite_1-expected_sha256sums.sh
	modified:   src/stub/mips.r3000-linux.elf-fold.h
	modified:   src/stub/mipsel.r3000-linux.elf-fold.h
	modified:   src/stub/tmp/mips.r3000-linux.elf-fold.map
	modified:   src/stub/tmp/mipsel.r3000-linux.elf-fold.map
@jreiser
Copy link
Collaborator

jreiser commented Feb 9, 2020

The hw executable in attachment hw.zip no longer is compressible because the MIPS stub grew 20 bytes. The stub is 2771 (0xad3) bytes; the .text of hw is 0x1c44 bytes and can be compressed to 0x1186 bytes, but that is only 0xabe bytes less. Currently this is the criterion that UPX uses for an ELF executable. It may be possible to consider the whole file (not just the .text); that would be an enhancement.
It is somewhat unusual for debug info to be present in the executable that is input to UPX, because the debuginfo is not needed during execution.

$ readelf --sections hw
Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [17] .debug_aranges    MIPS_DWARF      00000000 002610 0003c0 00      0   0  8
  [18] .debug_info       MIPS_DWARF      00000000 0029d0 008b1e 00      0   0  1
  [19] .debug_abbrev     MIPS_DWARF      00000000 00b4ee 002430 00      0   0  1
  [20] .debug_line       MIPS_DWARF      00000000 00d91e 001b13 00      0   0  1
  [21] .debug_frame      MIPS_DWARF      00000000 00f434 0005e8 00      0   0  4
  [22] .debug_str        MIPS_DWARF      00000000 00fa1c 00110f 01  MS  0   0  1
  [23] .debug_loc        MIPS_DWARF      00000000 010b2b 00200a 00      0   0  1
  [24] .debug_ranges     MIPS_DWARF      00000000 012b35 0002c8 00      0   0  1
  [25] .gnu.attributes   GNU_ATTRIBUTES  00000000 012dfd 000010 00      0   0  1
  [26] .mdebug.abi32     PROGBITS        00000000 012e0d 000000 00      0   0  1

so that is 0003c0+008b1e+002430+001b13+0005e8+00110f+00200a+0002c8 bytes that could be removed by /usr/bin/strip.

@bol-van
Copy link
Author

bol-van commented Feb 9, 2020

tpws.zip

look at this file. Its large enough, stripped. It still does not work.
Nothing works on mips

@jreiser
Copy link
Collaborator

jreiser commented Feb 9, 2020

The fix 4fb1d41 of 12 hours ago is on the devel branch. Please build the tip of devel, and use that. It works for me:

$ qemu-mips  -L /usr/mips-linux-gnu  -strace -- ./foo
16884 open("/proc/self/exe",O_RDONLY) = 3
16884 mmap(NULL,100180,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x7f7e6000
16884 mmap(0x7f7e6000,99327,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_FIXED,3,0) = 0x7f7e6000
16884 cacheflush(2139086088,2636,3,2147479872,0,0) = 0
16884 mprotect(0x7f7fd000,5972,PROT_EXEC|PROT_READ) = 0
16884 readlink("/proc/self/exe",0x7fffe2e8,4095) = 37
16884 cacheflush(2147475280,212,3,2147475176,0,0) = 0
16884 mmap(0x00400000,245760,PROT_NONE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,-1,0) = 0x00400000
16884 mmap(0x00400000,171848,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,-1,0) = 0x00400000
16884 cacheflush(4194304,212,3,2147475088,0,0) = 0
16884 cacheflush(4194516,171636,3,2147475088,0,0) = 0
16884 mprotect(0x00400000,171848,PROT_EXEC|PROT_READ) = 0
16884 mmap(0x0043a000,1600,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,-1,0) = 0x0043a000
16884 cacheflush(4431872,1600,3,2147475088,0,0) = 0
16884 mprotect(0x0043a000,1600,PROT_READ|PROT_WRITE) = 0
16884 mmap(0x0043b000,972,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,-1,0) = 0x0043b000
16884 brk(0x0043c000) = 0x0043c000
16884 mmap(NULL,4096,PROT_READ,MAP_PRIVATE,3,0) = 0x7f7e5000
16884 close(3) = 0
16884 munmap(0x7f7e6000,100180) = 0
16884 set_thread_area(0x00442048) = 0
16884 set_tid_address(4435948,4,140,0,0,0) = 16884
16884 clock_gettime(0,2147475352,28,28,0,0) = 0
16884 writev(2,0x7fffdc88,0x2)Need port number
 = 17
16884 exit_group(1)
$ 

Contrast with tpws_upx, which hangs shortly after mprotect() where the fix was needed:

$ qemu-mips  -L /usr/mips-linux-gnu -strace -- ./tpws_upx
16909 open("/proc/self/exe",O_RDONLY) = 3
16909 mmap(NULL,95040,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x7f7e7000
16909 mmap(0x7f7e7000,94137,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_FIXED,3,0) = 0x7f7e7000
16909 cacheflush(2139085064,2616,3,2147479856,0,0) = 0
16909 mprotect(0x7f7fd000,4928,PROT_EXEC|PROT_READ) = 0
16909 readlink("/proc/self/exe",0x7fffe2d8,4095) = 42
16909 cacheflush(2147475264,212,3,2147475160,0,0) = 0
16909 mmap(0x00400000,245760,PROT_NONE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,-1,0) = 0x00400000
16909 mmap(0x00400000,171848,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,-1,0) = 0x00400000
16909 cacheflush(4194304,212,3,2147475072,0,0) = 0
16909 cacheflush(4194516,171636,3,2147475072,0,0) = 0
16909 mprotect(0x00400000,171848,PROT_EXEC|PROT_READ) = 0
   ## spins forever
^C--- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL, si_pid=0, si_uid=0} ---

$

@bol-van
Copy link
Author

bol-van commented Feb 9, 2020

Confirm. it works

@varac
Copy link

varac commented Jan 1, 2022

Please release a new version of upx, latest release 3.96 still doesn't work on mips:

❯ qemu-mips  -L /usr/mips-linux-gnu  -strace -- ./upx
114266 open("/proc/self/exe",O_RDONLY) = 3
114266 mmap(NULL,438624,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x3ff94000
114266 mmap(0x3ff94000,437605,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_FIXED,3,0) = 0x3ff94000
114266 cacheflush(1073735464,2616,3,4631921,0,0) = 0
114266 mprotect(0x3fffd000,8544,PROT_EXEC|PROT_READ) = 0
114266 readlink("/proc/self/exe",0x407fecac,4095) = 28
114266 cacheflush(1082124400,244,3,1073299728,0,0) = 0
114266 mmap(0x00400000,2363392,PROT_NONE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,-1,0) = 0x00400000
114266 mmap(0x00400000,2241500,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,-1,0) = 0x00400000
114266 cacheflush(4194304,244,3,1073299728,0,0) = 0
114266 cacheflush(4194548,2241256,3,1073721798,0,0) = 0
114266 mprotect(0x00400000,2241500,PROT_EXEC|PROT_READ) = 0

@jreiser
Copy link
Collaborator

jreiser commented Jan 1, 2022

@varac See #504 (comment) : it is believed that the UPX stub source for mips* (at the tip of of devel branch) is correct. While there has not yet been a release with this code for native execution of UPX on mips*, nevertheless UPX itself is totally cross-platform: every instance of upx (on ANY platform) can compress (and de-compress) executables for EVERY supported platform. Thus a cross-platform work-around exists: copy the mips* executables onto a Linux or Windows x86_64 system, compress using the x86_64 system, then copy the compressed executables back onto the mips* system. Auto-builds of every commit to devel source code can be accessed beginning at https://github.com/upx/upx-automatic-builds . For example, see the current builds at https://github.com/upx/upx/actions/runs/1641716844 .

markus-oberhumer pushed a commit that referenced this issue Aug 17, 2022
#342
#339
	modified:   src/stub/src/include/linux.h
   consequences:
	modified:   .github/travis_testsuite_1-expected_sha256sums.sh
	modified:   src/stub/mips.r3000-linux.elf-fold.h
	modified:   src/stub/mipsel.r3000-linux.elf-fold.h
	modified:   src/stub/tmp/mips.r3000-linux.elf-fold.map
	modified:   src/stub/tmp/mipsel.r3000-linux.elf-fold.map
yuos-bit added a commit to yuos-bit/AutoBuild-OpenWrt that referenced this issue Mar 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants