Compare commits
645 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fbde0b9f35 | |||
| 0e5f5e54cc | |||
| cbb5902066 | |||
| 92ec1b0598 | |||
| a62fc3abff | |||
| 08f8e55446 | |||
| 68f54a3247 | |||
| 29c099fe56 | |||
| 76b81c7b35 | |||
| d6b33ffd6b | |||
| 16b9873fa8 | |||
| ba4a686d1c | |||
| 4be3d79e12 | |||
| 2569b09dbe | |||
| 5d71e69941 | |||
| 16163bf20b | |||
| f1a97fecbd | |||
| a050f82f0e | |||
| ef7beea334 | |||
| 3f4acb33f9 | |||
| 14822e6395 | |||
| e82db4ed38 | |||
| 87b7ea9cf3 | |||
| 787b1fceff | |||
| 140d6ad839 | |||
| 46e8e22236 | |||
| c386db2b33 | |||
| 8dad091c6b | |||
| 3365ccbb9c | |||
| 2ced230965 | |||
| 989d10a3e1 | |||
| 62d8c69774 | |||
| cf704257b0 | |||
| a6cb6f57d3 | |||
| 141c703ed5 | |||
| 796d58867b | |||
| 2f483ec8e8 | |||
| e338918773 | |||
| d9effc58cf | |||
| 05d03f97fc | |||
| 03e891c0e8 | |||
| 4dfe9d52e9 | |||
| 9e65692b69 | |||
| 0687c9a57a | |||
| ffe1287016 | |||
| 75b7e7260f | |||
| d631e081bc | |||
| db5843d904 | |||
| 5ec16153f7 | |||
| 8c873ccdc8 | |||
| c95088f8d5 | |||
| 519fa55df7 | |||
| b8dda033ed | |||
| 0359e9c5c7 | |||
| d822b4a62a | |||
| d9e8c953b1 | |||
| 9eca502026 | |||
| cd0efe3edb | |||
| 8146e9cbcd | |||
| 5d95275024 | |||
| 49a97eea4b | |||
| 36e9c27e9c | |||
| 6e5153cd07 | |||
| c73da864c8 | |||
| 071bb75700 | |||
| 99374de340 | |||
| db7ae4ed5d | |||
| e61f481881 | |||
| 396a3ad2fc | |||
| be235ddc38 | |||
| 9e72ecd93d | |||
| 8e0bd936eb | |||
| 9d0270dcd6 | |||
| 713415c354 | |||
| 786550572e | |||
| 46caeddc81 | |||
| 71bfde2bfe | |||
| 76771b845a | |||
| a74e239e28 | |||
| 6e763b0b42 | |||
| 2f41ece017 | |||
| 01cd5fe0d5 | |||
| ed12ff7bb3 | |||
| f1386bb60d | |||
| 417bd06e76 | |||
| 91e46e3cf8 | |||
| deb5139c4d | |||
| 862ac5d014 | |||
| 028235d421 | |||
| 143d399849 | |||
| 375f171e47 | |||
| 387edcf4b2 | |||
| 011cd37cfb | |||
| 0d4254f319 | |||
| 4c407c2850 | |||
| 829e2d6c5d | |||
| a31c4bd474 | |||
| 17f24dc377 | |||
| de3e9f2809 | |||
| 4442a282e1 | |||
| 261010f23d | |||
| ede44ca6ee | |||
| 452a953234 | |||
| 2b122562ad | |||
| 6891bc3da3 | |||
| b31b8cd7f0 | |||
| e1379ac5ce | |||
| 0ef3f75d7a | |||
| 407a9e5be0 | |||
| 892bb9bf30 | |||
| 47ac871a12 | |||
| a38c3e7f6d | |||
| 08818355d1 | |||
| 0a68afef00 | |||
| 2c0783e327 | |||
| c2e5e45c84 | |||
| 014236c861 | |||
| 610fd7561b | |||
| d6f4480a4f | |||
| 28a6ac09ad | |||
| 86e4d24476 | |||
| 913a697ab2 | |||
| ebef2b1e44 | |||
| a61457b422 | |||
| 8f7f1135df | |||
| 89612c10c9 | |||
| d55bfb32f1 | |||
| d2b72cf496 | |||
| 8d90fffd46 | |||
| b84af27a86 | |||
| b45f28f3e9 | |||
| bfa1b5656a | |||
| 47f946cd65 | |||
| 970e7bfcda | |||
| a81c7a7cd6 | |||
| b0e1bd239f | |||
| 53ca41717a | |||
| 6a5bee0cdd | |||
| fd3ae51f83 | |||
| 5e5954a808 | |||
| add8540909 | |||
| 06a302aed0 | |||
| 147432d38d | |||
| 2a003ff72b | |||
| 8660d3324d | |||
| 6c59b73ae5 | |||
| 80218c1eca | |||
| f24d96d59f | |||
| d14bd49f46 | |||
| 1a692a0873 | |||
| 631a1a4ddc | |||
| 57df7601d9 | |||
| f7650000aa | |||
| 6f93c2d9b2 | |||
| 1654764968 | |||
| 1a1b8416e2 | |||
| 36c66d52a6 | |||
| 68fe43d488 | |||
| 877b9ee23b | |||
| 80ff93beeb | |||
| b9ddd2812b | |||
| ba54b56de4 | |||
| 85be67bc2d | |||
| ae20e01d2c | |||
| d094e8c3fc | |||
| f009fe1f63 | |||
| 2007fe5f49 | |||
| 84989ffa04 | |||
| 31b629a19c | |||
| e762d9e274 | |||
| 6833267b19 | |||
| 05f2833388 | |||
| 0d026ef18d | |||
| b756d93891 | |||
| f54513586d | |||
| 6c519c237e | |||
| 4ffde4db98 | |||
| 41847d31e7 | |||
| 24ce25bb5c | |||
| e051b69e80 | |||
| 59283d1164 | |||
| 0de32a5edc | |||
| 4f80066dcb | |||
| 04ddc8003f | |||
| 3213f98d66 | |||
| 1f16f85c51 | |||
| c03cb3a11c | |||
| 62e29a6546 | |||
| 3574b065d6 | |||
| c0c47f41be | |||
| 37761d580f | |||
| e075c8e691 | |||
| 0c61ca1a6b | |||
| 1846fa1f54 | |||
| 579ce20cad | |||
| 12e4bcba5d | |||
| b4f57dee3b | |||
| f11673ae3f | |||
| a27af7dd7e | |||
| 2b26a3cc14 | |||
| 47c4849694 | |||
| 30a4adf331 | |||
| 117a721166 | |||
| 1a219e62ba | |||
| c8d54b324b | |||
| 0ac2971fc1 | |||
| 348a40201b | |||
| 9f20ddc800 | |||
| 6f1cc2c1e5 | |||
| 601cd95277 | |||
| 8e9ce59ef2 | |||
| d76ef8e3cf | |||
| c19ffafd8d | |||
| 996a99ad75 | |||
| affb926d44 | |||
| c506e534aa | |||
| 9994315070 | |||
| 4f0d89ef8b | |||
| aab984618d | |||
| 8b662bc6b5 | |||
| 03ce7a8db3 | |||
| 033e7928b5 | |||
| b095f2a158 | |||
| 196c0e0ebc | |||
| 8ab309630b | |||
| 42bac47a71 | |||
| 3bc4de2236 | |||
| a6e4b45a38 | |||
| 28e97ccaf2 | |||
| 255781c029 | |||
| 7f5635ea8c | |||
| 4f18ec726c | |||
| 263622d628 | |||
| 1dfd2443ac | |||
| 881bd53f60 | |||
| ec4404b1ba | |||
| badaeac81f | |||
| 618d5ddaff | |||
| 4ed74af868 | |||
| 123d9af7d0 | |||
| 4f17b30915 | |||
| 1fc265b0aa | |||
| afae9b8d17 | |||
| 481be44879 | |||
| b8530b0f0b | |||
| 69de79684f | |||
| 6e6fd057b5 | |||
| 4b0ebf2b80 | |||
| ee82c32119 | |||
| 3fe6731035 | |||
| 1c3f3b5705 | |||
| def1ccffc4 | |||
| fa2e531343 | |||
| 814ddbc6cc | |||
| 267e8dcfb6 | |||
| 49ec1561f8 | |||
| e2dc612153 | |||
| 8f225431fe | |||
| 194be5e0b7 | |||
| 6788a05dd1 | |||
| 6a7066ac2f | |||
| ec5ff4e973 | |||
| fe6d460531 | |||
| 9cb97af10f | |||
| 1c784eea3d | |||
| 59dd33a461 | |||
| 97ebd912dc | |||
| 742fcc060c | |||
| 3ad5cb8a23 | |||
| 0d1f12e31a | |||
| a8ddf8f66d | |||
| f7a9c0a248 | |||
| 190badb395 | |||
| 3d91ab6c31 | |||
| c15b8d71bc | |||
| 5a707dba8a | |||
| ffd2fcde6b | |||
| 8e4056c1e4 | |||
| 1554e2b135 | |||
| 4715cbb70d | |||
| fd1611079a | |||
| 8edc03df64 | |||
| 9f5c0af5b8 | |||
| 6d6eeba5d5 | |||
| 5dfb64ef71 | |||
| e5bda7add7 | |||
| 77f9b336bd | |||
| cf930d0dde | |||
| f01c94e8bc | |||
| 0d774527b4 | |||
| 58ba9496d0 | |||
| 1993e94e53 | |||
| 3bcc06ed09 | |||
| 2f6ce88e28 | |||
| cd1dec9fc7 | |||
| 05872d7650 | |||
| 1dcee2ffa2 | |||
| 5f622efb77 | |||
| 52e8326d54 | |||
| 436532bed7 | |||
| d15e789200 | |||
| 98942f5528 | |||
| c7c21dc122 | |||
| 4500c1d1a4 | |||
| b8b983dded | |||
| d6a6673971 | |||
| 0580fe8db8 | |||
| c727e24138 | |||
| b83698ebf5 | |||
| 3fbbaa5130 | |||
| 2f48b840ae | |||
| efdee11d5a | |||
| 4c87e11aeb | |||
| e881e008b8 | |||
| 1b2837915d | |||
| d076a6724f | |||
| 386af71c39 | |||
| 49f277192c | |||
| 5974a6276b | |||
| e06a390771 | |||
| b34e204676 | |||
| 755d990dfd | |||
| 7185358b98 | |||
| 3843ec1e02 | |||
| cfc5631d5d | |||
| e64555aca0 | |||
| ef52ebb529 | |||
| c98136ca4f | |||
| 65f44d24ca | |||
| 44f20782fd | |||
| 9b1d76a5d0 | |||
| 21b5074ce8 | |||
| 0b8825fecb | |||
| 3d3c20e507 | |||
| 67a282f19f | |||
| 92023b533a | |||
| c1d14c150e | |||
| aa656c74d5 | |||
| e39b7ffe30 | |||
| 1897148abc | |||
| b76118802a | |||
| 8266aa3343 | |||
| ab0c349261 | |||
| d5e0e66426 | |||
| c5b3107f83 | |||
| 1a0a64e4de | |||
| 6bd9805bcc | |||
| f74c2af65c | |||
| 9531bdf674 | |||
| 76e705e7ee | |||
| d35211328e | |||
| b7bbd81dda | |||
| 9836dd5d10 | |||
| 2109ad320d | |||
| c026121c0e | |||
| ee0c87f7b1 | |||
| 709fb93a22 | |||
| b38cd0a48d | |||
| 264435c32d | |||
| c285929ad3 | |||
| 1cbea8157d | |||
| 0a10334f1b | |||
| f0d5a6ebac | |||
| db7086b5e6 | |||
| 0e92280b33 | |||
| 0d7255158a | |||
| 33564b68dd | |||
| ba942b952a | |||
| bd7f28896e | |||
| 18fe124696 | |||
| ea3a3b6e1c | |||
| e6c06aacff | |||
| 1aee92cd5c | |||
| 40c4cad491 | |||
| 013d46fb02 | |||
| f0f465411f | |||
| 32ce83475d | |||
| ec0d3f5b5d | |||
| 75294b9146 | |||
| 26a0eb68ef | |||
| b983e29fb0 | |||
| 68dadabc29 | |||
| ed9fd3f0e0 | |||
| fa9573436a | |||
| 6d2058c3b7 | |||
| 0d7f93b877 | |||
| f022c9d510 | |||
| 5964a06386 | |||
| f14dc4a4e9 | |||
| fd56e2534c | |||
| 08962a74ab | |||
| f850d36c52 | |||
| c5fb161477 | |||
| bfc2fab33f | |||
| ec9d6c4fd2 | |||
| 6135d61e3d | |||
| a677242a2c | |||
| 6602f30112 | |||
| a4b8dc18c1 | |||
| c0d4741f88 | |||
| b33718180c | |||
| 3872393b29 | |||
| 1d72a7df99 | |||
| 5455908772 | |||
| 8882192fac | |||
| 7b77491c06 | |||
| 20bf214d6e | |||
| 8ab3e63aeb | |||
| 0dc03214c5 | |||
| 362e98b43d | |||
| 193e085cf0 | |||
| e0df2a342b | |||
| ba19ccac43 | |||
| d7261b7a78 | |||
| 0d80173efd | |||
| 930f07d15e | |||
| 66df7389d2 | |||
| c7bf0b6ddd | |||
| 0bc361adeb | |||
| 4fff523a6d | |||
| 67e09fb342 | |||
| c360806f47 | |||
| 7b74b73b08 | |||
| e9a851c0d4 | |||
| b13b169149 | |||
| 455329a745 | |||
| a68b76c8b4 | |||
| 96e3899216 | |||
| 771ab5ea9a | |||
| 3c87e6b270 | |||
| 6d8afec510 | |||
| 89e25657d8 | |||
| 29387f1fcf | |||
| 58e885c052 | |||
| 984dfcd7e1 | |||
| 3785479086 | |||
| 8ed280907c | |||
| d742671205 | |||
| 87e72c28a4 | |||
| 4dee357362 | |||
| 431f4b9b0d | |||
| dd5b7825d5 | |||
| 02bc48925a | |||
| 4eb505755e | |||
| 83e94a70ea | |||
| 8a150b27c3 | |||
| 1a51451ec2 | |||
| 41e51bfb77 | |||
| 7e1d9bc768 | |||
| ba065ec1d8 | |||
| fe057a91c8 | |||
| d2c36eefc9 | |||
| 28d56bab04 | |||
| 2500eff90d | |||
| 153446b3a1 | |||
| 391f5caaa2 | |||
| cc0df92444 | |||
| 03910d67c3 | |||
| fec5cc864e | |||
| cb78362713 | |||
| 4c5b1a6ff4 | |||
| 83c5727698 | |||
| 80838ff1e9 | |||
| 29e8d072b7 | |||
| d7592f01e1 | |||
| 392f283d9e | |||
| bcd738ebbb | |||
| 8020c52c48 | |||
| 3f566e541d | |||
| be4a631dc8 | |||
| 0bfdf908c1 | |||
| 6f2fc23f77 | |||
| f3a47c7e70 | |||
| 36349ffabb | |||
| b13f7366cf | |||
| 9181bcd9a7 | |||
| 7dbc1d894b | |||
| 5720445d15 | |||
| a90027521d | |||
| e02d400bf6 | |||
| efadb8fd31 | |||
| a19d06561b | |||
| 0b685d11c9 | |||
| 28f019d672 | |||
| bf5cbfffc2 | |||
| fe021e7c51 | |||
| c42fb54bc6 | |||
| 9382b68781 | |||
| 178198a417 | |||
| 7068e90771 | |||
| 1c762f23d0 | |||
| fd2b9a6e21 | |||
| db43910288 | |||
| f248c0460e | |||
| b8e3c0ceb4 | |||
| b5053d889e | |||
| 12ba7776b3 | |||
| 7817e88d03 | |||
| 8dec65853d | |||
| 88e3cb3be1 | |||
| fa702b48e3 | |||
| 299dcf6686 | |||
| 27f9ae5bbb | |||
| 9cb3a853f1 | |||
| 95c8ef4148 | |||
| a41bb52014 | |||
| 914cd7221e | |||
| 2dfc0a58ab | |||
| 0c9f3c638a | |||
| a966d6acf1 | |||
| 1e0c38b5f9 | |||
| d3323d6550 | |||
| ebed0b9f20 | |||
| f654a453dc | |||
| 10decf94cc | |||
| 96dd4817f1 | |||
| 72906cdc6a | |||
| fba4375be0 | |||
| 75120676ad | |||
| 7daf63fd3f | |||
| 014de25f6f | |||
| 3fc6535012 | |||
| 4fc0a32572 | |||
| dcc704a357 | |||
| bd8acbde97 | |||
| 112b10c19d | |||
| d89e561a85 | |||
| 49c1da79c8 | |||
| 0a72f00175 | |||
| 1af5820db0 | |||
| c117491549 | |||
| d8748f4270 | |||
| c0ba6e13e4 | |||
| c34daf1a35 | |||
| d461b53235 | |||
| c3ee14eb67 | |||
| 869fb8e327 | |||
| fbbc3024d6 | |||
| f1ba0c0aa7 | |||
| 54340ab4bf | |||
| 39732eee5e | |||
| a9e4526a6d | |||
| 57a6d2abf9 | |||
| d6246941ac | |||
| 2eb91f9b91 | |||
| 34ae413607 | |||
| ee9f8c184b | |||
| 7a84afcbdb | |||
| b8a16ea99d | |||
| 095466d5c7 | |||
| 89cfa22c3f | |||
| 1f18050930 | |||
| 537b78d564 | |||
| 717fd57ce1 | |||
| 3fb7786868 | |||
| 17ecfc9765 | |||
| 5326260a76 | |||
| e7522f4bdf | |||
| 504deeff42 | |||
| b7785b64cf | |||
| f914cb6858 | |||
| 91051d2521 | |||
| 51536a7acd | |||
| 263ccab6e3 | |||
| 9f87755dcb | |||
| 60b4cca5e5 | |||
| d2718e99a4 | |||
| 69a00c0ab3 | |||
| 3272d23917 | |||
| 7f0545cae7 | |||
| 68f35deb86 | |||
| c4f4035072 | |||
| a7d8845952 | |||
| a3378393b0 | |||
| 3dfe0ad478 | |||
| 9a3b7a4f3f | |||
| 78579b1103 | |||
| 7d50344512 | |||
| 7a00c12065 | |||
| af71e67681 | |||
| b3e20fc324 | |||
| bd1014abb6 | |||
| 7f76664a5d | |||
| 0a5a80b05d | |||
| 2d63da0660 | |||
| 8387527d2e | |||
| 5d03ba7d63 | |||
| 0ece50c122 | |||
| f2ac297252 | |||
| 0ca8ae17d4 | |||
| 88ca87cf9e | |||
| 0d69d228e4 | |||
| a3afe95306 | |||
| 9fb4af8658 | |||
| 9bb6ba9311 | |||
| faa42ba341 | |||
| 596827a912 | |||
| 89b4292445 | |||
| dd88737414 | |||
| 5456cfc304 | |||
| 1e66096ea7 | |||
| 2b6ae3908c | |||
| 1924612479 | |||
| 2af5bdeaab | |||
| b28565b38d | |||
| fec602362b | |||
| 6753c5f45a | |||
| 2f3c108d42 | |||
| ce6d99bdb4 | |||
| 86d4125893 | |||
| 3a18f00379 | |||
| e6274904a7 | |||
| 3677395444 | |||
| 22ba35b3b5 | |||
| 9c1ab9979b | |||
| eaa463e1c9 | |||
| 6984be48c3 | |||
| b739bd3d79 | |||
| 23f3e4396c | |||
| c264750924 | |||
| c155f0a5d5 | |||
| 76734f086d | |||
| 4f2d1172dd | |||
| 75caf4e297 | |||
| 509ab8261f | |||
| 1e05b40d4f | |||
| 451390f835 | |||
| 58cce9d2f8 | |||
| 2eb6e3b0ea | |||
| fb1181ed26 | |||
| 6d5e1d529d | |||
| 0e0ca08924 | |||
| 5d948a67a8 | |||
| 6a4db2ecab | |||
| f700273624 | |||
| 0c198e0ccc | |||
| 71ffbbc420 | |||
| 4fd09b889d | |||
| 4cb2a3eebe | |||
| c25186b1f6 | |||
| 779033d0bc | |||
| 3e31560e7d | |||
| d23d7e8775 | |||
| f6fdf5cb7f | |||
| 1879ccd27d |
-13
@@ -1,13 +0,0 @@
|
|||||||
.bzr*
|
|
||||||
.darcs*
|
|
||||||
.git*
|
|
||||||
.hg*
|
|
||||||
_darcs
|
|
||||||
B
|
|
||||||
build*
|
|
||||||
doxygen
|
|
||||||
maint
|
|
||||||
ChangeLog.cvs*
|
|
||||||
GNUmakefile
|
|
||||||
MMakefile
|
|
||||||
TODO.*
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
.bzr*
|
|
||||||
.darcs*
|
|
||||||
.git*
|
|
||||||
.hg*
|
|
||||||
_darcs
|
|
||||||
B
|
|
||||||
build*
|
|
||||||
doxygen
|
|
||||||
maint
|
|
||||||
ChangeLog.cvs*
|
|
||||||
GNUmakefile
|
|
||||||
MMakefile
|
|
||||||
TODO.*
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
syntax: regexp
|
||||||
|
|
||||||
|
^\.bzr
|
||||||
|
^ChangeLog
|
||||||
|
^build
|
||||||
|
^maint
|
||||||
|
|
||||||
|
syntax: glob
|
||||||
|
|
||||||
|
*.a
|
||||||
|
*.dll
|
||||||
|
*.lib
|
||||||
|
*.py[cdo]
|
||||||
|
*.so
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
doc/*.1
|
||||||
|
doc/*.doc
|
||||||
|
doc/*.html
|
||||||
|
doc/*.man
|
||||||
|
doc/*.ps
|
||||||
|
doc/*.tex
|
||||||
|
|
||||||
|
src/GNUmakefile
|
||||||
|
src/MMakefile
|
||||||
|
src/compress_nrv*
|
||||||
|
src/*.mft
|
||||||
|
src/*.rc
|
||||||
|
|
||||||
|
src/*.d
|
||||||
|
src/*.exe
|
||||||
|
src/*.map
|
||||||
|
src/*.o
|
||||||
|
src/*.obj
|
||||||
|
src/*.out
|
||||||
|
src/*.res
|
||||||
|
src/*.ttp
|
||||||
|
|
||||||
|
stub/**MMakefile
|
||||||
|
stub/**.*-stamp
|
||||||
|
stub/tmp*/*
|
||||||
|
stub/**/tmp*/*
|
||||||
|
|
||||||
|
stub/tools/armpe/armpe_tester
|
||||||
|
|
||||||
|
stub/tools/sstrip/amd64-linux-sstrip
|
||||||
|
stub/tools/sstrip/i386-linux-sstrip
|
||||||
|
stub/tools/sstrip/sstrip
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
140415ffbcef86a42b4d672249927364430d3d38 RELEASE_111
|
||||||
|
223ac5b23f9731ceac9ff8d65167df4900776e36 RELEASE_190
|
||||||
|
2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194
|
||||||
|
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
|
||||||
|
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
|
||||||
|
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
|
||||||
|
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
|
||||||
|
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
|
||||||
|
b82ef51896199484afe5b0553af7d1e59b7ce428 BRANCHPOINT_FOR_upx2.hg
|
||||||
|
c2e0cd4d621b047f254f2def42132a03683ff52c RELEASE_192
|
||||||
|
d276aa09033c24d0981bc3f4fee5628aecc988ad RELEASE_290
|
||||||
|
eb1ce56dce7dd1835964362470610925963b9043 RELEASE_110
|
||||||
|
ed96891ef795bceec6b7ff3ca1ca7764431bfb39 RELEASE_191
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
# Toplevel Makefile for UPX
|
#
|
||||||
|
# UPX toplevel Makefile - needs GNU make 3.80 or better
|
||||||
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
@@ -8,36 +10,38 @@ srcdir = .
|
|||||||
top_srcdir = .
|
top_srcdir = .
|
||||||
|
|
||||||
|
|
||||||
|
# info: src/stub needs GNU make 3.81 and special build tools
|
||||||
|
BUILD_STUB = 0
|
||||||
|
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
||||||
|
BUILD_STUB = 1
|
||||||
|
endif
|
||||||
|
ifneq ($(wildcard $(HOME)/bin/bin-upx/.),)
|
||||||
|
BUILD_STUB = 1
|
||||||
|
endif
|
||||||
|
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.79 3.79.1 3.80),)
|
||||||
|
BUILD_STUB = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@echo "UPX info: please choose a target for 'make'"
|
@echo "UPX info: please choose a target for 'make'"
|
||||||
|
|
||||||
all mostlyclean clean distclean maintainer-clean:
|
all mostlyclean clean distclean maintainer-clean:
|
||||||
$(MAKE) -C src/stub/util/sstrip $@
|
ifeq ($(BUILD_STUB),1)
|
||||||
$(MAKE) -C src/stub $@
|
$(MAKE) -C src/stub $@
|
||||||
|
endif
|
||||||
$(MAKE) -C src $@
|
$(MAKE) -C src $@
|
||||||
$(MAKE) -C doc $@
|
$(MAKE) -C doc $@
|
||||||
|
|
||||||
dist: distclean
|
# automatically generate ChangeLog from Mercurial repo
|
||||||
false
|
ChangeLog:
|
||||||
|
ifneq ($(wildcard .hg/data/.),)
|
||||||
|
hg log --style=changelog > $@
|
||||||
ifneq ($(wildcard CVS/R*),)
|
else
|
||||||
CVS_ROOT := $(shell cat CVS/Root)
|
@echo "UPX info: no hg repo found"
|
||||||
CVS_REPO := $(shell cat CVS/Repository)
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
cvs-info:
|
|
||||||
@echo 'CVS info: $(CVS_ROOT) $(CVS_REPO)'
|
|
||||||
|
|
||||||
cvs-admin-ko:
|
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
||||||
cvs admin -ko .
|
.PHONY: ChangeLog
|
||||||
cvs -q -z6 update -P -d
|
|
||||||
|
|
||||||
# automatically generate ChangeLog from CVS
|
|
||||||
ChangeLog ChangeLog.cvs:
|
|
||||||
perl $(srcdir)/scripts/cvs2cl.pl --utc -f ChangeLog.cvs
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
|
||||||
.PHONY: dist cvs-info cvs-admin-ko ChangeLog ChangeLog.cvs
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,55 @@
|
|||||||
User visible changes for UPX
|
User visible changes for UPX
|
||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
|
Changes in 2.91 beta (29 Nov 2006):
|
||||||
|
* assorted bug fixes
|
||||||
|
* arm/pe: fix "missing" icon & version info resource problem for wince 5
|
||||||
|
* win32/pe & arm/pe: added option --compress-icons=3 to compress all icons
|
||||||
|
|
||||||
|
Changes in 2.90 beta (08 Oct 2006):
|
||||||
|
* LZMA algorithm support for most of the 32-bit and 64-bit file formats;
|
||||||
|
use new option '--lzma' to enable
|
||||||
|
* new format: BSD/elf386 supporting FreeBSD, NetBSD and OpenBSD
|
||||||
|
via auto-detection of PT_NOTE or EI_OSABI
|
||||||
|
* arm/pe: all the NRV compression methods are now supported
|
||||||
|
(only NRV2D is missing in thumb mode)
|
||||||
|
* linux/elf386, linux/ElfAMD: remember /proc/self/exe in environment
|
||||||
|
* major source code changes: the runtime decompression stubs are now
|
||||||
|
built from internal ELF objects
|
||||||
|
|
||||||
|
==================================================================
|
||||||
|
|
||||||
|
Changes in 2.03 (07 Nov 2006):
|
||||||
|
* bvmlinuz/386: fix for kernels not at 0x100000; also allow x86_64
|
||||||
|
* linux/elf386: work around Linux kernel bug (0-length .bss needs PF_W)
|
||||||
|
|
||||||
|
Changes in 2.02 (13 Aug 2006):
|
||||||
|
* linux/386: work around Linux kernel bug (".bss" requires PF_W)
|
||||||
|
* linux/ppc32, mach/ppc32: compressed programs now work on a 405 CPU
|
||||||
|
* vmlinuz/386: fixed zlib uncompression problem on DOS
|
||||||
|
|
||||||
|
Changes in 2.01 (06 Jun 2006):
|
||||||
|
* arm/pe: better DLL support
|
||||||
|
* dos/exe: device driver support added
|
||||||
|
* linux/386: Fix --force-execve for PaX, grSecurity, and strict SELinux.
|
||||||
|
/tmp must support execve(); therefore /tmp cannot be mounted 'noexec'.
|
||||||
|
* win32/pe & arm/pe: added new option '--keep-resource=' for
|
||||||
|
excluding selected resources from compression
|
||||||
|
|
||||||
|
Changes in 2.00 (27 Apr 2006):
|
||||||
|
* linux/386: the stub now prints an error message if some strict
|
||||||
|
SELinux mode does prevent runtime decompression and execution
|
||||||
|
(for a fully SELinux-compatible but otherwise inferior compression
|
||||||
|
format you can use the '--force-execve' option)
|
||||||
|
* linux/386: worked around a problem where certain Linux kernels
|
||||||
|
clobber the %ebx register during a syscall
|
||||||
|
* win32/pe: disable filters for files with broken PE headers
|
||||||
|
|
||||||
|
Changes in 1.96 beta (13 Apr 2006):
|
||||||
|
* arm/pe: added filter support
|
||||||
|
* win32/pe: removed an unnecessary check so that Delphi 2006 and
|
||||||
|
Digital Mars C++ programs finally are supported
|
||||||
|
|
||||||
Changes in 1.95 beta (09 Apr 2006):
|
Changes in 1.95 beta (09 Apr 2006):
|
||||||
* arm/pe: added DLL support
|
* arm/pe: added DLL support
|
||||||
* arm/pe: added thumb mode stub support
|
* arm/pe: added thumb mode stub support
|
||||||
@@ -21,8 +70,8 @@ Changes in 1.93 beta (07 Feb 2005):
|
|||||||
* vmlinuz/386: fixes to support more kernels
|
* vmlinuz/386: fixes to support more kernels
|
||||||
|
|
||||||
Changes in 1.92 beta (20 Jul 2004):
|
Changes in 1.92 beta (20 Jul 2004):
|
||||||
* win32/pe: added option `--strip-loadconf' to strip the SEH
|
* win32/pe: added option '--strip-loadconf' to strip the SEH load
|
||||||
load config section
|
config section [NOTE: this option is obsolete since UPX 1.94]
|
||||||
* win32/pe: try to detect .NET (win32/net) files [not yet supported by UPX]
|
* win32/pe: try to detect .NET (win32/net) files [not yet supported by UPX]
|
||||||
* vmlinux/386: new format that directly supports building Linux kernels
|
* vmlinux/386: new format that directly supports building Linux kernels
|
||||||
* source code: now compiles cleanly under Win64
|
* source code: now compiles cleanly under Win64
|
||||||
@@ -33,7 +82,7 @@ Changes in 1.91 beta (30 Jun 2004):
|
|||||||
* vmlinuz/386: added support for recent kernels
|
* vmlinuz/386: added support for recent kernels
|
||||||
* watcom/le: don't crash on files without relocations
|
* watcom/le: don't crash on files without relocations
|
||||||
* win32/pe: stricter checks of some PE values
|
* win32/pe: stricter checks of some PE values
|
||||||
* option `--brute' now implies `--crp-ms=999999'.
|
* option '--brute' now implies '--crp-ms=999999'.
|
||||||
* source code: much improved portability using ACC, the
|
* source code: much improved portability using ACC, the
|
||||||
Automatic Compiler Configuration
|
Automatic Compiler Configuration
|
||||||
* source code: compile fixes for strict ISO C++ compilers
|
* source code: compile fixes for strict ISO C++ compilers
|
||||||
@@ -42,9 +91,9 @@ Changes in 1.91 beta (30 Jun 2004):
|
|||||||
|
|
||||||
Changes in 1.90 beta (11 Nov 2002):
|
Changes in 1.90 beta (11 Nov 2002):
|
||||||
* implemented several new options for finer compression control:
|
* implemented several new options for finer compression control:
|
||||||
`--all-methods', `--all-filters' and `--brute'
|
'--all-methods', '--all-filters' and '--brute'
|
||||||
* ps1/exe: new format - UPX now supports PlayStation One programs
|
* ps1/exe: new format - UPX now supports PlayStation One programs
|
||||||
* linux/386: added the option `--force-execve'
|
* linux/386: added the option '--force-execve'
|
||||||
* vmlinuz/386: better kernel detection and sanity checks
|
* vmlinuz/386: better kernel detection and sanity checks
|
||||||
* re-synced with upx 1.24 branch
|
* re-synced with upx 1.24 branch
|
||||||
* documentation updates
|
* documentation updates
|
||||||
@@ -89,9 +138,9 @@ Changes in 1.22 (27 Jun 2002)
|
|||||||
Digital Mars C++ and Watcom C++
|
Digital Mars C++ and Watcom C++
|
||||||
|
|
||||||
Changes in 1.21 (01 Jun 2002)
|
Changes in 1.21 (01 Jun 2002)
|
||||||
* New option `--crp-ms=' for slightly better compression at the cost
|
* New option '--crp-ms=' for slightly better compression at the cost
|
||||||
of higher memory requirements during compression.
|
of higher memory requirements during compression.
|
||||||
Try `upx --best --crp-ms=100000'. See the docs for more info.
|
Try 'upx --best --crp-ms=100000'. See the docs for more info.
|
||||||
* source code: portability fixes
|
* source code: portability fixes
|
||||||
* source code: compile fixes for g++ 3.0 and g++ 3.1
|
* source code: compile fixes for g++ 3.0 and g++ 3.1
|
||||||
|
|
||||||
@@ -129,7 +178,7 @@ Changes in 1.05 (24 Jan 2001)
|
|||||||
at the unstable UPX 1.1x beta versions for that)
|
at the unstable UPX 1.1x beta versions for that)
|
||||||
|
|
||||||
Changes in 1.04 (19 Dec 2000)
|
Changes in 1.04 (19 Dec 2000)
|
||||||
* dos/exe: fixed an internal error when using `--no-reloc'
|
* dos/exe: fixed an internal error when using '--no-reloc'
|
||||||
* win32/pe: fixed a rare bug in the relocation handling code
|
* win32/pe: fixed a rare bug in the relocation handling code
|
||||||
* some tunings for the default compression level
|
* some tunings for the default compression level
|
||||||
|
|
||||||
@@ -137,7 +186,7 @@ Changes in 1.03 (30 Nov 2000)
|
|||||||
* linked with a new version of the NRV compression library:
|
* linked with a new version of the NRV compression library:
|
||||||
- improved compression ratio a little bit
|
- improved compression ratio a little bit
|
||||||
- overall significantly faster compression
|
- overall significantly faster compression
|
||||||
- much faster when using high compression levels like `-9' or `--best'
|
- much faster when using high compression levels like '-9' or '--best'
|
||||||
- much faster with large files
|
- much faster with large files
|
||||||
* atari/tos: added support for FreeMiNT
|
* atari/tos: added support for FreeMiNT
|
||||||
* the 32-bit DOS version now uses the new CWSDSTUB extender
|
* the 32-bit DOS version now uses the new CWSDSTUB extender
|
||||||
@@ -145,7 +194,7 @@ Changes in 1.03 (30 Nov 2000)
|
|||||||
Changes in 1.02 (13 Sep 2000)
|
Changes in 1.02 (13 Sep 2000)
|
||||||
* watcom/le: fixed a problem with the Causeway extender
|
* watcom/le: fixed a problem with the Causeway extender
|
||||||
* win32/pe: don't automatically strip relocs if they seem needed
|
* win32/pe: don't automatically strip relocs if they seem needed
|
||||||
* support multiple backup generations when using `-k'
|
* support multiple backup generations when using '-k'
|
||||||
* updated the console screen driver
|
* updated the console screen driver
|
||||||
|
|
||||||
Changes in 1.01 (09 Apr 2000)
|
Changes in 1.01 (09 Apr 2000)
|
||||||
@@ -173,7 +222,7 @@ Changes in 0.99.1 (29 Feb 2000)
|
|||||||
|
|
||||||
Changes in 0.99 (25 Feb 2000)
|
Changes in 0.99 (25 Feb 2000)
|
||||||
* FULL SOURCE CODE RELEASED UNDER THE TERMS OF THE GNU GPL
|
* FULL SOURCE CODE RELEASED UNDER THE TERMS OF THE GNU GPL
|
||||||
* win32/pe: changed default to `--strip-relocs=1'
|
* win32/pe: changed default to '--strip-relocs=1'
|
||||||
* dos/com and dos/sys: fixed a bad decompressor problem
|
* dos/com and dos/sys: fixed a bad decompressor problem
|
||||||
* linux/386: the counter for the progress indicator was off by one
|
* linux/386: the counter for the progress indicator was off by one
|
||||||
|
|
||||||
@@ -196,7 +245,7 @@ Changes in 0.91 (13 Nov 1999)
|
|||||||
* dos/exe: correctly restore cs when uncompressing
|
* dos/exe: correctly restore cs when uncompressing
|
||||||
|
|
||||||
Changes in 0.90 (10 Nov 1999)
|
Changes in 0.90 (10 Nov 1999)
|
||||||
* all formats: `--overlay=copy' now is the default overlay mode
|
* all formats: '--overlay=copy' now is the default overlay mode
|
||||||
* improved compression ratio for most files
|
* improved compression ratio for most files
|
||||||
* win32/pe: uncompression is finally supported
|
* win32/pe: uncompression is finally supported
|
||||||
* win32/pe: never compress REGISTRY resources
|
* win32/pe: never compress REGISTRY resources
|
||||||
@@ -206,7 +255,7 @@ Changes in 0.90 (10 Nov 1999)
|
|||||||
* win32/pe: somewhat less memory is required during compression
|
* win32/pe: somewhat less memory is required during compression
|
||||||
* linux/386: fixed compression of scripts which was broken since 0.71
|
* linux/386: fixed compression of scripts which was broken since 0.71
|
||||||
* linux/386: more FreeBSD compatibility issues
|
* linux/386: more FreeBSD compatibility issues
|
||||||
* changed option: `-i' now prints some more details during compression
|
* changed option: '-i' now prints some more details during compression
|
||||||
(not finished yet)
|
(not finished yet)
|
||||||
|
|
||||||
Changes in 0.84 (04 Oct 1999)
|
Changes in 0.84 (04 Oct 1999)
|
||||||
@@ -222,7 +271,7 @@ Changes in 0.83 (17 Sep 1999)
|
|||||||
Changes in 0.82 (16 Aug 1999)
|
Changes in 0.82 (16 Aug 1999)
|
||||||
* dos/exe: fixed a decompressor bug which could cause crash on some files
|
* dos/exe: fixed a decompressor bug which could cause crash on some files
|
||||||
* linux/386: section headers are now stripped from the stub so that
|
* linux/386: section headers are now stripped from the stub so that
|
||||||
`strip' won't ruin a compressed file any longer
|
'strip' won't ruin a compressed file any longer
|
||||||
* wc/le: support for stack not in the last object disabled again
|
* wc/le: support for stack not in the last object disabled again
|
||||||
* win32/pe: removed some unneeded data
|
* win32/pe: removed some unneeded data
|
||||||
|
|
||||||
@@ -231,32 +280,32 @@ Changes in 0.81 (04 Aug 1999)
|
|||||||
* dos/com: fixed an internal error that could happen with very small files
|
* dos/com: fixed an internal error that could happen with very small files
|
||||||
|
|
||||||
Changes in 0.80 (03 Aug 1999)
|
Changes in 0.80 (03 Aug 1999)
|
||||||
* you can set some default options in the environment var `UPX'
|
* you can set some default options in the environment var 'UPX'
|
||||||
* dos/com: the decompressor stub now checks for enough free memory
|
* dos/com: the decompressor stub now checks for enough free memory
|
||||||
* dos/exe: decompressor rewritten, some bugs are fixed
|
* dos/exe: decompressor rewritten, some bugs are fixed
|
||||||
* dos/exe: new option `--no-reloc': no relocation data is put into
|
* dos/exe: new option '--no-reloc': no relocation data is put into
|
||||||
the DOS header
|
the DOS header
|
||||||
* tmt/adam: added support for more stubs, detect already packed files
|
* tmt/adam: added support for more stubs, detect already packed files
|
||||||
* tmt/adam: new option `--copy-overlay'
|
* tmt/adam: new option '--copy-overlay'
|
||||||
* wc/le: reduced memory requirement during uncompression
|
* wc/le: reduced memory requirement during uncompression
|
||||||
* wc/le: support files which do not contain their stack in the last object
|
* wc/le: support files which do not contain their stack in the last object
|
||||||
* wc/le: fixed a bug which could cause a crash, improved relocation
|
* wc/le: fixed a bug which could cause a crash, improved relocation
|
||||||
handling
|
handling
|
||||||
* wc/le: new option `--copy-overlay'
|
* wc/le: new option '--copy-overlay'
|
||||||
* win32/pe: `--compress-icons=2' is now the default
|
* win32/pe: '--compress-icons=2' is now the default
|
||||||
* win32/pe: even better TLS support
|
* win32/pe: even better TLS support
|
||||||
* win32/pe: versioninfo works on NT
|
* win32/pe: versioninfo works on NT
|
||||||
* win32/pe: import by ordinal from kernel32.dll works
|
* win32/pe: import by ordinal from kernel32.dll works
|
||||||
* win32/pe: other import improvements: importing a nonexistant DLL
|
* win32/pe: other import improvements: importing a nonexistant DLL
|
||||||
results in a usual Windows message, importing a nonexistant function
|
results in a usual Windows message, importing a nonexistant function
|
||||||
results in program exit (instead of crash ;-)
|
results in program exit (instead of crash ;-)
|
||||||
* win32/pe: new option: `--compress-resources=0'
|
* win32/pe: new option: '--compress-resources=0'
|
||||||
* win32/pe: reduced memory requirement during uncompression, some
|
* win32/pe: reduced memory requirement during uncompression, some
|
||||||
files might even require LESS memory when they're compressed
|
files might even require LESS memory when they're compressed
|
||||||
* win32/pe: TYPELIBs should work now
|
* win32/pe: TYPELIBs should work now
|
||||||
* win32/pe: improved relocation handling, 16-bit relocations should work
|
* win32/pe: improved relocation handling, 16-bit relocations should work
|
||||||
* win32/pe: new option `--strip-relocs' (only if you know what you are doing)
|
* win32/pe: new option '--strip-relocs' (only if you know what you are doing)
|
||||||
* win32/pe: new option `--copy-overlay'
|
* win32/pe: new option '--copy-overlay'
|
||||||
* important internal changes: now the stubs are built at runtime
|
* important internal changes: now the stubs are built at runtime
|
||||||
|
|
||||||
Changes in 0.72 (12 May 1999)
|
Changes in 0.72 (12 May 1999)
|
||||||
@@ -270,20 +319,20 @@ Changes in 0.72 (12 May 1999)
|
|||||||
* linux/386: minor decompressor stub updates, nicer progress bar
|
* linux/386: minor decompressor stub updates, nicer progress bar
|
||||||
|
|
||||||
Changes in 0.71 (19 Apr 1999)
|
Changes in 0.71 (19 Apr 1999)
|
||||||
* dos/exe: added option `--no-overlay'
|
* dos/exe: added option '--no-overlay'
|
||||||
* linux/386: various improvements in the stub, most notably the
|
* linux/386: various improvements in the stub, most notably the
|
||||||
overhead for an extra cleanup process has been removed
|
overhead for an extra cleanup process has been removed
|
||||||
* win32/pe: added support for export forwarders
|
* win32/pe: added support for export forwarders
|
||||||
* win32/pe: added support for DLLs without entry point or imports
|
* win32/pe: added support for DLLs without entry point or imports
|
||||||
* win32/pe: yet another .bss fix
|
* win32/pe: yet another .bss fix
|
||||||
* win32/pe: new option `--compress-icons=2': compress all icons
|
* win32/pe: new option '--compress-icons=2': compress all icons
|
||||||
which are not in the first icon directory
|
which are not in the first icon directory
|
||||||
* win32/pe: rearranged stub to avoid false alerts from some virus scanners
|
* win32/pe: rearranged stub to avoid false alerts from some virus scanners
|
||||||
|
|
||||||
Changes in 0.70 (30 Mar 1999)
|
Changes in 0.70 (30 Mar 1999)
|
||||||
* added support for linux/386 executables
|
* added support for linux/386 executables
|
||||||
* improved compression ratio quite a bit
|
* improved compression ratio quite a bit
|
||||||
* added new compression level `--best' to squeeze out even some more bytes
|
* added new compression level '--best' to squeeze out even some more bytes
|
||||||
* win32/pe: TLS support is much better now
|
* win32/pe: TLS support is much better now
|
||||||
* win32/pe: --compress-icons=0 should now work as well
|
* win32/pe: --compress-icons=0 should now work as well
|
||||||
* the usual minor fixes for win32/pe
|
* the usual minor fixes for win32/pe
|
||||||
|
|||||||
@@ -56,8 +56,6 @@ Existing formats:
|
|||||||
|
|
||||||
- dos/exe: implement filter support
|
- dos/exe: implement filter support
|
||||||
|
|
||||||
- dos/sys: add support for sys/exe combos
|
|
||||||
|
|
||||||
- linux/i386:
|
- linux/i386:
|
||||||
- use the new assembly preprocessor stuff (ie. process the file
|
- use the new assembly preprocessor stuff (ie. process the file
|
||||||
headers internally)
|
headers internally)
|
||||||
@@ -68,8 +66,7 @@ Existing formats:
|
|||||||
|
|
||||||
- win32/pe: display a nice dialog box in the stub in case
|
- win32/pe: display a nice dialog box in the stub in case
|
||||||
of problems (like importing a DLL or function fails)
|
of problems (like importing a DLL or function fails)
|
||||||
- win32/pe: finer control over resource compression, per section
|
- win32/pe: per section compression
|
||||||
compression
|
|
||||||
|
|
||||||
|
|
||||||
Compression ratio:
|
Compression ratio:
|
||||||
|
|||||||
@@ -13,31 +13,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
WARNING - UNSTABLE BETA VERSION
|
|
||||||
===============================
|
|
||||||
|
|
||||||
All versions 1.9x are unstable beta releases - use them only for testing,
|
|
||||||
and never distribute a program that is packed with them !
|
|
||||||
There will be hidden bugs. Really.
|
|
||||||
|
|
||||||
The current stable release is 1.25, and the next stable release
|
|
||||||
will be called version 2.00.
|
|
||||||
|
|
||||||
The main news since 1.25 are:
|
|
||||||
- slightly better compression using the new NRV2E algorithm
|
|
||||||
- new options for compression tuning (e.g. `--brute')
|
|
||||||
- support for bootable Linux kernels ("vmlinuz/386")
|
|
||||||
- support for Linux kernel building ("vmlinux/386")
|
|
||||||
- direct Linux ELF-to-memory decompression ("linux/elf386") and
|
|
||||||
shell-to-memory decompression ("linux/sh386")
|
|
||||||
- support for arm/WinCE ("arm/pe") exes
|
|
||||||
- support for mach/ppc32
|
|
||||||
- support for Linux elf/ppc32
|
|
||||||
- support for Linux elf/amd64
|
|
||||||
- support for playstation exes ("ps1/exe")
|
|
||||||
- lots of new bugs ;-) take care
|
|
||||||
|
|
||||||
|
|
||||||
WELCOME
|
WELCOME
|
||||||
=======
|
=======
|
||||||
|
|
||||||
@@ -62,7 +37,7 @@ and run exactly as before, with no runtime or memory penalty for most
|
|||||||
of the supported formats.
|
of the supported formats.
|
||||||
|
|
||||||
UPX supports a number of different executable formats, including
|
UPX supports a number of different executable formats, including
|
||||||
Windows 95/98/ME/NT/2000/XP programs and DLLs, DOS programs,
|
Windows 95/98/ME/NT/2000/XP/CE programs and DLLs, DOS programs,
|
||||||
and Linux executables and kernels.
|
and Linux executables and kernels.
|
||||||
|
|
||||||
UPX is free software distributed under the term of the GNU General
|
UPX is free software distributed under the term of the GNU General
|
||||||
@@ -80,8 +55,8 @@ UPX aims to be Commercial Quality Freeware.
|
|||||||
SHORT DOCUMENTATION
|
SHORT DOCUMENTATION
|
||||||
===================
|
===================
|
||||||
|
|
||||||
`upx program.exe' will compress a program or DLL. For best compression
|
'upx program.exe' will compress a program or DLL. For best compression
|
||||||
results try `upx --best program.exe'.
|
results try 'upx --brute program.exe'.
|
||||||
|
|
||||||
Please see the file UPX.DOC for the full documentation. The files
|
Please see the file UPX.DOC for the full documentation. The files
|
||||||
NEWS and BUGS also contain various tidbits of information.
|
NEWS and BUGS also contain various tidbits of information.
|
||||||
@@ -95,7 +70,7 @@ UPX comes with ABSOLUTELY NO WARRANTY; for details see the file LICENSE.
|
|||||||
Having said that, we think that UPX is quite stable now. Indeed we
|
Having said that, we think that UPX is quite stable now. Indeed we
|
||||||
have compressed lots of files without any problems. Also, the
|
have compressed lots of files without any problems. Also, the
|
||||||
current version has undergone several months of beta testing -
|
current version has undergone several months of beta testing -
|
||||||
actually it's more than 4 years since our first public beta.
|
actually it's almost 8 years since our first public beta.
|
||||||
|
|
||||||
This is the first production quality release, and we plan that future
|
This is the first production quality release, and we plan that future
|
||||||
releases will be backward compatible with this version.
|
releases will be backward compatible with this version.
|
||||||
|
|||||||
+11
-14
@@ -16,19 +16,16 @@
|
|||||||
WARNING - UNSTABLE BETA VERSION
|
WARNING - UNSTABLE BETA VERSION
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
The current stable release is 1.25, and the next stable release
|
The current stable release is 2.02, and the next stable release
|
||||||
will be called version 2.00.
|
will be called version 3.00.
|
||||||
|
|
||||||
The main news since 1.25 are:
|
|
||||||
- slightly better compression using the new NRV2E algorithm
|
MAJOR NEWS IN UPX 3
|
||||||
- new options for compression tuning (e.g. `--brute')
|
===================
|
||||||
- support for bootable Linux kernels ("vmlinuz/386")
|
|
||||||
- support for Linux kernel building ("vmlinux/386")
|
The main news since UPX 2 are:
|
||||||
- direct Linux ELF-to-memory decompression ("linux/elf386") and
|
|
||||||
shell-to-memory decompression ("linux/sh386")
|
* new format: added support for linux elf/arm
|
||||||
- support for arm/WinCE ("arm/pe") exes
|
|
||||||
- support for Linux elf/amd64
|
* better compression using the LZMA algorithm (option '--lzma')
|
||||||
- support for Linux elf/ppc32
|
|
||||||
- support for mach/ppc32
|
|
||||||
- support for playstation exes ("ps1/exe")
|
|
||||||
|
|
||||||
|
|||||||
+20
-34
@@ -69,53 +69,40 @@ Tools needed to build/modify the UPX sources
|
|||||||
- A C++ compiler supporting inner classes, templates, exceptions
|
- A C++ compiler supporting inner classes, templates, exceptions
|
||||||
and RTTI.
|
and RTTI.
|
||||||
|
|
||||||
- GNU make 3.80 for Win32
|
- GNU make 3.80 or better (GNU make 3.81 recommened).
|
||||||
http://www.cygwin.com/
|
|
||||||
|
|
||||||
- GNU make 3.80 for DOS
|
|
||||||
http://www.delorie.com/djgpp/
|
|
||||||
|
|
||||||
|
|
||||||
To compile the packer sources
|
To compile the packer sources
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
set the environment variable UCLDIR to point to your UCL installation, e.g.
|
Set the environment variable UPX_UCLDIR to point to your
|
||||||
|
UCL build directory, e.g.
|
||||||
|
|
||||||
set UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
|
set UPX_UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
|
||||||
export UCLDIR=$HOME/local/src/ucl-1.03 (Unix)
|
export UPX_UCLDIR=$HOME/local/src/ucl-1.03 (Unix)
|
||||||
|
|
||||||
then type
|
Set the environment variable UPX_LZMADIR to point to your
|
||||||
|
to your unpacked lzma443.tar.bz2 source directory, e.g.
|
||||||
|
|
||||||
make target=linux # linux
|
export UPX_LZMADIR=$HOME/local/src/lzma-4.43 (Unix)
|
||||||
make target=djgpp2 # dos32 - djgpp2
|
|
||||||
make target=cygwin # win32 - cygwin 1.3.x
|
Finally type
|
||||||
make target=mingw32 # win32 - mingw32
|
|
||||||
make target=no-cygwin # win32 - mingw32 as included in cygwin
|
make
|
||||||
|
|
||||||
|
|
||||||
If you want to modify the stub sources you'll also need
|
If you want to modify the stub sources you'll also need
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
- Nasm 0.98.38 - the Netwide Assembler
|
- GNU make 3.81 or better
|
||||||
http://upx.sourceforge.net/download/tools/
|
http://savannah.gnu.org/projects/make/
|
||||||
http://sourceforge.net/projects/nasm/
|
|
||||||
|
|
||||||
- A68K - a 68000 macro assembler
|
- Perl & Python
|
||||||
http://upx.sourceforge.net/download/tools/
|
|
||||||
|
|
||||||
- djasm - an assembler for the djgpp stub
|
- A number of cross-assemblers and cross-compilers - precompiled
|
||||||
http://upx.sourceforge.net/download/tools/
|
binaries for i386-linux hosts are available from
|
||||||
|
http://sourceforge.net/project/showfiles.php?group_id=2331
|
||||||
|
|
||||||
- Perl 5.6 or better
|
|
||||||
|
|
||||||
- Linux (for the linux/386 stubs)
|
|
||||||
|
|
||||||
- Other cross compilers targeted at the following architectures:
|
|
||||||
- powerpc-750-linux-gnu
|
|
||||||
- x86_64-unknown-linux-gnu
|
|
||||||
- arm-wince-pe
|
|
||||||
|
|
||||||
- ASM5900 - a MIPS R3000 assembler
|
|
||||||
|
|
||||||
Misc. notes
|
Misc. notes
|
||||||
-----------
|
-----------
|
||||||
@@ -129,9 +116,6 @@ Misc. notes
|
|||||||
stream.
|
stream.
|
||||||
- Use gcc extensions and other compiler specific stuff only through
|
- Use gcc extensions and other compiler specific stuff only through
|
||||||
macros.
|
macros.
|
||||||
- Keep in mind that it should be possible to build UPX on braindead
|
|
||||||
file systems (FAT). Don't use long file names or other things
|
|
||||||
that break building under plain DOS.
|
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
@@ -156,3 +140,5 @@ Patches/Contributions
|
|||||||
|
|
||||||
diff -uNr olddirectory newdirectory
|
diff -uNr olddirectory newdirectory
|
||||||
|
|
||||||
|
|
||||||
|
# vi:ts=4:et
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ John S. Fine <johnfine@erols.com>
|
|||||||
for the new version of the dos/exe decompressor
|
for the new version of the dos/exe decompressor
|
||||||
Lukundoo <Lukundoo@softhome.net>
|
Lukundoo <Lukundoo@softhome.net>
|
||||||
for beta testing
|
for beta testing
|
||||||
|
Michael Devore
|
||||||
|
for initial dos/exe device driver support
|
||||||
Oleg V. Volkov <rover@lglobus.ru>
|
Oleg V. Volkov <rover@lglobus.ru>
|
||||||
for various FreeBSD specific informations
|
for various FreeBSD specific informations
|
||||||
The Owl & G-RoM
|
The Owl & G-RoM
|
||||||
|
|||||||
@@ -105,9 +105,6 @@ FORMAT WIN32/PE
|
|||||||
|
|
||||||
- decrease runtime memory overhead
|
- decrease runtime memory overhead
|
||||||
|
|
||||||
2 - easy - mfx + ml) new switch(es) : do not compress resource types x,y,z
|
|
||||||
or resource names a,b,c
|
|
||||||
|
|
||||||
3 - difficult) don't compress the BSS section and other holes.
|
3 - difficult) don't compress the BSS section and other holes.
|
||||||
|
|
||||||
4 - medium - ml) fix when objectalign < 0x1000
|
4 - medium - ml) fix when objectalign < 0x1000
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
upx.1
|
|
||||||
upx.doc
|
|
||||||
upx.html
|
|
||||||
upx.man
|
|
||||||
upx.ps
|
|
||||||
upx.tex
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
upx.1
|
|
||||||
upx.doc
|
|
||||||
upx.html
|
|
||||||
upx.man
|
|
||||||
upx.ps
|
|
||||||
upx.tex
|
|
||||||
+47
-30
@@ -1,36 +1,51 @@
|
|||||||
|
#
|
||||||
|
# UPX doc Makefile - needs GNU make 3.80 or better
|
||||||
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
top_srcdir = ..
|
# internal make variables
|
||||||
|
comma := ,
|
||||||
|
empty :=
|
||||||
|
space := $(empty) $(empty)
|
||||||
|
tab := $(empty) $(empty)
|
||||||
|
|
||||||
|
# update $PATH for our special stub build tools
|
||||||
|
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
||||||
|
export PATH := $(HOME)/local/bin/bin-upx:$(PATH)
|
||||||
|
endif
|
||||||
|
ifneq ($(wildcard $(HOME)/bin/bin-upx/.),)
|
||||||
|
export PATH := $(HOME)/bin/bin-upx:$(PATH)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# //
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
top_srcdir ?= ..
|
||||||
|
|
||||||
PACKAGE = upx
|
PACKAGE = upx
|
||||||
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||||
VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||||
|
|
||||||
TRIMSPACE = cat
|
RTRIM := sed -e 's/[ $(tab)]*$$//'
|
||||||
TRIMSPACE = sed -e 's/ *$$//'
|
DETAB2 := sed -e 's/$(tab)/ /g'
|
||||||
|
|
||||||
BUILT_SOURCES = upx.1 upx.doc upx.html upx.man upx.ps upx.tex
|
BUILT_SOURCES = upx.1 upx.doc upx.html upx.man upx.ps upx.tex
|
||||||
BUILT_SOURCES = upx.1 upx.doc upx.html
|
BUILT_SOURCES = upx.1 upx.doc upx.html
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
###
|
### targets
|
||||||
###
|
###
|
||||||
|
|
||||||
all: $(BUILT_SOURCES)
|
all: $(BUILT_SOURCES)
|
||||||
|
|
||||||
mostlyclean:
|
mostlyclean clean distclean maintainer-clean:
|
||||||
-rm -f $(BUILT_SOURCES) pod2htm*
|
rm -f $(BUILT_SOURCES) pod2htm*
|
||||||
|
|
||||||
clean: mostlyclean
|
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
|
|
||||||
maintainer-clean: distclean
|
|
||||||
|
|
||||||
.SUFFIXES: .1 .doc .html .man .pod .ps .tex .texi
|
|
||||||
|
|
||||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||||
|
|
||||||
@@ -39,30 +54,32 @@ maintainer-clean: distclean
|
|||||||
### rules
|
### rules
|
||||||
###
|
###
|
||||||
|
|
||||||
.pod.1:
|
.SUFFIXES: .1 .doc .html .man .pod .ps .tex
|
||||||
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
.pod.html:
|
%.1 : %.pod
|
||||||
### pod2html $< | $(TRIMSPACE) > $@
|
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(RTRIM) > $@
|
||||||
pod2html --noindex $< | $(TRIMSPACE) > $@
|
|
||||||
@-rm -f pod2htm*
|
|
||||||
|
|
||||||
.pod.tex:
|
%.doc : %.pod
|
||||||
|
pod2text < $< | $(RTRIM) > $@
|
||||||
|
|
||||||
|
%.html : %.pod
|
||||||
|
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
|
||||||
|
@rm -f pod2htm*
|
||||||
|
|
||||||
|
%.man : %.1
|
||||||
|
nroff -man $< | $(RTRIM) > $@
|
||||||
|
|
||||||
|
%.ps : %.1
|
||||||
|
groff -man $< | $(RTRIM) > $@
|
||||||
|
|
||||||
|
%.tex : %.pod
|
||||||
pod2latex $<
|
pod2latex $<
|
||||||
|
|
||||||
.pod.doc:
|
|
||||||
pod2text < $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
.1.man:
|
|
||||||
nroff -man $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
.1.ps:
|
|
||||||
groff -man $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
### dependencies
|
### dependencies
|
||||||
###
|
###
|
||||||
|
|
||||||
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
||||||
|
.DELETE_ON_ERROR: $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
|||||||
+18
-2
@@ -1,5 +1,5 @@
|
|||||||
Decompressing ELF Directly to Memory on Linux/x86
|
Decompressing ELF Directly to Memory on Linux/x86
|
||||||
Copyright 2000 John F. Reiser jreiser@BitWagon.com
|
Copyright (C) 2000-2006 John F. Reiser jreiser@BitWagon.com
|
||||||
|
|
||||||
References:
|
References:
|
||||||
<elf.h> definitions for the ELF file format
|
<elf.h> definitions for the ELF file format
|
||||||
@@ -17,7 +17,7 @@ program itself. So, the decompressor program (which contains the
|
|||||||
compressed version of the original executable) must have the same
|
compressed version of the original executable) must have the same
|
||||||
brk() as the original executable. So, the second PT_LOAD
|
brk() as the original executable. So, the second PT_LOAD
|
||||||
ELF "segment" of the compressed program is used only to set the brk(0).
|
ELF "segment" of the compressed program is used only to set the brk(0).
|
||||||
See src/p_lx_elf.cpp, function PackLinuxI386elf::patchLoader().
|
See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr.
|
||||||
All of the decompressor's code, and all of the compressed image
|
All of the decompressor's code, and all of the compressed image
|
||||||
of the original executable, reside in the first PT_LOAD of the
|
of the original executable, reside in the first PT_LOAD of the
|
||||||
decompressor program.
|
decompressor program.
|
||||||
@@ -63,3 +63,19 @@ clear the free portion of the stack (to compensate for ld-linux.so.2
|
|||||||
assuming that its automatic stack variables are initialized to zero),
|
assuming that its automatic stack variables are initialized to zero),
|
||||||
and remove (all but 4 bytes of) the decompression program (and
|
and remove (all but 4 bytes of) the decompression program (and
|
||||||
compressed executable) from the address space.
|
compressed executable) from the address space.
|
||||||
|
|
||||||
|
Because the UPX runtime stub removes all traces of the compressed file
|
||||||
|
from the address space, then the Linux kernel erases the symlink
|
||||||
|
/proc/self/exe. Linux stores the pathname argument that was specified
|
||||||
|
to execve() immediately after the '\0' which terminates the character
|
||||||
|
string of the last environment variable [as of execve()]. This is true
|
||||||
|
for at least all Linux 2.6, 2.4, and 2.2 kernels. The pathname is not
|
||||||
|
"bound" to the file as strongly as /proc/self/exe (the file may be changed
|
||||||
|
without affecting the pathname), but the pathname does provide some
|
||||||
|
information. The pathname may be relative to the working directory,
|
||||||
|
so look before any chdir().
|
||||||
|
|
||||||
|
The Elf formats for Linux add an environment variable named " " [three
|
||||||
|
spaces] which saves the results of readlink("/proc/self/exe",,) before
|
||||||
|
the runtime stub unmaps all its pages. As of 2006-10-03 this works
|
||||||
|
for linux/elf386 and linux/ElfAMD.
|
||||||
|
|||||||
+27
-66
@@ -2,16 +2,8 @@ This documentation is written for those brave souls who want to
|
|||||||
understand and/or modify the UPX assembly stubs - the small snippets
|
understand and/or modify the UPX assembly stubs - the small snippets
|
||||||
that do the runtime decompression when a compressed program is started.
|
that do the runtime decompression when a compressed program is started.
|
||||||
|
|
||||||
So, how the runtime stub/loader generation works?
|
If you look at the C++ source files, you can find code fragments like
|
||||||
|
this:
|
||||||
You might have already noticed that for some file formats the loaders
|
|
||||||
are quite simple (linux/i386 & tos) while in the other cases the
|
|
||||||
loaders look very suspicious: they're full of `%ifdef's and contain
|
|
||||||
loads of cryptic comments like `__PERELOC2__'.
|
|
||||||
|
|
||||||
If you look at the C++ source files, however you can notice that these
|
|
||||||
comment strings (without the leading and trailing underscores) are used
|
|
||||||
in the following way:
|
|
||||||
|
|
||||||
addLoader("PEMAIN20",
|
addLoader("PEMAIN20",
|
||||||
ih.entry ? "PEDOJUMP" : "PERETURN",
|
ih.entry ? "PEDOJUMP" : "PERETURN",
|
||||||
@@ -19,71 +11,40 @@ in the following way:
|
|||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
Basically that's all you have to know: when you want to add a section
|
linker->defineSymbol("original_entry", ih.entry);
|
||||||
of assembly code to the runtime loader, you just write
|
|
||||||
|
|
||||||
l_foo.asm
|
and in the assembly files fragments like this:
|
||||||
---------
|
|
||||||
;__FOOBAR00__
|
|
||||||
|
|
||||||
|
section PEISDLL1
|
||||||
|
cmpb [esp + 8], 1
|
||||||
|
jnz reloc_end_jmp
|
||||||
|
|
||||||
|
section PEMAIN21
|
||||||
|
reloc_end_jmp:
|
||||||
|
|
||||||
|
section PERETURN
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
label1:
|
inc eax
|
||||||
jmps label1
|
ret 0x0C
|
||||||
|
section PEDOJUMP
|
||||||
|
jmp original_entry
|
||||||
|
|
||||||
;__FOOBARZZ__
|
Everything works as you would expect. If you want to add the code
|
||||||
|
fragment which is in `section PERETURN' to the runtime stub, then
|
||||||
p_foo.cpp
|
simply use `addLoader("PERETURN")' in the C++ source.
|
||||||
---------
|
|
||||||
|
|
||||||
addLoader("FOOBAR00", NULL);
|
|
||||||
|
|
||||||
This will add the assembly section starting from __FOOBAR00__ and ending
|
|
||||||
before __FOOBARZZ__ to the loader. You can add an %ifdef - %endif pair
|
|
||||||
before these comments if you wish - but these conditionals will NOT be
|
|
||||||
seen by the assembler, they are just syntactic sugar to make the code a
|
|
||||||
little bit more readable and understandable. (Note however, that only
|
|
||||||
%ifdefs which are started on the 1st column are removed by the upx
|
|
||||||
assembly preprocessor program, so you can still use preprocessor
|
|
||||||
conditionals if you wish - just write them starting from the 2nd
|
|
||||||
column.)
|
|
||||||
|
|
||||||
That's nice, you could say, but how cross section jumps and calls are
|
That's nice, you could say, but how cross section jumps and calls are
|
||||||
handled? Well, that is the nicest part of this stuff - they are handled
|
handled? Well, that is the nicest part of this stuff - they are handled
|
||||||
automatically. All you have to do is to add the required sections to the
|
automatically. All you have to do is to add the required sections to the
|
||||||
loader using `addLoader()' and the rest is done by upx. It will resolve
|
loader using `addLoader()' and the rest is done by upx. It will resolve
|
||||||
every conditional or unconditional jumps or subrutine calls for you.
|
every conditional or unconditional jumps or subroutine calls for you.
|
||||||
|
|
||||||
This functionality (we could say it's a simple linker) is achived by the
|
You can also use (undefined) symbols in the assembly for values that
|
||||||
assembly preprocessor (src/stub/scripts/app.pl) and a little C++ module
|
can only be computed during compression time (like `original_entry').
|
||||||
(src/linker.cpp). And of course NASM - the Netwide Assembler. You can
|
These symbols can be defined later in C++ using
|
||||||
see what's going on behind the scenes - just do:
|
|
||||||
|
|
||||||
cd src/stubs
|
linker->defineSymbol("xx", yy)
|
||||||
make maintainer-clean
|
|
||||||
make all
|
|
||||||
|
|
||||||
This will rebuild all the loaders - and keep the temporary files (*.as[xy])
|
This functionality (we could say it's a simple linker) is achived by
|
||||||
which are seen by the assembler.
|
compiling the assembly into an ELF object file which a little C++
|
||||||
|
module (src/linker.cpp) can interpret and work with.
|
||||||
Currently this loader/stub building method only works with ix86
|
|
||||||
assembly - both app.pl and linker.cpp heavily rely on this when dealing
|
|
||||||
with cross section references.
|
|
||||||
|
|
||||||
And finally some important features/requirements you should be aware of:
|
|
||||||
|
|
||||||
- as previously stated - preprocessor conditionals starting on the 1st
|
|
||||||
column are removed by app.pl
|
|
||||||
- sections are separated by comments in the form `;__X1234567__'
|
|
||||||
- jumps are recognized by searching for a word which starts with `j'
|
|
||||||
and followed by a label - this also means that `jmp short label1'
|
|
||||||
will NOT be recognized (but you can use a macro called `jmps' for it
|
|
||||||
by adding `%define jmps jmp short' to the beginning of the file)
|
|
||||||
- at the end of the file you need something like this
|
|
||||||
|
|
||||||
eof:
|
|
||||||
; __XTHEENDX__
|
|
||||||
section .data
|
|
||||||
dd -1
|
|
||||||
dw eof
|
|
||||||
|
|
||||||
That's all for now.
|
|
||||||
|
|||||||
+47
-17
@@ -75,9 +75,10 @@ B<UPX> is a versatile executable packer with the following features:
|
|||||||
* rtm32/pe
|
* rtm32/pe
|
||||||
* tmt/adam
|
* tmt/adam
|
||||||
* vmlinuz/386 [bootable Linux kernel]
|
* vmlinuz/386 [bootable Linux kernel]
|
||||||
|
* vmlinux/386
|
||||||
* watcom/le (supporting DOS4G, PMODE/W, DOS32a and CauseWay)
|
* watcom/le (supporting DOS4G, PMODE/W, DOS32a and CauseWay)
|
||||||
* win32/pe
|
* win32/pe (exe and dll)
|
||||||
* arm/pe
|
* arm/pe (exe and dll)
|
||||||
* linux/elfamd64
|
* linux/elfamd64
|
||||||
* linux/elfppc32
|
* linux/elfppc32
|
||||||
* mach/elfppc32
|
* mach/elfppc32
|
||||||
@@ -137,6 +138,9 @@ B<--help>: prints the help
|
|||||||
|
|
||||||
B<--version>: print the version of B<UPX>
|
B<--version>: print the version of B<UPX>
|
||||||
|
|
||||||
|
B<--exact>: when compressing, require to be able to get a byte-identical file
|
||||||
|
after decompression with option B<-d>
|
||||||
|
|
||||||
[ ...to be written... - type `B<upx --help>' for now ]
|
[ ...to be written... - type `B<upx --help>' for now ]
|
||||||
|
|
||||||
|
|
||||||
@@ -339,9 +343,6 @@ Extra options available for this executable format:
|
|||||||
|
|
||||||
=head2 NOTES FOR DOS/SYS
|
=head2 NOTES FOR DOS/SYS
|
||||||
|
|
||||||
You can only compress plain sys files, sys/exe (two in one)
|
|
||||||
combos are not supported.
|
|
||||||
|
|
||||||
Compressed programs only work on a 286+.
|
Compressed programs only work on a 286+.
|
||||||
|
|
||||||
Packed programs will be byte-identical to the original after uncompression.
|
Packed programs will be byte-identical to the original after uncompression.
|
||||||
@@ -701,19 +702,20 @@ nostalgic feelings of one of the authors.
|
|||||||
Packed programs will be byte-identical to the original after uncompression,
|
Packed programs will be byte-identical to the original after uncompression,
|
||||||
until further notice.
|
until further notice.
|
||||||
|
|
||||||
Maximum uncompressed size: ~1998848 bytes.
|
Maximum uncompressed size: ~1.89 / ~7.60 Mbytes.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
- UPX creates as default a 'CD-Rom only' PS1/PS2 compatible executable.
|
- UPX creates as default a suitable executable for CD-Mastering
|
||||||
For transfer between client/target use options below.
|
and console transfer. For a CD-Master main executable you could also try
|
||||||
|
the special option "--boot-only" as descriped below.
|
||||||
|
|
||||||
- Normally the packed files use the same memory areas like the uncompressed
|
- Normally the packed files use the same memory areas like the uncompressed
|
||||||
versions, so they will not override other memory areas while unpacking.
|
versions, so they will not override other memory areas while unpacking.
|
||||||
If this isn't possible UPX will abort showing a 'packed data overlap'
|
If this isn't possible UPX will abort showing a 'packed data overlap'
|
||||||
error. With the "--force" option UPX will set a few 'bytes higher' loading
|
error. With the "--force" option UPX will relocate the loading address
|
||||||
offset for the packed file, but this isn't a real problem if it is a
|
for the packed file, but this isn't a real problem if it is a single or
|
||||||
single or boot-only executable.
|
the main executable.
|
||||||
|
|
||||||
Extra options available for this executable format:
|
Extra options available for this executable format:
|
||||||
|
|
||||||
@@ -722,15 +724,19 @@ Extra options available for this executable format:
|
|||||||
the compression ratio in some cases, but usually
|
the compression ratio in some cases, but usually
|
||||||
the default method gives the best results anyway.
|
the default method gives the best results anyway.
|
||||||
|
|
||||||
--boot-only The format will only run from a CD and may slightly
|
--8-bit Uses 8 bit size compression [default: 32 bit]
|
||||||
improves the compression ratio. The decompression
|
|
||||||
routines are faster than default ones.
|
--8mb-ram PSone has 8 MB ram available [default: 2 MB]
|
||||||
But it cannot be used for host/client transfer !
|
|
||||||
|
--boot-only This format is for main exes and CD-Mastering only !
|
||||||
|
It may slightly improve the compression ratio,
|
||||||
|
decompression routines are faster than default ones.
|
||||||
|
But it cannot be used for console transfer !
|
||||||
|
|
||||||
--no-align This option disables CD mode 2 data sector format
|
--no-align This option disables CD mode 2 data sector format
|
||||||
alignment. May slightly improves the compression ratio,
|
alignment. May slightly improves the compression ratio,
|
||||||
but the compressed executable will not boot from a CD.
|
but the compressed executable will not boot from a CD.
|
||||||
Use it for client/target transfer only !
|
Use it for console transfer only !
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -840,12 +846,19 @@ smaller, but it's still there.
|
|||||||
If you're running executables from network, then compressed programs
|
If you're running executables from network, then compressed programs
|
||||||
will load faster, and require less bandwidth during execution.
|
will load faster, and require less bandwidth during execution.
|
||||||
|
|
||||||
DLLs are supported.
|
DLLs are supported. But UPX compressed DLLs can not share common data and
|
||||||
|
code when they got used by multiple applications. So compressing msvcrt.dll
|
||||||
|
is a waste of memory, but compressing the dll plugins of a particular
|
||||||
|
application may be a better idea.
|
||||||
|
|
||||||
Screensavers are supported, with the restriction that the filename
|
Screensavers are supported, with the restriction that the filename
|
||||||
must end with ".scr" (as screensavers are handled slightly different
|
must end with ".scr" (as screensavers are handled slightly different
|
||||||
than normal exe files).
|
than normal exe files).
|
||||||
|
|
||||||
|
UPX compressed PE files has some minor memory overhead (usually in the
|
||||||
|
10 - 30 kbytes range) which can be seen by specifying the "-i" command
|
||||||
|
line switch during compression.
|
||||||
|
|
||||||
Extra options available for this executable format:
|
Extra options available for this executable format:
|
||||||
|
|
||||||
--compress-exports=0 Don't compress the export section.
|
--compress-exports=0 Don't compress the export section.
|
||||||
@@ -862,9 +875,26 @@ Extra options available for this executable format:
|
|||||||
--compress-icons=1 Compress all but the first icon.
|
--compress-icons=1 Compress all but the first icon.
|
||||||
--compress-icons=2 Compress all icons which are not in the
|
--compress-icons=2 Compress all icons which are not in the
|
||||||
first icon directory. [DEFAULT]
|
first icon directory. [DEFAULT]
|
||||||
|
--compress-icons=3 Compress all icons.
|
||||||
|
|
||||||
--compress-resources=0 Don't compress any resources at all.
|
--compress-resources=0 Don't compress any resources at all.
|
||||||
|
|
||||||
|
--keep-resource=list Don't compress resources specified by the list.
|
||||||
|
The members of the list are separated by commas.
|
||||||
|
A list member has the following format: I<type[/name]>.
|
||||||
|
I<Type> is the type of the resource. Standard types
|
||||||
|
must be specified as decimal numbers, user types can be
|
||||||
|
specified by decimal IDs or strings. I<Name> is the
|
||||||
|
identifier of the resource. It can be a decimal number
|
||||||
|
or a string. For example:
|
||||||
|
|
||||||
|
--keep-resource=2/MYBITMAP,5,6/12345
|
||||||
|
|
||||||
|
UPX won't compress the named bitmap resource "MYBITMAP",
|
||||||
|
it leaves every dialog (5) resource uncompressed, and
|
||||||
|
it won't touch the string table resource with identifier
|
||||||
|
12345.
|
||||||
|
|
||||||
--force Force compression even when there is an
|
--force Force compression even when there is an
|
||||||
unexpected value in a header field.
|
unexpected value in a header field.
|
||||||
Use with care.
|
Use with care.
|
||||||
|
|||||||
-3220
File diff suppressed because it is too large
Load Diff
@@ -1,19 +0,0 @@
|
|||||||
*.0??
|
|
||||||
*.d
|
|
||||||
*.dat
|
|
||||||
*.idb
|
|
||||||
*.img
|
|
||||||
*.map
|
|
||||||
*.raw
|
|
||||||
*.rc
|
|
||||||
*.rel
|
|
||||||
*.res
|
|
||||||
*.pdb
|
|
||||||
*.out
|
|
||||||
*.upx
|
|
||||||
.gdbinit
|
|
||||||
GNUmakefile
|
|
||||||
MMakefile
|
|
||||||
compress_nrv.*
|
|
||||||
upx
|
|
||||||
version1*.h
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
*.0??
|
|
||||||
*.d
|
|
||||||
*.dat
|
|
||||||
*.idb
|
|
||||||
*.img
|
|
||||||
*.map
|
|
||||||
*.raw
|
|
||||||
*.rc
|
|
||||||
*.rel
|
|
||||||
*.res
|
|
||||||
*.pdb
|
|
||||||
*.out
|
|
||||||
*.upx
|
|
||||||
.gdbinit
|
|
||||||
GNUmakefile
|
|
||||||
MMakefile
|
|
||||||
compress_nrv.*
|
|
||||||
upx
|
|
||||||
version1*.h
|
|
||||||
+36
-9
@@ -17,9 +17,18 @@ endif
|
|||||||
ifeq ($(CXX),)
|
ifeq ($(CXX),)
|
||||||
CXX = g++
|
CXX = g++
|
||||||
endif
|
endif
|
||||||
ifeq ($(CXX),g++)
|
ifeq ($(firstword $(CXX)),g++)
|
||||||
CXXFLAGS += -O2 -MMD
|
USE_GNUC ?= 1
|
||||||
|
endif
|
||||||
|
ifeq ($(USE_GNUC),1)
|
||||||
|
CXXFLAGS += -MMD
|
||||||
|
ifeq ($(DEBUG),1)
|
||||||
|
CXXFLAGS += -O0 -g
|
||||||
|
else
|
||||||
|
CXXFLAGS += -O2
|
||||||
|
endif
|
||||||
CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wwrite-strings -Werror
|
CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wwrite-strings -Werror
|
||||||
|
##CXXFLAGS += -Wshadow
|
||||||
endif
|
endif
|
||||||
CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
|
CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
|
||||||
CXXLD ?= $(CXX)
|
CXXLD ?= $(CXX)
|
||||||
@@ -28,17 +37,24 @@ exeext ?= .out
|
|||||||
libext ?= .a
|
libext ?= .a
|
||||||
objext ?= .o
|
objext ?= .o
|
||||||
|
|
||||||
# we need UCL and zlib - you can set envvar UCLDIR
|
|
||||||
ifneq ($(wildcard $(UCLDIR)/include/ucl/ucl.h),)
|
|
||||||
INCLUDES += -I$(UCLDIR)/include
|
|
||||||
LIBS += $(addprefix -L,$(dir $(wildcard $(UCLDIR)/libucl$(libext) $(UCLDIR)/src/.libs/libucl$(libext))))
|
|
||||||
endif
|
|
||||||
LIBS += -lucl -lz
|
|
||||||
|
|
||||||
upx_SOURCES := $(wildcard $(srcdir)/*.cpp)
|
upx_SOURCES := $(wildcard $(srcdir)/*.cpp)
|
||||||
upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
|
upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
|
||||||
|
|
||||||
|
# we need UCL and zlib - you can set envvar UPX_UCLDIR
|
||||||
|
ifneq ($(wildcard $(UPX_UCLDIR)/include/ucl/ucl.h),)
|
||||||
|
INCLUDES += -I$(UPX_UCLDIR)/include
|
||||||
|
LIBS += $(addprefix -L,$(dir $(wildcard $(UPX_UCLDIR)/libucl$(libext) $(UPX_UCLDIR)/src/.libs/libucl$(libext))))
|
||||||
|
endif
|
||||||
|
LIBS += -lucl -lz
|
||||||
|
# you should set envvar UPX_LZMADIR to point to your unpacked lzma443.tar.bz2
|
||||||
|
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
|
||||||
|
DEFS += -DWITH_LZMA
|
||||||
|
INCLUDES += -I$(UPX_LZMADIR)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
all: upx$(exeext)
|
all: upx$(exeext)
|
||||||
|
.DELETE_ON_ERROR: upx$(exeext) $(upx_OBJECTS)
|
||||||
|
|
||||||
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
||||||
$($(notdir $@).PRE_LINK_STEP)
|
$($(notdir $@).PRE_LINK_STEP)
|
||||||
@@ -48,6 +64,17 @@ upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
|||||||
%.o : %.cpp
|
%.o : %.cpp
|
||||||
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
||||||
|
|
||||||
|
|
||||||
|
ifeq ($(USE_GNUC),1)
|
||||||
|
##compress_lzma$(objext) : CXXFLAGS += -O3 -fomit-frame-pointer
|
||||||
|
compress_lzma$(objext) : CXXFLAGS += -Wno-cast-qual
|
||||||
|
compress_lzma$(objext) : CXXFLAGS += -Wno-non-virtual-dtor
|
||||||
|
compress_lzma$(objext) : CXXFLAGS += -Wno-shadow
|
||||||
|
compress_lzma$(objext) : CXXFLAGS += -Wno-unused
|
||||||
|
##compress_lzma$(objext) : CXXFLAGS += -Wno-error
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
mostlyclean clean distclean maintainer-clean:
|
mostlyclean clean distclean maintainer-clean:
|
||||||
rm -f *.d *.map *.o *.obj *.res upx.exe upx.out upx.ttp upx$(exeext)
|
rm -f *.d *.map *.o *.obj *.res upx.exe upx.out upx.ttp upx$(exeext)
|
||||||
|
|
||||||
|
|||||||
+88
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2005 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -239,13 +239,65 @@ inline int get_le32_signed(const void *p)
|
|||||||
return sign_extend(v, 32);
|
return sign_extend(v, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_le64_signed(const void *p)
|
inline acc_int64l_t get_le64_signed(const void *p)
|
||||||
{
|
{
|
||||||
acc_int64l_t v = get_le64(p);
|
acc_int64l_t v = get_le64(p);
|
||||||
return sign_extend(v, 64);
|
return sign_extend(v, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// swab (bswap)
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
inline unsigned acc_swab16(unsigned v)
|
||||||
|
{
|
||||||
|
return ((v & 0x00ff) << 8) |
|
||||||
|
((v & 0xff00) >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned acc_swab32(unsigned v)
|
||||||
|
{
|
||||||
|
return ((v & 0x000000ff) << 24) |
|
||||||
|
((v & 0x0000ff00) << 8) |
|
||||||
|
((v & 0x00ff0000) >> 8) |
|
||||||
|
((v & 0xff000000) >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline unsigned acc_swab16p(const acc_uint16e_t *p)
|
||||||
|
{
|
||||||
|
return acc_swab16(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned acc_swap32p(const acc_uint32e_t *p)
|
||||||
|
{
|
||||||
|
return acc_swab32(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void acc_swab16s(acc_uint16e_t *p)
|
||||||
|
{
|
||||||
|
*p = acc_swab16(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void acc_swab32s(acc_uint32e_t *p)
|
||||||
|
{
|
||||||
|
*p = acc_swab32(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void acc_ua_swab16s(void *p)
|
||||||
|
{
|
||||||
|
set_be16(p, get_le16(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void acc_ua_swab32s(void *p)
|
||||||
|
{
|
||||||
|
set_be32(p, get_le32(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// classes for portable unaligned access
|
// classes for portable unaligned access
|
||||||
//
|
//
|
||||||
@@ -476,6 +528,39 @@ int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// Provide namespaces and classes to abtract endianness policies.
|
||||||
|
//
|
||||||
|
// CTP - Compile-Time Polymorphism (templates)
|
||||||
|
// RTP - Run-Time Polymorphism (virtual functions)
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
namespace N_BELE_CTP {
|
||||||
|
class BEPolicy; class LEPolicy;
|
||||||
|
}
|
||||||
|
namespace N_BELE_RTP {
|
||||||
|
class AbstractPolicy;
|
||||||
|
class BEPolicy; class LEPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace N_BELE_CTP {
|
||||||
|
#define BELE_CTP 1
|
||||||
|
#include "bele_policy.h"
|
||||||
|
#undef BELE_CTP
|
||||||
|
extern const BEPolicy be_policy;
|
||||||
|
extern const LEPolicy le_policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace N_BELE_RTP {
|
||||||
|
#define BELE_RTP 1
|
||||||
|
#include "bele_policy.h"
|
||||||
|
#undef BELE_RTP
|
||||||
|
extern const BEPolicy be_policy;
|
||||||
|
extern const LEPolicy le_policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,285 @@
|
|||||||
|
/* bele_policy.h -- access memory in BigEndian and LittleEndian byte order
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __UPX_BELE_H
|
||||||
|
# error "this is an internal include file"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if defined(BELE_CTP)
|
||||||
|
// CTP - Compile-Time Polymorphism (templates)
|
||||||
|
# define V static inline
|
||||||
|
# define S static int __acc_cdecl_qsort
|
||||||
|
# define C
|
||||||
|
#elif defined(BELE_RTP)
|
||||||
|
// RTP - Run-Time Polymorphism (virtual functions)
|
||||||
|
# define V virtual
|
||||||
|
# define S virtual int
|
||||||
|
# define C const
|
||||||
|
#else
|
||||||
|
# error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(BELE_RTP)
|
||||||
|
struct AbstractPolicy
|
||||||
|
{
|
||||||
|
AbstractPolicy() {}
|
||||||
|
virtual inline ~AbstractPolicy() {}
|
||||||
|
V bool isBE() C = 0;
|
||||||
|
V bool isLE() C = 0;
|
||||||
|
|
||||||
|
V unsigned get16(const void *p) C = 0;
|
||||||
|
V unsigned get24(const void *p) C = 0;
|
||||||
|
V unsigned get32(const void *p) C = 0;
|
||||||
|
V acc_uint64l_t get64(const void *p) C = 0;
|
||||||
|
|
||||||
|
V void set16(void *p, unsigned v) C = 0;
|
||||||
|
V void set24(void *p, unsigned v) C = 0;
|
||||||
|
V void set32(void *p, unsigned v) C = 0;
|
||||||
|
V void set64(void *p, acc_uint64l_t v) C = 0;
|
||||||
|
|
||||||
|
V unsigned get16_signed(const void *p) C = 0;
|
||||||
|
V unsigned get24_signed(const void *p) C = 0;
|
||||||
|
V unsigned get32_signed(const void *p) C = 0;
|
||||||
|
V acc_uint64l_t get64_signed(const void *p) C = 0;
|
||||||
|
|
||||||
|
S u16_compare(const void *a, const void *b) C = 0;
|
||||||
|
S u24_compare(const void *a, const void *b) C = 0;
|
||||||
|
S u32_compare(const void *a, const void *b) C = 0;
|
||||||
|
S u64_compare(const void *a, const void *b) C = 0;
|
||||||
|
|
||||||
|
S u16_compare_signed(const void *a, const void *b) C = 0;
|
||||||
|
S u24_compare_signed(const void *a, const void *b) C = 0;
|
||||||
|
S u32_compare_signed(const void *a, const void *b) C = 0;
|
||||||
|
S u64_compare_signed(const void *a, const void *b) C = 0;
|
||||||
|
|
||||||
|
// disable dynamic allocation
|
||||||
|
DISABLE_NEW_DELETE
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct BEPolicy
|
||||||
|
#if defined(BELE_RTP)
|
||||||
|
: public AbstractPolicy
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
BEPolicy() {}
|
||||||
|
#if defined(BELE_CTP)
|
||||||
|
typedef N_BELE_RTP::BEPolicy RTP_Policy;
|
||||||
|
enum { isBE = 1, isLE = 0 };
|
||||||
|
#elif defined(BELE_RTP)
|
||||||
|
typedef N_BELE_CTP::BEPolicy CTP_Policy;
|
||||||
|
V bool isBE() C { return CTP_Policy::isBE; }
|
||||||
|
V bool isLE() C { return CTP_Policy::isLE; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef BE16 U16;
|
||||||
|
typedef BE32 U32;
|
||||||
|
typedef BE64 U64;
|
||||||
|
|
||||||
|
V unsigned get16(const void *p) C
|
||||||
|
{ return get_be16(p); }
|
||||||
|
V unsigned get24(const void *p) C
|
||||||
|
{ return get_be24(p); }
|
||||||
|
V unsigned get32(const void *p) C
|
||||||
|
{ return get_be32(p); }
|
||||||
|
V acc_uint64l_t get64(const void *p) C
|
||||||
|
{ return get_be64(p); }
|
||||||
|
|
||||||
|
V void set16(void *p, unsigned v) C
|
||||||
|
{ set_be16(p, v); }
|
||||||
|
V void set24(void *p, unsigned v) C
|
||||||
|
{ set_be24(p, v); }
|
||||||
|
V void set32(void *p, unsigned v) C
|
||||||
|
{ set_be32(p, v); }
|
||||||
|
V void set64(void *p, acc_uint64l_t v) C
|
||||||
|
{ set_be64(p, v); }
|
||||||
|
|
||||||
|
V unsigned get16_signed(const void *p) C
|
||||||
|
{ return get_be16_signed(p); }
|
||||||
|
V unsigned get24_signed(const void *p) C
|
||||||
|
{ return get_be24_signed(p); }
|
||||||
|
V unsigned get32_signed(const void *p) C
|
||||||
|
{ return get_be32_signed(p); }
|
||||||
|
V acc_uint64l_t get64_signed(const void *p) C
|
||||||
|
{ return get_be64_signed(p); }
|
||||||
|
|
||||||
|
S u16_compare(const void *a, const void *b) C
|
||||||
|
{ return be16_compare(a, b); }
|
||||||
|
S u24_compare(const void *a, const void *b) C
|
||||||
|
{ return be24_compare(a, b); }
|
||||||
|
S u32_compare(const void *a, const void *b) C
|
||||||
|
{ return be32_compare(a, b); }
|
||||||
|
S u64_compare(const void *a, const void *b) C
|
||||||
|
{ return be64_compare(a, b); }
|
||||||
|
|
||||||
|
S u16_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return be16_compare_signed(a, b); }
|
||||||
|
S u24_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return be24_compare_signed(a, b); }
|
||||||
|
S u32_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return be32_compare_signed(a, b); }
|
||||||
|
S u64_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return be64_compare_signed(a, b); }
|
||||||
|
|
||||||
|
static void compileTimeAssertions() {
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U16, char)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U32, char)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U64, char)
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable dynamic allocation
|
||||||
|
DISABLE_NEW_DELETE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct LEPolicy
|
||||||
|
#if defined(BELE_RTP)
|
||||||
|
: public AbstractPolicy
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
LEPolicy() {}
|
||||||
|
#if defined(BELE_CTP)
|
||||||
|
typedef N_BELE_RTP::LEPolicy RTP_Policy;
|
||||||
|
enum { isBE = 0, isLE = 1 };
|
||||||
|
#elif defined(BELE_RTP)
|
||||||
|
typedef N_BELE_CTP::LEPolicy CTP_Policy;
|
||||||
|
V bool isBE() C { return CTP_Policy::isBE; }
|
||||||
|
V bool isLE() C { return CTP_Policy::isLE; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef LE16 U16;
|
||||||
|
typedef LE32 U32;
|
||||||
|
typedef LE64 U64;
|
||||||
|
|
||||||
|
V unsigned get16(const void *p) C
|
||||||
|
{ return get_le16(p); }
|
||||||
|
V unsigned get24(const void *p) C
|
||||||
|
{ return get_le24(p); }
|
||||||
|
V unsigned get32(const void *p) C
|
||||||
|
{ return get_le32(p); }
|
||||||
|
V acc_uint64l_t get64(const void *p) C
|
||||||
|
{ return get_le64(p); }
|
||||||
|
|
||||||
|
V void set16(void *p, unsigned v) C
|
||||||
|
{ set_le16(p, v); }
|
||||||
|
V void set24(void *p, unsigned v) C
|
||||||
|
{ set_le24(p, v); }
|
||||||
|
V void set32(void *p, unsigned v) C
|
||||||
|
{ set_le32(p, v); }
|
||||||
|
V void set64(void *p, acc_uint64l_t v) C
|
||||||
|
{ set_le64(p, v); }
|
||||||
|
|
||||||
|
V unsigned get16_signed(const void *p) C
|
||||||
|
{ return get_le16_signed(p); }
|
||||||
|
V unsigned get24_signed(const void *p) C
|
||||||
|
{ return get_le24_signed(p); }
|
||||||
|
V unsigned get32_signed(const void *p) C
|
||||||
|
{ return get_le32_signed(p); }
|
||||||
|
V acc_uint64l_t get64_signed(const void *p) C
|
||||||
|
{ return get_le64_signed(p); }
|
||||||
|
|
||||||
|
S u16_compare(const void *a, const void *b) C
|
||||||
|
{ return le16_compare(a, b); }
|
||||||
|
S u24_compare(const void *a, const void *b) C
|
||||||
|
{ return le24_compare(a, b); }
|
||||||
|
S u32_compare(const void *a, const void *b) C
|
||||||
|
{ return le32_compare(a, b); }
|
||||||
|
S u64_compare(const void *a, const void *b) C
|
||||||
|
{ return le64_compare(a, b); }
|
||||||
|
|
||||||
|
S u16_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return le16_compare_signed(a, b); }
|
||||||
|
S u24_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return le24_compare_signed(a, b); }
|
||||||
|
S u32_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return le32_compare_signed(a, b); }
|
||||||
|
S u64_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return le64_compare_signed(a, b); }
|
||||||
|
|
||||||
|
static void compileTimeAssertions() {
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U16, char)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U32, char)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U64, char)
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable dynamic allocation
|
||||||
|
DISABLE_NEW_DELETE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if (ACC_ABI_BIG_ENDIAN)
|
||||||
|
typedef BEPolicy HostPolicy;
|
||||||
|
#elif (ACC_ABI_LITTLE_ENDIAN)
|
||||||
|
typedef LEPolicy HostPolicy;
|
||||||
|
#else
|
||||||
|
# error "ACC_ABI_ENDIAN"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 /* UNUSED */
|
||||||
|
struct HostAlignedPolicy
|
||||||
|
{
|
||||||
|
#if defined(BELE_CTP)
|
||||||
|
enum { isBE = HostPolicy::isBE, isLE = HostPolicy::isLE };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef acc_uint16e_t U16;
|
||||||
|
typedef acc_uint32e_t U32;
|
||||||
|
typedef acc_uint64l_t U64;
|
||||||
|
|
||||||
|
static void compileTimeAssertions() {
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#undef V
|
||||||
|
#undef S
|
||||||
|
#undef C
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
vi:ts=4:et:nowrap
|
||||||
|
*/
|
||||||
|
|
||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -72,7 +72,7 @@ static void print0(FILE *f, const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -124,7 +124,7 @@ static int set_fg(FILE *f, int fg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
if (con == me)
|
if (con == me)
|
||||||
init(f,-1,-1);
|
init(f,-1,-1);
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -58,7 +58,7 @@ static void print0(FILE *f, const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -295,7 +295,7 @@ static void print0(FILE *f, const char *ss)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
#if defined(USE_FRAMES)
|
#if defined(USE_FRAMES)
|
||||||
|
|||||||
+186
-11
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -27,21 +27,196 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
|
||||||
#if defined(WITH_NRV)
|
/*************************************************************************
|
||||||
# include "compress_nrv.ch"
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
||||||
|
{
|
||||||
|
if (len == 0)
|
||||||
|
return adler;
|
||||||
|
assert(buf != NULL);
|
||||||
|
#if 0
|
||||||
|
return adler32(adler, (const Bytef *) buf, len); // zlib
|
||||||
#elif defined(WITH_UCL)
|
#elif defined(WITH_UCL)
|
||||||
# define ALG_NRV2E
|
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
||||||
# define upx_adler32 upx_adler32
|
|
||||||
//# define upx_crc32 upx_crc32
|
|
||||||
# define upx_compress upx_compress
|
|
||||||
# define upx_decompress upx_decompress
|
|
||||||
# define upx_test_overlap upx_test_overlap
|
|
||||||
# include "compress.ch"
|
|
||||||
#else
|
#else
|
||||||
# error
|
# error
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 /* UNUSED */
|
||||||
|
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||||
|
{
|
||||||
|
if (len == 0)
|
||||||
|
return crc;
|
||||||
|
assert(buf != NULL);
|
||||||
|
#if 0
|
||||||
|
return crc32(crc, (const Bytef *) buf, len); // zlib
|
||||||
|
#elif defined(WITH_UCL)
|
||||||
|
return ucl_crc32(crc, (const ucl_bytep) buf, len);
|
||||||
|
#else
|
||||||
|
# error
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* UNUSED */
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
upx_callback_p cb,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf,
|
||||||
|
upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
upx_compress_result_t cresult_buffer;
|
||||||
|
|
||||||
|
assert(method > 0); assert(level > 0);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// set available bytes in dst
|
||||||
|
if (*dst_len == 0)
|
||||||
|
*dst_len = MemBuffer::getSizeForCompression(src_len);
|
||||||
|
#else
|
||||||
|
// force users to provide *dst_len
|
||||||
|
assert(*dst_len != 0);
|
||||||
|
#endif
|
||||||
|
// for UPX, we always require a reasonably sized outbut buffer
|
||||||
|
assert(*dst_len >= MemBuffer::getSizeForCompression(src_len));
|
||||||
|
|
||||||
|
if (!cresult)
|
||||||
|
cresult = &cresult_buffer;
|
||||||
|
memset(cresult, 0, sizeof(*cresult));
|
||||||
|
#if 1
|
||||||
|
// debug
|
||||||
|
cresult->method = method;
|
||||||
|
cresult->level = level;
|
||||||
|
cresult->u_len = src_len;
|
||||||
|
cresult->c_len = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (0) {
|
||||||
|
}
|
||||||
|
#if defined(WITH_LZMA)
|
||||||
|
else if (M_IS_LZMA(method))
|
||||||
|
r = upx_lzma_compress(src, src_len, dst, dst_len,
|
||||||
|
cb, method, level, cconf, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_NRV)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_nrv_compress(src, src_len, dst, dst_len,
|
||||||
|
cb, method, level, cconf, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_UCL)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_ucl_compress(src, src_len, dst, dst_len,
|
||||||
|
cb, method, level, cconf, cresult);
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
throwInternalError("unknown compression method");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// debug
|
||||||
|
cresult->c_len = *dst_len;
|
||||||
|
#endif
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
|
||||||
|
assert(*dst_len > 0);
|
||||||
|
assert(src_len < *dst_len); // must be compressed
|
||||||
|
|
||||||
|
if (cresult && cresult->method == 0)
|
||||||
|
cresult = NULL;
|
||||||
|
|
||||||
|
if (0) {
|
||||||
|
}
|
||||||
|
#if defined(WITH_LZMA)
|
||||||
|
else if (M_IS_LZMA(method))
|
||||||
|
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_NRV)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_nrv_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_UCL)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_ucl_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_ZLIB)
|
||||||
|
else if (M_IS_DEFLATE(method))
|
||||||
|
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
throwInternalError("unknown decompression method");
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
|
||||||
|
if (cresult && cresult->method == 0)
|
||||||
|
cresult = NULL;
|
||||||
|
|
||||||
|
assert(*dst_len > 0);
|
||||||
|
assert(src_len < *dst_len); // must be compressed
|
||||||
|
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||||
|
assert((int)overlap_overhead > 0);
|
||||||
|
|
||||||
|
if (0) {
|
||||||
|
}
|
||||||
|
#if defined(WITH_LZMA)
|
||||||
|
else if (M_IS_LZMA(method))
|
||||||
|
r = upx_lzma_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_NRV)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_nrv_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_UCL)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_ucl_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
throwInternalError("unknown decompression method");
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+118
@@ -0,0 +1,118 @@
|
|||||||
|
/* compress.h --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __UPX_COMPRESS_H
|
||||||
|
#define __UPX_COMPRESS_H
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if defined(WITH_LZMA)
|
||||||
|
const char *upx_lzma_version_string(void);
|
||||||
|
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
upx_callback_p cb,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf,
|
||||||
|
upx_compress_result_t *cresult );
|
||||||
|
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(WITH_NRV)
|
||||||
|
const char *upx_nrv_version_string(void);
|
||||||
|
int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
upx_callback_p cb,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf,
|
||||||
|
upx_compress_result_t *cresult );
|
||||||
|
int upx_nrv_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_nrv_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(WITH_UCL)
|
||||||
|
const char *upx_ucl_version_string(void);
|
||||||
|
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
upx_callback_p cb,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf,
|
||||||
|
upx_compress_result_t *cresult );
|
||||||
|
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WITH_ZLIB)
|
||||||
|
const char *upx_zlib_version_string(void);
|
||||||
|
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
upx_callback_p cb,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf,
|
||||||
|
upx_compress_result_t *cresult );
|
||||||
|
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
vi:ts=4:et
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,515 @@
|
|||||||
|
/* compress_lzma.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
|
||||||
|
|
||||||
|
void lzma_compress_config_t::reset()
|
||||||
|
{
|
||||||
|
memset(this, 0, sizeof(*this));
|
||||||
|
|
||||||
|
pos_bits.reset();
|
||||||
|
lit_pos_bits.reset();
|
||||||
|
lit_context_bits.reset();
|
||||||
|
dict_size.reset();
|
||||||
|
fast_mode = 2;
|
||||||
|
num_fast_bytes.reset();
|
||||||
|
match_finder_cycles = 0;
|
||||||
|
|
||||||
|
max_num_probs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(WITH_LZMA)
|
||||||
|
extern int compress_lzma_dummy;
|
||||||
|
int compress_lzma_dummy = 0;
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
// INFO: the LZMA SDK is covered by a permissive license which allows
|
||||||
|
// using unmodified LZMA source code in UPX and the UPX stubs.
|
||||||
|
// See SPECIAL EXCEPTION below.
|
||||||
|
//
|
||||||
|
// Quoting from lzma-4.43/lzma.txt:
|
||||||
|
//
|
||||||
|
// LICENSE
|
||||||
|
// -------
|
||||||
|
//
|
||||||
|
// LZMA SDK is available under any of the following licenses:
|
||||||
|
//
|
||||||
|
// 1) GNU Lesser General Public License (GNU LGPL)
|
||||||
|
// 2) Common Public License (CPL)
|
||||||
|
// 3) Simplified license for unmodified code (read SPECIAL EXCEPTION)
|
||||||
|
// 4) Proprietary license
|
||||||
|
//
|
||||||
|
// It means that you can select one of these four options and follow rules
|
||||||
|
// of that license.
|
||||||
|
//
|
||||||
|
// 1,2) GNU LGPL and CPL licenses are pretty similar and both these
|
||||||
|
// licenses are classified as
|
||||||
|
// - "Free software licenses" at http://www.gnu.org/
|
||||||
|
// - "OSI-approved" at http://www.opensource.org/
|
||||||
|
//
|
||||||
|
// 3) SPECIAL EXCEPTION
|
||||||
|
//
|
||||||
|
// Igor Pavlov, as the author of this code, expressly permits you
|
||||||
|
// to statically or dynamically link your code (or bind by name)
|
||||||
|
// to the files from LZMA SDK without subjecting your linked
|
||||||
|
// code to the terms of the CPL or GNU LGPL.
|
||||||
|
// Any modifications or additions to files from LZMA SDK, however,
|
||||||
|
// are subject to the GNU LGPL or CPL terms.
|
||||||
|
//
|
||||||
|
// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
|
||||||
|
// while you keep LZMA SDK code unmodified.
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// cruft because of pseudo-COM layer
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#undef USE_LZMA_PROPERTIES
|
||||||
|
|
||||||
|
#undef MSDOS
|
||||||
|
#undef OS2
|
||||||
|
#undef _WIN32
|
||||||
|
#undef _WIN32_WCE
|
||||||
|
#undef COMPRESS_MF_MT
|
||||||
|
#undef _NO_EXCEPTIONS
|
||||||
|
#include "C/Common/MyInitGuid.h"
|
||||||
|
//#include "C/7zip/Compress/LZMA/LZMADecoder.h"
|
||||||
|
#include "C/7zip/Compress/LZMA/LZMAEncoder.h"
|
||||||
|
|
||||||
|
namespace MyLzma {
|
||||||
|
|
||||||
|
struct InStreamRam: public ISequentialInStream, public CMyUnknownImp
|
||||||
|
{
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
const Byte *Data; size_t Size; size_t Pos;
|
||||||
|
void Init(const Byte *data, size_t size) {
|
||||||
|
Data = data; Size = size; Pos = 0;
|
||||||
|
}
|
||||||
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
STDMETHODIMP InStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
|
{
|
||||||
|
UInt32 remain = Size - Pos;
|
||||||
|
if (size > remain) size = remain;
|
||||||
|
memmove(data, Data + Pos, size);
|
||||||
|
Pos += size;
|
||||||
|
if (processedSize != NULL) *processedSize = size;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OutStreamRam : public ISequentialOutStream, public CMyUnknownImp
|
||||||
|
{
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
Byte *Data; size_t Size; size_t Pos; bool Overflow;
|
||||||
|
void Init(Byte *data, size_t size) {
|
||||||
|
Data = data; Size = size; Pos = 0; Overflow = false;
|
||||||
|
}
|
||||||
|
HRESULT WriteByte(Byte b) {
|
||||||
|
if (Pos >= Size) { Overflow = true; return E_FAIL; }
|
||||||
|
Data[Pos++] = b;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
STDMETHODIMP OutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < size && Pos < Size; i++)
|
||||||
|
Data[Pos++] = ((const Byte *)data)[i];
|
||||||
|
if (processedSize != NULL) *processedSize = i;
|
||||||
|
if (i != size) { Overflow = true; return E_FAIL; }
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp
|
||||||
|
{
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||||
|
upx_callback_p cb;
|
||||||
|
};
|
||||||
|
|
||||||
|
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||||
|
{
|
||||||
|
if (cb && cb->nprogress)
|
||||||
|
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
#include "C/Common/Alloc.cpp"
|
||||||
|
#include "C/Common/CRC.cpp"
|
||||||
|
//#include "C/7zip/Common/InBuffer.cpp"
|
||||||
|
#include "C/7zip/Common/OutBuffer.cpp"
|
||||||
|
#include "C/7zip/Common/StreamUtils.cpp"
|
||||||
|
#include "C/7zip/Compress/LZ/LZInWindow.cpp"
|
||||||
|
//#include "C/7zip/Compress/LZ/LZOutWindow.cpp"
|
||||||
|
//#include "C/7zip/Compress/LZMA/LZMADecoder.cpp"
|
||||||
|
#include "C/7zip/Compress/LZMA/LZMAEncoder.cpp"
|
||||||
|
#include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp"
|
||||||
|
#undef RC_NORMALIZE
|
||||||
|
|
||||||
|
|
||||||
|
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
upx_callback_p cb,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf_parm,
|
||||||
|
upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
assert(method == M_LZMA);
|
||||||
|
assert(level > 0); assert(cresult != NULL);
|
||||||
|
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
HRESULT rh;
|
||||||
|
const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : NULL;
|
||||||
|
lzma_compress_result_t *res = &cresult->result_lzma;
|
||||||
|
|
||||||
|
MyLzma::InStreamRam is; is.AddRef();
|
||||||
|
MyLzma::OutStreamRam os; os.AddRef();
|
||||||
|
is.Init(src, src_len);
|
||||||
|
os.Init(dst, *dst_len);
|
||||||
|
|
||||||
|
MyLzma::ProgressInfo progress; progress.AddRef();
|
||||||
|
progress.cb = cb;
|
||||||
|
|
||||||
|
NCompress::NLZMA::CEncoder enc;
|
||||||
|
const PROPID propIDs[8] = {
|
||||||
|
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
|
||||||
|
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
|
||||||
|
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
|
||||||
|
NCoderPropID::kDictionarySize, // 3 ds
|
||||||
|
NCoderPropID::kAlgorithm, // 4 fm _fastmode
|
||||||
|
NCoderPropID::kNumFastBytes, // 5 fb
|
||||||
|
NCoderPropID::kMatchFinderCycles, // 6 mfc _matchFinderCycles, _cutValue
|
||||||
|
NCoderPropID::kMatchFinder // 7 mf
|
||||||
|
};
|
||||||
|
PROPVARIANT pr[8];
|
||||||
|
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4;
|
||||||
|
pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
|
||||||
|
pr[7].vt = VT_BSTR;
|
||||||
|
|
||||||
|
// setup defaults
|
||||||
|
pr[0].uintVal = 2; // 0 .. 4
|
||||||
|
pr[1].uintVal = 0; // 0 .. 4
|
||||||
|
pr[2].uintVal = 3; // 0 .. 8
|
||||||
|
pr[3].uintVal = 4 * 1024 * 1024; // 1 .. 2**30
|
||||||
|
pr[4].uintVal = 2;
|
||||||
|
pr[5].uintVal = 64; // 5 .. 273
|
||||||
|
pr[6].uintVal = 0;
|
||||||
|
#ifdef COMPRESS_MF_BT4
|
||||||
|
static wchar_t matchfinder[] = L"BT4";
|
||||||
|
#endif
|
||||||
|
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
|
||||||
|
pr[7].bstrVal = matchfinder;
|
||||||
|
#if 1
|
||||||
|
pr[0].uintVal = lzma_compress_config_t::pos_bits_t::default_value_c;
|
||||||
|
pr[1].uintVal = lzma_compress_config_t::lit_pos_bits_t::default_value_c;
|
||||||
|
pr[2].uintVal = lzma_compress_config_t::lit_context_bits_t::default_value_c;
|
||||||
|
pr[3].uintVal = lzma_compress_config_t::dict_size_t::default_value_c;
|
||||||
|
pr[5].uintVal = lzma_compress_config_t::num_fast_bytes_t::default_value_c;
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
// DEBUG - set sizes so that we use a maxmimum amount of stack.
|
||||||
|
// These settings cause res->num_probs == 3147574, i.e. we will
|
||||||
|
// need about 6 MB of stack during runtime decompression.
|
||||||
|
pr[1].uintVal = 4;
|
||||||
|
pr[2].uintVal = 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// FIXME: tune these settings according to level
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
pr[3].uintVal = 256 * 1024;
|
||||||
|
pr[4].uintVal = 0;
|
||||||
|
pr[5].uintVal = 8;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pr[3].uintVal = 256 * 1024;
|
||||||
|
pr[4].uintVal = 0;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
pr[3].uintVal = 8 * 1024 * 1024;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
pr[3].uintVal = src_len;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cconf overrides
|
||||||
|
if (lcconf)
|
||||||
|
{
|
||||||
|
oassign(pr[0].uintVal, lcconf->pos_bits);
|
||||||
|
oassign(pr[1].uintVal, lcconf->lit_pos_bits);
|
||||||
|
oassign(pr[2].uintVal, lcconf->lit_context_bits);
|
||||||
|
oassign(pr[3].uintVal, lcconf->dict_size);
|
||||||
|
oassign(pr[5].uintVal, lcconf->num_fast_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit dictionary size
|
||||||
|
if (pr[3].uintVal > src_len)
|
||||||
|
pr[3].uintVal = src_len;
|
||||||
|
|
||||||
|
// limit num_probs
|
||||||
|
if (lcconf && lcconf->max_num_probs)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
unsigned n = 1846 + (768 << (pr[2].uintVal + pr[1].uintVal));
|
||||||
|
if (n <= lcconf->max_num_probs)
|
||||||
|
break;
|
||||||
|
if (pr[1].uintVal > pr[2].uintVal)
|
||||||
|
{
|
||||||
|
if (pr[1].uintVal == 0)
|
||||||
|
goto error;
|
||||||
|
pr[1].uintVal -= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pr[2].uintVal == 0)
|
||||||
|
goto error;
|
||||||
|
pr[2].uintVal -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res->pos_bits = pr[0].uintVal;
|
||||||
|
res->lit_pos_bits = pr[1].uintVal;
|
||||||
|
res->lit_context_bits = pr[2].uintVal;
|
||||||
|
res->dict_size = pr[3].uintVal;
|
||||||
|
res->fast_mode = pr[4].uintVal;
|
||||||
|
res->num_fast_bytes = pr[5].uintVal;
|
||||||
|
res->match_finder_cycles = pr[6].uintVal;
|
||||||
|
//res->num_probs = LzmaGetNumProbs(&s.Properties));
|
||||||
|
//res->num_probs = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
|
||||||
|
res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
|
||||||
|
//printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
|
||||||
|
|
||||||
|
#ifndef _NO_EXCEPTIONS
|
||||||
|
try {
|
||||||
|
#else
|
||||||
|
# error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (enc.SetCoderProperties(propIDs, pr, 8) != S_OK)
|
||||||
|
goto error;
|
||||||
|
if (enc.WriteCoderProperties(&os) != S_OK)
|
||||||
|
goto error;
|
||||||
|
if (os.Overflow) {
|
||||||
|
//r = UPX_E_OUTPUT_OVERRUN;
|
||||||
|
r = UPX_E_NOT_COMPRESSIBLE;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
assert(os.Pos == 5);
|
||||||
|
#if defined(USE_LZMA_PROPERTIES)
|
||||||
|
os.Pos = 1;
|
||||||
|
#else
|
||||||
|
os.Pos = 0;
|
||||||
|
// extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||||
|
unsigned t = res->lit_context_bits + res->lit_pos_bits;
|
||||||
|
os.WriteByte((t << 3) | res->pos_bits);
|
||||||
|
os.WriteByte((res->lit_pos_bits << 4) | (res->lit_context_bits));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rh = enc.Code(&is, &os, NULL, NULL, &progress);
|
||||||
|
|
||||||
|
#ifndef _NO_EXCEPTIONS
|
||||||
|
} catch(...) { return UPX_E_OUT_OF_MEMORY; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert(is.Pos <= src_len);
|
||||||
|
assert(os.Pos <= *dst_len);
|
||||||
|
if (rh == E_OUTOFMEMORY)
|
||||||
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
|
else if (os.Overflow)
|
||||||
|
{
|
||||||
|
assert(os.Pos == *dst_len);
|
||||||
|
//r = UPX_E_OUTPUT_OVERRUN;
|
||||||
|
r = UPX_E_NOT_COMPRESSIBLE;
|
||||||
|
}
|
||||||
|
else if (rh == S_OK)
|
||||||
|
{
|
||||||
|
assert(is.Pos == src_len);
|
||||||
|
r = UPX_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
*dst_len = os.Pos;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// decompress
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#undef _LZMA_IN_CB
|
||||||
|
#undef _LZMA_OUT_READ
|
||||||
|
#undef _LZMA_PROB32
|
||||||
|
#undef _LZMA_LOC_OPT
|
||||||
|
#include "C/7zip/Compress/LZMA_C/LzmaDecode.h"
|
||||||
|
#include "C/7zip/Compress/LZMA_C/LzmaDecode.c"
|
||||||
|
|
||||||
|
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
assert(method == M_LZMA);
|
||||||
|
// see res->num_probs above
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
||||||
|
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
||||||
|
|
||||||
|
CLzmaDecoderState s; memset(&s, 0, sizeof(s));
|
||||||
|
SizeT src_out = 0, dst_out = 0;
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
int rh;
|
||||||
|
|
||||||
|
#if defined(USE_LZMA_PROPERTIES)
|
||||||
|
if (src_len < 2)
|
||||||
|
goto error;
|
||||||
|
rh = LzmaDecodeProperties(&s.Properties, src, src_len);
|
||||||
|
if (rh != 0)
|
||||||
|
goto error;
|
||||||
|
src += 1; src_len -= 1;
|
||||||
|
#else
|
||||||
|
if (src_len < 3)
|
||||||
|
goto error;
|
||||||
|
s.Properties.pb = src[0] & 7;
|
||||||
|
s.Properties.lp = (src[1] >> 4);
|
||||||
|
s.Properties.lc = src[1] & 15;
|
||||||
|
if (s.Properties.pb >= 5) goto error;
|
||||||
|
if (s.Properties.lp >= 5) goto error;
|
||||||
|
if (s.Properties.lc >= 9) goto error;
|
||||||
|
// extra
|
||||||
|
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp) goto error;
|
||||||
|
src += 2; src_len -= 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (cresult)
|
||||||
|
{
|
||||||
|
assert(cresult->method == method);
|
||||||
|
assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb);
|
||||||
|
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
|
||||||
|
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
||||||
|
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
||||||
|
const lzma_compress_result_t *res = &cresult->result_lzma;
|
||||||
|
UNUSED(res);
|
||||||
|
//printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
|
||||||
|
}
|
||||||
|
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||||
|
if (!s.Probs)
|
||||||
|
{
|
||||||
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out);
|
||||||
|
assert(src_out <= src_len);
|
||||||
|
assert(dst_out <= *dst_len);
|
||||||
|
if (rh == 0)
|
||||||
|
{
|
||||||
|
r = UPX_E_OK;
|
||||||
|
if (src_out != src_len)
|
||||||
|
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
*dst_len = dst_out;
|
||||||
|
free(s.Probs);
|
||||||
|
|
||||||
|
UNUSED(cresult);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// test_overlap
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
assert(method == M_LZMA);
|
||||||
|
|
||||||
|
// FIXME - implement this
|
||||||
|
// Note that Packer::verifyOverlappingDecompression() will
|
||||||
|
// verify the final result in any case.
|
||||||
|
UNUSED(buf);
|
||||||
|
|
||||||
|
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||||
|
//printf("upx_lzma_test_overlap: %d\n", overlap_overhead);
|
||||||
|
if ((int)overlap_overhead >= 256)
|
||||||
|
return UPX_E_OK;
|
||||||
|
|
||||||
|
UNUSED(cresult);
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// misc
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
const char *upx_lzma_version_string(void)
|
||||||
|
{
|
||||||
|
// FIXME
|
||||||
|
// return NULL;
|
||||||
|
return "4.43";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WITH_LZMA */
|
||||||
|
/*
|
||||||
|
vi:ts=4:et:nowrap
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
/* compress.ch --
|
/* compress_ucl.cpp --
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -26,6 +26,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
#if !defined(WITH_UCL)
|
||||||
|
extern int compress_ucl_dummy;
|
||||||
|
int compress_ucl_dummy = 0;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if 1 && !defined(UCL_USE_ASM) && (ACC_ARCH_I386)
|
||||||
|
# if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_MSC || ACC_CC_WATCOMC)
|
||||||
|
# define UCL_USE_ASM
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if defined(UCL_NO_ASM)
|
||||||
|
# undef UCL_USE_ASM
|
||||||
|
#endif
|
||||||
|
#if defined(ACC_CFG_NO_UNALIGNED)
|
||||||
|
# undef UCL_USE_ASM
|
||||||
|
#endif
|
||||||
#if 1 && defined(UCL_USE_ASM)
|
#if 1 && defined(UCL_USE_ASM)
|
||||||
# include <ucl/ucl_asm.h>
|
# include <ucl/ucl_asm.h>
|
||||||
# define ucl_nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8
|
# define ucl_nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8
|
||||||
@@ -44,115 +62,123 @@
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_adler32)
|
static int convert_errno_from_ucl(int r)
|
||||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
|
||||||
{
|
{
|
||||||
if (len == 0)
|
switch (r)
|
||||||
return adler;
|
{
|
||||||
assert(buf != NULL);
|
case UCL_E_OK: return UPX_E_OK;
|
||||||
return ucl_adler32(adler, (const ucl_bytep)buf, len);
|
case UCL_E_ERROR: return UPX_E_ERROR;
|
||||||
|
case UCL_E_OUT_OF_MEMORY: return UPX_E_OUT_OF_MEMORY;
|
||||||
|
case UCL_E_NOT_COMPRESSIBLE: return UPX_E_NOT_COMPRESSIBLE;
|
||||||
|
case UCL_E_INPUT_OVERRUN: return UPX_E_INPUT_OVERRUN;
|
||||||
|
case UCL_E_OUTPUT_OVERRUN: return UPX_E_OUTPUT_OVERRUN;
|
||||||
|
case UCL_E_LOOKBEHIND_OVERRUN: return UPX_E_LOOKBEHIND_OVERRUN;
|
||||||
|
case UCL_E_EOF_NOT_FOUND: return UPX_E_EOF_NOT_FOUND;
|
||||||
|
case UCL_E_INPUT_NOT_CONSUMED: return UPX_E_INPUT_NOT_CONSUMED;
|
||||||
|
// case UCL_E_NOT_YET_IMPLEMENTED: return UPX_E_NOT_YET_IMPLEMENTED;
|
||||||
|
case UCL_E_INVALID_ARGUMENT: return UPX_E_INVALID_ARGUMENT;
|
||||||
|
// UCL extra:
|
||||||
|
case UCL_E_OVERLAP_OVERRUN: return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(upx_crc32)
|
static void wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
|
||||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (state != -1 && state != 3) return;
|
||||||
return crc;
|
upx_callback_p cb = (upx_callback_p) user;
|
||||||
assert(buf != NULL);
|
if (cb && cb->nprogress)
|
||||||
return ucl_crc32(crc, (const ucl_bytep)buf, len);
|
cb->nprogress(cb, a, b);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_compress)
|
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int upx_compress ( const upx_bytep src, upx_uint src_len,
|
upx_callback_p cb_parm,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
|
||||||
upx_progress_callback_t *cb,
|
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const struct upx_compress_config_t *conf_parm,
|
const upx_compress_config_t *cconf_parm,
|
||||||
upx_uintp result )
|
upx_compress_result_t *cresult )
|
||||||
{
|
{
|
||||||
struct upx_compress_config_t conf;
|
int r;
|
||||||
upx_uint result_buffer[16];
|
assert(level > 0); assert(cresult != NULL);
|
||||||
int r = UPX_E_ERROR;
|
|
||||||
|
|
||||||
assert(level > 0);
|
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
|
||||||
memset(&conf, 0xff, sizeof(conf));
|
|
||||||
if (conf_parm)
|
|
||||||
conf = *conf_parm; // struct copy
|
|
||||||
if (!result)
|
|
||||||
result = result_buffer;
|
|
||||||
|
|
||||||
|
ucl_progress_callback_t cb;
|
||||||
|
cb.callback = 0;
|
||||||
|
cb.user = NULL;
|
||||||
|
if (cb_parm && cb_parm->nprogress) {
|
||||||
|
cb.callback = wrap_nprogress_ucl;
|
||||||
|
cb.user = cb_parm;
|
||||||
|
}
|
||||||
|
|
||||||
|
ucl_compress_config_t cconf; cconf.reset();
|
||||||
|
if (cconf_parm)
|
||||||
|
cconf = cconf_parm->conf_ucl; // struct copy
|
||||||
|
|
||||||
|
ucl_uint *res = cresult->result_ucl.result;
|
||||||
// assume no info available - fill in worst case results
|
// assume no info available - fill in worst case results
|
||||||
//result[0] = 1; // min_offset_found - NOT USED
|
//res[0] = 1; // min_offset_found - NOT USED
|
||||||
result[1] = src_len - 1; // max_offset_found
|
res[1] = src_len - 1; // max_offset_found
|
||||||
//result[2] = 2; // min_match_found - NOT USED
|
//res[2] = 2; // min_match_found - NOT USED
|
||||||
result[3] = src_len - 1; // max_match_found
|
res[3] = src_len - 1; // max_match_found
|
||||||
//result[4] = 1; // min_run_found - NOT USED
|
//res[4] = 1; // min_run_found - NOT USED
|
||||||
result[5] = src_len; // max_run_found
|
res[5] = src_len; // max_run_found
|
||||||
result[6] = 1; // first_offset_found
|
res[6] = 1; // first_offset_found
|
||||||
//result[7] = 999999; // same_match_offsets_found - NOT USED
|
//res[7] = 999999; // same_match_offsets_found - NOT USED
|
||||||
|
|
||||||
// prepare bit-buffer settings
|
// prepare bit-buffer settings
|
||||||
conf.bb_endian = 0;
|
cconf.bb_endian = 0;
|
||||||
conf.bb_size = 0;
|
cconf.bb_size = 0;
|
||||||
if (method >= M_NRV2B_LE32 && method <= M_CL1B_LE16)
|
if (method >= M_NRV2B_LE32 && method <= M_CL1B_LE16)
|
||||||
{
|
{
|
||||||
static const unsigned char sizes[3] = {32, 8, 16};
|
static const unsigned char sizes[3] = {32, 8, 16};
|
||||||
conf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// optimize compression parms
|
// optimize compression parms
|
||||||
if (level <= 3 && conf.max_offset == UPX_UINT_MAX)
|
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
conf.max_offset = 8*1024-1;
|
cconf.max_offset = 8*1024-1;
|
||||||
else if (level == 4 && conf.max_offset == UPX_UINT_MAX)
|
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
conf.max_offset = 32*1024-1;
|
cconf.max_offset = 32*1024-1;
|
||||||
|
|
||||||
if M_IS_NRV2B(method)
|
if M_IS_NRV2B(method)
|
||||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
||||||
cb, level, &conf, result);
|
&cb, level, &cconf, res);
|
||||||
else if M_IS_NRV2D(method)
|
else if M_IS_NRV2D(method)
|
||||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
||||||
cb, level, &conf, result);
|
&cb, level, &cconf, res);
|
||||||
#if defined(ALG_NRV2E)
|
|
||||||
else if M_IS_NRV2E(method)
|
else if M_IS_NRV2E(method)
|
||||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
||||||
cb, level, &conf, result);
|
&cb, level, &cconf, res);
|
||||||
#endif
|
else {
|
||||||
#if 0 /*{*/
|
|
||||||
else if M_IS_CL1B(method)
|
|
||||||
r = cl1b_compress(src, src_len, dst, dst_len,
|
|
||||||
cb, level, &conf, result);
|
|
||||||
#endif /*}*/
|
|
||||||
else
|
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* upx_compress */
|
return convert_errno_from_ucl(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_decompress)
|
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
int method,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
const upx_compress_result_t *cresult )
|
||||||
int method )
|
|
||||||
{
|
{
|
||||||
int r = UPX_E_ERROR;
|
int r;
|
||||||
|
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
@@ -174,7 +200,6 @@ int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
|||||||
case M_NRV2D_LE32:
|
case M_NRV2D_LE32:
|
||||||
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#if defined(ALG_NRV2E)
|
|
||||||
case M_NRV2E_8:
|
case M_NRV2E_8:
|
||||||
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
@@ -184,40 +209,26 @@ int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
|||||||
case M_NRV2E_LE32:
|
case M_NRV2E_LE32:
|
||||||
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#if 0 /*{*/
|
|
||||||
case M_CL1B_8:
|
|
||||||
r = cl1b_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE16:
|
|
||||||
r = cl1b_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE32:
|
|
||||||
r = cl1b_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
#endif /*}*/
|
|
||||||
default:
|
default:
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown decompression method");
|
||||||
break;
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
UNUSED(cresult);
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* upx_decompress */
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_test_overlap)
|
int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
int method,
|
||||||
upx_uint src_len, upx_uintp dst_len,
|
const upx_compress_result_t *cresult )
|
||||||
int method )
|
|
||||||
{
|
{
|
||||||
int r = UPX_E_ERROR;
|
int r;
|
||||||
|
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
@@ -239,7 +250,6 @@ int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
|||||||
case M_NRV2D_LE32:
|
case M_NRV2D_LE32:
|
||||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#if defined(ALG_NRV2E)
|
|
||||||
case M_NRV2E_8:
|
case M_NRV2E_8:
|
||||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
@@ -249,29 +259,27 @@ int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
|||||||
case M_NRV2E_LE32:
|
case M_NRV2E_LE32:
|
||||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#if 0 /*{*/
|
|
||||||
case M_CL1B_8:
|
|
||||||
r = cl1b_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE16:
|
|
||||||
r = cl1b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE32:
|
|
||||||
r = cl1b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
#endif /*}*/
|
|
||||||
default:
|
default:
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown decompression method");
|
||||||
break;
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
UNUSED(cresult);
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* upx_test_overlap */
|
|
||||||
|
/*************************************************************************
|
||||||
|
// misc
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
const char *upx_ucl_version_string(void)
|
||||||
|
{
|
||||||
|
return ucl_version_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WITH_UCL */
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et:nowrap
|
vi:ts=4:et:nowrap
|
||||||
*/
|
*/
|
||||||
@@ -0,0 +1,230 @@
|
|||||||
|
/* compress_zlib.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
|
||||||
|
|
||||||
|
void zlib_compress_config_t::reset()
|
||||||
|
{
|
||||||
|
memset(this, 0, sizeof(*this));
|
||||||
|
|
||||||
|
mem_level.reset();
|
||||||
|
window_bits.reset();
|
||||||
|
strategy.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(WITH_ZLIB)
|
||||||
|
extern int compress_zlib_dummy;
|
||||||
|
int compress_zlib_dummy = 0;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
static int convert_errno_from_zlib(int zr)
|
||||||
|
{
|
||||||
|
switch (zr)
|
||||||
|
{
|
||||||
|
case Z_OK: return UPX_E_OK;
|
||||||
|
case Z_DATA_ERROR: return UPX_E_ERROR;
|
||||||
|
case Z_NEED_DICT: return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
upx_callback_p cb_parm,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf_parm,
|
||||||
|
upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
assert(method == M_DEFLATE);
|
||||||
|
assert(level > 0); assert(cresult != NULL);
|
||||||
|
UNUSED(cb_parm);
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
int zr;
|
||||||
|
const zlib_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_zlib : NULL;
|
||||||
|
zlib_compress_result_t *res = &cresult->result_zlib;
|
||||||
|
|
||||||
|
if (level == 10)
|
||||||
|
level = 9;
|
||||||
|
|
||||||
|
zlib_compress_config_t::mem_level_t mem_level;
|
||||||
|
zlib_compress_config_t::window_bits_t window_bits;
|
||||||
|
zlib_compress_config_t::strategy_t strategy;
|
||||||
|
// cconf overrides
|
||||||
|
if (lcconf)
|
||||||
|
{
|
||||||
|
oassign(mem_level, lcconf->mem_level);
|
||||||
|
oassign(window_bits, lcconf->window_bits);
|
||||||
|
oassign(strategy, lcconf->strategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
res->dummy = 0;
|
||||||
|
|
||||||
|
z_stream s;
|
||||||
|
s.zalloc = (alloc_func) 0;
|
||||||
|
s.zfree = (free_func) 0;
|
||||||
|
s.next_in = const_cast<upx_bytep>(src); // UNCONST
|
||||||
|
s.avail_in = src_len;
|
||||||
|
s.next_out = dst;
|
||||||
|
s.avail_out = *dst_len;
|
||||||
|
s.total_in = s.total_out = 0;
|
||||||
|
|
||||||
|
zr = deflateInit2(&s, level, Z_DEFLATED, 0 - (int)window_bits,
|
||||||
|
mem_level, strategy);
|
||||||
|
if (zr != Z_OK)
|
||||||
|
goto error;
|
||||||
|
zr = deflate(&s, Z_FINISH);
|
||||||
|
if (zr != Z_STREAM_END)
|
||||||
|
goto error;
|
||||||
|
zr = deflateEnd(&s);
|
||||||
|
if (zr != Z_OK)
|
||||||
|
goto error;
|
||||||
|
r = UPX_E_OK;
|
||||||
|
goto done;
|
||||||
|
error:
|
||||||
|
(void) deflateEnd(&s);
|
||||||
|
r = convert_errno_from_zlib(zr);
|
||||||
|
if (r == UPX_E_OK)
|
||||||
|
r = UPX_E_ERROR;
|
||||||
|
done:
|
||||||
|
if (r == UPX_E_OK)
|
||||||
|
{
|
||||||
|
if (s.avail_in != 0 || s.total_in != src_len)
|
||||||
|
r = UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
assert(s.total_in <= src_len);
|
||||||
|
assert(s.total_out <= *dst_len);
|
||||||
|
*dst_len = s.total_out;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
assert(method == M_DEFLATE);
|
||||||
|
UNUSED(method);
|
||||||
|
UNUSED(cresult);
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
int zr;
|
||||||
|
|
||||||
|
z_stream s;
|
||||||
|
s.zalloc = (alloc_func) 0;
|
||||||
|
s.zfree = (free_func) 0;
|
||||||
|
s.next_in = const_cast<upx_bytep>(src); // UNCONST
|
||||||
|
s.avail_in = src_len;
|
||||||
|
s.next_out = dst;
|
||||||
|
s.avail_out = *dst_len;
|
||||||
|
s.total_in = s.total_out = 0;
|
||||||
|
|
||||||
|
zr = inflateInit2(&s, -15);
|
||||||
|
if (zr != Z_OK)
|
||||||
|
goto error;
|
||||||
|
zr = inflate(&s, Z_FINISH);
|
||||||
|
if (zr != Z_STREAM_END)
|
||||||
|
goto error;
|
||||||
|
zr = inflateEnd(&s);
|
||||||
|
if (zr != Z_OK)
|
||||||
|
goto error;
|
||||||
|
r = UPX_E_OK;
|
||||||
|
goto done;
|
||||||
|
error:
|
||||||
|
(void) inflateEnd(&s);
|
||||||
|
r = convert_errno_from_zlib(zr);
|
||||||
|
if (r == UPX_E_OK)
|
||||||
|
r = UPX_E_ERROR;
|
||||||
|
done:
|
||||||
|
if (r == UPX_E_OK)
|
||||||
|
{
|
||||||
|
if (s.avail_in != 0 || s.total_in != src_len)
|
||||||
|
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||||
|
}
|
||||||
|
assert(s.total_in <= src_len);
|
||||||
|
assert(s.total_out <= *dst_len);
|
||||||
|
*dst_len = s.total_out;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// test_overlap
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
assert(method == M_DEFLATE);
|
||||||
|
|
||||||
|
// FIXME - implement this
|
||||||
|
// Note that Packer::verifyOverlappingDecompression() will
|
||||||
|
// verify the final result in any case.
|
||||||
|
UNUSED(buf);
|
||||||
|
|
||||||
|
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||||
|
//printf("upx_zlib_test_overlap: %d\n", overlap_overhead);
|
||||||
|
if ((int)overlap_overhead >= 256)
|
||||||
|
return UPX_E_OK;
|
||||||
|
|
||||||
|
UNUSED(cresult);
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// misc
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
const char *upx_zlib_version_string(void)
|
||||||
|
{
|
||||||
|
return zlibVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WITH_ZLIB */
|
||||||
|
/*
|
||||||
|
vi:ts=4:et:nowrap
|
||||||
|
*/
|
||||||
|
|
||||||
+252
-79
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -40,8 +40,16 @@
|
|||||||
#if ((ACC_OS_WIN32 || ACC_OS_WIN64) && ACC_CC_MWERKS) && defined(__MSL__)
|
#if ((ACC_OS_WIN32 || ACC_OS_WIN64) && ACC_CC_MWERKS) && defined(__MSL__)
|
||||||
# undef HAVE_UTIME_H /* this pulls in <windows.h> */
|
# undef HAVE_UTIME_H /* this pulls in <windows.h> */
|
||||||
#endif
|
#endif
|
||||||
|
// FIXME - quick hack for arm-wince-gcc-3.4 (Debian pocketpc-*.deb packages)
|
||||||
|
#if 1 && (ACC_ARCH_ARM) && defined(__pe__) && !defined(_WIN32)
|
||||||
|
# undef HAVE_CHMOD
|
||||||
|
# undef HAVE_CHOWN
|
||||||
|
# undef HAVE_LSTAT
|
||||||
|
# undef HAVE_UTIME
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// pragmas
|
||||||
#if (ACC_CC_BORLANDC)
|
#if (ACC_CC_BORLANDC)
|
||||||
# if (__BORLANDC__ < 0x0500)
|
# if (__BORLANDC__ < 0x0500)
|
||||||
# error "need Borland C++ 5.0 or newer"
|
# error "need Borland C++ 5.0 or newer"
|
||||||
@@ -144,35 +152,30 @@
|
|||||||
# undef __unix
|
# undef __unix
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(WITH_UCL)
|
#if !defined(WITH_UCL)
|
||||||
# define WITH_UCL 1
|
# define WITH_UCL 1
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_UCL)
|
#if 0 && !defined(WITH_LZMA)
|
||||||
# include <ucl/uclconf.h>
|
# define WITH_LZMA 1
|
||||||
# include <ucl/ucl.h>
|
|
||||||
# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010200L)
|
|
||||||
# error "please upgrade your UCL installation"
|
|
||||||
#endif
|
#endif
|
||||||
# if !defined(UPX_UINT_MAX)
|
#if defined(UPX_OFFICIAL_BUILD)
|
||||||
# define UPX_UINT_MAX UCL_UINT_MAX
|
# if !defined(WITH_LZMA) || !defined(WITH_NRV) || !defined(WITH_UCL)
|
||||||
# define upx_uint ucl_uint
|
# error
|
||||||
# define upx_voidp ucl_voidp
|
|
||||||
# define upx_uintp ucl_uintp
|
|
||||||
# define upx_byte ucl_byte
|
|
||||||
# define upx_bytep ucl_bytep
|
|
||||||
# define upx_bool ucl_bool
|
|
||||||
# define upx_compress_config_t ucl_compress_config_t
|
|
||||||
# define upx_progress_callback_t ucl_progress_callback_t
|
|
||||||
# define UPX_E_OK UCL_E_OK
|
|
||||||
# define UPX_E_ERROR UCL_E_ERROR
|
|
||||||
# define UPX_E_OUT_OF_MEMORY UCL_E_OUT_OF_MEMORY
|
|
||||||
# define __UPX_CDECL __UCL_CDECL
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_NRV)
|
#if defined(WITH_NRV)
|
||||||
# include <nrv/nrvconf.h>
|
# include <nrv/nrvconf.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(WITH_UCL)
|
||||||
|
# define ucl_compress_config_t REAL_ucl_compress_config_t
|
||||||
|
# include <ucl/uclconf.h>
|
||||||
|
# include <ucl/ucl.h>
|
||||||
|
# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010300L)
|
||||||
|
# error "please upgrade your UCL installation"
|
||||||
|
# endif
|
||||||
|
# undef ucl_compress_config_t
|
||||||
|
# undef ucl_compress_config_p
|
||||||
|
#endif
|
||||||
#if !defined(__UPX_CHECKER)
|
#if !defined(__UPX_CHECKER)
|
||||||
# if defined(__UCL_CHECKER) || defined(__NRV_CHECKER)
|
# if defined(__UCL_CHECKER) || defined(__NRV_CHECKER)
|
||||||
# define __UPX_CHECKER
|
# define __UPX_CHECKER
|
||||||
@@ -182,6 +185,35 @@
|
|||||||
# error "UINT_MAX"
|
# error "UINT_MAX"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define upx_byte unsigned char
|
||||||
|
#define upx_bytep upx_byte *
|
||||||
|
#define UPX_E_OK (0)
|
||||||
|
#define UPX_E_ERROR (-1)
|
||||||
|
#define UPX_E_OUT_OF_MEMORY (-2)
|
||||||
|
#define UPX_E_NOT_COMPRESSIBLE (-3)
|
||||||
|
#define UPX_E_INPUT_OVERRUN (-4)
|
||||||
|
#define UPX_E_OUTPUT_OVERRUN (-5)
|
||||||
|
#define UPX_E_LOOKBEHIND_OVERRUN (-6)
|
||||||
|
#define UPX_E_EOF_NOT_FOUND (-7)
|
||||||
|
#define UPX_E_INPUT_NOT_CONSUMED (-8)
|
||||||
|
#define UPX_E_NOT_YET_IMPLEMENTED (-9)
|
||||||
|
#define UPX_E_INVALID_ARGUMENT (-10)
|
||||||
|
|
||||||
|
struct upx_callback_t;
|
||||||
|
#define upx_callback_p upx_callback_t *
|
||||||
|
typedef void* (__acc_cdecl *upx_alloc_func_t)
|
||||||
|
(upx_callback_p self, unsigned items, unsigned size);
|
||||||
|
typedef void (__acc_cdecl *upx_free_func_t)
|
||||||
|
(upx_callback_p self, void* ptr);
|
||||||
|
typedef void (__acc_cdecl *upx_progress_func_t)
|
||||||
|
(upx_callback_p, unsigned, unsigned);
|
||||||
|
|
||||||
|
struct upx_callback_t
|
||||||
|
{
|
||||||
|
upx_progress_func_t nprogress;
|
||||||
|
void * user1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// system includes
|
// system includes
|
||||||
@@ -190,18 +222,6 @@
|
|||||||
// malloc debuggers
|
// malloc debuggers
|
||||||
#if defined(WITH_VALGRIND)
|
#if defined(WITH_VALGRIND)
|
||||||
# include <valgrind/memcheck.h>
|
# include <valgrind/memcheck.h>
|
||||||
#elif defined(WITH_DMALLOC)
|
|
||||||
# define DMALLOC_FUNC_CHECK
|
|
||||||
# include <dmalloc.h>
|
|
||||||
#elif defined(WITH_GC)
|
|
||||||
# define GC_DEBUG
|
|
||||||
# include <gc/gc.h>
|
|
||||||
# undef malloc
|
|
||||||
# undef realloc
|
|
||||||
# undef free
|
|
||||||
# define malloc GC_MALLOC
|
|
||||||
# define realloc GC_REALLOC
|
|
||||||
# define free GC_FREE
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(VALGRIND_MAKE_WRITABLE)
|
#if !defined(VALGRIND_MAKE_WRITABLE)
|
||||||
@@ -219,6 +239,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// unconditionally turn on assertions
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
@@ -353,39 +374,6 @@
|
|||||||
|
|
||||||
#define UPX_MAX(a,b) ((a) >= (b) ? (a) : (b))
|
#define UPX_MAX(a,b) ((a) >= (b) ? (a) : (b))
|
||||||
#define UPX_MIN(a,b) ((a) <= (b) ? (a) : (b))
|
#define UPX_MIN(a,b) ((a) <= (b) ? (a) : (b))
|
||||||
#define UPX_MAX3(a,b,c) ((a) >= (b) ? UPX_MAX(a,c) : UPX_MAX(b,c))
|
|
||||||
#define UPX_MIN3(a,b,c) ((a) <= (b) ? UPX_MIN(a,c) : UPX_MIN(b,c))
|
|
||||||
|
|
||||||
|
|
||||||
#if 0 && defined(__cplusplus) && !defined(new) && !defined(delete)
|
|
||||||
// global operators - debug
|
|
||||||
inline void *operator new(size_t l)
|
|
||||||
{
|
|
||||||
void *p = malloc(l);
|
|
||||||
printf("new %6ld %p\n",(long)l,p);
|
|
||||||
fflush(stdout);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
inline void *operator new[](size_t l)
|
|
||||||
{
|
|
||||||
void *p = malloc(l);
|
|
||||||
printf("new[] %6ld %p\n",(long)l,p);
|
|
||||||
fflush(stdout);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
inline void operator delete(void *p)
|
|
||||||
{
|
|
||||||
printf("delete %p\n",p);
|
|
||||||
fflush(stdout);
|
|
||||||
if (p) free(p);
|
|
||||||
}
|
|
||||||
inline void operator delete[](void *p)
|
|
||||||
{
|
|
||||||
printf("delete[] %p\n",p);
|
|
||||||
fflush(stdout);
|
|
||||||
if (p) free(p);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// An Array allocates memory on the heap, but automatically
|
// An Array allocates memory on the heap, but automatically
|
||||||
@@ -397,6 +385,14 @@ inline void operator delete[](void *p)
|
|||||||
|
|
||||||
#define ByteArray(var, size) Array(unsigned char, var, size)
|
#define ByteArray(var, size) Array(unsigned char, var, size)
|
||||||
|
|
||||||
|
struct nocopy
|
||||||
|
{
|
||||||
|
inline nocopy() {}
|
||||||
|
private:
|
||||||
|
nocopy(const nocopy &); // undefined
|
||||||
|
nocopy& operator=(const nocopy &); // undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// constants
|
// constants
|
||||||
@@ -417,6 +413,8 @@ inline void operator delete[](void *p)
|
|||||||
|
|
||||||
|
|
||||||
// compression methods - DO NOT CHANGE
|
// compression methods - DO NOT CHANGE
|
||||||
|
#define M_SKIP (-2)
|
||||||
|
#define M_END (-1)
|
||||||
#define M_NRV2B_LE32 2
|
#define M_NRV2B_LE32 2
|
||||||
#define M_NRV2B_8 3
|
#define M_NRV2B_8 3
|
||||||
#define M_NRV2B_LE16 4
|
#define M_NRV2B_LE16 4
|
||||||
@@ -429,11 +427,15 @@ inline void operator delete[](void *p)
|
|||||||
#define M_CL1B_LE32 11
|
#define M_CL1B_LE32 11
|
||||||
#define M_CL1B_8 12
|
#define M_CL1B_8 12
|
||||||
#define M_CL1B_LE16 13
|
#define M_CL1B_LE16 13
|
||||||
|
#define M_LZMA 14
|
||||||
|
#define M_DEFLATE 15 /* zlib */
|
||||||
|
|
||||||
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
|
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
|
||||||
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
|
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
|
||||||
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
|
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
|
||||||
#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
||||||
|
#define M_IS_LZMA(x) ((x) == M_LZMA)
|
||||||
|
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
|
||||||
|
|
||||||
|
|
||||||
// Executable formats. Note: big endian types are >= 128.
|
// Executable formats. Note: big endian types are >= 128.
|
||||||
@@ -459,6 +461,10 @@ inline void operator delete[](void *p)
|
|||||||
#define UPX_F_LINUX_ELFI_i386 20
|
#define UPX_F_LINUX_ELFI_i386 20
|
||||||
#define UPX_F_WINCE_ARM_PE 21
|
#define UPX_F_WINCE_ARM_PE 21
|
||||||
#define UPX_F_LINUX_ELF64_AMD 22
|
#define UPX_F_LINUX_ELF64_AMD 22
|
||||||
|
#define UPX_F_LINUX_ELF32_ARMLE 23
|
||||||
|
#define UPX_F_BSD_i386 24
|
||||||
|
#define UPX_F_BSD_ELF_i386 25
|
||||||
|
#define UPX_F_BSD_SH_i386 26
|
||||||
|
|
||||||
#define UPX_F_PLAIN_TEXT 127
|
#define UPX_F_PLAIN_TEXT 127
|
||||||
|
|
||||||
@@ -466,12 +472,172 @@ inline void operator delete[](void *p)
|
|||||||
#define UPX_F_SOLARIS_SPARC 130
|
#define UPX_F_SOLARIS_SPARC 130
|
||||||
#define UPX_F_MACH_PPC32 131
|
#define UPX_F_MACH_PPC32 131
|
||||||
#define UPX_F_LINUX_ELFPPC32 132
|
#define UPX_F_LINUX_ELFPPC32 132
|
||||||
|
#define UPX_F_LINUX_ELF32_ARMBE 133
|
||||||
|
|
||||||
|
|
||||||
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
|
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
|
||||||
#define UPX_MAGIC2_LE32 0xD5D0D8A1
|
#define UPX_MAGIC2_LE32 0xD5D0D8A1
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compression - config_t
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
template <class T, T default_value, T min_value, T max_value>
|
||||||
|
struct OptVar
|
||||||
|
{
|
||||||
|
typedef T Type;
|
||||||
|
static const T default_value_c = default_value;
|
||||||
|
static const T min_value_c = min_value;
|
||||||
|
static const T max_value_c = max_value;
|
||||||
|
|
||||||
|
void assertValue() {
|
||||||
|
// FIXME: this generates annoying warnings "unsigned >= 0 is always true"
|
||||||
|
//assert((v >= min_value) && (v <= max_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
OptVar() : v(default_value), is_set(0) { }
|
||||||
|
OptVar& operator= (const T other) {
|
||||||
|
v = other; is_set += 1;
|
||||||
|
assertValue();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
#error
|
||||||
|
// there is too much implicit magic in this copy operator;
|
||||||
|
// better introduce an explicit "oassign" function.
|
||||||
|
OptVar& operator= (const OptVar& other) {
|
||||||
|
if (other.is_set) { v = other.v; is_set += 1; }
|
||||||
|
assertValue(); return *this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void reset() { v = default_value; is_set = 0; }
|
||||||
|
operator T () const { return v; }
|
||||||
|
|
||||||
|
T v;
|
||||||
|
unsigned is_set;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// optional assignments
|
||||||
|
template <class T> void oassign(T& self, const T& other) {
|
||||||
|
if (other.is_set) { self.v = other.v; self.is_set += 1; }
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
template <class V, class T> void oassign(V& v, const T& other) {
|
||||||
|
if (other.is_set) { v = other.v; }
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <class T> void oassign(unsigned& v, const T& other) {
|
||||||
|
if (other.is_set) { v = other.v; }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct lzma_compress_config_t
|
||||||
|
{
|
||||||
|
typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb
|
||||||
|
typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lb
|
||||||
|
typedef OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc
|
||||||
|
typedef OptVar<unsigned, (1u<<22), 1u, (1u<<30) > dict_size_t;
|
||||||
|
typedef OptVar<unsigned, 64u, 5u, 273u> num_fast_bytes_t;
|
||||||
|
|
||||||
|
pos_bits_t pos_bits; // pb
|
||||||
|
lit_pos_bits_t lit_pos_bits; // lp
|
||||||
|
lit_context_bits_t lit_context_bits; // lc
|
||||||
|
dict_size_t dict_size;
|
||||||
|
unsigned fast_mode;
|
||||||
|
num_fast_bytes_t num_fast_bytes;
|
||||||
|
unsigned match_finder_cycles;
|
||||||
|
|
||||||
|
unsigned max_num_probs;
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ucl_compress_config_t : public REAL_ucl_compress_config_t
|
||||||
|
{
|
||||||
|
void reset() { memset(this, 0xff, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct zlib_compress_config_t
|
||||||
|
{
|
||||||
|
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
|
||||||
|
typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb
|
||||||
|
typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st
|
||||||
|
|
||||||
|
mem_level_t mem_level; // ml
|
||||||
|
window_bits_t window_bits; // wb
|
||||||
|
strategy_t strategy; // st
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct upx_compress_config_t
|
||||||
|
{
|
||||||
|
lzma_compress_config_t conf_lzma;
|
||||||
|
ucl_compress_config_t conf_ucl;
|
||||||
|
zlib_compress_config_t conf_zlib;
|
||||||
|
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compression - result_t
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
struct lzma_compress_result_t
|
||||||
|
{
|
||||||
|
unsigned pos_bits; // pb
|
||||||
|
unsigned lit_pos_bits; // lp
|
||||||
|
unsigned lit_context_bits; // lc
|
||||||
|
unsigned dict_size;
|
||||||
|
unsigned fast_mode;
|
||||||
|
unsigned num_fast_bytes;
|
||||||
|
unsigned match_finder_cycles;
|
||||||
|
unsigned num_probs; // (computed result)
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ucl_compress_result_t
|
||||||
|
{
|
||||||
|
ucl_uint result[16];
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct zlib_compress_result_t
|
||||||
|
{
|
||||||
|
unsigned dummy;
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct upx_compress_result_t
|
||||||
|
{
|
||||||
|
// debug
|
||||||
|
int method, level;
|
||||||
|
unsigned u_len, c_len;
|
||||||
|
|
||||||
|
lzma_compress_result_t result_lzma;
|
||||||
|
ucl_compress_result_t result_ucl;
|
||||||
|
zlib_compress_result_t result_zlib;
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
memset(this, 0, sizeof(*this));
|
||||||
|
result_lzma.reset(); result_ucl.reset(); result_zlib.reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// globals
|
// globals
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -488,6 +654,11 @@ inline void operator delete[](void *p)
|
|||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
|
||||||
|
|
||||||
|
// classes
|
||||||
|
class ElfLinker;
|
||||||
|
typedef ElfLinker Linker;
|
||||||
|
|
||||||
|
|
||||||
// main.cpp
|
// main.cpp
|
||||||
extern const char *progname;
|
extern const char *progname;
|
||||||
void init_options(struct options_t *o);
|
void init_options(struct options_t *o);
|
||||||
@@ -537,7 +708,7 @@ void do_files(int i, int argc, char *argv[]);
|
|||||||
|
|
||||||
// help.cpp
|
// help.cpp
|
||||||
void show_head(void);
|
void show_head(void);
|
||||||
void show_help(int x = 0);
|
void show_help(int verbose=0);
|
||||||
void show_license(void);
|
void show_license(void);
|
||||||
void show_usage(void);
|
void show_usage(void);
|
||||||
void show_version(int);
|
void show_version(int);
|
||||||
@@ -547,18 +718,20 @@ void show_version(int);
|
|||||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
||||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc=0);
|
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc=0);
|
||||||
|
|
||||||
int upx_compress ( const upx_bytep src, upx_uint src_len,
|
int upx_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
upx_progress_callback_t *cb,
|
upx_callback_p cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const struct upx_compress_config_t *conf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_uintp result );
|
upx_compress_result_t *cresult );
|
||||||
int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
int upx_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int method );
|
int method,
|
||||||
int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
const upx_compress_result_t *cresult );
|
||||||
upx_uint src_len, upx_uintp dst_len,
|
int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
int method );
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -117,7 +117,7 @@ typedef struct
|
|||||||
int (*init)(FILE *f, int, int);
|
int (*init)(FILE *f, int, int);
|
||||||
int (*set_fg)(FILE *f, int fg);
|
int (*set_fg)(FILE *f, int fg);
|
||||||
void (*print0)(FILE *f, const char *s);
|
void (*print0)(FILE *f, const char *s);
|
||||||
upx_bool (*intro)(FILE *f);
|
bool (*intro)(FILE *f);
|
||||||
}
|
}
|
||||||
console_t;
|
console_t;
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -85,6 +85,11 @@ void throwCantPack(const char *msg)
|
|||||||
throw CantUnpackException(msg);
|
throw CantUnpackException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void throwCantPackExact()
|
||||||
|
{
|
||||||
|
throwCantPack("option '--exact' does not work with this file");
|
||||||
|
}
|
||||||
|
|
||||||
void throwFilterException()
|
void throwFilterException()
|
||||||
{
|
{
|
||||||
throwCantPack("filter problem");
|
throwCantPack("filter problem");
|
||||||
|
|||||||
+3
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -208,6 +208,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void throwCantPack(const char *msg) NORET;
|
void throwCantPack(const char *msg) NORET;
|
||||||
|
void throwCantPackExact() NORET;
|
||||||
void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET;
|
void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET;
|
||||||
void throwNotCompressible(const char *msg = NULL) NORET;
|
void throwNotCompressible(const char *msg = NULL) NORET;
|
||||||
void throwAlreadyPacked(const char *msg = NULL) NORET;
|
void throwAlreadyPacked(const char *msg = NULL) NORET;
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+77
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -383,6 +383,81 @@ static int s_ct32_e8e9_bswap_be(Filter *f)
|
|||||||
|
|
||||||
#undef CT32
|
#undef CT32
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// 24-bit ARM calltrick ("naive")
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#define CT24ARM_LE(f, cond, addvalue, get, set) \
|
||||||
|
upx_byte *b = f->buf; \
|
||||||
|
upx_byte *b_end = b + f->buf_len - 4; \
|
||||||
|
do { \
|
||||||
|
if (cond) \
|
||||||
|
{ \
|
||||||
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
|
f->lastcall = a; \
|
||||||
|
set(b, get(b) + (addvalue)); \
|
||||||
|
f->calls++; \
|
||||||
|
} \
|
||||||
|
b += 4; \
|
||||||
|
} while (b < b_end); \
|
||||||
|
if (f->lastcall) f->lastcall += 4; \
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
#define ARMCT_COND_le (((b[3] & 0x0f) == 0x0b))
|
||||||
|
|
||||||
|
static int f_ct24arm_le(Filter *f)
|
||||||
|
{
|
||||||
|
CT24ARM_LE(f, ARMCT_COND_le, a / 4 + f->addvalue, get_le24, set_le24)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int u_ct24arm_le(Filter *f)
|
||||||
|
{
|
||||||
|
CT24ARM_LE(f, ARMCT_COND_le, 0 - a / 4 - f->addvalue, get_le24, set_le24)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int s_ct24arm_le(Filter *f)
|
||||||
|
{
|
||||||
|
CT24ARM_LE(f, ARMCT_COND_le, a + f->addvalue, get_le24, set_dummy)
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CT24ARM_LE
|
||||||
|
|
||||||
|
#define CT24ARM_BE(f, cond, addvalue, get, set) \
|
||||||
|
upx_byte *b = f->buf; \
|
||||||
|
upx_byte *b_end = b + f->buf_len - 4; \
|
||||||
|
do { \
|
||||||
|
if (cond) \
|
||||||
|
{ \
|
||||||
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
|
f->lastcall = a; \
|
||||||
|
set(1+b, get(1+b) + (addvalue)); \
|
||||||
|
f->calls++; \
|
||||||
|
} \
|
||||||
|
b += 4; \
|
||||||
|
} while (b < b_end); \
|
||||||
|
if (f->lastcall) f->lastcall += 4; \
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#define ARMCT_COND_be (((b[0] & 0x0f) == 0x0b))
|
||||||
|
|
||||||
|
static int f_ct24arm_be(Filter *f)
|
||||||
|
{
|
||||||
|
CT24ARM_BE(f, ARMCT_COND_be, a / 4 + f->addvalue, get_be24, set_be24)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int u_ct24arm_be(Filter *f)
|
||||||
|
{
|
||||||
|
CT24ARM_BE(f, ARMCT_COND_be, 0 - a / 4 - f->addvalue, get_be24, set_be24)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int s_ct24arm_be(Filter *f)
|
||||||
|
{
|
||||||
|
CT24ARM_BE(f, ARMCT_COND_be, a + f->addvalue, get_be24, set_dummy)
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CT24ARM_BE
|
||||||
|
#undef ARMCT_COND
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et:nowrap
|
vi:ts=4:et:nowrap
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2004-2005 John F. Reiser
|
Copyright (C) 2004-2006 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+7
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -224,6 +224,10 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
|||||||
{ 0x46, 6, 0x00ffffff, f_ctok32_e8e9_bswap_le, u_ctok32_e8e9_bswap_le, s_ctok32_e8e9_bswap_le },
|
{ 0x46, 6, 0x00ffffff, f_ctok32_e8e9_bswap_le, u_ctok32_e8e9_bswap_le, s_ctok32_e8e9_bswap_le },
|
||||||
{ 0x49, 6, 0x00ffffff, f_ctok32_e8e9_bswap_le, u_ctok32_e8e9_bswap_le, s_ctok32_e8e9_bswap_le },
|
{ 0x49, 6, 0x00ffffff, f_ctok32_e8e9_bswap_le, u_ctok32_e8e9_bswap_le, s_ctok32_e8e9_bswap_le },
|
||||||
|
|
||||||
|
// 24-bit calltrick for arm
|
||||||
|
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
|
||||||
|
{ 0x51, 8, 0x01ffffff, f_ct24arm_be, u_ct24arm_be, s_ct24arm_be },
|
||||||
|
|
||||||
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
|
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
|
||||||
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
||||||
{ 0x81, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
{ 0x81, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
||||||
|
|||||||
+36
-15
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -88,7 +89,7 @@ void show_usage(void)
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void show_help(int x)
|
void show_help(int x/*verbose*/)
|
||||||
{
|
{
|
||||||
FILE *f = con_term;
|
FILE *f = con_term;
|
||||||
int fg;
|
int fg;
|
||||||
@@ -196,7 +197,8 @@ void show_help(int x)
|
|||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" --all-methods try all available compression methods\n"
|
" --all-methods try all available compression methods\n"
|
||||||
" --8-bit uses 8 bit size compression [default: 32 bit]\n"
|
" --8-bit uses 8 bit size compression [default: 32 bit]\n"
|
||||||
" --console-run enables client/host transfer compatibility\n"
|
" --8mb-ram 8 megabyte memory limit [default: 2 mb]\n"
|
||||||
|
" --boot-only disables client/host transfer compatibility\n"
|
||||||
" --no-align don't align to 2048 bytes [enables: --console-run]\n"
|
" --no-align don't align to 2048 bytes [enables: --console-run]\n"
|
||||||
"\n");
|
"\n");
|
||||||
fg = con_fg(f,FG_YELLOW);
|
fg = con_fg(f,FG_YELLOW);
|
||||||
@@ -229,6 +231,7 @@ void show_help(int x)
|
|||||||
" --compress-icons=1 compress all but the first icon\n"
|
" --compress-icons=1 compress all but the first icon\n"
|
||||||
" --compress-icons=2 compress all but the first icon directory [default]\n"
|
" --compress-icons=2 compress all but the first icon directory [default]\n"
|
||||||
" --compress-resources=0 do not compress any resources at all\n"
|
" --compress-resources=0 do not compress any resources at all\n"
|
||||||
|
" --keep-resource=list do not compress resources specified by list\n"
|
||||||
" --strip-relocs=0 do not strip relocations\n"
|
" --strip-relocs=0 do not strip relocations\n"
|
||||||
" --strip-relocs=1 strip relocations [default]\n"
|
" --strip-relocs=1 strip relocations [default]\n"
|
||||||
" --all-methods try all available compression methods\n"
|
" --all-methods try all available compression methods\n"
|
||||||
@@ -338,25 +341,43 @@ void show_license(void)
|
|||||||
|
|
||||||
void show_version(int x)
|
void show_version(int x)
|
||||||
{
|
{
|
||||||
FILE *f = stdout;
|
FILE *fp = stdout;
|
||||||
|
const char *v;
|
||||||
UNUSED(x);
|
UNUSED(x);
|
||||||
|
UNUSED(v);
|
||||||
|
|
||||||
#if (0 && ACC_CC_GNUC)
|
fprintf(fp, "upx %s\n", UPX_VERSION_STRING);
|
||||||
fprintf(f,"upx %s (gcc 0x%06lx)\n", UPX_VERSION_STRING, ACC_CC_GNUC);
|
|
||||||
#else
|
|
||||||
fprintf(f,"upx %s\n", UPX_VERSION_STRING);
|
|
||||||
#endif
|
|
||||||
#if defined(WITH_NRV)
|
#if defined(WITH_NRV)
|
||||||
fprintf(f,"NRV data compression library %s\n", nrv_version_string());
|
v = upx_nrv_version_string();
|
||||||
|
if (v != NULL && v[0])
|
||||||
|
fprintf(fp, "NRV data compression library %s\n", v);
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_UCL)
|
#if defined(WITH_UCL)
|
||||||
fprintf(f,"UCL data compression library %s\n", ucl_version_string());
|
v = upx_ucl_version_string();
|
||||||
|
if (v != NULL && v[0])
|
||||||
|
fprintf(fp, "UCL data compression library %s\n", v);
|
||||||
#endif
|
#endif
|
||||||
fprintf(f,"Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer\n");
|
#if defined(WITH_ZLIB)
|
||||||
fprintf(f,"Copyright (C) 1996-2006 Laszlo Molnar\n");
|
v = upx_zlib_version_string();
|
||||||
fprintf(f,"Copyright (C) 2000-2006 John F. Reiser\n");
|
if (v != NULL && v[0])
|
||||||
fprintf(f,"Copyright (C) 2002-2006 Jens Medoch\n");
|
fprintf(fp, "zlib data compression library %s\n", v);
|
||||||
fprintf(f,"UPX comes with ABSOLUTELY NO WARRANTY; for details type `%s -L'.\n", progname);
|
#endif
|
||||||
|
#if defined(WITH_LZMA)
|
||||||
|
v = upx_lzma_version_string();
|
||||||
|
if (v != NULL && v[0])
|
||||||
|
fprintf(fp, "LZMA SDK version %s\n", v);
|
||||||
|
#endif
|
||||||
|
fprintf(fp, "Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer\n");
|
||||||
|
fprintf(fp, "Copyright (C) 1996-2006 Laszlo Molnar\n");
|
||||||
|
fprintf(fp, "Copyright (C) 2000-2006 John F. Reiser\n");
|
||||||
|
fprintf(fp, "Copyright (C) 2002-2006 Jens Medoch\n");
|
||||||
|
#if defined(WITH_ZLIB)
|
||||||
|
fprintf(fp, "Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler\n");
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_LZMA)
|
||||||
|
fprintf(fp, "Copyright (C) 1999-2006 Igor Pavlov\n");
|
||||||
|
#endif
|
||||||
|
fprintf(fp, "UPX comes with ABSOLUTELY NO WARRANTY; for details type `%s -L'.\n", progname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+771
-179
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2005 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -29,108 +29,359 @@
|
|||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
|
|
||||||
class LinkerLabel
|
static unsigned hex(unsigned char c)
|
||||||
{
|
|
||||||
enum { LINKER_MAX_LABEL_LEN = 32 };
|
|
||||||
char label[LINKER_MAX_LABEL_LEN + 1];
|
|
||||||
|
|
||||||
public:
|
|
||||||
unsigned set(const char *l)
|
|
||||||
{
|
|
||||||
strncpy(label, l, sizeof(label));
|
|
||||||
return strlen(label) + 1;
|
|
||||||
}
|
|
||||||
operator const char *() const { return label; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct Linker::section
|
|
||||||
{
|
|
||||||
int istart;
|
|
||||||
int ostart;
|
|
||||||
int len;
|
|
||||||
LinkerLabel name;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Linker::jump
|
|
||||||
{
|
|
||||||
int pos;
|
|
||||||
int len;
|
|
||||||
int toffs;
|
|
||||||
LinkerLabel tsect;
|
|
||||||
};
|
|
||||||
|
|
||||||
Linker::Linker(const void *pdata, int plen, int pinfo)
|
|
||||||
{
|
|
||||||
iloader = new char[(ilen = plen) + 8192];
|
|
||||||
memcpy(iloader,pdata,plen);
|
|
||||||
oloader = new char[plen];
|
|
||||||
olen = 0;
|
|
||||||
align_hack = 0;
|
|
||||||
align_offset = 0;
|
|
||||||
info = pinfo;
|
|
||||||
njumps = nsections = frozen = 0;
|
|
||||||
jumps = new jump[200];
|
|
||||||
#define NSECTIONS 550
|
|
||||||
sections = new section[NSECTIONS];
|
|
||||||
|
|
||||||
char *p = iloader + info;
|
|
||||||
while (get32(p) != (unsigned)(-1))
|
|
||||||
{
|
|
||||||
if (get32(p))
|
|
||||||
{
|
|
||||||
p += sections[nsections].name.set(p);
|
|
||||||
sections[nsections].istart = get32(p);
|
|
||||||
sections[nsections++].ostart = -1;
|
|
||||||
p += 4;
|
|
||||||
assert(nsections < NSECTIONS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int l;
|
|
||||||
for (l = get32(p+4) - 1; iloader[l] == 0; l--)
|
|
||||||
;
|
|
||||||
|
|
||||||
jumps[njumps].pos = l+1;
|
|
||||||
jumps[njumps].len = get32(p+4)-jumps[njumps].pos;
|
|
||||||
p += 8 + jumps[njumps].tsect.set(p + 8);
|
|
||||||
jumps[njumps++].toffs = get32(p);
|
|
||||||
p += 4;
|
|
||||||
assert(njumps < 200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int ic;
|
|
||||||
for (ic = 0; ic < nsections - 1; ic++)
|
|
||||||
sections[ic].len = sections[ic+1].istart - sections[ic].istart;
|
|
||||||
sections[ic].len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Linker::~Linker()
|
|
||||||
{
|
|
||||||
delete [] iloader;
|
|
||||||
delete [] oloader;
|
|
||||||
delete [] jumps;
|
|
||||||
delete [] sections;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Linker::setLoaderAlignOffset(int offset)
|
|
||||||
{
|
|
||||||
align_offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hex(char c)
|
|
||||||
{
|
{
|
||||||
return (c & 0xf) + (c > '9' ? 9 : 0);
|
return (c & 0xf) + (c > '9' ? 9 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Linker::addSection(const char *psect)
|
static bool update_capacity(unsigned size, unsigned *capacity)
|
||||||
{
|
{
|
||||||
if (psect[0] == 0)
|
if (size < *capacity)
|
||||||
return olen;
|
return false;
|
||||||
char *begin = strdup(psect);
|
if (*capacity == 0)
|
||||||
|
*capacity = 16;
|
||||||
|
while (size >= *capacity)
|
||||||
|
*capacity *= 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// Section
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
ElfLinker::Section::Section(const char *n, const void *i, unsigned s, unsigned a) :
|
||||||
|
name(NULL), output(NULL), size(s), offset(0), p2align(a), next(NULL)
|
||||||
|
{
|
||||||
|
name = strdup(n);
|
||||||
|
assert(name != NULL);
|
||||||
|
input = malloc(s + 1);
|
||||||
|
assert(input != NULL);
|
||||||
|
memcpy(input, i, s);
|
||||||
|
((char *)input)[s] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Section::~Section()
|
||||||
|
{
|
||||||
|
free(name);
|
||||||
|
free(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// Symbol
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
ElfLinker::Symbol::Symbol(const char *n, Section *s, unsigned o) :
|
||||||
|
name(NULL), section(s), offset(o)
|
||||||
|
{
|
||||||
|
name = strdup(n);
|
||||||
|
assert(name != NULL);
|
||||||
|
assert(section != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Symbol::~Symbol()
|
||||||
|
{
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// Relocation
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
ElfLinker::Relocation::Relocation(const Section *s, unsigned o, const char *t,
|
||||||
|
const Symbol *v, unsigned a) :
|
||||||
|
section(s), offset(o), type(t), value(v), add(a)
|
||||||
|
{
|
||||||
|
assert(section != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// ElfLinker
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
ElfLinker::ElfLinker() :
|
||||||
|
bele(&N_BELE_RTP::le_policy),
|
||||||
|
input(NULL), output(NULL), head(NULL), tail(NULL),
|
||||||
|
sections(NULL), symbols(NULL), relocations(NULL),
|
||||||
|
nsections(0), nsections_capacity(0),
|
||||||
|
nsymbols(0), nsymbols_capacity(0),
|
||||||
|
nrelocations(0), nrelocations_capacity(0),
|
||||||
|
reloc_done(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::~ElfLinker()
|
||||||
|
{
|
||||||
|
delete [] input;
|
||||||
|
delete [] output;
|
||||||
|
|
||||||
|
unsigned ic;
|
||||||
|
for (ic = 0; ic < nsections; ic++)
|
||||||
|
delete sections[ic];
|
||||||
|
free(sections);
|
||||||
|
for (ic = 0; ic < nsymbols; ic++)
|
||||||
|
delete symbols[ic];
|
||||||
|
free(symbols);
|
||||||
|
for (ic = 0; ic < nrelocations; ic++)
|
||||||
|
delete relocations[ic];
|
||||||
|
free(relocations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::init(const void *pdata_v, int plen)
|
||||||
|
{
|
||||||
|
const upx_byte *pdata = (const upx_byte *) pdata_v;
|
||||||
|
if (plen >= 16 && memcmp(pdata, "UPX#", 4) == 0)
|
||||||
|
{
|
||||||
|
// decompress pre-compressed stub-loader
|
||||||
|
int method;
|
||||||
|
unsigned u_len, c_len;
|
||||||
|
if (pdata[4])
|
||||||
|
{
|
||||||
|
method = pdata[4];
|
||||||
|
u_len = get_le16(pdata + 5);
|
||||||
|
c_len = get_le16(pdata + 7);
|
||||||
|
pdata += 9;
|
||||||
|
assert(9 + c_len == (unsigned) plen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
method = pdata[5];
|
||||||
|
u_len = get_le32(pdata + 6);
|
||||||
|
c_len = get_le32(pdata + 10);
|
||||||
|
pdata += 14;
|
||||||
|
assert(14 + c_len == (unsigned) plen);
|
||||||
|
}
|
||||||
|
assert((unsigned) plen < u_len);
|
||||||
|
inputlen = u_len;
|
||||||
|
input = new upx_byte[inputlen + 1];
|
||||||
|
unsigned new_len = u_len;
|
||||||
|
int r = upx_decompress(pdata, c_len, input, &new_len, method, NULL);
|
||||||
|
if (r != 0 || new_len != u_len)
|
||||||
|
throwBadLoader();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inputlen = plen;
|
||||||
|
input = new upx_byte[inputlen + 1];
|
||||||
|
memcpy(input, pdata, inputlen);
|
||||||
|
}
|
||||||
|
input[inputlen] = 0; // NUL terminate
|
||||||
|
|
||||||
|
output = new upx_byte[inputlen];
|
||||||
|
outputlen = 0;
|
||||||
|
|
||||||
|
int pos = find(input, inputlen, "Sections:", 9);
|
||||||
|
assert(pos != -1);
|
||||||
|
char *psections = (char *) input + pos;
|
||||||
|
|
||||||
|
char *psymbols = strstr(psections, "SYMBOL TABLE:");
|
||||||
|
assert(psymbols != NULL);
|
||||||
|
|
||||||
|
char *prelocs = strstr(psymbols, "RELOCATION RECORDS FOR");
|
||||||
|
assert(prelocs != NULL);
|
||||||
|
|
||||||
|
preprocessSections(psections, psymbols);
|
||||||
|
preprocessSymbols(psymbols, prelocs);
|
||||||
|
preprocessRelocations(prelocs, (char*) input + inputlen);
|
||||||
|
addLoader("*UND*");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::preprocessSections(char *start, const char *end)
|
||||||
|
{
|
||||||
|
nsections = 0;
|
||||||
|
while (start < end)
|
||||||
|
{
|
||||||
|
char name[1024];
|
||||||
|
unsigned offset, size, align;
|
||||||
|
|
||||||
|
char *nextl = strchr(start, '\n');
|
||||||
|
assert(nextl != NULL);
|
||||||
|
|
||||||
|
if (sscanf(start, "%*d %1023s %x %*d %*d %x 2**%d",
|
||||||
|
name, &size, &offset, &align) == 4)
|
||||||
|
{
|
||||||
|
char *n = strstr(start, name);
|
||||||
|
n[strlen(name)] = 0;
|
||||||
|
addSection(n, input + offset, size, align);
|
||||||
|
|
||||||
|
//printf("section %s preprocessed\n", n);
|
||||||
|
}
|
||||||
|
start = nextl + 1;
|
||||||
|
}
|
||||||
|
addSection("*ABS*", NULL, 0, 0);
|
||||||
|
addSection("*UND*", NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::preprocessSymbols(char *start, const char *end)
|
||||||
|
{
|
||||||
|
nsymbols = 0;
|
||||||
|
while (start < end)
|
||||||
|
{
|
||||||
|
char section[1024];
|
||||||
|
char symbol[1024];
|
||||||
|
unsigned value, offset;
|
||||||
|
|
||||||
|
char *nextl = strchr(start, '\n');
|
||||||
|
assert(nextl != NULL);
|
||||||
|
|
||||||
|
if (sscanf(start, "%x g *ABS* %x %1023s",
|
||||||
|
&value, &offset, symbol) == 3)
|
||||||
|
{
|
||||||
|
char *s = strstr(start, symbol);
|
||||||
|
s[strlen(symbol)] = 0;
|
||||||
|
addSymbol(s, "*ABS*", value);
|
||||||
|
assert(offset == 0);
|
||||||
|
}
|
||||||
|
else if (sscanf(start, "%x%*8c %1023s %*x %1023s",
|
||||||
|
&offset, section, symbol) == 3)
|
||||||
|
{
|
||||||
|
char *s = strstr(start, symbol);
|
||||||
|
s[strlen(symbol)] = 0;
|
||||||
|
if (strcmp(section, "*UND*") == 0)
|
||||||
|
offset = 0xdeaddead;
|
||||||
|
assert(strcmp(section, "*ABS*") != 0);
|
||||||
|
addSymbol(s, section, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
start = nextl + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::preprocessRelocations(char *start, const char *end)
|
||||||
|
{
|
||||||
|
char sect[1024];
|
||||||
|
Section *section = NULL;
|
||||||
|
|
||||||
|
nrelocations = 0;
|
||||||
|
while (start < end)
|
||||||
|
{
|
||||||
|
if (sscanf(start, "RELOCATION RECORDS FOR [%[^]]", sect) == 1)
|
||||||
|
section = findSection(sect);
|
||||||
|
|
||||||
|
unsigned offset;
|
||||||
|
char type[100];
|
||||||
|
char symbol[1024];
|
||||||
|
|
||||||
|
char *nextl = strchr(start, '\n');
|
||||||
|
assert(nextl != NULL);
|
||||||
|
|
||||||
|
if (sscanf(start, "%x %99s %1023s",
|
||||||
|
&offset, type, symbol) == 3)
|
||||||
|
{
|
||||||
|
char *t = strstr(start, type);
|
||||||
|
t[strlen(type)] = 0;
|
||||||
|
|
||||||
|
unsigned add = 0;
|
||||||
|
if (char *p = strstr(symbol, "+0x"))
|
||||||
|
{
|
||||||
|
*p = 0; // terminate the symbol name
|
||||||
|
p += 3;
|
||||||
|
|
||||||
|
if (strlen(p) == 16) {
|
||||||
|
// skip 8 leading chars if sign of char 9 matches
|
||||||
|
if (memcmp(p, "000000000", 9))
|
||||||
|
p += 8;
|
||||||
|
else if (memcmp(p, "fffffffff", 9))
|
||||||
|
p += 8;
|
||||||
|
}
|
||||||
|
assert(strlen(p) == 8);
|
||||||
|
char *endptr = NULL;
|
||||||
|
unsigned long ul = strtoul(p, &endptr, 16);
|
||||||
|
add = (unsigned) ul;
|
||||||
|
assert(add == ul);
|
||||||
|
assert(endptr && *endptr == '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
addRelocation(section->name, offset, t, symbol, add);
|
||||||
|
//printf("relocation %s %s %x %d preprocessed\n", section->name, symbol, offset, add);
|
||||||
|
}
|
||||||
|
|
||||||
|
start = nextl + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Section *ElfLinker::findSection(const char *name, bool fatal) const
|
||||||
|
{
|
||||||
|
for (unsigned ic = 0; ic < nsections; ic++)
|
||||||
|
if (strcmp(sections[ic]->name, name) == 0)
|
||||||
|
return sections[ic];
|
||||||
|
if (fatal)
|
||||||
|
{
|
||||||
|
printf("unknown section %s\n", name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Symbol *ElfLinker::findSymbol(const char *name, bool fatal) const
|
||||||
|
{
|
||||||
|
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||||
|
if (strcmp(symbols[ic]->name, name) == 0)
|
||||||
|
return symbols[ic];
|
||||||
|
if (fatal)
|
||||||
|
{
|
||||||
|
printf("unknown symbol %s\n", name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata, int slen, unsigned p2align)
|
||||||
|
{
|
||||||
|
//printf("addSection: %s len=%d align=%d\n", sname, slen, p2align);
|
||||||
|
if (update_capacity(nsections, &nsections_capacity))
|
||||||
|
sections = static_cast<Section **>(realloc(sections, nsections_capacity * sizeof(Section *)));
|
||||||
|
assert(sections);
|
||||||
|
assert(sname); assert(sname[0]); assert(sname[strlen(sname)-1] != ':');
|
||||||
|
assert(findSection(sname, false) == NULL);
|
||||||
|
Section *sec = new Section(sname, sdata, slen, p2align);
|
||||||
|
sections[nsections++] = sec;
|
||||||
|
return sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section,
|
||||||
|
unsigned offset)
|
||||||
|
{
|
||||||
|
//printf("addSymbol: %s %s 0x%x\n", name, section, offset);
|
||||||
|
if (update_capacity(nsymbols, &nsymbols_capacity))
|
||||||
|
symbols = static_cast<Symbol **>(realloc(symbols, nsymbols_capacity * sizeof(Symbol *)));
|
||||||
|
assert(symbols != NULL);
|
||||||
|
assert(name); assert(name[0]); assert(name[strlen(name)-1] != ':');
|
||||||
|
assert(findSymbol(name, false) == NULL);
|
||||||
|
Symbol *sym = new Symbol(name, findSection(section), offset);
|
||||||
|
symbols[nsymbols++] = sym;
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned off,
|
||||||
|
const char *type, const char *symbol,
|
||||||
|
unsigned add)
|
||||||
|
{
|
||||||
|
if (update_capacity(nrelocations, &nrelocations_capacity))
|
||||||
|
relocations = static_cast<Relocation **>(realloc(relocations, (nrelocations_capacity) * sizeof(Relocation *)));
|
||||||
|
assert(relocations != NULL);
|
||||||
|
Relocation *rel = new Relocation(findSection(section), off,
|
||||||
|
type, findSymbol(symbol), add);
|
||||||
|
relocations[nrelocations++] = rel;
|
||||||
|
return rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::setLoaderAlignOffset(int phase)
|
||||||
|
{
|
||||||
|
//assert(phase & 0);
|
||||||
|
printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ElfLinker::addLoader(const char *sname)
|
||||||
|
{
|
||||||
|
assert(sname != NULL);
|
||||||
|
if (!sname[0])
|
||||||
|
return outputlen;
|
||||||
|
|
||||||
|
char *begin = strdup(sname);
|
||||||
char *end = begin + strlen(begin);
|
char *end = begin + strlen(begin);
|
||||||
for (char *sect = begin; sect < end; )
|
for (char *sect = begin; sect < end; )
|
||||||
{
|
{
|
||||||
@@ -141,102 +392,443 @@ int Linker::addSection(const char *psect)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*sect == '+') // alignment
|
if (sect[0] == '+') // alignment
|
||||||
{
|
{
|
||||||
if (sect[1] == '0')
|
assert(tail);
|
||||||
align_hack = olen + align_offset;
|
unsigned l = (hex(sect[2]) - tail->offset - tail->size) % hex(sect[1]);
|
||||||
|
if (l)
|
||||||
|
{
|
||||||
|
if (sect[3] == 'D')
|
||||||
|
alignData(l);
|
||||||
else
|
else
|
||||||
{
|
alignCode(l);
|
||||||
unsigned j = hex(sect[1]);
|
tail->size += l;
|
||||||
j = (hex(sect[2]) - ((olen + align_offset) - align_hack) ) % j;
|
|
||||||
memset(oloader+olen, (sect[3] == 'C' ? 0x90 : 0), j);
|
|
||||||
olen += j;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int ic;
|
Section *section = findSection(sect);
|
||||||
for (ic = 0; ic < nsections; ic++)
|
if (section->p2align) {
|
||||||
if (strcmp(sect, sections[ic].name) == 0)
|
assert(tail);
|
||||||
{
|
assert(tail != section);
|
||||||
memcpy(oloader+olen,iloader+sections[ic].istart,sections[ic].len);
|
unsigned const v = ~0u << section->p2align;
|
||||||
sections[ic].ostart = olen;
|
if (unsigned const l = ~v & -(tail->offset + tail->size)) {
|
||||||
olen += sections[ic].len;
|
alignCode(l);
|
||||||
break;
|
tail->size += l;
|
||||||
}
|
}
|
||||||
if (ic == nsections)
|
}
|
||||||
printf("%s", sect);
|
memcpy(output + outputlen, section->input, section->size);
|
||||||
assert(ic != nsections);
|
section->output = output + outputlen;
|
||||||
|
//printf("section added: 0x%04x %3d %s\n", outputlen, section->size, section->name);
|
||||||
|
outputlen += section->size;
|
||||||
|
|
||||||
|
if (head)
|
||||||
|
{
|
||||||
|
tail->next = section;
|
||||||
|
section->offset = tail->offset + tail->size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
head = section;
|
||||||
|
tail = section;
|
||||||
}
|
}
|
||||||
sect += strlen(sect) + 1;
|
sect += strlen(sect) + 1;
|
||||||
}
|
}
|
||||||
free(begin);
|
free(begin);
|
||||||
return olen;
|
return outputlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ElfLinker::getSection(const char *sname, int *slen) const
|
||||||
void Linker::addSection(const char *sname, const void *sdata, unsigned len)
|
|
||||||
{
|
|
||||||
// add a new section - can be used for adding stuff like ident or header
|
|
||||||
sections[nsections].name.set(sname);
|
|
||||||
sections[nsections].istart = ilen;
|
|
||||||
sections[nsections].len = len;
|
|
||||||
sections[nsections++].ostart = olen;
|
|
||||||
assert(nsections < NSECTIONS);
|
|
||||||
memcpy(iloader+ilen,sdata,len);
|
|
||||||
ilen += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char *Linker::getLoader(int *llen)
|
|
||||||
{
|
|
||||||
if (!frozen)
|
|
||||||
{
|
|
||||||
int ic,jc,kc;
|
|
||||||
for (ic = 0; ic < njumps; ic++)
|
|
||||||
{
|
|
||||||
for (jc = 0; jc < nsections-1; jc++)
|
|
||||||
if (jumps[ic].pos >= sections[jc].istart
|
|
||||||
&& jumps[ic].pos < sections[jc+1].istart)
|
|
||||||
break;
|
|
||||||
assert(jc!=nsections-1);
|
|
||||||
if (sections[jc].ostart < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (kc = 0; kc < nsections-1; kc++)
|
|
||||||
if (strcmp(jumps[ic].tsect,sections[kc].name) == 0)
|
|
||||||
break;
|
|
||||||
assert(kc!=nsections-1);
|
|
||||||
|
|
||||||
int offs = sections[kc].ostart+jumps[ic].toffs -
|
|
||||||
(jumps[ic].pos+jumps[ic].len -
|
|
||||||
sections[jc].istart+sections[jc].ostart);
|
|
||||||
|
|
||||||
if (jumps[ic].len == 1)
|
|
||||||
assert(-128 <= offs && offs <= 127);
|
|
||||||
|
|
||||||
set32(&offs,offs);
|
|
||||||
memcpy(oloader+sections[jc].ostart+jumps[ic].pos-sections[jc].istart,&offs,jumps[ic].len);
|
|
||||||
}
|
|
||||||
frozen=1;
|
|
||||||
}
|
|
||||||
if (llen) *llen = olen;
|
|
||||||
return oloader;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Linker::getSection(const char *name, int *slen) const
|
|
||||||
{
|
|
||||||
if (!frozen)
|
|
||||||
return -1;
|
|
||||||
for (int ic = 0; ic < nsections; ic++)
|
|
||||||
if (strcmp(name, sections[ic].name) == 0)
|
|
||||||
{
|
{
|
||||||
|
const Section *section = findSection(sname);
|
||||||
if (slen)
|
if (slen)
|
||||||
*slen = sections[ic].len;
|
*slen = section->size;
|
||||||
return sections[ic].ostart;
|
return section->output - output;
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
|
int ElfLinker::getSectionSize(const char *sname) const
|
||||||
|
{
|
||||||
|
const Section *section = findSection(sname);
|
||||||
|
return section->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
upx_byte *ElfLinker::getLoader(int *llen) const
|
||||||
|
{
|
||||||
|
if (llen)
|
||||||
|
*llen = outputlen;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::relocate()
|
||||||
|
{
|
||||||
|
assert(!reloc_done);
|
||||||
|
reloc_done = true;
|
||||||
|
for (unsigned ic = 0; ic < nrelocations; ic++)
|
||||||
|
{
|
||||||
|
const Relocation *rel = relocations[ic];
|
||||||
|
unsigned value;
|
||||||
|
|
||||||
|
if (rel->section->output == NULL)
|
||||||
|
continue;
|
||||||
|
if (strcmp(rel->value->section->name, "*ABS*") == 0)
|
||||||
|
{
|
||||||
|
value = rel->value->offset;
|
||||||
|
}
|
||||||
|
else if (strcmp(rel->value->section->name, "*UND*") == 0 &&
|
||||||
|
rel->value->offset == 0xdeaddead)
|
||||||
|
{
|
||||||
|
printf("undefined symbol '%s' referenced\n", rel->value->name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
else if (rel->value->section->output == NULL)
|
||||||
|
{
|
||||||
|
printf("can not apply reloc '%s:%x' without section '%s'\n",
|
||||||
|
rel->section->name, rel->offset,
|
||||||
|
rel->value->section->name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = rel->value->section->offset +
|
||||||
|
rel->value->offset + rel->add;
|
||||||
|
}
|
||||||
|
upx_byte *location = rel->section->output + rel->offset;
|
||||||
|
//printf("%-28s %-28s %-10s 0x%08x 0x%08x\n", rel->section->name, rel->value->name, rel->type, value, value - rel->section->offset - rel->offset);
|
||||||
|
//printf(" %d %d %d %d %d : %d\n", value, rel->value->section->offset, rel->value->offset, rel->offset, rel->add, *location);
|
||||||
|
relocate1(rel, location, value, rel->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::defineSymbol(const char *name, unsigned value)
|
||||||
|
{
|
||||||
|
Symbol *symbol = findSymbol(name);
|
||||||
|
if (strcmp(symbol->section->name, "*ABS*") == 0)
|
||||||
|
{
|
||||||
|
printf("defineSymbol: symbol '%s' is *ABS*\n", name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
else if (strcmp(symbol->section->name, "*UND*") == 0) // for undefined symbols
|
||||||
|
symbol->offset = value;
|
||||||
|
else if (strcmp(symbol->section->name, name) == 0) // for sections
|
||||||
|
{
|
||||||
|
for (Section *section = symbol->section; section; section = section->next)
|
||||||
|
{
|
||||||
|
assert(section->offset < value);
|
||||||
|
section->offset = value;
|
||||||
|
value += section->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("defineSymbol: symbol '%s' already defined\n", name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// debugging support
|
||||||
|
void ElfLinker::dumpSymbol(const Symbol *symbol, unsigned flags, FILE *fp) const
|
||||||
|
{
|
||||||
|
if ((flags & 1) && symbol->section->output == NULL)
|
||||||
|
return;
|
||||||
|
fprintf(fp, "%-28s 0x%08x | %-28s 0x%08x\n",
|
||||||
|
symbol->name, symbol->offset, symbol->section->name, symbol->section->offset);
|
||||||
|
}
|
||||||
|
void ElfLinker::dumpSymbols(unsigned flags, FILE *fp) const
|
||||||
|
{
|
||||||
|
if (fp == NULL)
|
||||||
|
fp = stdout;
|
||||||
|
if ((flags & 2) == 0)
|
||||||
|
{
|
||||||
|
// default: dump symbols in used section order
|
||||||
|
for (const Section *section = head; section; section = section->next)
|
||||||
|
{
|
||||||
|
fprintf(fp, "%-42s%-28s 0x%08x\n", "", section->name, section->offset);
|
||||||
|
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||||
|
{
|
||||||
|
const Symbol *symbol = symbols[ic];
|
||||||
|
if (symbol->section == section && strcmp(symbol->name, section->name) != 0)
|
||||||
|
dumpSymbol(symbol, flags, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// dump all symbols
|
||||||
|
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||||
|
dumpSymbol(symbols[ic], flags, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned ElfLinker::getSymbolOffset(const char *name) const
|
||||||
|
{
|
||||||
|
const Symbol *symbol = findSymbol(name);
|
||||||
|
if (symbol->section->output == NULL)
|
||||||
|
return 0xdeaddead;
|
||||||
|
return symbol->section->offset + symbol->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::alignWithByte(unsigned len, unsigned char b)
|
||||||
|
{
|
||||||
|
memset(output + outputlen, b, len);
|
||||||
|
outputlen += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::relocate1(const Relocation *rel, upx_byte *,
|
||||||
|
unsigned, const char *)
|
||||||
|
{
|
||||||
|
printf("unknown relocation type '%s\n", rel->type);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// ElfLinker arch subclasses
|
||||||
|
// FIXME: add more displacment overflow checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if 0 // FIXME
|
||||||
|
static void check8(const Relocation *rel, const upx_byte *location, int v, int d)
|
||||||
|
{
|
||||||
|
if (v < -128 || v > 127) {
|
||||||
|
printf("value out of range (%d) in reloc %s:%x\n",
|
||||||
|
v, rel->section->name, rel->offset);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (d < -128 || d > 127) {
|
||||||
|
printf("displacement target out of range (%d) in reloc %s:%x\n",
|
||||||
|
v, rel->section->name, rel->offset);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strncmp(type, "R_X86_64_", 9))
|
||||||
|
return super::relocate1(rel, location, value, type);
|
||||||
|
type += 9;
|
||||||
|
|
||||||
|
if (strncmp(type, "PC", 2) == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
type += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(type, "8") == 0)
|
||||||
|
{
|
||||||
|
int displ = (signed char) *location + (int) value;
|
||||||
|
if (displ < -128 || displ > 127)
|
||||||
|
{
|
||||||
|
printf("target out of range (%d) in reloc %s:%x\n",
|
||||||
|
displ, rel->section->name, rel->offset);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
*location += value;
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "16") == 0)
|
||||||
|
set_le16(location, get_le16(location) + value);
|
||||||
|
else if (strcmp(type, "32") == 0)
|
||||||
|
set_le32(location, get_le32(location) + value);
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strcmp(type, "R_ARM_PC24") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
set_be24(1+ location, get_be24(1+ location) + value / 4);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_ABS32") == 0)
|
||||||
|
{
|
||||||
|
set_be32(location, get_be32(location) + value);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_THM_CALL") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
value += ((get_be16(location) & 0x7ff) << 12);
|
||||||
|
value += (get_be16(location + 2) & 0x7ff) << 1;
|
||||||
|
|
||||||
|
set_be16(location, 0xf000 + ((value >> 12) & 0x7ff));
|
||||||
|
set_be16(location + 2, 0xf800 + ((value >> 1) & 0x7ff));
|
||||||
|
|
||||||
|
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
||||||
|
//set_be32(location, get_be32(location) + value / 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strcmp(type, "R_ARM_PC24") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
set_le24(location, get_le24(location) + value / 4);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_ABS32") == 0)
|
||||||
|
{
|
||||||
|
set_le32(location, get_le32(location) + value);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_THM_CALL") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
value += ((get_le16(location) & 0x7ff) << 12);
|
||||||
|
value += (get_le16(location + 2) & 0x7ff) << 1;
|
||||||
|
|
||||||
|
set_le16(location, 0xf000 + ((value >> 12) & 0x7ff));
|
||||||
|
set_le16(location + 2, 0xf800 + ((value >> 1) & 0x7ff));
|
||||||
|
|
||||||
|
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
||||||
|
//set_le32(location, get_le32(location) + value / 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerM68k::alignCode(unsigned len)
|
||||||
|
{
|
||||||
|
assert((len & 1) == 0);
|
||||||
|
assert((outputlen & 1) == 0);
|
||||||
|
for (unsigned i = 0; i < len; i += 2)
|
||||||
|
set_be16(output + outputlen + i, 0x4e71); // "nop"
|
||||||
|
outputlen += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strncmp(type, "R_68K_", 6))
|
||||||
|
return super::relocate1(rel, location, value, type);
|
||||||
|
type += 6;
|
||||||
|
|
||||||
|
if (strncmp(type, "PC", 2) == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
type += 2;
|
||||||
|
}
|
||||||
|
if (strcmp(type, "8") == 0) {
|
||||||
|
*location += value;
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "16") == 0) {
|
||||||
|
set_be16(location, get_be16(location) + value);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "32") == 0) {
|
||||||
|
set_be32(location, get_be32(location) + value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerMipsLE::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
|
||||||
|
#define MIPS_LO(a) ((a) & 0xffff)
|
||||||
|
#define MIPS_PC16(a) ((a) >> 2)
|
||||||
|
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
|
||||||
|
|
||||||
|
if (strcmp(type, "R_MIPS_HI16") == 0)
|
||||||
|
set_le16(location, get_le16(location) + MIPS_HI(value));
|
||||||
|
else if (strcmp(type, "R_MIPS_LO16") == 0)
|
||||||
|
set_le16(location, get_le16(location) + MIPS_LO(value));
|
||||||
|
else if (strcmp(type, "R_MIPS_PC16") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
set_le16(location, get_le16(location) + MIPS_PC16(value));
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_MIPS_26") == 0)
|
||||||
|
set_le32(location, get_le32(location) + MIPS_PC26(value));
|
||||||
|
else if (strcmp(type, "R_MIPS_32") == 0)
|
||||||
|
set_le32(location, get_le32(location) + value);
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
|
||||||
|
#undef MIPS_HI
|
||||||
|
#undef MIPS_LO
|
||||||
|
#undef MIPS_PC16
|
||||||
|
#undef MIPS_PC26
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strncmp(type, "R_PPC_", 6))
|
||||||
|
return super::relocate1(rel, location, value, type);
|
||||||
|
type += 6;
|
||||||
|
|
||||||
|
if (strncmp(type, "REL", 3) == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
type += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: more relocs
|
||||||
|
|
||||||
|
// Note that original (*location).displ is ignored.
|
||||||
|
if (strcmp(type, "24") == 0) {
|
||||||
|
if (3& value) {
|
||||||
|
printf("unaligned word diplacement");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
// FIXME: displacment overflow?
|
||||||
|
set_be32(location, (0xfc000003 & get_be32(location)) +
|
||||||
|
(0x03fffffc & value));
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "14") == 0) {
|
||||||
|
if (3& value) {
|
||||||
|
printf("unaligned word diplacement");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
// FIXME: displacment overflow?
|
||||||
|
set_be32(location, (0xffff0003 & get_be32(location)) +
|
||||||
|
(0x0000fffc & value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerX86::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strncmp(type, "R_386_", 6))
|
||||||
|
return super::relocate1(rel, location, value, type);
|
||||||
|
type += 6;
|
||||||
|
|
||||||
|
bool range_check = false;
|
||||||
|
if (strncmp(type, "PC", 2) == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
type += 2;
|
||||||
|
range_check = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(type, "8") == 0)
|
||||||
|
{
|
||||||
|
int displ = (signed char) *location + (int) value;
|
||||||
|
if (range_check && (displ < -128 || displ > 127)) {
|
||||||
|
printf("target out of range (%d) in reloc %s:%x\n",
|
||||||
|
displ, rel->section->name, rel->offset);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
*location += value;
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "16") == 0)
|
||||||
|
set_le16(location, get_le16(location) + value);
|
||||||
|
else if (strcmp(type, "32") == 0)
|
||||||
|
set_le32(location, get_le32(location) + value);
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+178
-46
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -30,64 +30,196 @@
|
|||||||
#define __UPX_LINKER_H
|
#define __UPX_LINKER_H
|
||||||
|
|
||||||
|
|
||||||
class Linker
|
/*************************************************************************
|
||||||
|
// ElfLinker
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
class ElfLinker : private nocopy
|
||||||
{
|
{
|
||||||
|
friend class Packer;
|
||||||
public:
|
public:
|
||||||
Linker(const void *pdata, int plen, int pinfo);
|
const N_BELE_RTP::AbstractPolicy *bele;
|
||||||
virtual ~Linker();
|
protected:
|
||||||
int addSection(const char *sect);
|
struct Section;
|
||||||
void addSection(const char *sname, const void *sdata, unsigned len);
|
struct Symbol;
|
||||||
const char *getLoader(int *llen);
|
struct Relocation;
|
||||||
int getSection(const char *name, int *slen) const;
|
|
||||||
int getLoaderSize() const { return olen; }
|
upx_byte *input;
|
||||||
void setLoaderAlignOffset(int phase);
|
int inputlen;
|
||||||
|
upx_byte *output;
|
||||||
|
int outputlen;
|
||||||
|
|
||||||
|
Section *head;
|
||||||
|
Section *tail;
|
||||||
|
|
||||||
|
Section **sections;
|
||||||
|
Symbol **symbols;
|
||||||
|
Relocation **relocations;
|
||||||
|
|
||||||
|
unsigned nsections;
|
||||||
|
unsigned nsections_capacity;
|
||||||
|
unsigned nsymbols;
|
||||||
|
unsigned nsymbols_capacity;
|
||||||
|
unsigned nrelocations;
|
||||||
|
unsigned nrelocations_capacity;
|
||||||
|
|
||||||
|
bool reloc_done;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// little endian
|
void preprocessSections(char *start, const char *end);
|
||||||
virtual unsigned get32(const void *b) const { return get_le32(b); }
|
void preprocessSymbols(char *start, const char *end);
|
||||||
virtual void set32(void *b, unsigned v) const { set_le32(b, v); }
|
void preprocessRelocations(char *start, const char *end);
|
||||||
|
Section *findSection(const char *name, bool fatal=true) const;
|
||||||
|
Symbol *findSymbol(const char *name, bool fatal=true) const;
|
||||||
|
|
||||||
private:
|
Symbol *addSymbol(const char *name, const char *section, unsigned offset);
|
||||||
struct section;
|
Relocation *addRelocation(const char *section, unsigned off, const char *type,
|
||||||
struct jump;
|
const char *symbol, unsigned add);
|
||||||
|
|
||||||
char *iloader, *oloader;
|
public:
|
||||||
int ilen, olen;
|
ElfLinker();
|
||||||
int info;
|
virtual ~ElfLinker();
|
||||||
jump *jumps;
|
|
||||||
int njumps;
|
|
||||||
section *sections;
|
|
||||||
int nsections;
|
|
||||||
int frozen;
|
|
||||||
int align_hack;
|
|
||||||
int align_offset;
|
|
||||||
|
|
||||||
private:
|
virtual void init(const void *pdata, int plen);
|
||||||
// disable copy and assignment
|
virtual void setLoaderAlignOffset(int phase);
|
||||||
Linker(const Linker &); // {}
|
virtual int addLoader(const char *sname);
|
||||||
Linker& operator= (const Linker &); // { return *this; }
|
virtual Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align);
|
||||||
|
virtual int getSection(const char *sname, int *slen=NULL) const;
|
||||||
|
virtual int getSectionSize(const char *sname) const;
|
||||||
|
virtual upx_byte *getLoader(int *llen=NULL) const;
|
||||||
|
virtual void defineSymbol(const char *name, unsigned value);
|
||||||
|
virtual unsigned getSymbolOffset(const char *) const;
|
||||||
|
|
||||||
|
virtual void dumpSymbol(const Symbol *, unsigned flags, FILE *fp) const;
|
||||||
|
virtual void dumpSymbols(unsigned flags=0, FILE *fp=NULL) const;
|
||||||
|
|
||||||
|
void alignWithByte(unsigned len, unsigned char b);
|
||||||
|
virtual void alignCode(unsigned len) { alignWithByte(len, 0); }
|
||||||
|
virtual void alignData(unsigned len) { alignWithByte(len, 0); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void relocate();
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BeLinker : public Linker
|
struct ElfLinker::Section : private nocopy
|
||||||
{
|
{
|
||||||
typedef Linker super;
|
char *name;
|
||||||
public:
|
void *input;
|
||||||
BeLinker(const void *pdata, int plen, int pinfo) :
|
upx_byte *output;
|
||||||
super(pdata, plen, pinfo) { }
|
unsigned size;
|
||||||
|
unsigned offset;
|
||||||
|
unsigned p2align; // log2
|
||||||
|
Section *next;
|
||||||
|
|
||||||
protected:
|
Section(const char *n, const void *i, unsigned s, unsigned a=0);
|
||||||
// big endian
|
~Section();
|
||||||
virtual unsigned get32(const void *b) const { return get_be32(b); }
|
|
||||||
virtual void set32(void *b, unsigned v) const { set_be32(b, v); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// disable copy and assignment
|
|
||||||
BeLinker(const BeLinker &); // {}
|
|
||||||
BeLinker& operator= (const BeLinker &); // { return *this; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ElfLinker::Symbol : private nocopy
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
Section *section;
|
||||||
|
unsigned offset;
|
||||||
|
|
||||||
|
Symbol(const char *n, Section *s, unsigned o);
|
||||||
|
~Symbol();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ElfLinker::Relocation : private nocopy
|
||||||
|
{
|
||||||
|
const Section *section;
|
||||||
|
unsigned offset;
|
||||||
|
const char *type;
|
||||||
|
const Symbol *value;
|
||||||
|
unsigned add; // used in .rela relocations
|
||||||
|
|
||||||
|
Relocation(const Section *s, unsigned o, const char *t,
|
||||||
|
const Symbol *v, unsigned a);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// ElfLinker arch subclasses
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
class ElfLinkerAMD64 : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void alignCode(unsigned len) { alignWithByte(len, 0x90); }
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerArmBE : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
public:
|
||||||
|
ElfLinkerArmBE() { bele = &N_BELE_RTP::be_policy; }
|
||||||
|
protected:
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerArmLE : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerM68k : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
public:
|
||||||
|
ElfLinkerM68k() { bele = &N_BELE_RTP::be_policy; }
|
||||||
|
protected:
|
||||||
|
virtual void alignCode(unsigned len);
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerMipsLE : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerPpc32 : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
public:
|
||||||
|
ElfLinkerPpc32() { bele = &N_BELE_RTP::be_policy; }
|
||||||
|
protected:
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerX86 : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void alignCode(unsigned len) { alignWithByte(len, 0x90); }
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+227
-86
@@ -30,6 +30,7 @@
|
|||||||
#include "mygetopt.h"
|
#include "mygetopt.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
|
#include "p_elf.h"
|
||||||
|
|
||||||
|
|
||||||
#if 1 && defined(__DJGPP__)
|
#if 1 && defined(__DJGPP__)
|
||||||
@@ -42,10 +43,11 @@ int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;
|
|||||||
// options
|
// options
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void init_options(struct options_t *o)
|
void options_t::reset()
|
||||||
{
|
{
|
||||||
|
options_t *o = this;
|
||||||
memset(o, 0, sizeof(*o));
|
memset(o, 0, sizeof(*o));
|
||||||
memset(&o->crp, 0xff, sizeof(o->crp));
|
o->crp.reset();
|
||||||
|
|
||||||
o->cmd = CMD_NONE;
|
o->cmd = CMD_NONE;
|
||||||
o->method = -1;
|
o->method = -1;
|
||||||
@@ -72,6 +74,7 @@ void init_options(struct options_t *o)
|
|||||||
o->win32_pe.compress_rt[i] = -1;
|
o->win32_pe.compress_rt[i] = -1;
|
||||||
o->win32_pe.compress_rt[24] = false; // 24 == RT_MANIFEST
|
o->win32_pe.compress_rt[24] = false; // 24 == RT_MANIFEST
|
||||||
o->win32_pe.strip_relocs = -1;
|
o->win32_pe.strip_relocs = -1;
|
||||||
|
o->win32_pe.keep_resource = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct options_t global_options;
|
static struct options_t global_options;
|
||||||
@@ -234,12 +237,24 @@ void check_options(int i, int argc)
|
|||||||
{
|
{
|
||||||
assert(i <= argc);
|
assert(i <= argc);
|
||||||
|
|
||||||
|
if (opt->cmd != CMD_COMPRESS)
|
||||||
|
{
|
||||||
|
// invalidate compression options
|
||||||
|
opt->method = 0;
|
||||||
|
opt->level = 0;
|
||||||
|
opt->exact = 0;
|
||||||
|
opt->small = 0;
|
||||||
|
opt->crp.reset();
|
||||||
|
}
|
||||||
|
|
||||||
// set default overlay action
|
// set default overlay action
|
||||||
if (!(opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS))
|
if (!(opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS))
|
||||||
opt->overlay = opt->COPY_OVERLAY;
|
opt->overlay = opt->COPY_OVERLAY;
|
||||||
else if (opt->overlay < 0)
|
else if (opt->overlay < 0)
|
||||||
opt->overlay = opt->COPY_OVERLAY;
|
opt->overlay = opt->COPY_OVERLAY;
|
||||||
|
|
||||||
|
check_not_both(opt->exact, opt->overlay == opt->STRIP_OVERLAY, "--exact", "--overlay=strip");
|
||||||
|
|
||||||
// set default backup option
|
// set default backup option
|
||||||
if (opt->backup < 0)
|
if (opt->backup < 0)
|
||||||
opt->backup = 0;
|
opt->backup = 0;
|
||||||
@@ -297,9 +312,15 @@ static bool set_method(int m, int l)
|
|||||||
{
|
{
|
||||||
if (!Packer::isValidCompressionMethod(m))
|
if (!Packer::isValidCompressionMethod(m))
|
||||||
return false;
|
return false;
|
||||||
|
#if 1
|
||||||
|
// something like "--brute --lzma" should not disable "--brute"
|
||||||
|
if (!opt->all_methods)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
opt->method = m;
|
opt->method = m;
|
||||||
opt->all_methods = false;
|
opt->all_methods = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (l > 0)
|
if (l > 0)
|
||||||
opt->level = l;
|
opt->level = l;
|
||||||
set_cmd(CMD_COMPRESS);
|
set_cmd(CMD_COMPRESS);
|
||||||
@@ -403,28 +424,58 @@ char* prepare_shortopts(char *buf, const char *n,
|
|||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
int getoptvar(T *var, const T minval, const T maxval)
|
int getoptvar(T *var, const T min_value, const T max_value, const char *arg_fatal)
|
||||||
{
|
{
|
||||||
const char *p = mfx_optarg;
|
const char *p = mfx_optarg;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
int r = 0;
|
||||||
|
long n;
|
||||||
|
T v;
|
||||||
|
|
||||||
if (!p || !p[0])
|
if (!p || !p[0])
|
||||||
return -1;
|
{ r = -1; goto error; }
|
||||||
// avoid interpretation as octal value
|
// avoid interpretation as octal value
|
||||||
while (p[0] == '0' && isdigit(p[1]))
|
while (p[0] == '0' && isdigit(p[1]))
|
||||||
p++;
|
p++;
|
||||||
long n = strtol(p, &endptr, 0);
|
n = strtol(p, &endptr, 0);
|
||||||
if (*endptr != '\0')
|
if (*endptr != '\0')
|
||||||
return -2;
|
{ r = -2; goto error; }
|
||||||
T v = (T) n;
|
v = (T) n;
|
||||||
if (v < minval)
|
if (v < min_value)
|
||||||
return -3;
|
{ r = -3; goto error; }
|
||||||
if (v > maxval)
|
if (v > max_value)
|
||||||
return -4;
|
{ r = -4; goto error; }
|
||||||
*var = v;
|
*var = v;
|
||||||
return 0;
|
goto done;
|
||||||
|
error:
|
||||||
|
if (arg_fatal != NULL)
|
||||||
|
e_optval(arg_fatal);
|
||||||
|
done:
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1 && (ACC_CC_GNUC >= 0x030300)
|
||||||
|
template <class T, T default_value, T min_value, T max_value>
|
||||||
|
int getoptvar(OptVar<T,default_value,min_value,max_value> *var, const char *arg_fatal)
|
||||||
|
{
|
||||||
|
T v = default_value;
|
||||||
|
int r = getoptvar(&v, min_value, max_value, arg_fatal);
|
||||||
|
if (r == 0)
|
||||||
|
*var = v;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <class T>
|
||||||
|
int getoptvar(T *var, const char *arg_fatal)
|
||||||
|
{
|
||||||
|
typename T::Type v = T::default_value_c;
|
||||||
|
int r = getoptvar(&v, T::min_value_c, T::max_value_c, arg_fatal);
|
||||||
|
if (r == 0)
|
||||||
|
*var = v;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int do_option(int optc, const char *arg)
|
static int do_option(int optc, const char *arg)
|
||||||
{
|
{
|
||||||
@@ -510,6 +561,16 @@ static int do_option(int optc, const char *arg)
|
|||||||
if (!set_method(M_NRV2E_LE32, -1))
|
if (!set_method(M_NRV2E_LE32, -1))
|
||||||
e_method(M_NRV2E_LE32, opt->level);
|
e_method(M_NRV2E_LE32, opt->level);
|
||||||
break;
|
break;
|
||||||
|
case 721:
|
||||||
|
opt->all_methods_use_lzma = true;
|
||||||
|
if (!set_method(M_LZMA, -1))
|
||||||
|
e_method(M_LZMA, opt->level);
|
||||||
|
break;
|
||||||
|
case 722:
|
||||||
|
opt->all_methods_use_lzma = false;
|
||||||
|
if (opt->method == M_LZMA)
|
||||||
|
opt->method = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
// compression level
|
// compression level
|
||||||
case '1':
|
case '1':
|
||||||
@@ -527,10 +588,11 @@ static int do_option(int optc, const char *arg)
|
|||||||
|
|
||||||
case 901: // --brute
|
case 901: // --brute
|
||||||
opt->all_methods = true;
|
opt->all_methods = true;
|
||||||
|
opt->all_methods_use_lzma = true;
|
||||||
opt->method = -1;
|
opt->method = -1;
|
||||||
opt->all_filters = true;
|
opt->all_filters = true;
|
||||||
opt->filter = -1;
|
opt->filter = -1;
|
||||||
opt->crp.m_size = 999999;
|
opt->crp.crp_ucl.m_size = 999999;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 900: // --best
|
case 900: // --best
|
||||||
if (!set_method(-1, 10))
|
if (!set_method(-1, 10))
|
||||||
@@ -553,6 +615,9 @@ static int do_option(int optc, const char *arg)
|
|||||||
e_optarg(arg);
|
e_optarg(arg);
|
||||||
opt->debug.dump_stub_loader = mfx_optarg;
|
opt->debug.dump_stub_loader = mfx_optarg;
|
||||||
break;
|
break;
|
||||||
|
case 545:
|
||||||
|
opt->debug.disable_random_id = true;
|
||||||
|
break;
|
||||||
|
|
||||||
// misc
|
// misc
|
||||||
case 512:
|
case 512:
|
||||||
@@ -577,7 +642,7 @@ static int do_option(int optc, const char *arg)
|
|||||||
opt->small++;
|
opt->small++;
|
||||||
break;
|
break;
|
||||||
case 521: // --filter=
|
case 521: // --filter=
|
||||||
getoptvar(&opt->filter, 0, 255);
|
getoptvar(&opt->filter, 0, 255, arg);
|
||||||
opt->all_filters = false;
|
opt->all_filters = false;
|
||||||
break;
|
break;
|
||||||
case 522: // --no-filter
|
case 522: // --no-filter
|
||||||
@@ -593,28 +658,54 @@ static int do_option(int optc, const char *arg)
|
|||||||
opt->all_methods = true;
|
opt->all_methods = true;
|
||||||
opt->method = -1;
|
opt->method = -1;
|
||||||
break;
|
break;
|
||||||
// compression parms
|
case 525: // --exact
|
||||||
case 531:
|
opt->exact = true;
|
||||||
getoptvar(&opt->crp.c_flags, 0, 3);
|
|
||||||
break;
|
break;
|
||||||
case 532:
|
// compression runtime parameters
|
||||||
getoptvar(&opt->crp.s_level, 0, 2);
|
case 801:
|
||||||
|
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
|
||||||
break;
|
break;
|
||||||
case 533:
|
case 802:
|
||||||
getoptvar(&opt->crp.h_level, 0, 1);
|
getoptvar(&opt->crp.crp_ucl.s_level, 0, 2, arg);
|
||||||
break;
|
break;
|
||||||
case 534:
|
case 803:
|
||||||
getoptvar(&opt->crp.p_level, 0, 7);
|
getoptvar(&opt->crp.crp_ucl.h_level, 0, 1, arg);
|
||||||
break;
|
break;
|
||||||
case 535:
|
case 804:
|
||||||
getoptvar(&opt->crp.max_offset, 256u, ~0u);
|
getoptvar(&opt->crp.crp_ucl.p_level, 0, 7, arg);
|
||||||
break;
|
break;
|
||||||
case 536:
|
case 805:
|
||||||
getoptvar(&opt->crp.max_match, 16u, ~0u);
|
getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u, arg);
|
||||||
break;
|
break;
|
||||||
case 537:
|
case 806:
|
||||||
if (getoptvar(&opt->crp.m_size, 10000u, 999999u) != 0)
|
getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u, arg);
|
||||||
e_optval("--crp-ms=");
|
break;
|
||||||
|
case 807:
|
||||||
|
getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u, arg);
|
||||||
|
break;
|
||||||
|
case 811:
|
||||||
|
getoptvar(&opt->crp.crp_lzma.pos_bits, arg);
|
||||||
|
break;
|
||||||
|
case 812:
|
||||||
|
getoptvar(&opt->crp.crp_lzma.lit_pos_bits, arg);
|
||||||
|
break;
|
||||||
|
case 813:
|
||||||
|
getoptvar(&opt->crp.crp_lzma.lit_context_bits, arg);
|
||||||
|
break;
|
||||||
|
case 814:
|
||||||
|
getoptvar(&opt->crp.crp_lzma.dict_size, arg);
|
||||||
|
break;
|
||||||
|
case 816:
|
||||||
|
getoptvar(&opt->crp.crp_lzma.num_fast_bytes, arg);
|
||||||
|
break;
|
||||||
|
case 821:
|
||||||
|
getoptvar(&opt->crp.crp_zlib.mem_level, arg);
|
||||||
|
break;
|
||||||
|
case 822:
|
||||||
|
getoptvar(&opt->crp.crp_zlib.window_bits, arg);
|
||||||
|
break;
|
||||||
|
case 823:
|
||||||
|
getoptvar(&opt->crp.crp_zlib.strategy, arg);
|
||||||
break;
|
break;
|
||||||
// backup
|
// backup
|
||||||
case 'k':
|
case 'k':
|
||||||
@@ -679,18 +770,20 @@ static int do_option(int optc, const char *arg)
|
|||||||
break;
|
break;
|
||||||
case 630:
|
case 630:
|
||||||
opt->win32_pe.compress_exports = 1;
|
opt->win32_pe.compress_exports = 1;
|
||||||
getoptvar(&opt->win32_pe.compress_exports, 0, 1);
|
if (mfx_optarg && mfx_optarg[0])
|
||||||
|
getoptvar(&opt->win32_pe.compress_exports, 0, 1, arg);
|
||||||
//printf("compress_exports: %d\n", opt->win32_pe.compress_exports);
|
//printf("compress_exports: %d\n", opt->win32_pe.compress_exports);
|
||||||
break;
|
break;
|
||||||
case 631:
|
case 631:
|
||||||
opt->win32_pe.compress_icons = 1;
|
opt->win32_pe.compress_icons = 1;
|
||||||
getoptvar(&opt->win32_pe.compress_icons, 0, 2);
|
if (mfx_optarg && mfx_optarg[0])
|
||||||
|
getoptvar(&opt->win32_pe.compress_icons, 0, 3, arg);
|
||||||
//printf("compress_icons: %d\n", opt->win32_pe.compress_icons);
|
//printf("compress_icons: %d\n", opt->win32_pe.compress_icons);
|
||||||
break;
|
break;
|
||||||
case 632:
|
case 632:
|
||||||
opt->win32_pe.compress_resources = true;
|
opt->win32_pe.compress_resources = 1;
|
||||||
if (mfx_optarg && strcmp(mfx_optarg,"0") == 0)
|
if (mfx_optarg && mfx_optarg[0])
|
||||||
opt->win32_pe.compress_resources = false;
|
getoptvar(&opt->win32_pe.compress_resources, 0, 1, arg);
|
||||||
//printf("compress_resources: %d\n", opt->win32_pe.compress_resources);
|
//printf("compress_resources: %d\n", opt->win32_pe.compress_resources);
|
||||||
break;
|
break;
|
||||||
case 633:
|
case 633:
|
||||||
@@ -698,15 +791,20 @@ static int do_option(int optc, const char *arg)
|
|||||||
break;
|
break;
|
||||||
case 634:
|
case 634:
|
||||||
opt->win32_pe.strip_relocs = 1;
|
opt->win32_pe.strip_relocs = 1;
|
||||||
if (mfx_optarg && strcmp(mfx_optarg,"0") == 0)
|
if (mfx_optarg && mfx_optarg[0])
|
||||||
opt->win32_pe.strip_relocs = 0;
|
getoptvar(&opt->win32_pe.strip_relocs, 0, 1, arg);
|
||||||
//printf("strip_relocs: %d\n", opt->win32_pe.strip_relocs);
|
//printf("strip_relocs: %d\n", opt->win32_pe.strip_relocs);
|
||||||
break;
|
break;
|
||||||
|
case 635:
|
||||||
|
if (!mfx_optarg || !mfx_optarg[0])
|
||||||
|
e_optarg(arg);
|
||||||
|
opt->win32_pe.keep_resource = mfx_optarg;
|
||||||
|
break;
|
||||||
case 650:
|
case 650:
|
||||||
opt->atari_tos.split_segments = true;
|
opt->atari_tos.split_segments = true;
|
||||||
break;
|
break;
|
||||||
case 660:
|
case 660:
|
||||||
getoptvar(&opt->o_unix.blocksize, 8192u, ~0u);
|
getoptvar(&opt->o_unix.blocksize, 8192u, ~0u, arg);
|
||||||
break;
|
break;
|
||||||
case 661:
|
case 661:
|
||||||
opt->o_unix.force_execve = true;
|
opt->o_unix.force_execve = true;
|
||||||
@@ -725,6 +823,18 @@ static int do_option(int optc, const char *arg)
|
|||||||
case 665:
|
case 665:
|
||||||
opt->o_unix.make_ptinterp = true;
|
opt->o_unix.make_ptinterp = true;
|
||||||
break;
|
break;
|
||||||
|
case 666: // Linux
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
|
||||||
|
break;
|
||||||
|
case 667: // FreeBSD
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_FREEBSD;
|
||||||
|
break;
|
||||||
|
case 668: // NetBSD
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_NETBSD;
|
||||||
|
break;
|
||||||
|
case 669: // OpenBSD
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_OPENBSD;
|
||||||
|
break;
|
||||||
case 670:
|
case 670:
|
||||||
opt->ps1_exe.boot_only = true;
|
opt->ps1_exe.boot_only = true;
|
||||||
break;
|
break;
|
||||||
@@ -735,6 +845,9 @@ static int do_option(int optc, const char *arg)
|
|||||||
case 672:
|
case 672:
|
||||||
opt->ps1_exe.do_8bit = true;
|
opt->ps1_exe.do_8bit = true;
|
||||||
break;
|
break;
|
||||||
|
case 673:
|
||||||
|
opt->ps1_exe.do_8mb = false;
|
||||||
|
break;
|
||||||
|
|
||||||
case '\0':
|
case '\0':
|
||||||
return -1;
|
return -1;
|
||||||
@@ -790,18 +903,19 @@ static const struct mfx_option longopts[] =
|
|||||||
{"dump-stub-loader" ,0x31, 0, 544}, // for internal debugging
|
{"dump-stub-loader" ,0x31, 0, 544}, // for internal debugging
|
||||||
{"fake-stub-version",0x31, 0, 542}, // for internal debugging
|
{"fake-stub-version",0x31, 0, 542}, // for internal debugging
|
||||||
{"fake-stub-year" ,0x31, 0, 543}, // for internal debugging
|
{"fake-stub-year" ,0x31, 0, 543}, // for internal debugging
|
||||||
|
{"disable-random-id",0x10, 0, 545}, // for internal debugging
|
||||||
|
|
||||||
// backup options
|
// backup options
|
||||||
{"backup", 0, 0, 'k'},
|
{"backup", 0x10, 0, 'k'},
|
||||||
{"keep", 0, 0, 'k'},
|
{"keep", 0x10, 0, 'k'},
|
||||||
{"no-backup", 0, 0, 541},
|
{"no-backup", 0x10, 0, 541},
|
||||||
|
|
||||||
// overlay options
|
// overlay options
|
||||||
{"overlay", 0x31, 0, 551}, // --overlay=
|
{"overlay", 0x31, 0, 551}, // --overlay=
|
||||||
{"skip-overlay", 0, 0, 552},
|
{"skip-overlay", 0x10, 0, 552},
|
||||||
{"no-overlay", 0, 0, 552}, // old name
|
{"no-overlay", 0x10, 0, 552}, // old name
|
||||||
{"copy-overlay", 0, 0, 553},
|
{"copy-overlay", 0x10, 0, 553},
|
||||||
{"strip-overlay", 0, 0, 554},
|
{"strip-overlay", 0x10, 0, 554},
|
||||||
|
|
||||||
// CPU options
|
// CPU options
|
||||||
{"cpu", 0x31, 0, 560}, // --cpu=
|
{"cpu", 0x31, 0, 560}, // --cpu=
|
||||||
@@ -810,33 +924,53 @@ static const struct mfx_option longopts[] =
|
|||||||
{"486", 0x10, 0, 564},
|
{"486", 0x10, 0, 564},
|
||||||
|
|
||||||
// color options
|
// color options
|
||||||
{"no-color", 0, 0, 512},
|
{"no-color", 0x10, 0, 512},
|
||||||
{"mono", 0, 0, 513},
|
{"mono", 0x10, 0, 513},
|
||||||
{"color", 0, 0, 514},
|
{"color", 0x10, 0, 514},
|
||||||
|
|
||||||
// compression method
|
// compression method
|
||||||
{"nrv2b", 0x10, 0, 702}, // --nrv2b
|
{"nrv2b", 0x10, 0, 702}, // --nrv2b
|
||||||
{"nrv2d", 0x10, 0, 704}, // --nrv2d
|
{"nrv2d", 0x10, 0, 704}, // --nrv2d
|
||||||
{"nrv2e", 0x10, 0, 705}, // --nrv2e
|
{"nrv2e", 0x10, 0, 705}, // --nrv2e
|
||||||
|
{"lzma", 0x10, 0, 721}, // --lzma
|
||||||
|
{"no-lzma", 0x10, 0, 722}, // (disable all_methods_use_lzma)
|
||||||
// compression settings
|
// compression settings
|
||||||
{"all-filters", 0x10, 0, 523},
|
{"all-filters", 0x10, 0, 523},
|
||||||
{"all-methods", 0x10, 0, 524},
|
{"all-methods", 0x10, 0, 524},
|
||||||
|
{"exact", 0x10, 0, 525}, // user requires byte-identical decompression
|
||||||
{"filter", 0x31, 0, 521}, // --filter=
|
{"filter", 0x31, 0, 521}, // --filter=
|
||||||
{"no-filter", 0x10, 0, 522},
|
{"no-filter", 0x10, 0, 522},
|
||||||
{"small", 0x10, 0, 520},
|
{"small", 0x10, 0, 520},
|
||||||
// compression runtime parameters
|
// compression runtime parameters
|
||||||
{"crp-cf", 0x31, 0, 531},
|
{"crp-nrv-cf", 0x31, 0, 801},
|
||||||
{"crp-sl", 0x31, 0, 532},
|
{"crp-nrv-sl", 0x31, 0, 802},
|
||||||
{"crp-hl", 0x31, 0, 533},
|
{"crp-nrv-hl", 0x31, 0, 803},
|
||||||
{"crp-pl", 0x31, 0, 534},
|
{"crp-nrv-pl", 0x31, 0, 804},
|
||||||
{"crp-mo", 0x31, 0, 535},
|
{"crp-nrv-mo", 0x31, 0, 805},
|
||||||
{"crp-mm", 0x31, 0, 536},
|
{"crp-nrv-mm", 0x31, 0, 806},
|
||||||
{"crp-ms", 0x31, 0, 537},
|
{"crp-nrv-ms", 0x31, 0, 807},
|
||||||
|
{"crp-ucl-cf", 0x31, 0, 801},
|
||||||
|
{"crp-ucl-sl", 0x31, 0, 802},
|
||||||
|
{"crp-ucl-hl", 0x31, 0, 803},
|
||||||
|
{"crp-ucl-pl", 0x31, 0, 804},
|
||||||
|
{"crp-ucl-mo", 0x31, 0, 805},
|
||||||
|
{"crp-ucl-mm", 0x31, 0, 806},
|
||||||
|
{"crp-ucl-ms", 0x31, 0, 807},
|
||||||
|
{"crp-lzma-pb", 0x31, 0, 811},
|
||||||
|
{"crp-lzma-lp", 0x31, 0, 812},
|
||||||
|
{"crp-lzma-lc", 0x31, 0, 813},
|
||||||
|
{"crp-lzma-ds", 0x31, 0, 814},
|
||||||
|
{"crp-lzma-fb", 0x31, 0, 816},
|
||||||
|
{"crp-zlib-ml", 0x31, 0, 821},
|
||||||
|
{"crp-zlib-wb", 0x31, 0, 822},
|
||||||
|
{"crp-zlib-st", 0x31, 0, 823},
|
||||||
|
// [deprecated - only for compatibility with UPX 2.0x]
|
||||||
|
{"crp-ms", 0x31, 0, 807},
|
||||||
|
|
||||||
// atari/tos
|
// atari/tos
|
||||||
{"split-segments", 0x10, 0, 650},
|
{"split-segments", 0x10, 0, 650},
|
||||||
// djgpp2/coff
|
// djgpp2/coff
|
||||||
{"coff", 0, 0, 610}, // produce COFF output
|
{"coff", 0x10, 0, 610}, // produce COFF output
|
||||||
// dos/com
|
// dos/com
|
||||||
// dos/exe
|
// dos/exe
|
||||||
//{"force-stub", 0x10, 0, 600},
|
//{"force-stub", 0x10, 0, 600},
|
||||||
@@ -848,21 +982,31 @@ static const struct mfx_option longopts[] =
|
|||||||
#if 0
|
#if 0
|
||||||
{"script", 0x31, 0, 662}, // --script=
|
{"script", 0x31, 0, 662}, // --script=
|
||||||
#endif
|
#endif
|
||||||
{"is_ptinterp", 0, 0, 663}, // linux/elf386 PT_INTERP program
|
{"is_ptinterp", 0x10, 0, 663}, // linux/elf386 PT_INTERP program
|
||||||
{"use_ptinterp", 0, 0, 664}, // linux/elf386 PT_INTERP program
|
{"use_ptinterp", 0x10, 0, 664}, // linux/elf386 PT_INTERP program
|
||||||
{"make_ptinterp", 0, 0, 665}, // linux/elf386 PT_INTERP program
|
{"make_ptinterp", 0x10, 0, 665}, // linux/elf386 PT_INTERP program
|
||||||
|
{"Linux", 0x10, 0, 666},
|
||||||
|
{"linux", 0x10, 0, 666},
|
||||||
|
{"FreeBSD", 0x10, 0, 667},
|
||||||
|
{"freebsd", 0x10, 0, 667},
|
||||||
|
{"NetBSD", 0x10, 0, 668},
|
||||||
|
{"netbsd", 0x10, 0, 668},
|
||||||
|
{"OpenBSD", 0x10, 0, 669},
|
||||||
|
{"openbsd", 0x10, 0, 669},
|
||||||
// watcom/le
|
// watcom/le
|
||||||
{"le", 0, 0, 620}, // produce LE output
|
{"le", 0x10, 0, 620}, // produce LE output
|
||||||
// win32/pe
|
// win32/pe
|
||||||
{"compress-exports", 2, 0, 630},
|
{"compress-exports", 2, 0, 630},
|
||||||
{"compress-icons", 2, 0, 631},
|
{"compress-icons", 2, 0, 631},
|
||||||
{"compress-resources", 2, 0, 632},
|
{"compress-resources", 2, 0, 632},
|
||||||
{"strip-loadconf", 0x12, 0, 633}, // OBSOLETE - IGNORED
|
{"strip-loadconf", 0x12, 0, 633}, // OBSOLETE - IGNORED
|
||||||
{"strip-relocs", 0x12, 0, 634},
|
{"strip-relocs", 0x12, 0, 634},
|
||||||
|
{"keep-resource", 0x31, 0, 635},
|
||||||
// ps1/exe
|
// ps1/exe
|
||||||
{"boot-only", 0x10, 0, 670},
|
{"boot-only", 0x10, 0, 670},
|
||||||
{"no-align", 0x10, 0, 671},
|
{"no-align", 0x10, 0, 671},
|
||||||
{"8-bit", 0x10, 0, 672},
|
{"8-bit", 0x10, 0, 672},
|
||||||
|
{"8mb-ram", 0x10, 0, 673},
|
||||||
|
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
@@ -873,6 +1017,7 @@ static const struct mfx_option longopts[] =
|
|||||||
prepare_shortopts(buf,"123456789hH?V",longopts),
|
prepare_shortopts(buf,"123456789hH?V",longopts),
|
||||||
mfx_optind = 0;
|
mfx_optind = 0;
|
||||||
mfx_opterr = 1;
|
mfx_opterr = 1;
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
|
||||||
while ((optc = mfx_getopt_long(argc, argv, buf, longopts, &longind)) >= 0)
|
while ((optc = mfx_getopt_long(argc, argv, buf, longopts, &longind)) >= 0)
|
||||||
{
|
{
|
||||||
if (do_option(optc, argv[mfx_optind-1]) != 0)
|
if (do_option(optc, argv[mfx_optind-1]) != 0)
|
||||||
@@ -903,17 +1048,20 @@ static const struct mfx_option longopts[] =
|
|||||||
{"silent", 0, 0, 'q'}, // quiet mode
|
{"silent", 0, 0, 'q'}, // quiet mode
|
||||||
{"verbose", 0, 0, 'v'}, // verbose mode
|
{"verbose", 0, 0, 'v'}, // verbose mode
|
||||||
|
|
||||||
|
// debug options
|
||||||
|
{"disable-random-id",0x10, 0, 545}, // for internal debugging
|
||||||
|
|
||||||
// backup options
|
// backup options
|
||||||
{"backup", 0, 0, 'k'},
|
{"backup", 0x10, 0, 'k'},
|
||||||
{"keep", 0, 0, 'k'},
|
{"keep", 0x10, 0, 'k'},
|
||||||
{"no-backup", 0x10, 0, 541},
|
{"no-backup", 0x10, 0, 541},
|
||||||
|
|
||||||
// overlay options
|
// overlay options
|
||||||
{"overlay", 0x31, 0, 551}, // --overlay=
|
{"overlay", 0x31, 0, 551}, // --overlay=
|
||||||
{"skip-overlay", 0, 0, 552},
|
{"skip-overlay", 0x10, 0, 552},
|
||||||
{"no-overlay", 0, 0, 552}, // old name
|
{"no-overlay", 0x10, 0, 552}, // old name
|
||||||
{"copy-overlay", 0, 0, 553},
|
{"copy-overlay", 0x10, 0, 553},
|
||||||
{"strip-overlay", 0, 0, 554},
|
{"strip-overlay", 0x10, 0, 554},
|
||||||
|
|
||||||
// CPU options
|
// CPU options
|
||||||
{"cpu", 0x31, 0, 560}, // --cpu=
|
{"cpu", 0x31, 0, 560}, // --cpu=
|
||||||
@@ -922,18 +1070,14 @@ static const struct mfx_option longopts[] =
|
|||||||
{"486", 0x10, 0, 564},
|
{"486", 0x10, 0, 564},
|
||||||
|
|
||||||
// color options
|
// color options
|
||||||
{"no-color", 0, 0, 512},
|
{"no-color", 0x10, 0, 512},
|
||||||
{"mono", 0, 0, 513},
|
{"mono", 0x10, 0, 513},
|
||||||
{"color", 0, 0, 514},
|
{"color", 0x10, 0, 514},
|
||||||
|
|
||||||
|
// compression settings
|
||||||
|
{"exact", 0x10, 0, 525}, // user requires byte-identical decompression
|
||||||
|
|
||||||
// compression runtime parameters
|
// compression runtime parameters
|
||||||
{"crp-cf", 0x31, 0, 531},
|
|
||||||
{"crp-sl", 0x31, 0, 532},
|
|
||||||
{"crp-hl", 0x31, 0, 533},
|
|
||||||
{"crp-pl", 0x31, 0, 534},
|
|
||||||
{"crp-mo", 0x31, 0, 535},
|
|
||||||
{"crp-mm", 0x31, 0, 536},
|
|
||||||
{"crp-ms", 0x31, 0, 537},
|
|
||||||
|
|
||||||
// win32/pe
|
// win32/pe
|
||||||
{"compress-exports", 2, 0, 630},
|
{"compress-exports", 2, 0, 630},
|
||||||
@@ -941,6 +1085,7 @@ static const struct mfx_option longopts[] =
|
|||||||
{"compress-resources", 2, 0, 632},
|
{"compress-resources", 2, 0, 632},
|
||||||
{"strip-loadconf", 0x12, 0, 633}, // OBSOLETE - IGNORED
|
{"strip-loadconf", 0x12, 0, 633}, // OBSOLETE - IGNORED
|
||||||
{"strip-relocs", 0x12, 0, 634},
|
{"strip-relocs", 0x12, 0, 634},
|
||||||
|
{"keep-resource", 0x31, 0, 635},
|
||||||
|
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
@@ -1120,7 +1265,7 @@ void upx_sanity_check(void)
|
|||||||
assert(memcmp(UPX_VERSION_DATE + strlen(UPX_VERSION_DATE) - 4, UPX_VERSION_YEAR, 4) == 0);
|
assert(memcmp(UPX_VERSION_DATE + strlen(UPX_VERSION_DATE) - 4, UPX_VERSION_YEAR, 4) == 0);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
# if 1
|
# if 1 && !defined(UPX_OFFICIAL_BUILD)
|
||||||
assert(TestBELE<LE16>::test());
|
assert(TestBELE<LE16>::test());
|
||||||
assert(TestBELE<LE32>::test());
|
assert(TestBELE<LE32>::test());
|
||||||
assert(TestBELE<LE64>::test());
|
assert(TestBELE<LE64>::test());
|
||||||
@@ -1170,6 +1315,10 @@ void upx_sanity_check(void)
|
|||||||
|
|
||||||
#if !defined(WITH_GUI)
|
#if !defined(WITH_GUI)
|
||||||
|
|
||||||
|
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||||
|
extern "C" { extern long _stksize; long _stksize = 256 * 1024L; }
|
||||||
|
#endif
|
||||||
|
|
||||||
int __acc_cdecl_main main(int argc, char *argv[])
|
int __acc_cdecl_main main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -1183,7 +1332,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
|||||||
acc_wildargv(&argc, &argv);
|
acc_wildargv(&argc, &argv);
|
||||||
|
|
||||||
upx_sanity_check();
|
upx_sanity_check();
|
||||||
init_options(opt);
|
opt->reset();
|
||||||
|
|
||||||
if (!argv[0] || !argv[0][0])
|
if (!argv[0] || !argv[0][0])
|
||||||
argv[0] = default_argv0;
|
argv[0] = default_argv0;
|
||||||
@@ -1284,14 +1433,6 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt->cmd != CMD_COMPRESS)
|
|
||||||
{
|
|
||||||
// invalidate compression options
|
|
||||||
opt->method = 0;
|
|
||||||
opt->level = 0;
|
|
||||||
memset(&opt->crp, 0xff, sizeof(opt->crp));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
e_help();
|
e_help();
|
||||||
|
|||||||
+21
-6
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -101,16 +101,15 @@ void MemBuffer::dealloc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MemBuffer::allocForCompression(unsigned uncompressed_size, unsigned extra)
|
unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned extra)
|
||||||
{
|
{
|
||||||
assert((int)uncompressed_size > 0);
|
assert((int)uncompressed_size > 0);
|
||||||
assert((int)extra >= 0);
|
assert((int)extra >= 0);
|
||||||
unsigned size = uncompressed_size + uncompressed_size/8 + 256 + extra;
|
unsigned size = uncompressed_size + uncompressed_size/8 + 256 + extra;
|
||||||
alloc(size);
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned MemBuffer::getSizeForUncompression(unsigned uncompressed_size, unsigned extra)
|
||||||
void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra)
|
|
||||||
{
|
{
|
||||||
assert((int)uncompressed_size > 0);
|
assert((int)uncompressed_size > 0);
|
||||||
assert((int)extra >= 0);
|
assert((int)extra >= 0);
|
||||||
@@ -120,6 +119,20 @@ void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra
|
|||||||
#if (ACC_ARCH_I386)
|
#if (ACC_ARCH_I386)
|
||||||
size += 3;
|
size += 3;
|
||||||
#endif
|
#endif
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MemBuffer::allocForCompression(unsigned uncompressed_size, unsigned extra)
|
||||||
|
{
|
||||||
|
unsigned size = getSizeForCompression(uncompressed_size, extra);
|
||||||
|
alloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra)
|
||||||
|
{
|
||||||
|
unsigned size = getSizeForUncompression(uncompressed_size, extra);
|
||||||
alloc(size);
|
alloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +209,8 @@ void MemBuffer::alloc(unsigned size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
b = p ;
|
b = p ;
|
||||||
|
|
||||||
|
//fill(0, b_size, (rand() & 0xff) | 1); // debug
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -38,9 +38,12 @@ class MemBuffer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemBuffer();
|
MemBuffer();
|
||||||
MemBuffer(unsigned size);
|
explicit MemBuffer(unsigned size);
|
||||||
~MemBuffer();
|
~MemBuffer();
|
||||||
|
|
||||||
|
static unsigned getSizeForCompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
|
static unsigned getSizeForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
|
|
||||||
void alloc(unsigned size);
|
void alloc(unsigned size);
|
||||||
void allocForCompression(unsigned uncompressed_size, unsigned extra=0);
|
void allocForCompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
void allocForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
void allocForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
|
|||||||
+249
-132
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
#ifndef __ACC_H_INCLUDED
|
#ifndef __ACC_H_INCLUDED
|
||||||
#define __ACC_H_INCLUDED 1
|
#define __ACC_H_INCLUDED 1
|
||||||
#define ACC_VERSION 20060404L
|
#define ACC_VERSION 20060823L
|
||||||
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
|
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
|
||||||
# define __CYGWIN__ __CYGWIN32__
|
# define __CYGWIN__ __CYGWIN32__
|
||||||
#endif
|
#endif
|
||||||
@@ -301,6 +301,17 @@
|
|||||||
#if defined(_CRAY) && defined(_CRAY1)
|
#if defined(_CRAY) && defined(_CRAY1)
|
||||||
# define ACC_BROKEN_SIGNED_RIGHT_SHIFT 1
|
# define ACC_BROKEN_SIGNED_RIGHT_SHIFT 1
|
||||||
#endif
|
#endif
|
||||||
|
#define ACC_PP_STRINGIZE(x) #x
|
||||||
|
#define ACC_PP_MACRO_EXPAND(x) ACC_PP_STRINGIZE(x)
|
||||||
|
#define ACC_PP_CONCAT2(a,b) a ## b
|
||||||
|
#define ACC_PP_CONCAT3(a,b,c) a ## b ## c
|
||||||
|
#define ACC_PP_CONCAT4(a,b,c,d) a ## b ## c ## d
|
||||||
|
#define ACC_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
|
||||||
|
#define ACC_PP_ECONCAT2(a,b) ACC_PP_CONCAT2(a,b)
|
||||||
|
#define ACC_PP_ECONCAT3(a,b,c) ACC_PP_CONCAT3(a,b,c)
|
||||||
|
#define ACC_PP_ECONCAT4(a,b,c,d) ACC_PP_CONCAT4(a,b,c,d)
|
||||||
|
#define ACC_PP_ECONCAT5(a,b,c,d,e) ACC_PP_CONCAT5(a,b,c,d,e)
|
||||||
|
#if 1
|
||||||
#define ACC_CPP_STRINGIZE(x) #x
|
#define ACC_CPP_STRINGIZE(x) #x
|
||||||
#define ACC_CPP_MACRO_EXPAND(x) ACC_CPP_STRINGIZE(x)
|
#define ACC_CPP_MACRO_EXPAND(x) ACC_CPP_STRINGIZE(x)
|
||||||
#define ACC_CPP_CONCAT2(a,b) a ## b
|
#define ACC_CPP_CONCAT2(a,b) a ## b
|
||||||
@@ -311,6 +322,7 @@
|
|||||||
#define ACC_CPP_ECONCAT3(a,b,c) ACC_CPP_CONCAT3(a,b,c)
|
#define ACC_CPP_ECONCAT3(a,b,c) ACC_CPP_CONCAT3(a,b,c)
|
||||||
#define ACC_CPP_ECONCAT4(a,b,c,d) ACC_CPP_CONCAT4(a,b,c,d)
|
#define ACC_CPP_ECONCAT4(a,b,c,d) ACC_CPP_CONCAT4(a,b,c,d)
|
||||||
#define ACC_CPP_ECONCAT5(a,b,c,d,e) ACC_CPP_CONCAT5(a,b,c,d,e)
|
#define ACC_CPP_ECONCAT5(a,b,c,d,e) ACC_CPP_CONCAT5(a,b,c,d,e)
|
||||||
|
#endif
|
||||||
#define __ACC_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o))
|
#define __ACC_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o))
|
||||||
#if 1 && defined(__cplusplus)
|
#if 1 && defined(__cplusplus)
|
||||||
# if !defined(__STDC_CONSTANT_MACROS)
|
# if !defined(__STDC_CONSTANT_MACROS)
|
||||||
@@ -509,14 +521,14 @@
|
|||||||
# define ACC_CC_CILLY 1
|
# define ACC_CC_CILLY 1
|
||||||
# define ACC_INFO_CC "Cilly"
|
# define ACC_INFO_CC "Cilly"
|
||||||
# if defined(__CILLY__)
|
# if defined(__CILLY__)
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__CILLY__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__CILLY__)
|
||||||
# else
|
# else
|
||||||
# define ACC_INFO_CCVER "unknown"
|
# define ACC_INFO_CCVER "unknown"
|
||||||
# endif
|
# endif
|
||||||
#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__)
|
#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__)
|
||||||
# define ACC_CC_SDCC 1
|
# define ACC_CC_SDCC 1
|
||||||
# define ACC_INFO_CC "sdcc"
|
# define ACC_INFO_CC "sdcc"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(SDCC)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(SDCC)
|
||||||
#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__)
|
#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__)
|
||||||
# define ACC_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__)
|
# define ACC_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__)
|
||||||
# define ACC_INFO_CC "Pathscale C"
|
# define ACC_INFO_CC "Pathscale C"
|
||||||
@@ -524,7 +536,7 @@
|
|||||||
#elif defined(__INTEL_COMPILER)
|
#elif defined(__INTEL_COMPILER)
|
||||||
# define ACC_CC_INTELC 1
|
# define ACC_CC_INTELC 1
|
||||||
# define ACC_INFO_CC "Intel C"
|
# define ACC_INFO_CC "Intel C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__INTEL_COMPILER)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__INTEL_COMPILER)
|
||||||
# if defined(_WIN32) || defined(_WIN64)
|
# if defined(_WIN32) || defined(_WIN64)
|
||||||
# define ACC_CC_SYNTAX_MSC 1
|
# define ACC_CC_SYNTAX_MSC 1
|
||||||
# else
|
# else
|
||||||
@@ -533,9 +545,13 @@
|
|||||||
#elif defined(__POCC__) && defined(_WIN32)
|
#elif defined(__POCC__) && defined(_WIN32)
|
||||||
# define ACC_CC_PELLESC 1
|
# define ACC_CC_PELLESC 1
|
||||||
# define ACC_INFO_CC "Pelles C"
|
# define ACC_INFO_CC "Pelles C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__POCC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__POCC__)
|
||||||
#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__)
|
#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__)
|
||||||
# define ACC_CC_LLVM 1
|
# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
|
||||||
|
# define ACC_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
|
||||||
|
# else
|
||||||
|
# define ACC_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
|
||||||
|
# endif
|
||||||
# define ACC_INFO_CC "llvm-gcc"
|
# define ACC_INFO_CC "llvm-gcc"
|
||||||
# define ACC_INFO_CCVER __VERSION__
|
# define ACC_INFO_CCVER __VERSION__
|
||||||
#elif defined(__GNUC__) && defined(__VERSION__)
|
#elif defined(__GNUC__) && defined(__VERSION__)
|
||||||
@@ -555,23 +571,23 @@
|
|||||||
#elif defined(__AZTEC_C__)
|
#elif defined(__AZTEC_C__)
|
||||||
# define ACC_CC_AZTECC 1
|
# define ACC_CC_AZTECC 1
|
||||||
# define ACC_INFO_CC "Aztec C"
|
# define ACC_INFO_CC "Aztec C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__AZTEC_C__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__AZTEC_C__)
|
||||||
#elif defined(__BORLANDC__)
|
#elif defined(__BORLANDC__)
|
||||||
# define ACC_CC_BORLANDC 1
|
# define ACC_CC_BORLANDC 1
|
||||||
# define ACC_INFO_CC "Borland C"
|
# define ACC_INFO_CC "Borland C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__BORLANDC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__BORLANDC__)
|
||||||
#elif defined(_CRAYC) && defined(_RELEASE)
|
#elif defined(_CRAYC) && defined(_RELEASE)
|
||||||
# define ACC_CC_CRAYC 1
|
# define ACC_CC_CRAYC 1
|
||||||
# define ACC_INFO_CC "Cray C"
|
# define ACC_INFO_CC "Cray C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(_RELEASE)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(_RELEASE)
|
||||||
#elif defined(__DMC__) && defined(__SC__)
|
#elif defined(__DMC__) && defined(__SC__)
|
||||||
# define ACC_CC_DMC 1
|
# define ACC_CC_DMC 1
|
||||||
# define ACC_INFO_CC "Digital Mars C"
|
# define ACC_INFO_CC "Digital Mars C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__DMC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__DMC__)
|
||||||
#elif defined(__DECC)
|
#elif defined(__DECC)
|
||||||
# define ACC_CC_DECC 1
|
# define ACC_CC_DECC 1
|
||||||
# define ACC_INFO_CC "DEC C"
|
# define ACC_INFO_CC "DEC C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__DECC)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__DECC)
|
||||||
#elif defined(__HIGHC__)
|
#elif defined(__HIGHC__)
|
||||||
# define ACC_CC_HIGHC 1
|
# define ACC_CC_HIGHC 1
|
||||||
# define ACC_INFO_CC "MetaWare High C"
|
# define ACC_INFO_CC "MetaWare High C"
|
||||||
@@ -580,18 +596,18 @@
|
|||||||
# define ACC_CC_IARC 1
|
# define ACC_CC_IARC 1
|
||||||
# define ACC_INFO_CC "IAR C"
|
# define ACC_INFO_CC "IAR C"
|
||||||
# if defined(__VER__)
|
# if defined(__VER__)
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__VER__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__VER__)
|
||||||
# else
|
# else
|
||||||
# define ACC_INFO_CCVER "unknown"
|
# define ACC_INFO_CCVER "unknown"
|
||||||
# endif
|
# endif
|
||||||
#elif defined(__IBMC__)
|
#elif defined(__IBMC__)
|
||||||
# define ACC_CC_IBMC 1
|
# define ACC_CC_IBMC 1
|
||||||
# define ACC_INFO_CC "IBM C"
|
# define ACC_INFO_CC "IBM C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__IBMC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__IBMC__)
|
||||||
#elif defined(__KEIL__) && defined(__C166__)
|
#elif defined(__KEIL__) && defined(__C166__)
|
||||||
# define ACC_CC_KEILC 1
|
# define ACC_CC_KEILC 1
|
||||||
# define ACC_INFO_CC "Keil C"
|
# define ACC_INFO_CC "Keil C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__C166__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__C166__)
|
||||||
#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL)
|
#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL)
|
||||||
# define ACC_CC_LCCWIN32 1
|
# define ACC_CC_LCCWIN32 1
|
||||||
# define ACC_INFO_CC "lcc-win32"
|
# define ACC_INFO_CC "lcc-win32"
|
||||||
@@ -600,7 +616,7 @@
|
|||||||
# define ACC_CC_LCC 1
|
# define ACC_CC_LCC 1
|
||||||
# define ACC_INFO_CC "lcc"
|
# define ACC_INFO_CC "lcc"
|
||||||
# if defined(__LCC_VERSION__)
|
# if defined(__LCC_VERSION__)
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__LCC_VERSION__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__LCC_VERSION__)
|
||||||
# else
|
# else
|
||||||
# define ACC_INFO_CCVER "unknown"
|
# define ACC_INFO_CCVER "unknown"
|
||||||
# endif
|
# endif
|
||||||
@@ -608,14 +624,14 @@
|
|||||||
# define ACC_CC_MSC 1
|
# define ACC_CC_MSC 1
|
||||||
# define ACC_INFO_CC "Microsoft C"
|
# define ACC_INFO_CC "Microsoft C"
|
||||||
# if defined(_MSC_FULL_VER)
|
# if defined(_MSC_FULL_VER)
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(_MSC_VER) "." ACC_CPP_MACRO_EXPAND(_MSC_FULL_VER)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(_MSC_VER) "." ACC_PP_MACRO_EXPAND(_MSC_FULL_VER)
|
||||||
# else
|
# else
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(_MSC_VER)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(_MSC_VER)
|
||||||
# endif
|
# endif
|
||||||
#elif defined(__MWERKS__)
|
#elif defined(__MWERKS__)
|
||||||
# define ACC_CC_MWERKS 1
|
# define ACC_CC_MWERKS 1
|
||||||
# define ACC_INFO_CC "Metrowerks C"
|
# define ACC_INFO_CC "Metrowerks C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__MWERKS__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__MWERKS__)
|
||||||
#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386)
|
#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386)
|
||||||
# define ACC_CC_NDPC 1
|
# define ACC_CC_NDPC 1
|
||||||
# define ACC_INFO_CC "Microway NDP C"
|
# define ACC_INFO_CC "Microway NDP C"
|
||||||
@@ -623,7 +639,7 @@
|
|||||||
#elif defined(__PACIFIC__)
|
#elif defined(__PACIFIC__)
|
||||||
# define ACC_CC_PACIFICC 1
|
# define ACC_CC_PACIFICC 1
|
||||||
# define ACC_INFO_CC "Pacific C"
|
# define ACC_INFO_CC "Pacific C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__PACIFIC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__PACIFIC__)
|
||||||
#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__))
|
#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__))
|
||||||
# define ACC_CC_PGI 1
|
# define ACC_CC_PGI 1
|
||||||
# define ACC_INFO_CC "Portland Group PGI C"
|
# define ACC_INFO_CC "Portland Group PGI C"
|
||||||
@@ -631,16 +647,16 @@
|
|||||||
#elif defined(__PUREC__) && defined(__TOS__)
|
#elif defined(__PUREC__) && defined(__TOS__)
|
||||||
# define ACC_CC_PUREC 1
|
# define ACC_CC_PUREC 1
|
||||||
# define ACC_INFO_CC "Pure C"
|
# define ACC_INFO_CC "Pure C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__PUREC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__PUREC__)
|
||||||
#elif defined(__SC__) && defined(__ZTC__)
|
#elif defined(__SC__) && defined(__ZTC__)
|
||||||
# define ACC_CC_SYMANTECC 1
|
# define ACC_CC_SYMANTECC 1
|
||||||
# define ACC_INFO_CC "Symantec C"
|
# define ACC_INFO_CC "Symantec C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__SC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__SC__)
|
||||||
#elif defined(__SUNPRO_C)
|
#elif defined(__SUNPRO_C)
|
||||||
# define ACC_INFO_CC "SunPro C"
|
# define ACC_INFO_CC "SunPro C"
|
||||||
# if ((__SUNPRO_C)+0 > 0)
|
# if ((__SUNPRO_C)+0 > 0)
|
||||||
# define ACC_CC_SUNPROC __SUNPRO_C
|
# define ACC_CC_SUNPROC __SUNPRO_C
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__SUNPRO_C)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__SUNPRO_C)
|
||||||
# else
|
# else
|
||||||
# define ACC_CC_SUNPROC 1
|
# define ACC_CC_SUNPROC 1
|
||||||
# define ACC_INFO_CCVER "unknown"
|
# define ACC_INFO_CCVER "unknown"
|
||||||
@@ -649,7 +665,7 @@
|
|||||||
# define ACC_INFO_CC "SunPro C"
|
# define ACC_INFO_CC "SunPro C"
|
||||||
# if ((__SUNPRO_CC)+0 > 0)
|
# if ((__SUNPRO_CC)+0 > 0)
|
||||||
# define ACC_CC_SUNPROC __SUNPRO_CC
|
# define ACC_CC_SUNPROC __SUNPRO_CC
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__SUNPRO_CC)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__SUNPRO_CC)
|
||||||
# else
|
# else
|
||||||
# define ACC_CC_SUNPROC 1
|
# define ACC_CC_SUNPROC 1
|
||||||
# define ACC_INFO_CCVER "unknown"
|
# define ACC_INFO_CCVER "unknown"
|
||||||
@@ -657,26 +673,26 @@
|
|||||||
#elif defined(__TINYC__)
|
#elif defined(__TINYC__)
|
||||||
# define ACC_CC_TINYC 1
|
# define ACC_CC_TINYC 1
|
||||||
# define ACC_INFO_CC "Tiny C"
|
# define ACC_INFO_CC "Tiny C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__TINYC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__TINYC__)
|
||||||
#elif defined(__TSC__)
|
#elif defined(__TSC__)
|
||||||
# define ACC_CC_TOPSPEEDC 1
|
# define ACC_CC_TOPSPEEDC 1
|
||||||
# define ACC_INFO_CC "TopSpeed C"
|
# define ACC_INFO_CC "TopSpeed C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__TSC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__TSC__)
|
||||||
#elif defined(__WATCOMC__)
|
#elif defined(__WATCOMC__)
|
||||||
# define ACC_CC_WATCOMC 1
|
# define ACC_CC_WATCOMC 1
|
||||||
# define ACC_INFO_CC "Watcom C"
|
# define ACC_INFO_CC "Watcom C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__WATCOMC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__WATCOMC__)
|
||||||
#elif defined(__TURBOC__)
|
#elif defined(__TURBOC__)
|
||||||
# define ACC_CC_TURBOC 1
|
# define ACC_CC_TURBOC 1
|
||||||
# define ACC_INFO_CC "Turbo C"
|
# define ACC_INFO_CC "Turbo C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__TURBOC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__TURBOC__)
|
||||||
#elif defined(__ZTC__)
|
#elif defined(__ZTC__)
|
||||||
# define ACC_CC_ZORTECHC 1
|
# define ACC_CC_ZORTECHC 1
|
||||||
# define ACC_INFO_CC "Zortech C"
|
# define ACC_INFO_CC "Zortech C"
|
||||||
# if (__ZTC__ == 0x310)
|
# if (__ZTC__ == 0x310)
|
||||||
# define ACC_INFO_CCVER "0x310"
|
# define ACC_INFO_CCVER "0x310"
|
||||||
# else
|
# else
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__ZTC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__ZTC__)
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# define ACC_CC_UNKNOWN 1
|
# define ACC_CC_UNKNOWN 1
|
||||||
@@ -1299,6 +1315,10 @@ extern "C" {
|
|||||||
# define ACC_ABI_BIG_ENDIAN 1
|
# define ACC_ABI_BIG_ENDIAN 1
|
||||||
#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
|
#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
|
||||||
# define ACC_ABI_LITTLE_ENDIAN 1
|
# define ACC_ABI_LITTLE_ENDIAN 1
|
||||||
|
#elif 1 && (ACC_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__)
|
||||||
|
# define ACC_ABI_BIG_ENDIAN 1
|
||||||
|
#elif 1 && (ACC_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__)
|
||||||
|
# define ACC_ABI_LITTLE_ENDIAN 1
|
||||||
#elif 1 && (ACC_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__)
|
#elif 1 && (ACC_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__)
|
||||||
# define ACC_ABI_BIG_ENDIAN 1
|
# define ACC_ABI_BIG_ENDIAN 1
|
||||||
#elif 1 && (ACC_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__)
|
#elif 1 && (ACC_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__)
|
||||||
@@ -1382,6 +1402,9 @@ extern "C" {
|
|||||||
#else
|
#else
|
||||||
# define __acc_gnuc_extension__
|
# define __acc_gnuc_extension__
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(__acc_ua_volatile)
|
||||||
|
# define __acc_ua_volatile volatile
|
||||||
|
#endif
|
||||||
#if !defined(__acc_alignof)
|
#if !defined(__acc_alignof)
|
||||||
#if (ACC_CC_CILLY || ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE || ACC_CC_PGI)
|
#if (ACC_CC_CILLY || ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE || ACC_CC_PGI)
|
||||||
# define __acc_alignof(e) __alignof__(e)
|
# define __acc_alignof(e) __alignof__(e)
|
||||||
@@ -1391,6 +1414,36 @@ extern "C" {
|
|||||||
# define __acc_alignof(e) __alignof(e)
|
# define __acc_alignof(e) __alignof(e)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__acc_alignof)
|
||||||
|
# define __acc_HAVE_alignof 1
|
||||||
|
#endif
|
||||||
|
#if !defined(__acc_constructor)
|
||||||
|
#if (ACC_CC_GNUC >= 0x030400ul)
|
||||||
|
# define __acc_constructor __attribute__((__constructor__,__used__))
|
||||||
|
#elif (ACC_CC_GNUC >= 0x020700ul)
|
||||||
|
# define __acc_constructor __attribute__((__constructor__))
|
||||||
|
#elif (ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
||||||
|
# define __acc_constructor __attribute__((__constructor__))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if defined(__acc_constructor)
|
||||||
|
# define __acc_HAVE_constructor 1
|
||||||
|
#endif
|
||||||
|
#if !defined(__acc_destructor)
|
||||||
|
#if (ACC_CC_GNUC >= 0x030400ul)
|
||||||
|
# define __acc_destructor __attribute__((__destructor__,__used__))
|
||||||
|
#elif (ACC_CC_GNUC >= 0x020700ul)
|
||||||
|
# define __acc_destructor __attribute__((__destructor__))
|
||||||
|
#elif (ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
||||||
|
# define __acc_destructor __attribute__((__destructor__))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if defined(__acc_destructor)
|
||||||
|
# define __acc_HAVE_destructor 1
|
||||||
|
#endif
|
||||||
|
#if defined(__acc_HAVE_destructor) && !defined(__acc_HAVE_constructor)
|
||||||
|
# error "this should not happen"
|
||||||
|
#endif
|
||||||
#if !defined(__acc_inline)
|
#if !defined(__acc_inline)
|
||||||
#if (ACC_CC_TURBOC && (__TURBOC__ <= 0x0295))
|
#if (ACC_CC_TURBOC && (__TURBOC__ <= 0x0295))
|
||||||
#elif defined(__cplusplus)
|
#elif defined(__cplusplus)
|
||||||
@@ -1411,6 +1464,11 @@ extern "C" {
|
|||||||
# define __acc_inline inline
|
# define __acc_inline inline
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__acc_inline)
|
||||||
|
# define __acc_HAVE_inline 1
|
||||||
|
#else
|
||||||
|
# define __acc_inline
|
||||||
|
#endif
|
||||||
#if !defined(__acc_forceinline)
|
#if !defined(__acc_forceinline)
|
||||||
#if (ACC_CC_GNUC >= 0x030200ul)
|
#if (ACC_CC_GNUC >= 0x030200ul)
|
||||||
# define __acc_forceinline __inline__ __attribute__((__always_inline__))
|
# define __acc_forceinline __inline__ __attribute__((__always_inline__))
|
||||||
@@ -1424,6 +1482,11 @@ extern "C" {
|
|||||||
# define __acc_forceinline __forceinline
|
# define __acc_forceinline __forceinline
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__acc_forceinline)
|
||||||
|
# define __acc_HAVE_forceinline 1
|
||||||
|
#else
|
||||||
|
# define __acc_forceinline
|
||||||
|
#endif
|
||||||
#if !defined(__acc_noinline)
|
#if !defined(__acc_noinline)
|
||||||
#if 1 && (ACC_ARCH_I386) && (ACC_CC_GNUC >= 0x040000ul) && (ACC_CC_GNUC < 0x040003ul)
|
#if 1 && (ACC_ARCH_I386) && (ACC_CC_GNUC >= 0x040000ul) && (ACC_CC_GNUC < 0x040003ul)
|
||||||
# define __acc_noinline __attribute__((__noinline__,__used__))
|
# define __acc_noinline __attribute__((__noinline__,__used__))
|
||||||
@@ -1444,7 +1507,12 @@ extern "C" {
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if (defined(__acc_forceinline) || defined(__acc_noinline)) && !defined(__acc_inline)
|
#if defined(__acc_noinline)
|
||||||
|
# define __acc_HAVE_noinline 1
|
||||||
|
#else
|
||||||
|
# define __acc_noinline
|
||||||
|
#endif
|
||||||
|
#if (defined(__acc_HAVE_forceinline) || defined(__acc_HAVE_noinline)) && !defined(__acc_HAVE_inline)
|
||||||
# error "this should not happen"
|
# error "this should not happen"
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_noreturn)
|
#if !defined(__acc_noreturn)
|
||||||
@@ -1460,6 +1528,11 @@ extern "C" {
|
|||||||
# define __acc_noreturn __declspec(noreturn)
|
# define __acc_noreturn __declspec(noreturn)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__acc_noreturn)
|
||||||
|
# define __acc_HAVE_noreturn 1
|
||||||
|
#else
|
||||||
|
# define __acc_noreturn
|
||||||
|
#endif
|
||||||
#if !defined(__acc_nothrow)
|
#if !defined(__acc_nothrow)
|
||||||
#if (ACC_CC_GNUC >= 0x030300ul)
|
#if (ACC_CC_GNUC >= 0x030300ul)
|
||||||
# define __acc_nothrow __attribute__((__nothrow__))
|
# define __acc_nothrow __attribute__((__nothrow__))
|
||||||
@@ -1473,26 +1546,10 @@ extern "C" {
|
|||||||
# define __acc_nothrow __declspec(nothrow)
|
# define __acc_nothrow __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_constructor)
|
#if defined(__acc_nothrow)
|
||||||
#if (ACC_CC_GNUC >= 0x030400ul)
|
# define __acc_HAVE_nothrow 1
|
||||||
# define __acc_constructor __attribute__((__constructor__,__used__))
|
#else
|
||||||
#elif (ACC_CC_GNUC >= 0x020700ul)
|
# define __acc_nothrow
|
||||||
# define __acc_constructor __attribute__((__constructor__))
|
|
||||||
#elif (ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
|
||||||
# define __acc_constructor __attribute__((__constructor__))
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if !defined(__acc_destructor)
|
|
||||||
#if (ACC_CC_GNUC >= 0x030400ul)
|
|
||||||
# define __acc_destructor __attribute__((__destructor__,__used__))
|
|
||||||
#elif (ACC_CC_GNUC >= 0x020700ul)
|
|
||||||
# define __acc_destructor __attribute__((__destructor__))
|
|
||||||
#elif (ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
|
||||||
# define __acc_destructor __attribute__((__destructor__))
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if defined(__acc_destructor) && !defined(__acc_constructor)
|
|
||||||
# error "this should not happen"
|
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_restrict)
|
#if !defined(__acc_restrict)
|
||||||
#if (ACC_CC_GNUC >= 0x030400ul)
|
#if (ACC_CC_GNUC >= 0x030400ul)
|
||||||
@@ -1505,8 +1562,10 @@ extern "C" {
|
|||||||
# define __acc_restrict __restrict
|
# define __acc_restrict __restrict
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_ua_volatile)
|
#if defined(__acc_restrict)
|
||||||
# define __acc_ua_volatile volatile
|
# define __acc_HAVE_restrict 1
|
||||||
|
#else
|
||||||
|
# define __acc_restrict
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_likely) && !defined(__acc_unlikely)
|
#if !defined(__acc_likely) && !defined(__acc_unlikely)
|
||||||
#if (ACC_CC_GNUC >= 0x030200ul)
|
#if (ACC_CC_GNUC >= 0x030200ul)
|
||||||
@@ -1520,10 +1579,14 @@ extern "C" {
|
|||||||
# define __acc_unlikely(e) (__builtin_expect(!!(e),0))
|
# define __acc_unlikely(e) (__builtin_expect(!!(e),0))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_likely)
|
#if defined(__acc_likely)
|
||||||
|
# define __acc_HAVE_likely 1
|
||||||
|
#else
|
||||||
# define __acc_likely(e) (e)
|
# define __acc_likely(e) (e)
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_unlikely)
|
#if defined(__acc_unlikely)
|
||||||
|
# define __acc_HAVE_unlikely 1
|
||||||
|
#else
|
||||||
# define __acc_unlikely(e) (e)
|
# define __acc_unlikely(e) (e)
|
||||||
#endif
|
#endif
|
||||||
#if !defined(ACC_UNUSED)
|
#if !defined(ACC_UNUSED)
|
||||||
@@ -2453,6 +2516,45 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#if defined(acc_int32e_t)
|
#if defined(acc_int32e_t)
|
||||||
# define ACC_SIZEOF_ACC_INT32E_T 4
|
# define ACC_SIZEOF_ACC_INT32E_T 4
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(acc_int64e_t)
|
||||||
|
#if (ACC_SIZEOF___INT64 == 8)
|
||||||
|
# if (ACC_CC_BORLANDC) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
||||||
|
# define ACC_CFG_TYPE_PREFER___INT64 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if (ACC_SIZEOF_INT == 8) && (ACC_SIZEOF_INT < ACC_SIZEOF_LONG)
|
||||||
|
# define acc_int64e_t int
|
||||||
|
# define acc_uint64e_t unsigned int
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_INT
|
||||||
|
#elif (ACC_SIZEOF_LONG == 8)
|
||||||
|
# define acc_int64e_t long int
|
||||||
|
# define acc_uint64e_t unsigned long int
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_LONG
|
||||||
|
#elif (ACC_SIZEOF_LONG_LONG == 8) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
||||||
|
# define acc_int64e_t acc_llong_t
|
||||||
|
# define acc_uint64e_t acc_ullong_t
|
||||||
|
# if (ACC_CC_BORLANDC)
|
||||||
|
# define ACC_INT64_C(c) ((c) + 0ll)
|
||||||
|
# define ACC_UINT64_C(c) ((c) + 0ull)
|
||||||
|
# else
|
||||||
|
# define ACC_INT64_C(c) c##LL
|
||||||
|
# define ACC_UINT64_C(c) c##ULL
|
||||||
|
# endif
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_LONG_LONG
|
||||||
|
#elif (ACC_SIZEOF___INT64 == 8)
|
||||||
|
# define acc_int64e_t __int64
|
||||||
|
# define acc_uint64e_t unsigned __int64
|
||||||
|
# if (ACC_CC_BORLANDC)
|
||||||
|
# define ACC_INT64_C(c) ((c) + 0i64)
|
||||||
|
# define ACC_UINT64_C(c) ((c) + 0ui64)
|
||||||
|
# else
|
||||||
|
# define ACC_INT64_C(c) c##i64
|
||||||
|
# define ACC_UINT64_C(c) c##ui64
|
||||||
|
# endif
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF___INT64
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#if !defined(acc_int32l_t)
|
#if !defined(acc_int32l_t)
|
||||||
#if defined(acc_int32e_t)
|
#if defined(acc_int32e_t)
|
||||||
# define acc_int32l_t acc_int32e_t
|
# define acc_int32l_t acc_int32e_t
|
||||||
@@ -2471,41 +2573,10 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(acc_int64l_t)
|
#if !defined(acc_int64l_t)
|
||||||
#if (ACC_SIZEOF___INT64 >= 8)
|
#if defined(acc_int64e_t)
|
||||||
# if (ACC_CC_BORLANDC) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
# define acc_int64l_t acc_int64e_t
|
||||||
# define ACC_CFG_TYPE_PREFER___INT64 1
|
# define acc_uint64l_t acc_uint64e_t
|
||||||
# endif
|
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_ACC_INT64E_T
|
||||||
#endif
|
|
||||||
#if (ACC_SIZEOF_INT >= 8) && (ACC_SIZEOF_INT < ACC_SIZEOF_LONG)
|
|
||||||
# define acc_int64l_t int
|
|
||||||
# define acc_uint64l_t unsigned int
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_INT
|
|
||||||
#elif (ACC_SIZEOF_LONG >= 8)
|
|
||||||
# define acc_int64l_t long int
|
|
||||||
# define acc_uint64l_t unsigned long int
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_LONG
|
|
||||||
#elif (ACC_SIZEOF_LONG_LONG >= 8) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
|
||||||
# define acc_int64l_t acc_llong_t
|
|
||||||
# define acc_uint64l_t acc_ullong_t
|
|
||||||
# if (ACC_CC_BORLANDC)
|
|
||||||
# define ACC_INT64_C(c) ((c) + 0ll)
|
|
||||||
# define ACC_UINT64_C(c) ((c) + 0ull)
|
|
||||||
# else
|
|
||||||
# define ACC_INT64_C(c) c##LL
|
|
||||||
# define ACC_UINT64_C(c) c##ULL
|
|
||||||
# endif
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_LONG_LONG
|
|
||||||
#elif (ACC_SIZEOF___INT64 >= 8)
|
|
||||||
# define acc_int64l_t __int64
|
|
||||||
# define acc_uint64l_t unsigned __int64
|
|
||||||
# if (ACC_CC_BORLANDC)
|
|
||||||
# define ACC_INT64_C(c) ((c) + 0i64)
|
|
||||||
# define ACC_UINT64_C(c) ((c) + 0ui64)
|
|
||||||
# else
|
|
||||||
# define ACC_INT64_C(c) c##i64
|
|
||||||
# define ACC_UINT64_C(c) c##ui64
|
|
||||||
# endif
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF___INT64
|
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -2650,6 +2721,9 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#if !defined(SIZEOF_ACC_INT32E_T) && defined(ACC_SIZEOF_ACC_INT32E_T)
|
#if !defined(SIZEOF_ACC_INT32E_T) && defined(ACC_SIZEOF_ACC_INT32E_T)
|
||||||
# define SIZEOF_ACC_INT32E_T ACC_SIZEOF_ACC_INT32E_T
|
# define SIZEOF_ACC_INT32E_T ACC_SIZEOF_ACC_INT32E_T
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(SIZEOF_ACC_INT64E_T) && defined(ACC_SIZEOF_ACC_INT64E_T)
|
||||||
|
# define SIZEOF_ACC_INT64E_T ACC_SIZEOF_ACC_INT64E_T
|
||||||
|
#endif
|
||||||
#if !defined(SIZEOF_ACC_INT32L_T) && defined(ACC_SIZEOF_ACC_INT32L_T)
|
#if !defined(SIZEOF_ACC_INT32L_T) && defined(ACC_SIZEOF_ACC_INT32L_T)
|
||||||
# define SIZEOF_ACC_INT32L_T ACC_SIZEOF_ACC_INT32L_T
|
# define SIZEOF_ACC_INT32L_T ACC_SIZEOF_ACC_INT32L_T
|
||||||
#endif
|
#endif
|
||||||
@@ -2861,6 +2935,45 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#if defined(acc_int32e_t)
|
#if defined(acc_int32e_t)
|
||||||
# define ACC_SIZEOF_ACC_INT32E_T 4
|
# define ACC_SIZEOF_ACC_INT32E_T 4
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(acc_int64e_t)
|
||||||
|
#if (ACC_SIZEOF___INT64 == 8)
|
||||||
|
# if (ACC_CC_BORLANDC) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
||||||
|
# define ACC_CFG_TYPE_PREFER___INT64 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if (ACC_SIZEOF_INT == 8) && (ACC_SIZEOF_INT < ACC_SIZEOF_LONG)
|
||||||
|
# define acc_int64e_t int
|
||||||
|
# define acc_uint64e_t unsigned int
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_INT
|
||||||
|
#elif (ACC_SIZEOF_LONG == 8)
|
||||||
|
# define acc_int64e_t long int
|
||||||
|
# define acc_uint64e_t unsigned long int
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_LONG
|
||||||
|
#elif (ACC_SIZEOF_LONG_LONG == 8) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
||||||
|
# define acc_int64e_t acc_llong_t
|
||||||
|
# define acc_uint64e_t acc_ullong_t
|
||||||
|
# if (ACC_CC_BORLANDC)
|
||||||
|
# define ACC_INT64_C(c) ((c) + 0ll)
|
||||||
|
# define ACC_UINT64_C(c) ((c) + 0ull)
|
||||||
|
# else
|
||||||
|
# define ACC_INT64_C(c) c##LL
|
||||||
|
# define ACC_UINT64_C(c) c##ULL
|
||||||
|
# endif
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_LONG_LONG
|
||||||
|
#elif (ACC_SIZEOF___INT64 == 8)
|
||||||
|
# define acc_int64e_t __int64
|
||||||
|
# define acc_uint64e_t unsigned __int64
|
||||||
|
# if (ACC_CC_BORLANDC)
|
||||||
|
# define ACC_INT64_C(c) ((c) + 0i64)
|
||||||
|
# define ACC_UINT64_C(c) ((c) + 0ui64)
|
||||||
|
# else
|
||||||
|
# define ACC_INT64_C(c) c##i64
|
||||||
|
# define ACC_UINT64_C(c) c##ui64
|
||||||
|
# endif
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF___INT64
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#if !defined(acc_int32l_t)
|
#if !defined(acc_int32l_t)
|
||||||
#if defined(acc_int32e_t)
|
#if defined(acc_int32e_t)
|
||||||
# define acc_int32l_t acc_int32e_t
|
# define acc_int32l_t acc_int32e_t
|
||||||
@@ -2879,41 +2992,10 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(acc_int64l_t)
|
#if !defined(acc_int64l_t)
|
||||||
#if (ACC_SIZEOF___INT64 >= 8)
|
#if defined(acc_int64e_t)
|
||||||
# if (ACC_CC_BORLANDC) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
# define acc_int64l_t acc_int64e_t
|
||||||
# define ACC_CFG_TYPE_PREFER___INT64 1
|
# define acc_uint64l_t acc_uint64e_t
|
||||||
# endif
|
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_ACC_INT64E_T
|
||||||
#endif
|
|
||||||
#if (ACC_SIZEOF_INT >= 8) && (ACC_SIZEOF_INT < ACC_SIZEOF_LONG)
|
|
||||||
# define acc_int64l_t int
|
|
||||||
# define acc_uint64l_t unsigned int
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_INT
|
|
||||||
#elif (ACC_SIZEOF_LONG >= 8)
|
|
||||||
# define acc_int64l_t long int
|
|
||||||
# define acc_uint64l_t unsigned long int
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_LONG
|
|
||||||
#elif (ACC_SIZEOF_LONG_LONG >= 8) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
|
||||||
# define acc_int64l_t acc_llong_t
|
|
||||||
# define acc_uint64l_t acc_ullong_t
|
|
||||||
# if (ACC_CC_BORLANDC)
|
|
||||||
# define ACC_INT64_C(c) ((c) + 0ll)
|
|
||||||
# define ACC_UINT64_C(c) ((c) + 0ull)
|
|
||||||
# else
|
|
||||||
# define ACC_INT64_C(c) c##LL
|
|
||||||
# define ACC_UINT64_C(c) c##ULL
|
|
||||||
# endif
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_LONG_LONG
|
|
||||||
#elif (ACC_SIZEOF___INT64 >= 8)
|
|
||||||
# define acc_int64l_t __int64
|
|
||||||
# define acc_uint64l_t unsigned __int64
|
|
||||||
# if (ACC_CC_BORLANDC)
|
|
||||||
# define ACC_INT64_C(c) ((c) + 0i64)
|
|
||||||
# define ACC_UINT64_C(c) ((c) + 0ui64)
|
|
||||||
# else
|
|
||||||
# define ACC_INT64_C(c) c##i64
|
|
||||||
# define ACC_UINT64_C(c) c##ui64
|
|
||||||
# endif
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF___INT64
|
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -3058,6 +3140,9 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#if !defined(SIZEOF_ACC_INT32E_T) && defined(ACC_SIZEOF_ACC_INT32E_T)
|
#if !defined(SIZEOF_ACC_INT32E_T) && defined(ACC_SIZEOF_ACC_INT32E_T)
|
||||||
# define SIZEOF_ACC_INT32E_T ACC_SIZEOF_ACC_INT32E_T
|
# define SIZEOF_ACC_INT32E_T ACC_SIZEOF_ACC_INT32E_T
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(SIZEOF_ACC_INT64E_T) && defined(ACC_SIZEOF_ACC_INT64E_T)
|
||||||
|
# define SIZEOF_ACC_INT64E_T ACC_SIZEOF_ACC_INT64E_T
|
||||||
|
#endif
|
||||||
#if !defined(SIZEOF_ACC_INT32L_T) && defined(ACC_SIZEOF_ACC_INT32L_T)
|
#if !defined(SIZEOF_ACC_INT32L_T) && defined(ACC_SIZEOF_ACC_INT32L_T)
|
||||||
# define SIZEOF_ACC_INT32L_T ACC_SIZEOF_ACC_INT32L_T
|
# define SIZEOF_ACC_INT32L_T ACC_SIZEOF_ACC_INT32L_T
|
||||||
#endif
|
#endif
|
||||||
@@ -3234,7 +3319,9 @@ typedef unsigned short wchar_t;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef NULL
|
#ifndef NULL
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus) && defined(__GNUC__) && (__GNUC__ >= 4)
|
||||||
|
#define NULL __null
|
||||||
|
#elif defined(__cplusplus)
|
||||||
#define NULL 0
|
#define NULL 0
|
||||||
#else
|
#else
|
||||||
#define NULL ((void*)0)
|
#define NULL ((void*)0)
|
||||||
@@ -3731,8 +3818,10 @@ ACCLIB_EXTERN(int, acc_mkdir) (const char*, unsigned);
|
|||||||
ACCLIB_EXTERN(int, acc_rmdir) (const char*);
|
ACCLIB_EXTERN(int, acc_rmdir) (const char*);
|
||||||
ACCLIB_EXTERN(int, acc_response) (int*, char***);
|
ACCLIB_EXTERN(int, acc_response) (int*, char***);
|
||||||
ACCLIB_EXTERN(int, acc_set_binmode) (int, int);
|
ACCLIB_EXTERN(int, acc_set_binmode) (int, int);
|
||||||
ACCLIB_EXTERN(acc_int32l_t, acc_muldiv32) (acc_int32l_t, acc_int32l_t, acc_int32l_t);
|
#if defined(acc_int32e_t)
|
||||||
ACCLIB_EXTERN(acc_uint32l_t, acc_umuldiv32) (acc_uint32l_t, acc_uint32l_t, acc_uint32l_t);
|
ACCLIB_EXTERN(acc_int32e_t, acc_muldiv32s) (acc_int32e_t, acc_int32e_t, acc_int32e_t);
|
||||||
|
ACCLIB_EXTERN(acc_uint32e_t, acc_muldiv32u) (acc_uint32e_t, acc_uint32e_t, acc_uint32e_t);
|
||||||
|
#endif
|
||||||
ACCLIB_EXTERN(void, acc_wildargv) (int*, char***);
|
ACCLIB_EXTERN(void, acc_wildargv) (int*, char***);
|
||||||
ACCLIB_EXTERN_NOINLINE(void, acc_debug_break) (void);
|
ACCLIB_EXTERN_NOINLINE(void, acc_debug_break) (void);
|
||||||
ACCLIB_EXTERN_NOINLINE(void, acc_debug_nop) (void);
|
ACCLIB_EXTERN_NOINLINE(void, acc_debug_nop) (void);
|
||||||
@@ -4332,7 +4421,21 @@ ACCLIB_EXTERN(int, acc_spawnve) (int mode, const char* fn, const char* const * a
|
|||||||
ACCCHK_ASSERT(((( (acc_int32f_t)1 << 30) + 1) >> 30) == 1)
|
ACCCHK_ASSERT(((( (acc_int32f_t)1 << 30) + 1) >> 30) == 1)
|
||||||
ACCCHK_ASSERT_IS_UNSIGNED_T(acc_uint32f_t)
|
ACCCHK_ASSERT_IS_UNSIGNED_T(acc_uint32f_t)
|
||||||
ACCCHK_ASSERT(((( (acc_uint32f_t)1 << 31) + 1) >> 31) == 1)
|
ACCCHK_ASSERT(((( (acc_uint32f_t)1 << 31) + 1) >> 31) == 1)
|
||||||
|
#if defined(acc_int64e_t)
|
||||||
|
ACCCHK_ASSERT(sizeof(acc_int64e_t) == 8)
|
||||||
|
ACCCHK_ASSERT(sizeof(acc_int64e_t) == SIZEOF_ACC_INT64E_T)
|
||||||
|
ACCCHK_ASSERT(sizeof(acc_uint64e_t) == 8)
|
||||||
|
ACCCHK_ASSERT(sizeof(acc_int64e_t) == sizeof(acc_uint64e_t))
|
||||||
|
ACCCHK_ASSERT_IS_SIGNED_T(acc_int64e_t)
|
||||||
|
#if (ACC_CC_BORLANDC && (__BORLANDC__ < 0x0530))
|
||||||
|
#else
|
||||||
|
ACCCHK_ASSERT_IS_UNSIGNED_T(acc_uint64e_t)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#if defined(acc_int64l_t)
|
#if defined(acc_int64l_t)
|
||||||
|
#if defined(acc_int64e_t)
|
||||||
|
ACCCHK_ASSERT(sizeof(acc_int64l_t) >= sizeof(acc_int64e_t))
|
||||||
|
#endif
|
||||||
ACCCHK_ASSERT(sizeof(acc_int64l_t) >= 8)
|
ACCCHK_ASSERT(sizeof(acc_int64l_t) >= 8)
|
||||||
ACCCHK_ASSERT(sizeof(acc_int64l_t) == SIZEOF_ACC_INT64L_T)
|
ACCCHK_ASSERT(sizeof(acc_int64l_t) == SIZEOF_ACC_INT64L_T)
|
||||||
ACCCHK_ASSERT(sizeof(acc_uint64l_t) >= 8)
|
ACCCHK_ASSERT(sizeof(acc_uint64l_t) >= 8)
|
||||||
@@ -6191,20 +6294,34 @@ ACCLIB_PUBLIC(int, acc_rmdir) (const char* name)
|
|||||||
return rmdir(name);
|
return rmdir(name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
ACCLIB_PUBLIC(acc_int32l_t, acc_muldiv32) (acc_int32l_t a, acc_int32l_t b, acc_int32l_t x)
|
#if defined(acc_int32e_t)
|
||||||
|
ACCLIB_PUBLIC(acc_int32e_t, acc_muldiv32s) (acc_int32e_t a, acc_int32e_t b, acc_int32e_t x)
|
||||||
{
|
{
|
||||||
acc_int32l_t r = 0;
|
acc_int32e_t r = 0;
|
||||||
if (x == 0) return x;
|
if __acc_likely(x != 0)
|
||||||
|
{
|
||||||
|
#if defined(acc_int64l_t)
|
||||||
|
r = (acc_int32e_t) (((acc_int64l_t) a * b) / x);
|
||||||
|
#else
|
||||||
ACC_UNUSED(a); ACC_UNUSED(b);
|
ACC_UNUSED(a); ACC_UNUSED(b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
ACCLIB_PUBLIC(acc_uint32l_t, acc_umuldiv32) (acc_uint32l_t a, acc_uint32l_t b, acc_uint32l_t x)
|
ACCLIB_PUBLIC(acc_uint32e_t, acc_muldiv32u) (acc_uint32e_t a, acc_uint32e_t b, acc_uint32e_t x)
|
||||||
{
|
{
|
||||||
acc_uint32l_t r = 0;
|
acc_uint32e_t r = 0;
|
||||||
if (x == 0) return x;
|
if __acc_likely(x != 0)
|
||||||
|
{
|
||||||
|
#if defined(acc_int64l_t)
|
||||||
|
r = (acc_uint32e_t) (((acc_uint64l_t) a * b) / x);
|
||||||
|
#else
|
||||||
ACC_UNUSED(a); ACC_UNUSED(b);
|
ACC_UNUSED(a); ACC_UNUSED(b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#if (ACC_OS_WIN32 && ACC_CC_PELLESC && (__POCC__ >= 290))
|
#if (ACC_OS_WIN32 && ACC_CC_PELLESC && (__POCC__ >= 290))
|
||||||
# pragma warn(push)
|
# pragma warn(push)
|
||||||
# pragma warn(disable:2007)
|
# pragma warn(disable:2007)
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+18
-12
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -50,8 +50,10 @@ struct options_t {
|
|||||||
int level; // compression level 1..10
|
int level; // compression level 1..10
|
||||||
int filter; // preferred filter from Packer::getFilters()
|
int filter; // preferred filter from Packer::getFilters()
|
||||||
bool all_methods; // try all available compression methods ?
|
bool all_methods; // try all available compression methods ?
|
||||||
|
bool all_methods_use_lzma;
|
||||||
bool all_filters; // try all available filters ?
|
bool all_filters; // try all available filters ?
|
||||||
bool no_filter; // force no filter
|
bool no_filter; // force no filter
|
||||||
|
bool exact; // user requires byte-identical decompression
|
||||||
|
|
||||||
// other options
|
// other options
|
||||||
int backup;
|
int backup;
|
||||||
@@ -69,6 +71,7 @@ struct options_t {
|
|||||||
// debug options
|
// debug options
|
||||||
struct {
|
struct {
|
||||||
int debug_level;
|
int debug_level;
|
||||||
|
bool disable_random_id; // for Packer::getRandomId()
|
||||||
const char *dump_stub_loader;
|
const char *dump_stub_loader;
|
||||||
char fake_stub_version[4+1]; // for internal debugging
|
char fake_stub_version[4+1]; // for internal debugging
|
||||||
char fake_stub_year[4+1]; // for internal debugging
|
char fake_stub_year[4+1]; // for internal debugging
|
||||||
@@ -82,16 +85,14 @@ struct options_t {
|
|||||||
};
|
};
|
||||||
int overlay;
|
int overlay;
|
||||||
|
|
||||||
// compression runtime parameters - see struct ucl_compress_config_t
|
// compression runtime parameters - see struct XXX_compress_config_t
|
||||||
struct {
|
struct crp_t {
|
||||||
upx_uint max_offset;
|
lzma_compress_config_t crp_lzma;
|
||||||
upx_uint max_match;
|
ucl_compress_config_t crp_ucl;
|
||||||
int s_level;
|
zlib_compress_config_t crp_zlib;
|
||||||
int h_level;
|
void reset() { crp_lzma.reset(); crp_ucl.reset(); crp_zlib.reset(); }
|
||||||
int p_level;
|
};
|
||||||
int c_flags;
|
crp_t crp;
|
||||||
upx_uint m_size;
|
|
||||||
} crp;
|
|
||||||
|
|
||||||
// CPU
|
// CPU
|
||||||
enum {
|
enum {
|
||||||
@@ -120,6 +121,7 @@ struct options_t {
|
|||||||
bool boot_only;
|
bool boot_only;
|
||||||
bool no_align;
|
bool no_align;
|
||||||
bool do_8bit;
|
bool do_8bit;
|
||||||
|
bool do_8mb;
|
||||||
} ps1_exe;
|
} ps1_exe;
|
||||||
struct {
|
struct {
|
||||||
unsigned blocksize;
|
unsigned blocksize;
|
||||||
@@ -127,6 +129,7 @@ struct options_t {
|
|||||||
bool is_ptinterp; // is PT_INTERP, so don't adjust auxv_t
|
bool is_ptinterp; // is PT_INTERP, so don't adjust auxv_t
|
||||||
bool use_ptinterp; // use PT_INTERP /opt/upx/run
|
bool use_ptinterp; // use PT_INTERP /opt/upx/run
|
||||||
bool make_ptinterp; // make PT_INTERP [ignore current file!]
|
bool make_ptinterp; // make PT_INTERP [ignore current file!]
|
||||||
|
unsigned char osabi0; // replacement if 0==.e_ident[EI_OSABI]
|
||||||
enum { SCRIPT_MAX = 32 };
|
enum { SCRIPT_MAX = 32 };
|
||||||
const char *script_name;
|
const char *script_name;
|
||||||
} o_unix;
|
} o_unix;
|
||||||
@@ -139,7 +142,10 @@ struct options_t {
|
|||||||
int compress_resources;
|
int compress_resources;
|
||||||
signed char compress_rt[25]; // 25 == RT_LAST
|
signed char compress_rt[25]; // 25 == RT_LAST
|
||||||
int strip_relocs;
|
int strip_relocs;
|
||||||
|
const char *keep_resource;
|
||||||
} win32_pe;
|
} win32_pe;
|
||||||
|
|
||||||
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct options_t *opt;
|
extern struct options_t *opt;
|
||||||
|
|||||||
+162
-1470
File diff suppressed because it is too large
Load Diff
+11
-192
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -29,219 +29,38 @@
|
|||||||
#ifndef __UPX_P_ARMPE_H
|
#ifndef __UPX_P_ARMPE_H
|
||||||
#define __UPX_P_ARMPE_H
|
#define __UPX_P_ARMPE_H
|
||||||
|
|
||||||
|
|
||||||
class PackArmPe_Interval;
|
|
||||||
class PackArmPe_Reloc;
|
|
||||||
class PackArmPe_Resource;
|
|
||||||
class PackArmPe_Export;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// arm/pe
|
// arm/pe
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PackArmPe : public Packer
|
class PackArmPe : public PeFile
|
||||||
{
|
{
|
||||||
typedef Packer super;
|
typedef PeFile super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PackArmPe(InputFile *f);
|
PackArmPe(InputFile *f);
|
||||||
~PackArmPe();
|
virtual ~PackArmPe();
|
||||||
virtual int getVersion() const { return 13; }
|
|
||||||
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
|
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
|
||||||
virtual const char *getName() const { return "arm/pe"; }
|
virtual const char *getName() const { return "arm/pe"; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
virtual void pack(OutputFile *fo);
|
virtual void pack(OutputFile *fo);
|
||||||
virtual void unpack(OutputFile *fo);
|
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual int canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
// unpacker capabilities
|
|
||||||
virtual bool canUnpackVersion(int version) const
|
|
||||||
{ return version == 13; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int readFileHeader();
|
virtual void buildLoader(const Filter *ft);
|
||||||
virtual bool testUnpackVersion(int version) const;
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual unsigned processImports();
|
||||||
|
virtual void processImports(unsigned, unsigned);
|
||||||
|
virtual void rebuildImports(upx_byte *&);
|
||||||
|
|
||||||
unsigned pe_offset;
|
virtual void processTls(Interval *);
|
||||||
|
|
||||||
unsigned processImports();
|
|
||||||
void processImports(unsigned);
|
|
||||||
void rebuildImports(upx_byte *&);
|
|
||||||
upx_byte *oimport;
|
|
||||||
unsigned soimport;
|
|
||||||
upx_byte *oimpdlls;
|
|
||||||
unsigned soimpdlls;
|
|
||||||
|
|
||||||
void processRelocs();
|
|
||||||
void processRelocs(PackArmPe_Reloc *);
|
|
||||||
void rebuildRelocs(upx_byte *&);
|
|
||||||
upx_byte *orelocs;
|
|
||||||
unsigned sorelocs;
|
|
||||||
upx_byte *oxrelocs;
|
|
||||||
unsigned soxrelocs;
|
|
||||||
|
|
||||||
void processExports(PackArmPe_Export *);
|
|
||||||
void processExports(PackArmPe_Export *,unsigned);
|
|
||||||
void rebuildExports();
|
|
||||||
upx_byte *oexport;
|
|
||||||
unsigned soexport;
|
|
||||||
|
|
||||||
void processResources(PackArmPe_Resource *);
|
|
||||||
void processResources(PackArmPe_Resource *, unsigned);
|
|
||||||
void rebuildResources(upx_byte *&);
|
|
||||||
upx_byte *oresources;
|
|
||||||
unsigned soresources;
|
|
||||||
|
|
||||||
void processTls(PackArmPe_Interval *);
|
|
||||||
void processTls(PackArmPe_Reloc *,const PackArmPe_Interval *,unsigned);
|
|
||||||
void rebuildTls();
|
|
||||||
upx_byte *otls;
|
|
||||||
unsigned sotls;
|
|
||||||
|
|
||||||
unsigned stripDebug(unsigned);
|
|
||||||
|
|
||||||
unsigned icondir_offset;
|
|
||||||
int icondir_count;
|
|
||||||
|
|
||||||
bool importbyordinal;
|
|
||||||
bool kernel32ordinal;
|
|
||||||
unsigned tlsindex;
|
|
||||||
unsigned rvamin;
|
|
||||||
unsigned cimports; // rva of preprocessed imports
|
|
||||||
unsigned crelocs; // rva of preprocessed fixups
|
|
||||||
int big_relocs;
|
|
||||||
|
|
||||||
bool use_thumb_stub;
|
bool use_thumb_stub;
|
||||||
|
|
||||||
struct pe_header_t
|
|
||||||
{
|
|
||||||
// 0x0
|
|
||||||
char _[4]; // pemagic
|
|
||||||
LE16 cpu;
|
|
||||||
LE16 objects;
|
|
||||||
char __[12]; // timestamp + reserved
|
|
||||||
LE16 opthdrsize;
|
|
||||||
LE16 flags;
|
|
||||||
// optional header
|
|
||||||
char ___[4]; // coffmagic + linkerversion
|
|
||||||
LE32 codesize;
|
|
||||||
// 0x20
|
|
||||||
LE32 datasize;
|
|
||||||
LE32 bsssize;
|
|
||||||
LE32 entry;
|
|
||||||
LE32 codebase;
|
|
||||||
// 0x30
|
|
||||||
LE32 database;
|
|
||||||
// nt specific fields
|
|
||||||
LE32 imagebase;
|
|
||||||
LE32 objectalign;
|
|
||||||
LE32 filealign; // should set to 0x200 ?
|
|
||||||
// 0x40
|
|
||||||
char ____[16]; // versions
|
|
||||||
// 0x50
|
|
||||||
LE32 imagesize;
|
|
||||||
LE32 headersize;
|
|
||||||
LE32 chksum; // should set to 0
|
|
||||||
LE16 subsystem;
|
|
||||||
LE16 dllflags;
|
|
||||||
// 0x60
|
|
||||||
char _____[20]; // stack + heap sizes
|
|
||||||
// 0x74
|
|
||||||
LE32 ddirsentries; // usually 16
|
|
||||||
|
|
||||||
struct ddirs_t
|
|
||||||
{
|
|
||||||
LE32 vaddr;
|
|
||||||
LE32 size;
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct ddirs_t ddirs[16];
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct pe_section_t
|
|
||||||
{
|
|
||||||
char name[8];
|
|
||||||
LE32 vsize;
|
|
||||||
LE32 vaddr;
|
|
||||||
LE32 size;
|
|
||||||
LE32 rawdataptr;
|
|
||||||
char _[12];
|
|
||||||
LE32 flags;
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
pe_header_t ih, oh;
|
|
||||||
pe_section_t *isection;
|
|
||||||
|
|
||||||
static unsigned virta2objnum (unsigned, pe_section_t *, unsigned);
|
|
||||||
unsigned tryremove (unsigned, unsigned);
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PEDIR_EXPORT = 0,
|
|
||||||
PEDIR_IMPORT = 1,
|
|
||||||
PEDIR_RESOURCE = 2,
|
|
||||||
PEDIR_EXCEPTION = 3, // Exception table
|
|
||||||
PEDIR_SEC = 4, // Certificate table (file pointer)
|
|
||||||
PEDIR_RELOC = 5,
|
|
||||||
PEDIR_DEBUG = 6,
|
|
||||||
PEDIR_COPYRIGHT = 7, // Architecture-specific data
|
|
||||||
PEDIR_GLOBALPTR = 8, // Global pointer
|
|
||||||
PEDIR_TLS = 9,
|
|
||||||
PEDIR_LOADCONF = 10, // Load Config Table
|
|
||||||
PEDIR_BOUNDIM = 11,
|
|
||||||
PEDIR_IAT = 12,
|
|
||||||
PEDIR_DELAYIMP = 13, // Delay Import Descriptor
|
|
||||||
PEDIR_COMRT = 14 // Com+ Runtime Header
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PEFL_CODE = 0x20,
|
|
||||||
PEFL_DATA = 0x40,
|
|
||||||
PEFL_BSS = 0x80,
|
|
||||||
PEFL_INFO = 0x200,
|
|
||||||
PEFL_EXTRELS = 0x01000000, // extended relocations
|
|
||||||
PEFL_DISCARD = 0x02000000,
|
|
||||||
PEFL_NOCACHE = 0x04000000,
|
|
||||||
PEFL_NOPAGE = 0x08000000,
|
|
||||||
PEFL_SHARED = 0x10000000,
|
|
||||||
PEFL_EXEC = 0x20000000,
|
|
||||||
PEFL_READ = 0x40000000,
|
|
||||||
PEFL_WRITE = 0x80000000
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
RELOCS_STRIPPED = 0x0001,
|
|
||||||
EXECUTABLE = 0x0002,
|
|
||||||
LNUM_STRIPPED = 0x0004,
|
|
||||||
LSYMS_STRIPPED = 0x0008,
|
|
||||||
AGGRESSIVE_TRIM = 0x0010,
|
|
||||||
TWO_GIGS_AWARE = 0x0020,
|
|
||||||
FLITTLE_ENDIAN = 0x0080,
|
|
||||||
BITS_32_MACHINE = 0x0100,
|
|
||||||
DEBUG_STRIPPED = 0x0200,
|
|
||||||
REMOVABLE_SWAP = 0x0400,
|
|
||||||
SYSTEM_PROGRAM = 0x1000,
|
|
||||||
DLL_FLAG = 0x2000,
|
|
||||||
FBIG_ENDIAN = 0x8000
|
|
||||||
};
|
|
||||||
|
|
||||||
// predefined resource types
|
|
||||||
enum {
|
|
||||||
RT_CURSOR = 1, RT_BITMAP, RT_ICON, RT_MENU, RT_DIALOG, RT_STRING,
|
|
||||||
RT_FONTDIR, RT_FONT, RT_ACCELERATOR, RT_RCDATA, RT_MESSAGETABLE,
|
|
||||||
RT_GROUP_CURSOR, RT_GROUP_ICON = 14, RT_VERSION = 16, RT_DLGINCLUDE,
|
|
||||||
RT_PLUGPLAY = 19, RT_VXD, RT_ANICURSOR, RT_ANIICON, RT_HTML,
|
|
||||||
RT_MANIFEST, RT_LAST
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+26
-24
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -31,9 +31,10 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_com.h"
|
#include "p_com.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_com.h"
|
#include "stub/i086-dos16.com.h"
|
||||||
|
|
||||||
//#define TESTING
|
//#define TESTING
|
||||||
|
|
||||||
@@ -98,10 +99,9 @@ void PackCom::patchLoader(OutputFile *fo,
|
|||||||
upx_byte *loader, int lsize,
|
upx_byte *loader, int lsize,
|
||||||
unsigned calls)
|
unsigned calls)
|
||||||
{
|
{
|
||||||
const int filter_id = ph.filter;
|
|
||||||
const int e_len = getLoaderSectionStart("COMCUTPO");
|
const int e_len = getLoaderSectionStart("COMCUTPO");
|
||||||
const int d_len = lsize - e_len;
|
const int d_len = lsize - e_len;
|
||||||
assert(e_len > 0 && e_len < 256);
|
assert(e_len > 0 && e_len < 128);
|
||||||
assert(d_len > 0 && d_len < 256);
|
assert(d_len > 0 && d_len < 256);
|
||||||
|
|
||||||
const unsigned upper_end = ph.u_len + ph.overlap_overhead + d_len + 0x100;
|
const unsigned upper_end = ph.u_len + ph.overlap_overhead + d_len + 0x100;
|
||||||
@@ -111,22 +111,19 @@ void PackCom::patchLoader(OutputFile *fo,
|
|||||||
if (upper_end + stacksize > 0xfffe)
|
if (upper_end + stacksize > 0xfffe)
|
||||||
throwCantPack("file is too big for dos/com");
|
throwCantPack("file is too big for dos/com");
|
||||||
|
|
||||||
if (filter_id)
|
linker->defineSymbol("calltrick_calls", calls);
|
||||||
{
|
linker->defineSymbol("sp_limit", upper_end + stacksize);
|
||||||
assert(calls > 0);
|
linker->defineSymbol("bytes_to_copy", ph.c_len + lsize);
|
||||||
patch_le16(loader,lsize,"CT",calls);
|
linker->defineSymbol("copy_source", ph.c_len + lsize + 0x100);
|
||||||
}
|
linker->defineSymbol("copy_destination", upper_end);
|
||||||
|
linker->defineSymbol("neg_e_len", 0 - e_len);
|
||||||
|
linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead);
|
||||||
|
|
||||||
|
relocateLoader();
|
||||||
|
loader = getLoader();
|
||||||
|
|
||||||
|
// some day we could use the relocation stuff for patchPackHeader too
|
||||||
patchPackHeader(loader,e_len);
|
patchPackHeader(loader,e_len);
|
||||||
|
|
||||||
// NOTE: Depends on: decompr_start == cutpoint+1 !!!
|
|
||||||
patch_le16(loader,e_len,"JM",upper_end - 0xff - d_len - getLoaderSection("UPX1HEAD"));
|
|
||||||
loader[getLoaderSectionStart("COMSUBSI") - 1] = (upx_byte) -e_len;
|
|
||||||
patch_le16(loader,e_len,"DI",upper_end);
|
|
||||||
patch_le16(loader,e_len,"SI",ph.c_len + lsize + 0x100);
|
|
||||||
patch_le16(loader,e_len,"CX",ph.c_len + lsize);
|
|
||||||
patch_le16(loader,e_len,"SP",upper_end + stacksize);
|
|
||||||
|
|
||||||
// write loader + compressed file
|
// write loader + compressed file
|
||||||
fo->write(loader,e_len); // entry
|
fo->write(loader,e_len); // entry
|
||||||
fo->write(obuf,ph.c_len);
|
fo->write(obuf,ph.c_len);
|
||||||
@@ -139,10 +136,10 @@ void PackCom::patchLoader(OutputFile *fo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackCom::buildLoader(const Filter *ft)
|
void PackCom::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
initLoader(stub_i086_dos16_com, sizeof(stub_i086_dos16_com));
|
||||||
addLoader("COMMAIN1,COMSUBSI",
|
addLoader("COMMAIN1",
|
||||||
ph.first_offset_found == 1 ? "COMSBBBP" : "",
|
ph.first_offset_found == 1 ? "COMSBBBP" : "",
|
||||||
"COMPSHDI",
|
"COMPSHDI",
|
||||||
ft->id ? "COMCALLT" : "",
|
ft->id ? "COMCALLT" : "",
|
||||||
@@ -150,7 +147,7 @@ int PackCom::buildLoader(const Filter *ft)
|
|||||||
ft->id ? "NRVDDONE" : "NRVDRETU",
|
ft->id ? "NRVDDONE" : "NRVDRETU",
|
||||||
"NRVDECO1",
|
"NRVDECO1",
|
||||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
||||||
"NRVDECO2,NRV2B169",
|
"NRVDECO2",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
@@ -158,7 +155,6 @@ int PackCom::buildLoader(const Filter *ft)
|
|||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
addFilter16(ft->id);
|
addFilter16(ft->id);
|
||||||
}
|
}
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -270,6 +266,12 @@ void PackCom::unpack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackCom::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et
|
vi:ts=4:et
|
||||||
*/
|
*/
|
||||||
|
|||||||
+6
-5
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ class PackCom : public Packer
|
|||||||
{
|
{
|
||||||
typedef Packer super;
|
typedef Packer super;
|
||||||
public:
|
public:
|
||||||
PackCom(InputFile *f) : super(f) { }
|
PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_DOS_COM; }
|
virtual int getFormat() const { return UPX_F_DOS_COM; }
|
||||||
virtual const char *getName() const { return "dos/com"; }
|
virtual const char *getName() const { return "dos/com"; }
|
||||||
@@ -53,9 +53,10 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual unsigned getCallTrickOffset() const { return 0x100; }
|
virtual unsigned getCallTrickOffset() const { return 0x100; }
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
|
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
|
||||||
virtual void addFilter16(int filter_id);
|
virtual void addFilter16(int filter_id);
|
||||||
};
|
};
|
||||||
|
|||||||
+73
-29
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -31,11 +31,12 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_djgpp2.h"
|
#include "p_djgpp2.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_djgpp2.h"
|
#include "stub/i386-dos32.djgpp2.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/stubify.h"
|
#include "stub/i386-dos32.djgpp2-stubify.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -45,13 +46,14 @@ static const
|
|||||||
PackDjgpp2::PackDjgpp2(InputFile *f) :
|
PackDjgpp2::PackDjgpp2(InputFile *f) :
|
||||||
super(f), coff_offset(0)
|
super(f), coff_offset(0)
|
||||||
{
|
{
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40);
|
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40);
|
||||||
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8);
|
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8);
|
||||||
COMPILE_TIME_ASSERT(sizeof(stubify_stub) == 2048);
|
|
||||||
COMPILE_TIME_ASSERT_ALIGNOF(external_scnhdr_t, char)
|
COMPILE_TIME_ASSERT_ALIGNOF(external_scnhdr_t, char)
|
||||||
COMPILE_TIME_ASSERT_ALIGNOF(coff_header_t, char)
|
COMPILE_TIME_ASSERT_ALIGNOF(coff_header_t, char)
|
||||||
COMPILE_TIME_ASSERT(STUBIFY_STUB_ADLER32 == 0xbf689ba8);
|
COMPILE_TIME_ASSERT(sizeof(stub_i386_dos32_djgpp2_stubify) == 2048);
|
||||||
COMPILE_TIME_ASSERT(STUBIFY_STUB_CRC32 == 0x2ae982b2);
|
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_ADLER32 == 0xbf689ba8)
|
||||||
|
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_CRC32 == 0x2ae982b2)
|
||||||
//printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
|
//printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
|
||||||
//assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
//assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
||||||
}
|
}
|
||||||
@@ -82,14 +84,22 @@ unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackDjgpp2::buildLoader(const Filter *ft)
|
Linker* PackDjgpp2::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PackDjgpp2::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
|
||||||
addLoader("IDENTSTR,DJ2MAIN1",
|
addLoader("IDENTSTR,DJ2MAIN1",
|
||||||
ft->id ? "DJCALLT1" : "",
|
ft->id ? "DJCALLT1" : "",
|
||||||
"DJ2MAIN2",
|
"DJ2MAIN2",
|
||||||
getDecompressor(),
|
ph.method == M_LZMA ? "LZMA_INIT_STACK" : "",
|
||||||
|
getDecompressorSections(),
|
||||||
|
ph.method == M_LZMA ? "LZMA_DONE_STACK" : "",
|
||||||
"DJ2BSS00",
|
"DJ2BSS00",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
@@ -99,8 +109,7 @@ int PackDjgpp2::buildLoader(const Filter *ft)
|
|||||||
addLoader("DJCALLT2", NULL);
|
addLoader("DJCALLT2", NULL);
|
||||||
addFilter32(ft->id);
|
addFilter32(ft->id);
|
||||||
}
|
}
|
||||||
addLoader("DJRETURN,+40DXXXX,UPX1HEAD", NULL);
|
addLoader("DJRETURN,+40C,UPX1HEAD", NULL);
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -120,8 +129,8 @@ void PackDjgpp2::handleStub(OutputFile *fo)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// "stubify" stub
|
// "stubify" stub
|
||||||
info("Adding stub: %ld bytes", (long)sizeof(stubify_stub));
|
info("Adding stub: %ld bytes", (long)sizeof(stub_i386_dos32_djgpp2_stubify));
|
||||||
fo->write(stubify_stub, sizeof(stubify_stub));
|
fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,6 +234,29 @@ void PackDjgpp2::stripDebug()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||||
|
{
|
||||||
|
if (ft->id == 0)
|
||||||
|
return false;
|
||||||
|
assert(ft->calls > 0);
|
||||||
|
|
||||||
|
linker->defineSymbol("filter_cto", ft->cto);
|
||||||
|
linker->defineSymbol("filter_length",
|
||||||
|
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||||
|
ft->lastcall - ft->calls * 4);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (0x80==(ft->id & 0xF0)) {
|
||||||
|
int const mru = ph.n_mru ? 1+ ph.n_mru : 0;
|
||||||
|
if (mru && mru!=256) {
|
||||||
|
unsigned const is_pwr2 = (0==((mru -1) & mru));
|
||||||
|
//patch_le32(0x80 + (char *)loader, lsize - 0x80, "NMRU", mru - is_pwr2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -290,33 +322,35 @@ void PackDjgpp2::pack(OutputFile *fo)
|
|||||||
ft.buf_len = usize - data->size;
|
ft.buf_len = usize - data->size;
|
||||||
ft.addvalue = text->vaddr - hdrsize;
|
ft.addvalue = text->vaddr - hdrsize;
|
||||||
// compress
|
// compress
|
||||||
compressWithFilters(&ft, 512);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
// limit stack size needed for runtime decompression
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||||
|
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||||
|
|
||||||
// patch coff header #2
|
// patch coff header #2
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
|
assert(lsize % 4 == 0);
|
||||||
text->size = lsize; // new size of .text
|
text->size = lsize; // new size of .text
|
||||||
data->size = ph.c_len; // new size of .data
|
data->size = ph.c_len; // new size of .data
|
||||||
|
|
||||||
if (bss->size < ph.overlap_overhead) // give it a .bss
|
unsigned stack = 1024 + ph.overlap_overhead + getDecompressorWrkmemSize();
|
||||||
bss->size = ph.overlap_overhead;
|
stack = ALIGN_UP(stack, 16);
|
||||||
|
if (bss->size < stack) // give it a .bss
|
||||||
|
bss->size = stack;
|
||||||
|
|
||||||
text->scnptr = sizeof(coff_hdr);
|
text->scnptr = sizeof(coff_hdr);
|
||||||
data->scnptr = text->scnptr + text->size;
|
data->scnptr = text->scnptr + text->size;
|
||||||
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + ph.overlap_overhead - 0x200;
|
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + ph.overlap_overhead - 0x200;
|
||||||
coff_hdr.f_nscns = 3;
|
coff_hdr.f_nscns = 3;
|
||||||
|
|
||||||
// prepare loader
|
linker->defineSymbol("original_entry", coff_hdr.a_entry);
|
||||||
MemBuffer loader(lsize);
|
linker->defineSymbol("length_of_bss", ph.overlap_overhead / 4);
|
||||||
memcpy(loader, getLoader(), lsize);
|
defineDecompressorSymbols();
|
||||||
|
|
||||||
// patch loader
|
|
||||||
patchPackHeader(loader, lsize);
|
|
||||||
patch_le32(loader, lsize, "ENTR", coff_hdr.a_entry);
|
|
||||||
patchFilter32(loader, lsize, &ft);
|
|
||||||
patch_le32(loader, lsize, "BSSL", ph.overlap_overhead / 4);
|
|
||||||
assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
|
assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
|
||||||
patch_le32(loader, lsize, "OUTP", text->vaddr - hdrsize);
|
linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size);
|
||||||
patch_le32(loader, lsize, "INPP", data->vaddr);
|
linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize);
|
||||||
|
linker->defineSymbol("start_of_compressed", data->vaddr);
|
||||||
|
defineFilterSymbols(linker, &ft);
|
||||||
|
|
||||||
// we should not overwrite our decompressor during unpacking
|
// we should not overwrite our decompressor during unpacking
|
||||||
// the original coff header (which is put just before the
|
// the original coff header (which is put just before the
|
||||||
@@ -333,9 +367,19 @@ void PackDjgpp2::pack(OutputFile *fo)
|
|||||||
memcpy(obuf+data->size, "UPX", 3);
|
memcpy(obuf+data->size, "UPX", 3);
|
||||||
data->size = ALIGN_UP(data->size, 4);
|
data->size = ALIGN_UP(data->size, 4);
|
||||||
|
|
||||||
|
linker->defineSymbol("DJ2MAIN1", coff_hdr.a_entry);
|
||||||
|
relocateLoader();
|
||||||
|
|
||||||
|
// prepare loader
|
||||||
|
MemBuffer loader(lsize);
|
||||||
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
patchPackHeader(loader, lsize);
|
||||||
|
|
||||||
// write coff header, loader and compressed file
|
// write coff header, loader and compressed file
|
||||||
fo->write(&coff_hdr, sizeof(coff_hdr));
|
fo->write(&coff_hdr, sizeof(coff_hdr));
|
||||||
fo->write(loader, lsize);
|
fo->write(loader, lsize);
|
||||||
|
if (opt->debug.dump_stub_loader)
|
||||||
|
OutputFile::dump(opt->debug.dump_stub_loader, loader, lsize);
|
||||||
fo->write(obuf, data->size);
|
fo->write(obuf, data->size);
|
||||||
#if 0
|
#if 0
|
||||||
printf("%-13s: coff hdr : %8ld bytes\n", getName(), (long) sizeof(coff_hdr));
|
printf("%-13s: coff hdr : %8ld bytes\n", getName(), (long) sizeof(coff_hdr));
|
||||||
@@ -367,7 +411,7 @@ int PackDjgpp2::canUnpack()
|
|||||||
if (is_dlm(fi, coff_offset))
|
if (is_dlm(fi, coff_offset))
|
||||||
throwCantUnpack("can't handle DLM");
|
throwCantUnpack("can't handle DLM");
|
||||||
fi->seek(coff_offset, SEEK_SET);
|
fi->seek(coff_offset, SEEK_SET);
|
||||||
return readPackHeader(1024) ? 1 : -1;
|
return readPackHeader(4096) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -59,7 +59,8 @@ protected:
|
|||||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
||||||
unsigned range = 0,
|
unsigned range = 0,
|
||||||
unsigned upper_limit = ~0u) const;
|
unsigned upper_limit = ~0u) const;
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
long coff_offset;
|
long coff_offset;
|
||||||
|
|
||||||
|
|||||||
+82
-44
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
// Some ELF type definitinons
|
// Some ELF type definitinons
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
namespace TT_Elf {
|
namespace N_Elf {
|
||||||
|
|
||||||
// The ELF file header. This appears at the start of every ELF file.
|
// The ELF file header. This appears at the start of every ELF file.
|
||||||
template <class Word, class Addr, class Off, class Half>
|
template <class Word, class Addr, class Off, class Half>
|
||||||
@@ -71,7 +71,12 @@ struct Ehdr
|
|||||||
ELFDATA2MSB = 2 /* 2's complement, big endian */
|
ELFDATA2MSB = 2 /* 2's complement, big endian */
|
||||||
};
|
};
|
||||||
enum { // e_ident[EI_OSABI]
|
enum { // e_ident[EI_OSABI]
|
||||||
ELFOSABI_LINUX = 3
|
ELFOSABI_NONE = 0,
|
||||||
|
ELFOSABI_NETBSD = 2,
|
||||||
|
ELFOSABI_LINUX = 3,
|
||||||
|
ELFOSABI_FREEBSD = 9,
|
||||||
|
ELFOSABI_OPENBSD = 12,
|
||||||
|
ELFOSABI_ARM = 97
|
||||||
};
|
};
|
||||||
enum { // e_type
|
enum { // e_type
|
||||||
ET_NONE = 0, /* No file type */
|
ET_NONE = 0, /* No file type */
|
||||||
@@ -111,10 +116,10 @@ struct Dyn
|
|||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
} // namespace TT_Elf
|
} // namespace N_Elf
|
||||||
|
|
||||||
|
|
||||||
namespace TT_Elf32 {
|
namespace N_Elf32 {
|
||||||
|
|
||||||
// Program segment header.
|
// Program segment header.
|
||||||
template <class Word, class Addr, class Off>
|
template <class Word, class Addr, class Off>
|
||||||
@@ -133,6 +138,7 @@ struct Phdr
|
|||||||
PT_LOAD = 1, /* Loadable program segment */
|
PT_LOAD = 1, /* Loadable program segment */
|
||||||
PT_DYNAMIC = 2, /* Dynamic linking information */
|
PT_DYNAMIC = 2, /* Dynamic linking information */
|
||||||
PT_INTERP = 3, /* Name of program interpreter */
|
PT_INTERP = 3, /* Name of program interpreter */
|
||||||
|
PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */
|
||||||
PT_PHDR = 6, /* Entry for header table itself */
|
PT_PHDR = 6, /* Entry for header table itself */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -192,7 +198,7 @@ struct Shdr
|
|||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
template <class TT16, class TT32, class TT64>
|
template <class TT16, class TT32>
|
||||||
struct Sym
|
struct Sym
|
||||||
{
|
{
|
||||||
TT32 st_name; /* symbol name (index into string table) */
|
TT32 st_name; /* symbol name (index into string table) */
|
||||||
@@ -237,9 +243,10 @@ struct Sym
|
|||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
} // namespace TT_Elf32
|
} // namespace N_Elf32
|
||||||
|
|
||||||
namespace TT_Elf64 {
|
|
||||||
|
namespace N_Elf64 {
|
||||||
|
|
||||||
// Program segment header.
|
// Program segment header.
|
||||||
template <class Word, class Xword, class Addr, class Off>
|
template <class Word, class Xword, class Addr, class Off>
|
||||||
@@ -307,29 +314,58 @@ struct Shdr
|
|||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
} // namespace TT_Elf64
|
} // namespace N_Elf64
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// now for the actual types
|
// now for the actual types
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
typedef TT_Elf ::Ehdr<LE32,LE32,LE32,LE16> Elf_LE32_Ehdr;
|
#define P N_BELE_CTP::HostPolicy
|
||||||
typedef TT_Elf32::Phdr<LE32,LE32,LE32> Elf_LE32_Phdr;
|
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf32_Ehdr;
|
||||||
typedef TT_Elf32::Shdr<LE32,LE32,LE32> Elf_LE32_Shdr;
|
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf32_Phdr;
|
||||||
typedef TT_Elf ::Dyn <LE32,LE32> Elf_LE32_Dyn;
|
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf32_Shdr;
|
||||||
typedef TT_Elf32::Sym <LE16,LE32,void> Elf_LE32_Sym;
|
typedef N_Elf ::Dyn <P::U32,P::U32> Elf32_Dyn;
|
||||||
|
typedef N_Elf32::Sym <P::U16,P::U32> Elf32_Sym;
|
||||||
|
#undef P
|
||||||
|
|
||||||
typedef TT_Elf ::Ehdr<unsigned int,unsigned int,unsigned int,unsigned short> Elf32_Ehdr;
|
#define P N_BELE_CTP::BEPolicy
|
||||||
typedef TT_Elf32::Phdr<unsigned int,unsigned int,unsigned int> Elf32_Phdr;
|
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_BE32_Ehdr;
|
||||||
typedef TT_Elf32::Shdr<unsigned int,unsigned int,unsigned int> Elf32_Shdr;
|
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf_BE32_Phdr;
|
||||||
typedef TT_Elf ::Dyn <unsigned int,unsigned int> Elf32_Dyn;
|
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf_BE32_Shdr;
|
||||||
typedef TT_Elf32::Sym <unsigned short,unsigned int,void> Elf32_Sym;
|
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_BE32_Dyn;
|
||||||
|
typedef N_Elf32::Sym <P::U16,P::U32> Elf_BE32_Sym;
|
||||||
|
#undef P
|
||||||
|
|
||||||
|
#define P N_BELE_CTP::LEPolicy
|
||||||
|
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_LE32_Ehdr;
|
||||||
|
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf_LE32_Phdr;
|
||||||
|
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf_LE32_Shdr;
|
||||||
|
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_LE32_Dyn;
|
||||||
|
typedef N_Elf32::Sym <P::U16,P::U32> Elf_LE32_Sym;
|
||||||
|
#undef P
|
||||||
|
|
||||||
|
#define P N_BELE_CTP::HostPolicy
|
||||||
|
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf64_Ehdr;
|
||||||
|
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf64_Phdr;
|
||||||
|
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf64_Shdr;
|
||||||
|
typedef N_Elf ::Dyn <P::U64,P::U64> Elf64_Dyn;
|
||||||
|
#undef P
|
||||||
|
|
||||||
|
#define P N_BELE_CTP::BEPolicy
|
||||||
|
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_BE64_Ehdr;
|
||||||
|
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Phdr;
|
||||||
|
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Shdr;
|
||||||
|
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_BE64_Dyn;
|
||||||
|
#undef P
|
||||||
|
|
||||||
|
#define P N_BELE_CTP::LEPolicy
|
||||||
|
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_LE64_Ehdr;
|
||||||
|
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Phdr;
|
||||||
|
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Shdr;
|
||||||
|
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_LE64_Dyn;
|
||||||
|
#undef P
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Ehdr) == 52)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Phdr) == 32)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16)
|
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Ehdr) == 52)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Ehdr) == 52)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Phdr) == 32)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Phdr) == 32)
|
||||||
@@ -337,31 +373,33 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Shdr) == 40)
|
|||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Dyn) == 8)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Dyn) == 8)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Sym) == 16)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Sym) == 16)
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Ehdr) == 52)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Phdr) == 32)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Shdr) == 40)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Dyn) == 8)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Sym) == 16)
|
||||||
|
|
||||||
typedef TT_Elf ::Ehdr<LE32,LE64,LE64,LE16> Elf_LE64_Ehdr;
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Ehdr) == 52)
|
||||||
typedef TT_Elf64::Phdr<LE32,LE64,LE64,LE64> Elf_LE64_Phdr;
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Phdr) == 32)
|
||||||
typedef TT_Elf64::Shdr<LE32,LE64,LE64,LE64> Elf_LE64_Shdr;
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40)
|
||||||
typedef TT_Elf ::Dyn <LE64,LE64> Elf_LE64_Dyn;
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16)
|
||||||
typedef TT_Elf ::Ehdr<unsigned int,unsigned long long,
|
|
||||||
unsigned long long,unsigned short> Elf64_Ehdr;
|
|
||||||
typedef TT_Elf64::Phdr<unsigned int,unsigned long long,
|
|
||||||
unsigned long long,unsigned long long> Elf64_Phdr;
|
|
||||||
typedef TT_Elf64::Shdr<unsigned int,unsigned long long,
|
|
||||||
unsigned long long,unsigned long long> Elf64_Shdr;
|
|
||||||
typedef TT_Elf ::Dyn <unsigned long long,unsigned long long> Elf64_Dyn;
|
|
||||||
|
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Ehdr) == 64)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Phdr) == 56)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Shdr) == 64)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Dyn) == 16)
|
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Ehdr) == 64)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Ehdr) == 64)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Phdr) == 56)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Phdr) == 56)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Shdr) == 64)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Shdr) == 64)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Dyn) == 16)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Dyn) == 16)
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Ehdr) == 64)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Phdr) == 56)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Shdr) == 64)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Dyn) == 16)
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Ehdr) == 64)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Phdr) == 56)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Shdr) == 64)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Dyn) == 16)
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|||||||
+9
-9
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -94,13 +94,12 @@ void PackElks8086::readKernel()
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int PackElks8086::buildLoader(const Filter *ft)
|
void PackElks8086::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||||
// FIXME
|
// FIXME
|
||||||
UNUSED(ft);
|
UNUSED(ft);
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -122,10 +121,11 @@ void PackElks8086::pack(OutputFile *fo)
|
|||||||
patchPackHeader(loader, lsize);
|
patchPackHeader(loader, lsize);
|
||||||
#if 0
|
#if 0
|
||||||
// FIXME
|
// FIXME
|
||||||
patchFilter32(loader, lsize, &ft);
|
defineFilterSymbols();
|
||||||
patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
defineDecompressorSymbols();
|
||||||
patch_le32(loader, lsize, "KEIP", kernel_entry);
|
//patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
||||||
patch_le32(loader, lsize, "STAK", stack_during_uncompression);
|
//patch_le32(loader, lsize, "KEIP", kernel_entry);
|
||||||
|
//patch_le32(loader, lsize, "STAK", stack_during_uncompression);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
||||||
|
|||||||
+71
-40
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -31,9 +31,10 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_exe.h"
|
#include "p_exe.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_exe.h"
|
#include "stub/i086-dos16.exe.h"
|
||||||
|
|
||||||
#define RSFCRI 4096 // Reserved Space For Compressed Relocation Info
|
#define RSFCRI 4096 // Reserved Space For Compressed Relocation Info
|
||||||
#define MAXMATCH 0x2000
|
#define MAXMATCH 0x2000
|
||||||
@@ -49,6 +50,7 @@ static const
|
|||||||
PackExe::PackExe(InputFile *f) :
|
PackExe::PackExe(InputFile *f) :
|
||||||
super(f)
|
super(f)
|
||||||
{
|
{
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32);
|
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32);
|
||||||
ih_exesize = ih_imagesize = ih_overlay = 0;
|
ih_exesize = ih_imagesize = ih_overlay = 0;
|
||||||
}
|
}
|
||||||
@@ -56,8 +58,20 @@ PackExe::PackExe(InputFile *f) :
|
|||||||
|
|
||||||
const int *PackExe::getCompressionMethods(int method, int level) const
|
const int *PackExe::getCompressionMethods(int method, int level) const
|
||||||
{
|
{
|
||||||
|
static const int m_nrv2b[] = { M_NRV2B_8, M_NRV2D_8, M_NRV2E_8, M_END };
|
||||||
|
static const int m_nrv2d[] = { M_NRV2D_8, M_NRV2B_8, M_NRV2E_8, M_END };
|
||||||
|
static const int m_nrv2e[] = { M_NRV2E_8, M_NRV2B_8, M_NRV2D_8, M_END };
|
||||||
|
|
||||||
bool small = ih_imagesize <= 256*1024;
|
bool small = ih_imagesize <= 256*1024;
|
||||||
return Packer::getDefaultCompressionMethods_8(method, level, small);
|
if (M_IS_NRV2B(method))
|
||||||
|
return m_nrv2b;
|
||||||
|
if (M_IS_NRV2D(method))
|
||||||
|
return m_nrv2d;
|
||||||
|
if (M_IS_NRV2E(method))
|
||||||
|
return m_nrv2e;
|
||||||
|
if (level == 1 || small)
|
||||||
|
return m_nrv2b;
|
||||||
|
return m_nrv2e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -80,7 +94,6 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
|||||||
memset(&oh,0,sizeof(oh));
|
memset(&oh,0,sizeof(oh));
|
||||||
oh.ident = 'M' + 'Z' * 256;
|
oh.ident = 'M' + 'Z' * 256;
|
||||||
oh.headsize16 = 2;
|
oh.headsize16 = 2;
|
||||||
oh.ip = 0;
|
|
||||||
|
|
||||||
oh.sp = ih.sp > 0x200 ? (unsigned) ih.sp : 0x200;
|
oh.sp = ih.sp > 0x200 ? (unsigned) ih.sp : 0x200;
|
||||||
|
|
||||||
@@ -101,14 +114,18 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackExe::buildLoader(const Filter *)
|
void PackExe::buildLoader(const Filter *)
|
||||||
{
|
{
|
||||||
struct exe_header_t tmp_oh;
|
struct exe_header_t tmp_oh;
|
||||||
int flag = fillExeHeader(&tmp_oh);
|
int flag = fillExeHeader(&tmp_oh);
|
||||||
|
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
|
||||||
|
if (device_driver)
|
||||||
|
addLoader("DEVICEENTRY", NULL);
|
||||||
addLoader("EXEENTRY",
|
addLoader("EXEENTRY",
|
||||||
|
device_driver ? "DEVICESUB" : "EXESUB",
|
||||||
|
"JNCDOCOPY",
|
||||||
relocsize ? "EXERELPU" : "",
|
relocsize ? "EXERELPU" : "",
|
||||||
"EXEMAIN4,+G5DXXXX,UPX1HEAD,EXECUTPO",
|
"EXEMAIN4,+G5DXXXX,UPX1HEAD,EXECUTPO",
|
||||||
NULL
|
NULL
|
||||||
@@ -122,7 +139,7 @@ int PackExe::buildLoader(const Filter *)
|
|||||||
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
|
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
|
||||||
"NRV2BEX3",
|
"NRV2BEX3",
|
||||||
ph.c_len > 0xffff ? "N2B64K02" : "",
|
ph.c_len > 0xffff ? "N2B64K02" : "",
|
||||||
"NRV2BEX9,NRV2B16E",
|
"NRV2BEX9",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
else if (ph.method == M_NRV2D_8)
|
else if (ph.method == M_NRV2D_8)
|
||||||
@@ -134,7 +151,7 @@ int PackExe::buildLoader(const Filter *)
|
|||||||
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
|
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
|
||||||
"NRV2DEX3",
|
"NRV2DEX3",
|
||||||
ph.c_len > 0xffff ? "N2D64K02" : "",
|
ph.c_len > 0xffff ? "N2D64K02" : "",
|
||||||
"NRV2DEX9,NRV2D16E",
|
"NRV2DEX9",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
else if (ph.method == M_NRV2E_8)
|
else if (ph.method == M_NRV2E_8)
|
||||||
@@ -146,7 +163,7 @@ int PackExe::buildLoader(const Filter *)
|
|||||||
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602",
|
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602",
|
||||||
"NRV2EEX3",
|
"NRV2EEX3",
|
||||||
ph.c_len > 0xffff ? "N2E64K02" : "",
|
ph.c_len > 0xffff ? "N2E64K02" : "",
|
||||||
"NRV2EEX9,NRV2E16E",
|
"NRV2EEX9",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
@@ -162,6 +179,7 @@ int PackExe::buildLoader(const Filter *)
|
|||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
addLoader("EXEMAIN8",
|
addLoader("EXEMAIN8",
|
||||||
|
device_driver ? "DEVICEEND" : "",
|
||||||
(flag & SS) ? "EXESTACK" : "",
|
(flag & SS) ? "EXESTACK" : "",
|
||||||
(flag & SP) ? "EXESTASP" : "",
|
(flag & SP) ? "EXESTASP" : "",
|
||||||
(flag & USEJUMP) ? "EXEJUMPF" : "",
|
(flag & USEJUMP) ? "EXEJUMPF" : "",
|
||||||
@@ -172,7 +190,6 @@ int PackExe::buildLoader(const Filter *)
|
|||||||
"EXERETIP",
|
"EXERETIP",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -231,6 +248,9 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||||||
const upx_byte *relocs, const unsigned nrelocs,
|
const upx_byte *relocs, const unsigned nrelocs,
|
||||||
upx_byte *crel, bool *has_9a)
|
upx_byte *crel, bool *has_9a)
|
||||||
{
|
{
|
||||||
|
if (opt->exact)
|
||||||
|
throwCantPackExact();
|
||||||
|
|
||||||
upx_byte * const crel_save = crel;
|
upx_byte * const crel_save = crel;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned seg_high = 0;
|
unsigned seg_high = 0;
|
||||||
@@ -367,6 +387,8 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
|
|
||||||
checkAlreadyPacked(ibuf, UPX_MIN(ih_imagesize, 127u));
|
checkAlreadyPacked(ibuf, UPX_MIN(ih_imagesize, 127u));
|
||||||
|
|
||||||
|
device_driver = get_le32(ibuf) == 0xffffffffu;
|
||||||
|
|
||||||
// relocations
|
// relocations
|
||||||
has_9a = false;
|
has_9a = false;
|
||||||
upx_byte *w = ibuf + ih_imagesize;
|
upx_byte *w = ibuf + ih_imagesize;
|
||||||
@@ -405,8 +427,10 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
ph.u_len = ih_imagesize + relocsize;
|
ph.u_len = ih_imagesize + relocsize;
|
||||||
// prepare filter
|
// prepare filter
|
||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
// compress
|
// compress (max_match = 8192)
|
||||||
compressWithFilters(&ft, 32, 0, NULL, 0, MAXMATCH);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
cconf.conf_ucl.max_match = MAXMATCH;
|
||||||
|
compressWithFilters(&ft, 32, 0, NULL, &cconf);
|
||||||
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
||||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
throwCantPack("decompressor limit exceeded, send a bugreport");
|
||||||
|
|
||||||
@@ -474,21 +498,27 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
extra_info[eisize++] = (unsigned char) flag;
|
extra_info[eisize++] = (unsigned char) flag;
|
||||||
|
|
||||||
|
linker->defineSymbol("original_cs", ih.cs);
|
||||||
|
linker->defineSymbol("original_ip", ih.ip);
|
||||||
|
linker->defineSymbol("original_sp", ih.sp);
|
||||||
|
linker->defineSymbol("original_ss", ih.ss);
|
||||||
|
linker->defineSymbol("reloc_size",
|
||||||
|
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
|
||||||
|
>= relocsize ? 0 : MAXRELOCS) - relocsize);
|
||||||
|
linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((packedsize & 15) + 1));
|
||||||
|
linker->defineSymbol("decompressor_entry", (packedsize & 15) + 1);
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
if (flag & USEJUMP)
|
if (flag & USEJUMP)
|
||||||
{
|
{
|
||||||
// I use a relocation entry to set the original cs
|
// I use a relocation entry to set the original cs
|
||||||
unsigned n = find_le32(loader,lsize,get_le32("IPCS"));
|
unsigned n = getLoaderSectionStart("EXEJUMPF") + 1;
|
||||||
patch_le32(loader,lsize,get_le32("IPCS"), ih.cs*0x10000 + ih.ip);
|
|
||||||
n += packedsize + 2;
|
n += packedsize + 2;
|
||||||
oh.relocs = 1;
|
oh.relocs = 1;
|
||||||
oh.firstreloc = (n & 0xf) + ((n >> 4) << 16);
|
oh.firstreloc = (n & 0xf) + ((n >> 4) << 16);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
patch_le16(loader,lsize,"IP",ih.ip);
|
|
||||||
if (ih.cs)
|
|
||||||
patch_le16(loader,lsize,"CS",ih.cs);
|
|
||||||
oh.relocs = 0;
|
oh.relocs = 0;
|
||||||
oh.firstreloc = ih.cs * 0x10000 + ih.ip;
|
oh.firstreloc = ih.cs * 0x10000 + ih.ip;
|
||||||
}
|
}
|
||||||
@@ -497,33 +527,28 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
// oh.relocoffs = offsetof(exe_header_t, firstreloc);
|
// oh.relocoffs = offsetof(exe_header_t, firstreloc);
|
||||||
oh.relocoffs = ptr_diff(&oh.firstreloc, &oh);
|
oh.relocoffs = ptr_diff(&oh.firstreloc, &oh);
|
||||||
|
|
||||||
if (flag & SP)
|
linker->defineSymbol("destination_segment", oh.ss - ph.c_len / 16 - e_len / 16);
|
||||||
patch_le16(loader,lsize,"SP",ih.sp);
|
linker->defineSymbol("source_segment", e_len / 16 + (copysize - firstcopy) / 16);
|
||||||
if (flag & SS)
|
linker->defineSymbol("copy_offset", firstcopy - 2);
|
||||||
patch_le16(loader,lsize,"SS",ih.ss);
|
linker->defineSymbol("words_to_copy",firstcopy / 2);
|
||||||
if (relocsize)
|
|
||||||
patch_le16(loader,lsize,"RS",(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? 0 : MAXRELOCS) - relocsize);
|
|
||||||
|
|
||||||
patchPackHeader(loader,e_len);
|
linker->defineSymbol("exe_stack_sp", oh.sp);
|
||||||
|
linker->defineSymbol("exe_stack_ss", oh.ss);
|
||||||
patch_le16(loader,e_len,"BX",0x800F + 0x10*((packedsize&15)+1) - 0x10);
|
linker->defineSymbol("interrupt", get_le16(ibuf + 8));
|
||||||
patch_le16(loader,e_len,"BP",(packedsize&15)+1);
|
linker->defineSymbol("attribute", get_le16(ibuf + 4));
|
||||||
|
linker->defineSymbol("orig_strategy", get_le16(ibuf + 6));
|
||||||
unsigned destpara = oh.ss - ph.c_len/16;
|
|
||||||
patch_le16(loader,e_len,"ES",destpara-e_len/16);
|
|
||||||
patch_le16(loader,e_len,"DS",e_len/16+(copysize-firstcopy)/16);
|
|
||||||
patch_le16(loader,e_len,"SI",firstcopy-2);
|
|
||||||
patch_le16(loader,e_len,"CX",firstcopy/2);
|
|
||||||
|
|
||||||
// finish --stub support
|
|
||||||
//if (ih.relocoffs >= 0x40 && memcmp(&ih.relocoffs,">TIPPACH",8))
|
|
||||||
// throwCantPack("FIXME");
|
|
||||||
|
|
||||||
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
||||||
oh.m512 = outputlen & 511;
|
oh.m512 = outputlen & 511;
|
||||||
oh.p512 = (outputlen + 511) >> 9;
|
oh.p512 = (outputlen + 511) >> 9;
|
||||||
|
|
||||||
//fprintf(stderr,"\ne_len=%x d_len=%x clen=%x oo=%x ulen=%x destp=%x copys=%x images=%x",e_len,d_len,packedsize,ph.overlap_overhead,ph.u_len,destpara,copysize,ih_imagesize);
|
oh.ip = device_driver ? getLoaderSection("EXEENTRY") - 2 : 0;
|
||||||
|
|
||||||
|
relocateLoader();
|
||||||
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
patchPackHeader(loader,e_len);
|
||||||
|
|
||||||
|
//fprintf(stderr,"\ne_len=%x d_len=%x c_len=%x oo=%x ulen=%x destp=%x copys=%x images=%x",e_len,d_len,packedsize,ph.overlap_overhead,ph.u_len,destpara,copysize,ih_imagesize);
|
||||||
|
|
||||||
// write header + write loader + compressed file
|
// write header + write loader + compressed file
|
||||||
#ifdef TESTING
|
#ifdef TESTING
|
||||||
@@ -567,7 +592,7 @@ int PackExe::canUnpack()
|
|||||||
return false;
|
return false;
|
||||||
const off_t off = ih.headsize16 * 16;
|
const off_t off = ih.headsize16 * 16;
|
||||||
fi->seek(off, SEEK_SET);
|
fi->seek(off, SEEK_SET);
|
||||||
bool b = readPackHeader(128);
|
bool b = readPackHeader(256);
|
||||||
return b && (off + (off_t) ph.c_len <= file_size);
|
return b && (off + (off_t) ph.c_len <= file_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -697,6 +722,12 @@ void PackExe::unpack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackExe::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et
|
vi:ts=4:et
|
||||||
*/
|
*/
|
||||||
|
|||||||
+6
-4
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -68,7 +68,8 @@ protected:
|
|||||||
virtual int readFileHeader(void);
|
virtual int readFileHeader(void);
|
||||||
|
|
||||||
virtual int fillExeHeader(struct exe_header_t *) const;
|
virtual int fillExeHeader(struct exe_header_t *) const;
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
struct exe_header_t
|
struct exe_header_t
|
||||||
{
|
{
|
||||||
@@ -98,6 +99,7 @@ protected:
|
|||||||
unsigned relocsize;
|
unsigned relocsize;
|
||||||
|
|
||||||
bool has_9a;
|
bool has_9a;
|
||||||
|
bool device_driver;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NORELOC = 1,
|
NORELOC = 1,
|
||||||
|
|||||||
+882
-598
File diff suppressed because it is too large
Load Diff
+187
-93
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,8 +22,11 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -37,7 +40,7 @@ class PackLinuxElf : public PackUnix
|
|||||||
public:
|
public:
|
||||||
PackLinuxElf(InputFile *f);
|
PackLinuxElf(InputFile *f);
|
||||||
virtual ~PackLinuxElf();
|
virtual ~PackLinuxElf();
|
||||||
/*virtual int buildLoader(const Filter *);*/
|
/*virtual void buildLoader(const Filter *);*/
|
||||||
virtual bool canUnpackVersion(int version) const { return (version >= 11); }
|
virtual bool canUnpackVersion(int version) const { return (version >= 11); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -48,26 +51,31 @@ protected:
|
|||||||
|
|
||||||
virtual void pack1(OutputFile *, Filter &) = 0; // generate executable header
|
virtual void pack1(OutputFile *, Filter &) = 0; // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &) = 0; // append compressed data
|
virtual void pack2(OutputFile *, Filter &) = 0; // append compressed data
|
||||||
//virtual void pack3(OutputFile *, Filter &) = 0; // append loader
|
virtual void pack3(OutputFile *, Filter &) = 0; // append loader
|
||||||
virtual void pack4(OutputFile *, Filter &) = 0; // append pack header
|
//virtual void pack4(OutputFile *, Filter &) = 0; // append pack header
|
||||||
|
|
||||||
virtual void generateElfHdr(
|
virtual void generateElfHdr(
|
||||||
OutputFile *,
|
OutputFile *,
|
||||||
void const *proto,
|
void const *proto,
|
||||||
unsigned const brka
|
unsigned const brka
|
||||||
) = 0;
|
) = 0;
|
||||||
virtual int buildLinuxLoader(
|
virtual void defineSymbols(Filter const *);
|
||||||
upx_byte const *const proto, // assembly-only sections
|
virtual void addStubEntrySections(Filter const *);
|
||||||
unsigned const szproto,
|
|
||||||
upx_byte const *const fold, // linked assembly + C section
|
|
||||||
unsigned const szfold,
|
|
||||||
Filter const *ft
|
|
||||||
) = 0;
|
|
||||||
virtual void unpack(OutputFile *fo) = 0;
|
virtual void unpack(OutputFile *fo) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
char *file_image; // if ET_DYN investigation
|
||||||
|
char const *dynstr; // from DT_STRTAB
|
||||||
|
|
||||||
unsigned sz_phdrs; // sizeof Phdr[]
|
unsigned sz_phdrs; // sizeof Phdr[]
|
||||||
unsigned sz_elf_hdrs; // all Elf headers
|
unsigned sz_elf_hdrs; // all Elf headers
|
||||||
|
unsigned sz_pack2; // after pack2(), before loader
|
||||||
|
|
||||||
|
unsigned short e_machine;
|
||||||
|
unsigned char ei_class;
|
||||||
|
unsigned char ei_data;
|
||||||
|
unsigned char ei_osabi;
|
||||||
|
char const *osabi_note;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PackLinuxElf32 : public PackLinuxElf
|
class PackLinuxElf32 : public PackLinuxElf
|
||||||
@@ -77,15 +85,17 @@ public:
|
|||||||
PackLinuxElf32(InputFile *f);
|
PackLinuxElf32(InputFile *f);
|
||||||
virtual ~PackLinuxElf32();
|
virtual ~PackLinuxElf32();
|
||||||
protected:
|
protected:
|
||||||
virtual int checkEhdr(
|
virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
|
||||||
Elf32_Ehdr const *ehdr,
|
virtual bool canPack();
|
||||||
unsigned char e_machine,
|
|
||||||
unsigned char ei_class,
|
// These ARM routines are essentially common to big/little endian,
|
||||||
unsigned char ei_data) const;
|
// but the class hierarchy splits after this class.
|
||||||
|
virtual void ARM_defineSymbols(Filter const *ft);
|
||||||
|
virtual void ARM_updateLoader(OutputFile *);
|
||||||
|
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||||
//virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
virtual void pack4(OutputFile *, Filter &); // append pack header
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
@@ -94,16 +104,33 @@ protected:
|
|||||||
void const *proto,
|
void const *proto,
|
||||||
unsigned const brka
|
unsigned const brka
|
||||||
);
|
);
|
||||||
|
virtual void buildLinuxLoader(
|
||||||
|
upx_byte const *const proto, // assembly-only sections
|
||||||
|
unsigned const szproto,
|
||||||
|
upx_byte const *const fold, // linked assembly + C section
|
||||||
|
unsigned const szfold,
|
||||||
|
Filter const *ft
|
||||||
|
);
|
||||||
virtual off_t getbrk(const Elf32_Phdr *phdr, int e_phnum) const;
|
virtual off_t getbrk(const Elf32_Phdr *phdr, int e_phnum) const;
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
virtual void updateLoader(OutputFile *fo);
|
virtual void updateLoader(OutputFile *fo);
|
||||||
virtual unsigned find_LOAD_gap(Elf32_Phdr const *const phdri, unsigned const k,
|
virtual unsigned find_LOAD_gap(Elf32_Phdr const *const phdri, unsigned const k,
|
||||||
unsigned const e_phnum);
|
unsigned const e_phnum);
|
||||||
|
virtual off_t getbase(const Elf32_Phdr *phdr, int e_phnum) const;
|
||||||
|
|
||||||
|
static unsigned elf_hash(char const *) /*const*/;
|
||||||
|
virtual void const *elf_find_dynamic(unsigned) const;
|
||||||
|
virtual Elf32_Sym const *elf_lookup(char const *) const;
|
||||||
|
virtual unsigned elf_get_offset_from_address(unsigned) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Elf32_Ehdr ehdri; // from input file
|
Elf32_Ehdr ehdri; // from input file
|
||||||
Elf32_Phdr *phdri; // for input file
|
Elf32_Phdr *phdri; // for input file
|
||||||
|
|
||||||
|
Elf32_Dyn const *dynseg; // from PT_DYNAMIC
|
||||||
|
unsigned int const *hashtab; // from DT_HASH
|
||||||
|
Elf32_Sym const *dynsym; // from DT_SYMTAB
|
||||||
|
|
||||||
struct cprElfHdr1 {
|
struct cprElfHdr1 {
|
||||||
Elf32_Ehdr ehdr;
|
Elf32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[1];
|
Elf32_Phdr phdr[1];
|
||||||
@@ -126,6 +153,14 @@ protected:
|
|||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
cprElfHdr3 elfout;
|
cprElfHdr3 elfout;
|
||||||
|
|
||||||
|
struct Elf32_Note {
|
||||||
|
unsigned namesz; // 8
|
||||||
|
unsigned descsz; // 4
|
||||||
|
unsigned type; // 1
|
||||||
|
char text[0x18 - 4*4]; // "OpenBSD"
|
||||||
|
unsigned end; // 0
|
||||||
|
} elfnote;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -135,18 +170,14 @@ class PackLinuxElf64 : public PackLinuxElf
|
|||||||
public:
|
public:
|
||||||
PackLinuxElf64(InputFile *f);
|
PackLinuxElf64(InputFile *f);
|
||||||
virtual ~PackLinuxElf64();
|
virtual ~PackLinuxElf64();
|
||||||
/*virtual int buildLoader(const Filter *);*/
|
/*virtual void buildLoader(const Filter *);*/
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int checkEhdr(
|
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
|
||||||
Elf64_Ehdr const *ehdr,
|
|
||||||
unsigned char e_machine,
|
|
||||||
unsigned char ei_class,
|
|
||||||
unsigned char ei_data) const;
|
|
||||||
|
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||||
//virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
virtual void pack4(OutputFile *, Filter &); // append pack header
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
@@ -155,6 +186,13 @@ protected:
|
|||||||
void const *proto,
|
void const *proto,
|
||||||
unsigned const brka
|
unsigned const brka
|
||||||
);
|
);
|
||||||
|
virtual void buildLinuxLoader(
|
||||||
|
upx_byte const *const proto, // assembly-only sections
|
||||||
|
unsigned const szproto,
|
||||||
|
upx_byte const *const fold, // linked assembly + C section
|
||||||
|
unsigned const szfold,
|
||||||
|
Filter const *ft
|
||||||
|
);
|
||||||
virtual off_t getbrk(const Elf64_Phdr *phdr, int e_phnum) const;
|
virtual off_t getbrk(const Elf64_Phdr *phdr, int e_phnum) const;
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
virtual void updateLoader(OutputFile *fo);
|
virtual void updateLoader(OutputFile *fo);
|
||||||
@@ -193,7 +231,7 @@ class PackLinuxElf32Be : public PackLinuxElf32
|
|||||||
{
|
{
|
||||||
typedef PackLinuxElf32 super;
|
typedef PackLinuxElf32 super;
|
||||||
protected:
|
protected:
|
||||||
PackLinuxElf32Be(InputFile *f) : super(f) { }
|
PackLinuxElf32Be(InputFile *f) : super(f) { bele = &N_BELE_RTP::be_policy; }
|
||||||
|
|
||||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
|
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
|
||||||
virtual unsigned get_native32(const void *b) const { return get_be32(b); }
|
virtual unsigned get_native32(const void *b) const { return get_be32(b); }
|
||||||
@@ -203,11 +241,25 @@ protected:
|
|||||||
virtual void set_native16(void *b, unsigned v) const { set_be16(b, v); }
|
virtual void set_native16(void *b, unsigned v) const { set_be16(b, v); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PackLinuxElf32Le : public PackLinuxElf32
|
||||||
|
{
|
||||||
|
typedef PackLinuxElf32 super;
|
||||||
|
protected:
|
||||||
|
PackLinuxElf32Le(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||||
|
|
||||||
|
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
||||||
|
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
||||||
|
virtual unsigned get_native16(const void *b) const { return get_le16(b); }
|
||||||
|
virtual void set_native64(void *b, acc_uint64l_t v) const { set_le64(b, v); }
|
||||||
|
virtual void set_native32(void *b, unsigned v) const { set_le32(b, v); }
|
||||||
|
virtual void set_native16(void *b, unsigned v) const { set_le16(b, v); }
|
||||||
|
};
|
||||||
|
|
||||||
class PackLinuxElf64Le : public PackLinuxElf64
|
class PackLinuxElf64Le : public PackLinuxElf64
|
||||||
{
|
{
|
||||||
typedef PackLinuxElf64 super;
|
typedef PackLinuxElf64 super;
|
||||||
protected:
|
protected:
|
||||||
PackLinuxElf64Le(InputFile *f) : super(f) { }
|
PackLinuxElf64Le(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||||
|
|
||||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
||||||
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
||||||
@@ -232,21 +284,11 @@ public:
|
|||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
protected:
|
protected:
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
//virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
virtual int buildLinuxLoader(
|
virtual void buildLoader(const Filter *);
|
||||||
upx_byte const *const proto, // assembly-only sections
|
virtual Linker* newLinker() const;
|
||||||
unsigned const szproto,
|
virtual void defineSymbols(Filter const *);
|
||||||
upx_byte const *const fold, // linked assembly + C section
|
|
||||||
unsigned const szfold,
|
|
||||||
Filter const *ft
|
|
||||||
);
|
|
||||||
virtual int buildLoader(const Filter *);
|
|
||||||
virtual void generateElfHdr(
|
|
||||||
OutputFile *,
|
|
||||||
void const *proto,
|
|
||||||
unsigned const brka
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -262,18 +304,77 @@ public:
|
|||||||
virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
|
||||||
virtual const char *getName() const { return "linux/ElfPPC"; }
|
virtual const char *getName() const { return "linux/ElfPPC"; }
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
virtual bool canPack();
|
|
||||||
protected:
|
protected:
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual void buildLoader(const Filter *);
|
||||||
virtual int buildLinuxLoader(
|
virtual Linker* newLinker() const;
|
||||||
upx_byte const *const proto, // assembly-only sections
|
};
|
||||||
unsigned const szproto,
|
|
||||||
upx_byte const *const fold, // linked assembly + C section
|
/*************************************************************************
|
||||||
unsigned const szfold,
|
// linux/elf386
|
||||||
Filter const *ft
|
**************************************************************************/
|
||||||
);
|
|
||||||
virtual int buildLoader(const Filter *);
|
class PackLinuxElf32x86 : public PackLinuxElf32Le
|
||||||
|
{
|
||||||
|
typedef PackLinuxElf32Le super;
|
||||||
|
public:
|
||||||
|
PackLinuxElf32x86(InputFile *f);
|
||||||
|
virtual ~PackLinuxElf32x86();
|
||||||
|
virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; }
|
||||||
|
virtual const char *getName() const { return "linux/elf386"; }
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
|
|
||||||
|
virtual void buildLoader(const Filter *);
|
||||||
|
virtual void addStubEntrySections(Filter const *);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void defineSymbols(Filter const *);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackBSDElf32x86 : public PackLinuxElf32x86
|
||||||
|
{
|
||||||
|
typedef PackLinuxElf32x86 super;
|
||||||
|
public:
|
||||||
|
PackBSDElf32x86(InputFile *f);
|
||||||
|
virtual ~PackBSDElf32x86();
|
||||||
|
virtual int getFormat() const { return UPX_F_BSD_ELF_i386; }
|
||||||
|
virtual const char *getName() const { return "BSD/elf386"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
|
|
||||||
|
virtual void buildLoader(const Filter *);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackFreeBSDElf32x86 : public PackBSDElf32x86
|
||||||
|
{
|
||||||
|
typedef PackBSDElf32x86 super;
|
||||||
|
public:
|
||||||
|
PackFreeBSDElf32x86(InputFile *f);
|
||||||
|
virtual ~PackFreeBSDElf32x86();
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackNetBSDElf32x86 : public PackBSDElf32x86
|
||||||
|
{
|
||||||
|
typedef PackBSDElf32x86 super;
|
||||||
|
public:
|
||||||
|
PackNetBSDElf32x86(InputFile *f);
|
||||||
|
virtual ~PackNetBSDElf32x86();
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackOpenBSDElf32x86 : public PackBSDElf32x86
|
||||||
|
{
|
||||||
|
typedef PackBSDElf32x86 super;
|
||||||
|
public:
|
||||||
|
PackOpenBSDElf32x86(InputFile *f);
|
||||||
|
virtual ~PackOpenBSDElf32x86();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
virtual void generateElfHdr(
|
virtual void generateElfHdr(
|
||||||
OutputFile *,
|
OutputFile *,
|
||||||
void const *proto,
|
void const *proto,
|
||||||
@@ -282,53 +383,46 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// linux/elf386
|
// linux/elfarm
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PackLinuxI386elf : public PackLinuxI386
|
class PackLinuxElf32armLe : public PackLinuxElf32Le
|
||||||
{
|
{
|
||||||
typedef PackLinuxI386 super;
|
typedef PackLinuxElf32Le super;
|
||||||
public:
|
public:
|
||||||
PackLinuxI386elf(InputFile *f);
|
PackLinuxElf32armLe(InputFile *f);
|
||||||
virtual ~PackLinuxI386elf();
|
virtual ~PackLinuxElf32armLe();
|
||||||
virtual int getVersion() const { return 13; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; }
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; }
|
virtual const char *getName() const { return "linux/armLE"; }
|
||||||
virtual const char *getName() const { return "linux/elf386"; }
|
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
virtual int buildLoader(const Filter *);
|
|
||||||
|
|
||||||
virtual void unpack(OutputFile *fo);
|
|
||||||
|
|
||||||
virtual bool canPack();
|
|
||||||
virtual bool canUnpackVersion(int version) const
|
|
||||||
{ return (version >= 11); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
virtual void buildLoader(const Filter *);
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void updateLoader(OutputFile *);
|
||||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
virtual void defineSymbols(Filter const *);
|
||||||
|
|
||||||
virtual void patchLoader();
|
|
||||||
|
|
||||||
Elf32_Ehdr ehdri; // from input file
|
|
||||||
Elf32_Phdr *phdri; // for input file
|
|
||||||
unsigned sz_phdrs; // sizeof Phdr[]
|
|
||||||
|
|
||||||
char *file_image; // if ET_DYN investigation
|
|
||||||
Elf32_Dyn const *dynseg; // from PT_DYNAMIC
|
|
||||||
unsigned int const *hashtab; // from DT_HASH
|
|
||||||
char const *dynstr; // from DT_STRTAB
|
|
||||||
Elf32_Sym const *dynsym; // from DT_SYMTAB
|
|
||||||
|
|
||||||
static unsigned elf_hash(char const *) /*const*/;
|
|
||||||
virtual void const *elf_find_dynamic(unsigned) const;
|
|
||||||
virtual Elf32_Sym const *elf_lookup(char const *) const;
|
|
||||||
virtual unsigned elf_get_offset_from_address(unsigned) const;
|
|
||||||
virtual unsigned find_LOAD_gap(Elf32_Phdr const *const phdri, unsigned const k,
|
|
||||||
unsigned const e_phnum);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PackLinuxElf32armBe : public PackLinuxElf32Be
|
||||||
|
{
|
||||||
|
typedef PackLinuxElf32Be super;
|
||||||
|
public:
|
||||||
|
PackLinuxElf32armBe(InputFile *f);
|
||||||
|
virtual ~PackLinuxElf32armBe();
|
||||||
|
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; }
|
||||||
|
virtual const char *getName() const { return "linux/armBE"; }
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
|
virtual void buildLoader(const Filter *);
|
||||||
|
virtual void updateLoader(OutputFile *);
|
||||||
|
virtual void defineSymbols(Filter const *);
|
||||||
|
};
|
||||||
|
|
||||||
#endif /*} already included */
|
#endif /*} already included */
|
||||||
|
|
||||||
|
|||||||
+237
-202
@@ -22,8 +22,11 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -51,10 +54,35 @@
|
|||||||
// linux/386 (generic "execve" format)
|
// linux/386 (generic "execve" format)
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
PackLinuxI386::PackLinuxI386(InputFile *f) : super(f),
|
||||||
|
ei_osabi(Elf32_Ehdr::ELFOSABI_LINUX), osabi_note(NULL)
|
||||||
|
{
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackBSDI386::PackBSDI386(InputFile *f) : super(f)
|
||||||
|
{
|
||||||
|
// Shell scripts need help specifying the target operating system.
|
||||||
|
// Elf input will override this with .e_ident[EI_OSABI] or PT_NOTE.
|
||||||
|
// [2006-09-27: Today's only runtime stub for shell is for linux.]
|
||||||
|
if (Elf32_Ehdr::ELFOSABI_LINUX==opt->o_unix.osabi0) {
|
||||||
|
// Disallow an incompatibility.
|
||||||
|
ei_osabi = Elf32_Ehdr::ELFOSABI_NONE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ei_osabi = opt->o_unix.osabi0; // might be ELFOSABI_NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_lx_exec86.h"
|
#include "stub/i386-linux.elf.execve-entry.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/fold_exec86.h"
|
#include "stub/i386-linux.elf.execve-fold.h"
|
||||||
|
|
||||||
|
static const
|
||||||
|
#include "stub/i386-bsd.elf.execve-entry.h"
|
||||||
|
static const
|
||||||
|
#include "stub/i386-bsd.elf.execve-fold.h"
|
||||||
|
|
||||||
|
|
||||||
const int *PackLinuxI386::getCompressionMethods(int method, int level) const
|
const int *PackLinuxI386::getCompressionMethods(int method, int level) const
|
||||||
@@ -66,14 +94,9 @@ const int *PackLinuxI386::getFilters() const
|
|||||||
{
|
{
|
||||||
static const int filters[] = {
|
static const int filters[] = {
|
||||||
0x49, 0x46,
|
0x49, 0x46,
|
||||||
// FIXME 2002-11-11: We use stub/fold_exec86.asm, which calls the
|
|
||||||
// decompressor multiple times, and unfilter is independent of decompress.
|
|
||||||
// Currently only filters 0x49, 0x46, 0x80..0x87 can handle this;
|
|
||||||
// and 0x80..0x87 are regarded as "untested".
|
|
||||||
#if 0
|
|
||||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
||||||
#endif
|
|
||||||
#if 0
|
#if 0
|
||||||
|
// 0x80..0x87 are regarded as "untested".
|
||||||
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
|
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
|
||||||
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
||||||
#endif
|
#endif
|
||||||
@@ -81,6 +104,27 @@ const int *PackLinuxI386::getFilters() const
|
|||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_stub_brk(Elf_LE32_Phdr *const phdr1, unsigned brka)
|
||||||
|
{
|
||||||
|
#define PAGE_MASK (~0ul<<12)
|
||||||
|
// linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary
|
||||||
|
unsigned const brkb = brka | ((0==(~PAGE_MASK & brka)) ? 0x20 : 0);
|
||||||
|
phdr1->p_type = PT_LOAD; // be sure
|
||||||
|
phdr1->p_offset = ~PAGE_MASK & brkb;
|
||||||
|
phdr1->p_vaddr = brkb;
|
||||||
|
phdr1->p_paddr = brkb;
|
||||||
|
phdr1->p_filesz = 0;
|
||||||
|
phdr1->p_memsz = 0;
|
||||||
|
if (0==phdr1->p_flags) {
|
||||||
|
phdr1->p_flags = Elf32_Phdr::PF_R|Elf32_Phdr::PF_W;
|
||||||
|
}
|
||||||
|
if (0==phdr1->p_align) {
|
||||||
|
phdr1->p_align = 0x1000;
|
||||||
|
}
|
||||||
|
#undef PAGE_MASK
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PackLinuxI386::generateElfHdr(
|
PackLinuxI386::generateElfHdr(
|
||||||
OutputFile *fo,
|
OutputFile *fo,
|
||||||
@@ -88,7 +132,6 @@ PackLinuxI386::generateElfHdr(
|
|||||||
unsigned const brka
|
unsigned const brka
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
cprElfHdr1 *const h1 = (cprElfHdr1 *)&elfout;
|
|
||||||
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout;
|
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout;
|
||||||
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;
|
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;
|
||||||
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
|
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
|
||||||
@@ -108,40 +151,22 @@ PackLinuxI386::generateElfHdr(
|
|||||||
|
|
||||||
// Info for OS kernel to set the brk()
|
// Info for OS kernel to set the brk()
|
||||||
if (brka) {
|
if (brka) {
|
||||||
#define PAGE_MASK (~0ul<<12)
|
set_stub_brk(&h2->phdr[1], brka);
|
||||||
// linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary
|
|
||||||
unsigned const brkb = brka | ((0==(~PAGE_MASK & brka)) ? 0x20 : 0);
|
|
||||||
h2->phdr[1].p_type = PT_LOAD; // be sure
|
|
||||||
h2->phdr[1].p_offset = ~PAGE_MASK & brkb;
|
|
||||||
h2->phdr[1].p_vaddr = brkb;
|
|
||||||
h2->phdr[1].p_paddr = brkb;
|
|
||||||
h2->phdr[1].p_filesz = 0;
|
|
||||||
h2->phdr[1].p_memsz = 0;
|
|
||||||
if (0==h2->phdr[1].p_flags) {
|
|
||||||
h2->phdr[1].p_flags = Elf32_Phdr::PF_R|Elf32_Phdr::PF_W;
|
|
||||||
}
|
|
||||||
if (0==h2->phdr[1].p_align) {
|
|
||||||
h2->phdr[1].p_align = 0x1000;
|
|
||||||
}
|
|
||||||
#undef PAGE_MASK
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ph.format==UPX_F_LINUX_i386 ) {
|
if (ph.format==UPX_F_LINUX_i386
|
||||||
assert(h1->ehdr.e_phnum==1);
|
|| ph.format==UPX_F_LINUX_SH_i386
|
||||||
memset(&h1->linfo, 0, sizeof(h1->linfo));
|
|| ph.format==UPX_F_BSD_i386
|
||||||
fo->write(h1, sizeof(*h1));
|
) {
|
||||||
}
|
// SELinux, PAx, grSecurity demand no PF_W if PF_X.
|
||||||
else if (ph.format==UPX_F_LINUX_ELF_i386) {
|
// kernel-2.6.12-2.3.legacy_FC3 has a bug which demands
|
||||||
|
// a PT_LOAD with PF_W, else SIGSEGV when clearing page fragment
|
||||||
|
// on low page of ".bss", which is the high page of .text.
|
||||||
|
// So the minimum number of PT_LOAD is 2.
|
||||||
assert(h2->ehdr.e_phnum==2);
|
assert(h2->ehdr.e_phnum==2);
|
||||||
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
||||||
fo->write(h2, sizeof(*h2));
|
fo->write(h2, sizeof(*h2));
|
||||||
}
|
}
|
||||||
else if (ph.format==UPX_F_LINUX_SH_i386) {
|
|
||||||
assert(h2->ehdr.e_phnum==1);
|
|
||||||
h2->ehdr.e_phnum = 1;
|
|
||||||
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
|
||||||
fo->write(h2, sizeof(*h2));
|
|
||||||
}
|
|
||||||
else if (ph.format==UPX_F_LINUX_ELFI_i386) {
|
else if (ph.format==UPX_F_LINUX_ELFI_i386) {
|
||||||
assert(h3->ehdr.e_phnum==3);
|
assert(h3->ehdr.e_phnum==3);
|
||||||
memset(&h3->linfo, 0, sizeof(h3->linfo));
|
memset(&h3->linfo, 0, sizeof(h3->linfo));
|
||||||
@@ -158,7 +183,16 @@ PackLinuxI386::pack1(OutputFile *fo, Filter &)
|
|||||||
// create a pseudo-unique program id for our paranoid stub
|
// create a pseudo-unique program id for our paranoid stub
|
||||||
progid = getRandomId();
|
progid = getRandomId();
|
||||||
|
|
||||||
generateElfHdr(fo, linux_i386exec_fold, 0);
|
generateElfHdr(fo, stub_i386_linux_elf_execve_fold, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PackBSDI386::pack1(OutputFile *fo, Filter &)
|
||||||
|
{
|
||||||
|
// create a pseudo-unique program id for our paranoid stub
|
||||||
|
progid = getRandomId();
|
||||||
|
|
||||||
|
generateElfHdr(fo, stub_i386_bsd_elf_execve_fold, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -168,10 +202,11 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
|||||||
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||||
sizeof(l_info) +
|
sizeof(l_info) +
|
||||||
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
|
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
|
||||||
unsigned len = fo->getBytesWritten();
|
unsigned nw = fo->getBytesWritten();
|
||||||
set_native32(&elfout.phdr[0].p_filesz, len);
|
elfout.phdr[0].p_filesz = nw;
|
||||||
|
nw = -(-elfout.phdr[0].p_align & -nw); // ALIGN_UP
|
||||||
super::pack4(fo, ft); // write PackHeader and overlay_offset
|
super::pack4(fo, ft); // write PackHeader and overlay_offset
|
||||||
|
set_stub_brk(&elfout.phdr[1], nw + elfout.phdr[0].p_vaddr);
|
||||||
|
|
||||||
#if 0 // {
|
#if 0 // {
|
||||||
// /usr/bin/strip from RedHat 8.0 (binutils-2.13.90.0.2-2)
|
// /usr/bin/strip from RedHat 8.0 (binutils-2.13.90.0.2-2)
|
||||||
@@ -188,48 +223,56 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
|||||||
|
|
||||||
// Supply a "linking view" that covers everything,
|
// Supply a "linking view" that covers everything,
|
||||||
// so that 'strip' does not omit everything.
|
// so that 'strip' does not omit everything.
|
||||||
Elf32_Shdr shdr;
|
Elf_LE32_Shdr shdr;
|
||||||
// The section header string table.
|
// The section header string table.
|
||||||
char const shstrtab[] = "\0.\0.shstrtab";
|
char const shstrtab[] = "\0.\0.shstrtab";
|
||||||
|
|
||||||
unsigned eod = elfout.phdr[0].p_filesz;
|
unsigned eod = elfout.phdr[0].p_filesz;
|
||||||
set_native32(&elfout.ehdr.e_shoff, eod);
|
elfout.ehdr.e_shoff = eod;
|
||||||
set_native16(&elfout.ehdr.e_shentsize, sizeof(shdr));
|
elfout.ehdr.e_shentsize = sizeof(shdr);
|
||||||
set_native16(&elfout.ehdr.e_shnum, 3);
|
elfout.ehdr.e_shnum = 3;
|
||||||
set_native16(&elfout.ehdr.e_shstrndx, 2);
|
elfout.ehdr.e_shstrndx = 2;
|
||||||
|
|
||||||
// An empty Elf32_Shdr for space as a null index.
|
// An empty Elf32_Shdr for space as a null index.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
memset(&shdr, 0, sizeof(shdr));
|
||||||
set_native32(&shdr.sh_type, Elf32_Shdr::SHT_NULL);
|
shdr.sh_type = Elf32_Shdr::SHT_NULL;
|
||||||
fo->write(&shdr, sizeof(shdr));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
// Cover all the bits we need at runtime.
|
// Cover all the bits we need at runtime.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
memset(&shdr, 0, sizeof(shdr));
|
||||||
set_native32(&shdr.sh_name, 1);
|
shdr.sh_name = 1;
|
||||||
set_native32(&shdr.sh_type, Elf32_Shdr::SHT_PROGBITS);
|
shdr.sh_type = Elf32_Shdr::SHT_PROGBITS;
|
||||||
set_native32(&shdr.sh_flags, Elf32_Shdr::SHF_ALLOC);
|
shdr.sh_flags = Elf32_Shdr::SHF_ALLOC;
|
||||||
set_native32(&shdr.sh_addr, elfout.phdr[0].p_vaddr);
|
shdr.sh_addr = elfout.phdr[0].p_vaddr;
|
||||||
set_native32(&shdr.sh_offset, overlay_offset);
|
shdr.sh_offset = overlay_offset;
|
||||||
set_native32(&shdr.sh_size, eod - overlay_offset);
|
shdr.sh_size = eod - overlay_offset;
|
||||||
set_native32(&shdr.sh_addralign, 4096);
|
shdr.sh_addralign = 4096;
|
||||||
fo->write(&shdr, sizeof(shdr));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
// A section header for the section header string table.
|
// A section header for the section header string table.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
memset(&shdr, 0, sizeof(shdr));
|
||||||
set_native32(&shdr.sh_name, 3);
|
shdr.sh_name = 3;
|
||||||
set_native32(&shdr.sh_type, Elf32_Shdr::SHT_STRTAB);
|
shdr.sh_type = Elf32_Shdr::SHT_STRTAB;
|
||||||
set_native32(&shdr.sh_offset, 3*sizeof(shdr) + eod);
|
shdr.sh_offset = 3*sizeof(shdr) + eod;
|
||||||
set_native32(&shdr.sh_size, sizeof(shstrtab));
|
shdr.sh_size = sizeof(shstrtab);
|
||||||
fo->write(&shdr, sizeof(shdr));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
fo->write(shstrtab, sizeof(shstrtab));
|
fo->write(shstrtab, sizeof(shstrtab));
|
||||||
#endif // }
|
#endif // }
|
||||||
|
|
||||||
|
|
||||||
|
// Cannot pre-round .p_memsz. If .p_filesz < .p_memsz, then kernel
|
||||||
|
// tries to make .bss, which requires PF_W.
|
||||||
|
// But strict SELinux (or PaX, grSecurity) disallows PF_W with PF_X.
|
||||||
|
#if 0 /*{*/
|
||||||
#undef PAGE_MASK
|
#undef PAGE_MASK
|
||||||
#define PAGE_MASK (~0u<<12)
|
#define PAGE_MASK (~0u<<12)
|
||||||
// pre-calculate for benefit of runtime disappearing act via munmap()
|
// pre-calculate for benefit of runtime disappearing act via munmap()
|
||||||
elfout.phdr[0].p_memsz = PAGE_MASK & (~PAGE_MASK + elfout.phdr[0].p_filesz);
|
elfout.phdr[0].p_memsz = PAGE_MASK & (~PAGE_MASK + elfout.phdr[0].p_filesz);
|
||||||
#undef PAGE_MASK
|
#undef PAGE_MASK
|
||||||
|
#else /*}{*/
|
||||||
|
elfout.phdr[0].p_memsz = elfout.phdr[0].p_filesz;
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
// rewrite Elf header
|
// rewrite Elf header
|
||||||
fo->seek(0, SEEK_SET);
|
fo->seek(0, SEEK_SET);
|
||||||
@@ -245,7 +288,12 @@ umax(unsigned a, unsigned b)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
Linker *PackLinuxI386::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
PackLinuxI386::buildLinuxLoader(
|
PackLinuxI386::buildLinuxLoader(
|
||||||
upx_byte const *const proto,
|
upx_byte const *const proto,
|
||||||
unsigned const szproto,
|
unsigned const szproto,
|
||||||
@@ -256,7 +304,6 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
{
|
{
|
||||||
initLoader(proto, szproto);
|
initLoader(proto, szproto);
|
||||||
|
|
||||||
struct b_info h; memset(&h, 0, sizeof(h));
|
|
||||||
unsigned fold_hdrlen = 0;
|
unsigned fold_hdrlen = 0;
|
||||||
if (0 < szfold) {
|
if (0 < szfold) {
|
||||||
cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
|
cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
|
||||||
@@ -266,84 +313,45 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
||||||
fold_hdrlen = umax(0x80, fold_hdrlen);
|
fold_hdrlen = umax(0x80, fold_hdrlen);
|
||||||
}
|
}
|
||||||
h.sz_unc = (szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen);
|
|
||||||
h.b_method = (unsigned char) ph.method;
|
|
||||||
h.b_ftid = (unsigned char) ph.filter;
|
|
||||||
h.b_cto8 = (unsigned char) ph.filter_cto;
|
|
||||||
}
|
}
|
||||||
unsigned char const *const uncLoader = fold_hdrlen + fold;
|
|
||||||
|
|
||||||
unsigned char *const cprLoader = new unsigned char[sizeof(h) + h.sz_unc];
|
|
||||||
if (0 < szfold) {
|
|
||||||
unsigned sz_cpr;
|
|
||||||
int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &sz_cpr,
|
|
||||||
NULL, ph.method, 10, NULL, NULL );
|
|
||||||
h.sz_cpr = sz_cpr;
|
|
||||||
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
|
|
||||||
throwInternalError("loader compression failed");
|
|
||||||
}
|
|
||||||
memcpy(cprLoader, &h, sizeof(h));
|
|
||||||
|
|
||||||
// This adds the definition to the "library", to be used later.
|
// This adds the definition to the "library", to be used later.
|
||||||
linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + h.sz_cpr);
|
// NOTE: the stub is NOT compressed! The savings is not worth it.
|
||||||
delete [] cprLoader;
|
linker->addSection("FOLDEXEC", fold + fold_hdrlen, szfold - fold_hdrlen, 0);
|
||||||
|
|
||||||
n_mru = ft->n_mru;
|
n_mru = ft->n_mru;
|
||||||
|
|
||||||
// Here is a quick summary of the format of the output file:
|
// Rely on "+80CXXXX" [etc] in getDecompressorSections() packer_c.cpp */
|
||||||
linker->setLoaderAlignOffset(
|
// // Here is a quick summary of the format of the output file:
|
||||||
// Elf32_Edhr
|
// linker->setLoaderAlignOffset(
|
||||||
sizeof(elfout.ehdr) +
|
// // Elf32_Edhr
|
||||||
// Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
|
// sizeof(elfout.ehdr) +
|
||||||
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
// // Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
|
||||||
// checksum UPX! lsize version format
|
// (elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||||
sizeof(l_info) +
|
// // checksum UPX! lsize version format
|
||||||
// PT_DYNAMIC with DT_NEEDED "forwarded" from original file
|
// sizeof(l_info) +
|
||||||
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) +
|
// // PT_DYNAMIC with DT_NEEDED "forwarded" from original file
|
||||||
// p_progid, p_filesize, p_blocksize
|
// ((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) +
|
||||||
sizeof(p_info) +
|
// // p_progid, p_filesize, p_blocksize
|
||||||
// compressed data
|
// sizeof(p_info) +
|
||||||
b_len + ph.c_len );
|
// // compressed data
|
||||||
// entry to stub
|
// b_len + ph.c_len );
|
||||||
|
// // entry to stub
|
||||||
addLoader("LEXEC000", NULL);
|
addLoader("LEXEC000", NULL);
|
||||||
|
|
||||||
if (ft->id) {
|
if (ft->id) {
|
||||||
if (ph.format==UPX_F_LINUX_ELF_i386) { // decompr, unfilter are separate
|
|
||||||
addLoader("LXUNF000", NULL);
|
|
||||||
addLoader("LXUNF002", NULL);
|
|
||||||
if (0x80==(ft->id & 0xF0)) {
|
|
||||||
if (256==n_mru) {
|
|
||||||
addLoader("MRUBYTE0", NULL);
|
|
||||||
}
|
|
||||||
else if (n_mru) {
|
|
||||||
addLoader("LXMRU005", NULL);
|
|
||||||
}
|
|
||||||
if (n_mru) {
|
|
||||||
addLoader("LXMRU006", NULL);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addLoader("LXMRU007", NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (0x40==(ft->id & 0xF0)) {
|
|
||||||
addLoader("LXUNF008", NULL);
|
|
||||||
}
|
|
||||||
addLoader("LXUNF010", NULL);
|
|
||||||
}
|
|
||||||
if (n_mru) {
|
if (n_mru) {
|
||||||
addLoader("LEXEC009", NULL);
|
addLoader("LEXEC009", NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addLoader("LEXEC010", NULL);
|
addLoader("LEXEC010", NULL);
|
||||||
addLoader(getDecompressor(), NULL);
|
linker->defineSymbol("filter_cto", ft->cto);
|
||||||
|
linker->defineSymbol("filter_length",
|
||||||
|
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||||
|
ft->lastcall - ft->calls * 4);
|
||||||
|
addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LEXEC015", NULL);
|
addLoader("LEXEC015", NULL);
|
||||||
if (ft->id) {
|
if (ft->id) {
|
||||||
if (ph.format==UPX_F_LINUX_ELF_i386) { // decompr, unfilter are separate
|
{ // decompr, unfilter not separate
|
||||||
if (0x80!=(ft->id & 0xF0)) {
|
|
||||||
addLoader("LXUNF042", NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // decompr, unfilter not separate
|
|
||||||
if (0x80==(ft->id & 0xF0)) {
|
if (0x80==(ft->id & 0xF0)) {
|
||||||
addLoader("LEXEC110", NULL);
|
addLoader("LEXEC110", NULL);
|
||||||
if (n_mru) {
|
if (n_mru) {
|
||||||
@@ -354,15 +362,7 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
addFilter32(ft->id);
|
addFilter32(ft->id);
|
||||||
if (ph.format==UPX_F_LINUX_ELF_i386) { // decompr, unfilter are separate
|
{ // decompr always unfilters
|
||||||
if (0x80==(ft->id & 0xF0)) {
|
|
||||||
if (0==n_mru) {
|
|
||||||
addLoader("LXMRU058", NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addLoader("LXUNF035", NULL);
|
|
||||||
}
|
|
||||||
else { // decompr always unfilters
|
|
||||||
addLoader("LEXEC017", NULL);
|
addLoader("LEXEC017", NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,25 +373,37 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
addLoader("IDENTSTR", NULL);
|
addLoader("IDENTSTR", NULL);
|
||||||
addLoader("LEXEC020", NULL);
|
addLoader("LEXEC020", NULL);
|
||||||
addLoader("FOLDEXEC", NULL);
|
addLoader("FOLDEXEC", NULL);
|
||||||
|
if (ph.method == M_LZMA) {
|
||||||
char *ptr_cto = (char *)const_cast<unsigned char *>(getLoader());
|
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
|
||||||
int sz_cto = getLoaderSize();
|
acc_uint32e_t properties = // lc, lp, pb, dummy
|
||||||
if (0x20==(ft->id & 0xF0) || 0x30==(ft->id & 0xF0)) { // push byte '?' ; cto8
|
(res->lit_context_bits << 0) |
|
||||||
patch_le16(ptr_cto, sz_cto, "\x6a?", 0x6a + (ft->cto << 8));
|
(res->lit_pos_bits << 8) |
|
||||||
checkPatch(NULL, 0, 0, 0); // reset
|
(res->pos_bits << 16);
|
||||||
|
if (linker->bele->isBE()) // big endian - bswap32
|
||||||
|
acc_swab32s(&properties);
|
||||||
|
linker->defineSymbol("lzma_properties", properties);
|
||||||
|
// -2 for properties
|
||||||
|
linker->defineSymbol("lzma_c_len", ph.c_len - 2);
|
||||||
|
linker->defineSymbol("lzma_u_len", ph.u_len);
|
||||||
|
unsigned const stack = getDecompressorWrkmemSize();
|
||||||
|
linker->defineSymbol("lzma_stack_adjust", 0u - stack);
|
||||||
}
|
}
|
||||||
// PackHeader and overlay_offset at the end of the output file,
|
if (0x80==(ft->id & 0xF0)) {
|
||||||
// after the compressed data.
|
int const mru = ft->n_mru ? 1+ ft->n_mru : 0;
|
||||||
|
if (mru && mru!=256) {
|
||||||
return getLoaderSize();
|
unsigned const is_pwr2 = (0==((mru -1) & mru));
|
||||||
|
linker->defineSymbol("NMRU", mru - is_pwr2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
relocateLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
PackLinuxI386::buildLoader(Filter const *ft)
|
PackLinuxI386::buildLoader(Filter const *ft)
|
||||||
{
|
{
|
||||||
unsigned const sz_fold = sizeof(linux_i386exec_fold);
|
unsigned const sz_fold = sizeof(stub_i386_linux_elf_execve_fold);
|
||||||
MemBuffer buf(sz_fold);
|
MemBuffer buf(sz_fold);
|
||||||
memcpy(buf, linux_i386exec_fold, sz_fold);
|
memcpy(buf, stub_i386_linux_elf_execve_fold, sz_fold);
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
// note: we only can use /proc/<pid>/fd when exetype > 0.
|
// note: we only can use /proc/<pid>/fd when exetype > 0.
|
||||||
@@ -401,26 +413,28 @@ PackLinuxI386::buildLoader(Filter const *ft)
|
|||||||
patch_le32(buf,sz_fold,"UPX3",progid);
|
patch_le32(buf,sz_fold,"UPX3",progid);
|
||||||
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
|
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
|
||||||
|
|
||||||
// get fresh filter
|
buildLinuxLoader(
|
||||||
Filter fold_ft = *ft;
|
stub_i386_linux_elf_execve_entry, sizeof(stub_i386_linux_elf_execve_entry),
|
||||||
fold_ft.init(ft->id, ft->addvalue);
|
buf, sz_fold, ft );
|
||||||
int preferred_ctos[2] = {ft->cto, -1};
|
|
||||||
fold_ft.preferred_ctos = preferred_ctos;
|
|
||||||
|
|
||||||
// filter
|
|
||||||
optimizeFilter(&fold_ft, buf, sz_fold);
|
|
||||||
|
|
||||||
unsigned fold_hdrlen = sizeof(l_info) + sizeof(Elf32_Ehdr) +
|
|
||||||
sizeof(Elf32_Phdr) * get_native32(&((Elf32_Ehdr const *)(void *)buf)->e_phnum);
|
|
||||||
if (0 == get_le32(fold_hdrlen + buf)) {
|
|
||||||
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
|
||||||
fold_hdrlen = umax(0x80, fold_hdrlen);
|
|
||||||
}
|
}
|
||||||
bool success = fold_ft.filter(buf + fold_hdrlen, sz_fold - fold_hdrlen);
|
|
||||||
(void)success;
|
|
||||||
|
|
||||||
return buildLinuxLoader(
|
void
|
||||||
linux_i386exec_loader, sizeof(linux_i386exec_loader),
|
PackBSDI386::buildLoader(Filter const *ft)
|
||||||
|
{
|
||||||
|
unsigned const sz_fold = sizeof(stub_i386_bsd_elf_execve_fold);
|
||||||
|
MemBuffer buf(sz_fold);
|
||||||
|
memcpy(buf, stub_i386_bsd_elf_execve_fold, sz_fold);
|
||||||
|
|
||||||
|
// patch loader
|
||||||
|
// note: we only can use /proc/<pid>/fd when exetype > 0.
|
||||||
|
// also, we sleep much longer when compressing a script.
|
||||||
|
checkPatch(NULL, 0, 0, 0); // reset
|
||||||
|
patch_le32(buf,sz_fold,"UPX4",exetype > 0 ? 3 : 15); // sleep time
|
||||||
|
patch_le32(buf,sz_fold,"UPX3",progid);
|
||||||
|
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
|
||||||
|
|
||||||
|
buildLinuxLoader(
|
||||||
|
stub_i386_bsd_elf_execve_entry, sizeof(stub_i386_bsd_elf_execve_entry),
|
||||||
buf, sz_fold, ft );
|
buf, sz_fold, ft );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,7 +450,7 @@ int PackLinuxI386::getLoaderPrefixSize() const
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
// basic check of an Linux ELF Ehdr
|
// basic check of an Linux ELF Ehdr
|
||||||
int PackLinuxI386::checkEhdr(const Elf32_Ehdr *ehdr) const
|
int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
|
||||||
{
|
{
|
||||||
const unsigned char * const buf = ehdr->e_ident;
|
const unsigned char * const buf = ehdr->e_ident;
|
||||||
|
|
||||||
@@ -476,34 +490,6 @@ int PackLinuxI386::checkEhdr(const Elf32_Ehdr *ehdr) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
off_t PackLinuxI386::getbrk(const Elf32_Phdr *phdr, int e_phnum) const
|
|
||||||
{
|
|
||||||
off_t brka = 0;
|
|
||||||
for (int j = 0; j < e_phnum; ++phdr, ++j) {
|
|
||||||
if (phdr->PT_LOAD == phdr->p_type) {
|
|
||||||
off_t b = phdr->p_vaddr + phdr->p_memsz;
|
|
||||||
if (b > brka)
|
|
||||||
brka = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return brka;
|
|
||||||
}
|
|
||||||
|
|
||||||
off_t PackLinuxI386::getbase(const Elf32_Phdr *phdr, int e_phnum) const
|
|
||||||
{
|
|
||||||
off_t base = ~0u;
|
|
||||||
for (int j = 0; j < e_phnum; ++phdr, ++j) {
|
|
||||||
if (phdr->PT_LOAD == phdr->p_type) {
|
|
||||||
if (phdr->p_vaddr < (unsigned) base)
|
|
||||||
base = phdr->p_vaddr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (0!=base) {
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
return 0x12000;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -514,9 +500,10 @@ bool PackLinuxI386::canPack()
|
|||||||
if (exetype != 0)
|
if (exetype != 0)
|
||||||
return super::canPack();
|
return super::canPack();
|
||||||
|
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
unsigned char *buf = ehdr.e_ident;
|
unsigned char *buf = ehdr.e_ident;
|
||||||
|
|
||||||
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(&ehdr, sizeof(ehdr));
|
fi->readx(&ehdr, sizeof(ehdr));
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
|
|
||||||
@@ -524,12 +511,58 @@ bool PackLinuxI386::canPack()
|
|||||||
const unsigned l = get_le32(buf);
|
const unsigned l = get_le32(buf);
|
||||||
|
|
||||||
int elf = checkEhdr(&ehdr);
|
int elf = checkEhdr(&ehdr);
|
||||||
if (elf >= 0)
|
if (elf >= 0) {
|
||||||
{
|
|
||||||
// NOTE: ELF executables are now handled by p_lx_elf.cpp,
|
// NOTE: ELF executables are now handled by p_lx_elf.cpp,
|
||||||
// so we only handle them here if force_execve
|
// so we only handle them here if force_execve
|
||||||
if (elf == 0 && opt->o_unix.force_execve)
|
if (elf == 0 && opt->o_unix.force_execve) {
|
||||||
exetype = 1;
|
exetype = 1;
|
||||||
|
|
||||||
|
unsigned osabi0 = ehdr.e_ident[Elf32_Ehdr::EI_OSABI];
|
||||||
|
switch (osabi0) {
|
||||||
|
case Elf32_Ehdr::ELFOSABI_LINUX:
|
||||||
|
case Elf32_Ehdr::ELFOSABI_FREEBSD:
|
||||||
|
case Elf32_Ehdr::ELFOSABI_NETBSD:
|
||||||
|
case Elf32_Ehdr::ELFOSABI_OPENBSD:
|
||||||
|
ei_osabi = osabi0; // Proudly declares its osabi in Ehdr.
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
unsigned const e_phnum = get_native16(&ehdr.e_phnum);
|
||||||
|
if (e_phnum<=(512/sizeof(Elf32_Phdr))) {
|
||||||
|
char buf2[512];
|
||||||
|
fi->seek(get_native32(&ehdr.e_phoff), SEEK_SET);
|
||||||
|
fi->readx(buf2, sizeof(buf2));
|
||||||
|
fi->seek(0, SEEK_SET);
|
||||||
|
Elf32_Phdr const *phdr = (Elf32_Phdr const *)buf2;
|
||||||
|
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
||||||
|
if (phdr->PT_NOTE == get_native32(&phdr->p_type)) {
|
||||||
|
unsigned const offset = get_native32(&phdr->p_offset);
|
||||||
|
struct Elf32_Note note; memset(¬e, 0, sizeof(note));
|
||||||
|
fi->seek(offset, SEEK_SET);
|
||||||
|
fi->readx(¬e, sizeof(note));
|
||||||
|
fi->seek(0, SEEK_SET);
|
||||||
|
if (4==get_native32(¬e.descsz)
|
||||||
|
&& 1==get_native32(¬e.type)
|
||||||
|
&& 0==note.end ) {
|
||||||
|
if (0==strcmp("NetBSD", (char const *)¬e.text)) {
|
||||||
|
ei_osabi = Elf32_Ehdr::ELFOSABI_NETBSD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (0==strcmp("OpenBSD", (char const *)¬e.text)) {
|
||||||
|
ei_osabi = Elf32_Ehdr::ELFOSABI_OPENBSD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (UPX_F_BSD_i386==getFormat()
|
||||||
|
&& !(Elf32_Ehdr::ELFOSABI_FREEBSD==ei_osabi
|
||||||
|
|| Elf32_Ehdr::ELFOSABI_NETBSD ==ei_osabi
|
||||||
|
|| Elf32_Ehdr::ELFOSABI_OPENBSD==ei_osabi )) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (l == 0x00640107 || l == 0x00640108 || l == 0x0064010b || l == 0x006400cc)
|
else if (l == 0x00640107 || l == 0x00640108 || l == 0x0064010b || l == 0x006400cc)
|
||||||
{
|
{
|
||||||
@@ -538,15 +571,17 @@ bool PackLinuxI386::canPack()
|
|||||||
// FIXME: N_TRSIZE, N_DRSIZE
|
// FIXME: N_TRSIZE, N_DRSIZE
|
||||||
// FIXME: check for aout shared libraries
|
// FIXME: check for aout shared libraries
|
||||||
}
|
}
|
||||||
#if defined(__linux__)
|
else { // shell scripts and other interpreters
|
||||||
// only compress scripts when running under Linux
|
if (Elf32_Ehdr::ELFOSABI_LINUX!=ei_osabi) {
|
||||||
|
return false; // so far, only Linux has runtime stub for shell
|
||||||
|
}
|
||||||
else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh
|
else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh
|
||||||
exetype = -1;
|
exetype = -1;
|
||||||
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
||||||
exetype = -1;
|
exetype = -1;
|
||||||
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
||||||
exetype = -2;
|
exetype = -2;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
return super::canPack();
|
return super::canPack();
|
||||||
}
|
}
|
||||||
@@ -557,7 +592,7 @@ void PackLinuxI386::patchLoader() { }
|
|||||||
|
|
||||||
void PackLinuxI386::patchLoaderChecksum()
|
void PackLinuxI386::patchLoaderChecksum()
|
||||||
{
|
{
|
||||||
unsigned char *const ptr = const_cast<unsigned char *>(getLoader());
|
unsigned char *const ptr = getLoader();
|
||||||
l_info *const lp = (l_info *)(sizeof(elfout.ehdr) +
|
l_info *const lp = (l_info *)(sizeof(elfout.ehdr) +
|
||||||
(elfout.ehdr.e_phnum * elfout.ehdr.e_phentsize) + (char *)&elfout );
|
(elfout.ehdr.e_phnum * elfout.ehdr.e_phentsize) + (char *)&elfout );
|
||||||
// checksum for loader + p_info
|
// checksum for loader + p_info
|
||||||
|
|||||||
+40
-15
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,10 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -38,7 +41,7 @@ class PackLinuxI386 : public PackUnixLe32
|
|||||||
{
|
{
|
||||||
typedef PackUnixLe32 super;
|
typedef PackUnixLe32 super;
|
||||||
public:
|
public:
|
||||||
PackLinuxI386(InputFile *f) : super(f) { }
|
PackLinuxI386(InputFile *f);
|
||||||
virtual void generateElfHdr(
|
virtual void generateElfHdr(
|
||||||
OutputFile *,
|
OutputFile *,
|
||||||
void const *proto,
|
void const *proto,
|
||||||
@@ -48,7 +51,7 @@ public:
|
|||||||
virtual const char *getName() const { return "linux/386"; }
|
virtual const char *getName() const { return "linux/386"; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
virtual int buildLoader(const Filter *);
|
virtual void buildLoader(const Filter *);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
|
|
||||||
@@ -59,8 +62,9 @@ protected:
|
|||||||
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
|
||||||
// loader util
|
// loader util
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
virtual int getLoaderPrefixSize() const;
|
virtual int getLoaderPrefixSize() const;
|
||||||
virtual int buildLinuxLoader(
|
virtual void buildLinuxLoader(
|
||||||
upx_byte const *const proto, // assembly-only sections
|
upx_byte const *const proto, // assembly-only sections
|
||||||
unsigned const szproto,
|
unsigned const szproto,
|
||||||
upx_byte const *const fold, // linked assembly + C section
|
upx_byte const *const fold, // linked assembly + C section
|
||||||
@@ -74,9 +78,7 @@ protected:
|
|||||||
virtual void updateLoader(OutputFile *);
|
virtual void updateLoader(OutputFile *);
|
||||||
|
|
||||||
// ELF util
|
// ELF util
|
||||||
virtual int checkEhdr(const Elf32_Ehdr *ehdr) const;
|
virtual int checkEhdr(const Elf_LE32_Ehdr *ehdr) const;
|
||||||
virtual off_t getbrk(const Elf32_Phdr *phdr, int e_phnum) const;
|
|
||||||
virtual off_t getbase(const Elf32_Phdr *phdr, int e_phnum) const;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
|
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
|
||||||
@@ -85,31 +87,54 @@ protected:
|
|||||||
unsigned n_mru;
|
unsigned n_mru;
|
||||||
|
|
||||||
struct cprElfHdr1 {
|
struct cprElfHdr1 {
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[1];
|
Elf_LE32_Phdr phdr[1];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
struct cprElfHdr2 {
|
struct cprElfHdr2 {
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[2];
|
Elf_LE32_Phdr phdr[2];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
struct cprElfHdr3 {
|
struct cprElfHdr3 {
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[3];
|
Elf_LE32_Phdr phdr[3];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
cprElfHdr3 elfout;
|
cprElfHdr3 elfout;
|
||||||
|
|
||||||
|
struct Elf32_Note {
|
||||||
|
unsigned namesz; // 8
|
||||||
|
unsigned descsz; // 4
|
||||||
|
unsigned type; // 1
|
||||||
|
char text[0x18 - 4*4]; // "OpenBSD"
|
||||||
|
unsigned end; // 0
|
||||||
|
} elfnote;
|
||||||
|
|
||||||
|
unsigned char ei_osabi;
|
||||||
|
char const *osabi_note;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PackBSDI386 : public PackLinuxI386
|
||||||
|
{
|
||||||
|
typedef PackLinuxI386 super;
|
||||||
|
public:
|
||||||
|
PackBSDI386(InputFile *f);
|
||||||
|
virtual int getFormat() const { return UPX_F_BSD_i386; }
|
||||||
|
virtual const char *getName() const { return "*BSD/386"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
|
|
||||||
|
virtual void buildLoader(const Filter *);
|
||||||
|
};
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+20
-17
@@ -22,8 +22,11 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -48,20 +51,20 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_lx_pti86.h"
|
#include "stub/i386-linux.elf.interp-entry.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/fold_pti86.h"
|
#include "stub/i386-linux.elf.interp-fold.h"
|
||||||
|
|
||||||
PackLinuxI386interp::PackLinuxI386interp(InputFile *f) :
|
PackLinuxElf32x86interp::PackLinuxElf32x86interp(InputFile *f) :
|
||||||
super(f)
|
super(f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PackLinuxI386interp::~PackLinuxI386interp()
|
PackLinuxElf32x86interp::~PackLinuxElf32x86interp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PackLinuxI386interp::canPack()
|
bool PackLinuxElf32x86interp::canPack()
|
||||||
{
|
{
|
||||||
if (opt->o_unix.make_ptinterp) {
|
if (opt->o_unix.make_ptinterp) {
|
||||||
return true;
|
return true;
|
||||||
@@ -72,7 +75,7 @@ bool PackLinuxI386interp::canPack()
|
|||||||
return super::canPack();
|
return super::canPack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackLinuxI386interp::pack1(OutputFile *fo, Filter &)
|
void PackLinuxElf32x86interp::pack1(OutputFile *fo, Filter &)
|
||||||
{
|
{
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(&ehdri, sizeof(ehdri));
|
fi->readx(&ehdri, sizeof(ehdri));
|
||||||
@@ -121,7 +124,7 @@ void PackLinuxI386interp::pack1(OutputFile *fo, Filter &)
|
|||||||
#undef E
|
#undef E
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackLinuxI386interp::pack2(OutputFile *fo, Filter &ft)
|
void PackLinuxElf32x86interp::pack2(OutputFile *fo, Filter &ft)
|
||||||
{
|
{
|
||||||
if (opt->o_unix.make_ptinterp) {
|
if (opt->o_unix.make_ptinterp) {
|
||||||
return; // ignore current input file!
|
return; // ignore current input file!
|
||||||
@@ -132,7 +135,7 @@ void PackLinuxI386interp::pack2(OutputFile *fo, Filter &ft)
|
|||||||
#undef PAGE_MASK
|
#undef PAGE_MASK
|
||||||
#define PAGE_MASK (~0u<<12)
|
#define PAGE_MASK (~0u<<12)
|
||||||
|
|
||||||
void PackLinuxI386interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
||||||
{
|
{
|
||||||
unsigned base = getbase(phdri, ehdri.e_phnum);
|
unsigned base = getbase(phdri, ehdri.e_phnum);
|
||||||
unsigned sz = PAGE_MASK & (~PAGE_MASK + elfout.phdr[0].p_filesz);
|
unsigned sz = PAGE_MASK & (~PAGE_MASK + elfout.phdr[0].p_filesz);
|
||||||
@@ -144,25 +147,25 @@ void PackLinuxI386interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
|||||||
}
|
}
|
||||||
elfout.phdr[0].p_paddr = elfout.phdr[0].p_vaddr = base - sz;
|
elfout.phdr[0].p_paddr = elfout.phdr[0].p_vaddr = base - sz;
|
||||||
if (opt->o_unix.make_ptinterp) {
|
if (opt->o_unix.make_ptinterp) {
|
||||||
initLoader(linux_i386pti_loader, sizeof(linux_i386pti_loader));
|
initLoader(stub_i386_linux_elf_interp_entry, sizeof(stub_i386_linux_elf_interp_entry));
|
||||||
linker->addSection("FOLDEXEC", linux_i386pti_fold, sizeof(linux_i386pti_fold));
|
linker->addSection("FOLDEXEC", stub_i386_linux_elf_interp_fold, sizeof(stub_i386_linux_elf_interp_fold), 0);
|
||||||
|
|
||||||
addLoader("LXPTI000", NULL);
|
addLoader("LXPTI000", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI040", NULL);
|
addLoader("LXPTI040", NULL);
|
||||||
ph.method = M_NRV2B_LE32; addLoader(getDecompressor(), NULL);
|
ph.method = M_NRV2B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI041", NULL);
|
addLoader("LXPTI041", NULL);
|
||||||
ph.method = M_NRV2D_LE32; addLoader(getDecompressor(), NULL);
|
ph.method = M_NRV2D_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI042", NULL);
|
addLoader("LXPTI042", NULL);
|
||||||
ph.method = M_NRV2E_LE32; addLoader(getDecompressor(), NULL);
|
ph.method = M_NRV2E_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI043", NULL);
|
addLoader("LXPTI043", NULL);
|
||||||
ph.method = M_CL1B_LE32; addLoader(getDecompressor(), NULL);
|
ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI091", NULL);
|
addLoader("LXPTI091", NULL);
|
||||||
@@ -191,7 +194,7 @@ void PackLinuxI386interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PackLinuxI386interp::unpack(OutputFile *fo)
|
void PackLinuxElf32x86interp::unpack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
#define MAX_INTERP_HDR 512
|
#define MAX_INTERP_HDR 512
|
||||||
char bufehdr[MAX_INTERP_HDR];
|
char bufehdr[MAX_INTERP_HDR];
|
||||||
|
|||||||
+12
-9
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,8 +22,11 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -35,12 +38,12 @@
|
|||||||
// linux/interp386
|
// linux/interp386
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PackLinuxI386interp : public PackLinuxI386elf
|
class PackLinuxElf32x86interp : public PackLinuxElf32x86
|
||||||
{
|
{
|
||||||
typedef PackLinuxI386elf super;
|
typedef PackLinuxElf32x86 super;
|
||||||
public:
|
public:
|
||||||
PackLinuxI386interp(InputFile *f);
|
PackLinuxElf32x86interp(InputFile *f);
|
||||||
virtual ~PackLinuxI386interp();
|
virtual ~PackLinuxElf32x86interp();
|
||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_ELFI_i386; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELFI_i386; }
|
||||||
virtual const char *getName() const { return "linux/elfi386"; }
|
virtual const char *getName() const { return "linux/elfi386"; }
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
/* p_lx_sep.cpp --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2006 Laszlo Molnar
|
|
||||||
Copyright (C) 2000-2006 John F. Reiser
|
|
||||||
All Rights Reserved.
|
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
|
||||||
and/or modify them under the terms of the GNU General Public License as
|
|
||||||
published by the Free Software Foundation; either version 2 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation, Inc.,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#include "file.h"
|
|
||||||
#include "packer.h"
|
|
||||||
#include "p_elf.h"
|
|
||||||
#include "p_unix.h"
|
|
||||||
#include "p_lx_exc.h"
|
|
||||||
#include "p_lx_elf.h"
|
|
||||||
#include "p_lx_sep.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
//#define SCRIPT_SIZE (opt->o_unix.SCRIPT_MAX + sizeof(l_info))
|
|
||||||
#define SCRIPT_SIZE (32 + sizeof(l_info))
|
|
||||||
|
|
||||||
const upx_byte *PackLinuxI386sep::getLoader() const
|
|
||||||
{
|
|
||||||
static char script[SCRIPT_SIZE];
|
|
||||||
|
|
||||||
memset(script, 0, sizeof(script));
|
|
||||||
char const *name = opt->o_unix.script_name;
|
|
||||||
if (0==name) {
|
|
||||||
name = "/usr/local/lib/upxX";
|
|
||||||
}
|
|
||||||
upx_snprintf(script, sizeof(script), "#!%s\n", name);
|
|
||||||
if (M_IS_NRV2B(ph.method)) {
|
|
||||||
script[strlen(script)-2] = 'b';
|
|
||||||
return (upx_byte const *)script;
|
|
||||||
}
|
|
||||||
if (M_IS_NRV2D(ph.method)) {
|
|
||||||
script[strlen(script)-2] = 'd';
|
|
||||||
return (upx_byte const *)script;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PackLinuxI386sep::getLoaderSize() const
|
|
||||||
{
|
|
||||||
if (M_IS_NRV2B(ph.method))
|
|
||||||
return SCRIPT_SIZE;
|
|
||||||
if (M_IS_NRV2D(ph.method))
|
|
||||||
return SCRIPT_SIZE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PackLinuxI386sep::getLoaderPrefixSize() const
|
|
||||||
{
|
|
||||||
return opt->o_unix.SCRIPT_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PackLinuxI386sep::patchLoader()
|
|
||||||
{
|
|
||||||
patchLoaderChecksum();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
vi:ts=4:et
|
|
||||||
*/
|
|
||||||
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/* p_lx_sep.h --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
|
||||||
All Rights Reserved.
|
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
|
||||||
and/or modify them under the terms of the GNU General Public License as
|
|
||||||
published by the Free Software Foundation; either version 2 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation, Inc.,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_LX_SEP_H //{
|
|
||||||
#define __UPX_P_LX_SEP_H
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// linux/sep386
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
class PackLinuxI386sep : public PackLinuxI386elf
|
|
||||||
{
|
|
||||||
typedef PackLinuxI386elf super;
|
|
||||||
public:
|
|
||||||
PackLinuxI386sep(InputFile *f) : super(f) { }
|
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_SEP_i386; }
|
|
||||||
virtual const char *getName() const { return "linux/sep386"; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual const upx_byte *getLoader() const;
|
|
||||||
virtual int getLoaderSize() const;
|
|
||||||
virtual int getLoaderPrefixSize() const;
|
|
||||||
|
|
||||||
virtual void patchLoader();
|
|
||||||
virtual void updateLoader(OutputFile *) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*} already included */
|
|
||||||
|
|
||||||
/*
|
|
||||||
vi:ts=4:et
|
|
||||||
*/
|
|
||||||
|
|
||||||
+13
-10
@@ -22,8 +22,11 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -45,9 +48,9 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_lx_sh86.h"
|
#include "stub/i386-linux.elf.shell-entry.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/fold_sh86.h"
|
#include "stub/i386-linux.elf.shell-fold.h"
|
||||||
|
|
||||||
|
|
||||||
PackLinuxI386sh::PackLinuxI386sh(InputFile *f) :
|
PackLinuxI386sh::PackLinuxI386sh(InputFile *f) :
|
||||||
@@ -68,12 +71,12 @@ umax(unsigned a, unsigned b)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
PackLinuxI386sh::buildLoader(Filter const *ft)
|
PackLinuxI386sh::buildLoader(Filter const *ft)
|
||||||
{
|
{
|
||||||
unsigned const sz_fold = sizeof(linux_i386sh_fold);
|
unsigned const sz_fold = sizeof(stub_i386_linux_elf_shell_fold);
|
||||||
MemBuffer buf(sz_fold);
|
MemBuffer buf(sz_fold);
|
||||||
memcpy(buf, linux_i386sh_fold, sz_fold);
|
memcpy(buf, stub_i386_linux_elf_shell_fold, sz_fold);
|
||||||
|
|
||||||
checkPatch(NULL, 0, 0, 0); // reset
|
checkPatch(NULL, 0, 0, 0); // reset
|
||||||
patch_le32(buf,sz_fold,"UPX3",l_shname);
|
patch_le32(buf,sz_fold,"UPX3",l_shname);
|
||||||
@@ -96,8 +99,8 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
|
|||||||
bool success = fold_ft.filter(buf + fold_hdrlen, sz_fold - fold_hdrlen);
|
bool success = fold_ft.filter(buf + fold_hdrlen, sz_fold - fold_hdrlen);
|
||||||
UNUSED(success);
|
UNUSED(success);
|
||||||
|
|
||||||
return buildLinuxLoader(
|
buildLinuxLoader(
|
||||||
linux_i386sh_loader, sizeof(linux_i386sh_loader),
|
stub_i386_linux_elf_shell_entry, sizeof(stub_i386_linux_elf_shell_entry),
|
||||||
buf, sz_fold, ft );
|
buf, sz_fold, ft );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +158,7 @@ bool PackLinuxI386sh::canPack()
|
|||||||
void
|
void
|
||||||
PackLinuxI386sh::pack1(OutputFile *fo, Filter &)
|
PackLinuxI386sh::pack1(OutputFile *fo, Filter &)
|
||||||
{
|
{
|
||||||
generateElfHdr(fo, linux_i386sh_fold, 0x08048000);
|
generateElfHdr(fo, stub_i386_linux_elf_shell_fold, 0x08048000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
+9
-6
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,8 +22,11 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -45,7 +48,7 @@ public:
|
|||||||
virtual int getFormat() const { return UPX_F_LINUX_SH_i386; }
|
virtual int getFormat() const { return UPX_F_LINUX_SH_i386; }
|
||||||
virtual const char *getName() const { return "linux/sh386"; }
|
virtual const char *getName() const { return "linux/sh386"; }
|
||||||
virtual const int *getFilters() const { return NULL; }
|
virtual const int *getFilters() const { return NULL; }
|
||||||
virtual int buildLoader(const Filter *);
|
virtual void buildLoader(const Filter *);
|
||||||
|
|
||||||
virtual void pack1(OutputFile *fo, Filter &ft);
|
virtual void pack1(OutputFile *fo, Filter &ft);
|
||||||
virtual void pack3(OutputFile *fo, Filter &ft);
|
virtual void pack3(OutputFile *fo, Filter &ft);
|
||||||
|
|||||||
+50
-26
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 2004 John Reiser
|
Copyright (C) 2004-2006 John Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -32,12 +32,12 @@
|
|||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_mach.h"
|
#include "p_mach.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_mac_ppc32.h"
|
#include "stub/powerpc-darwin.macho-entry.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/fold_machppc32.h"
|
#include "stub/powerpc-darwin.macho-fold.h"
|
||||||
|
|
||||||
PackMachPPC32::PackMachPPC32(InputFile *f) :
|
PackMachPPC32::PackMachPPC32(InputFile *f) :
|
||||||
super(f), n_segment(0), rawmseg(0), msegcmd(0)
|
super(f), n_segment(0), rawmseg(0), msegcmd(0)
|
||||||
@@ -64,17 +64,42 @@ const int *PackMachPPC32::getFilters() const
|
|||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
Linker *PackMachPPC32::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerPpc32;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PackMachPPC32::addStubEntrySections(Filter const *)
|
||||||
|
{
|
||||||
|
addLoader("MACOS000", NULL);
|
||||||
|
//addLoader(getDecompressorSections(), NULL);
|
||||||
|
addLoader(
|
||||||
|
( M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E,NRV_TAIL"
|
||||||
|
: M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D,NRV_TAIL"
|
||||||
|
: M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B,NRV_TAIL"
|
||||||
|
: M_IS_LZMA(ph.method) ? "LZMA_ELF00,LZMA_DEC20,LZMA_DEC30"
|
||||||
|
: NULL), NULL);
|
||||||
|
addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PackMachPPC32::defineSymbols(Filter const *)
|
||||||
|
{
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
PackMachPPC32::buildMachLoader(
|
PackMachPPC32::buildMachLoader(
|
||||||
upx_byte const *const proto,
|
upx_byte const *const proto,
|
||||||
unsigned const szproto,
|
unsigned const szproto,
|
||||||
upx_byte const *const fold,
|
upx_byte const *const fold,
|
||||||
unsigned const szfold,
|
unsigned const szfold,
|
||||||
Filter const */*ft*/
|
Filter const *ft
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int eof_empty = -1;
|
initLoader(proto, szproto);
|
||||||
initLoader(&eof_empty, 4096, 0, 0);
|
|
||||||
|
|
||||||
struct b_info h; memset(&h, 0, sizeof(h));
|
struct b_info h; memset(&h, 0, sizeof(h));
|
||||||
unsigned fold_hdrlen = 0;
|
unsigned fold_hdrlen = 0;
|
||||||
@@ -88,7 +113,7 @@ PackMachPPC32::buildMachLoader(
|
|||||||
|
|
||||||
unsigned char *const cprLoader = new unsigned char[sizeof(h) + h.sz_unc];
|
unsigned char *const cprLoader = new unsigned char[sizeof(h) + h.sz_unc];
|
||||||
if (0 < szfold) {
|
if (0 < szfold) {
|
||||||
unsigned sz_cpr;
|
unsigned sz_cpr = 0;
|
||||||
int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &sz_cpr,
|
int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &sz_cpr,
|
||||||
NULL, ph.method, 10, NULL, NULL );
|
NULL, ph.method, 10, NULL, NULL );
|
||||||
h.sz_cpr = sz_cpr;
|
h.sz_cpr = sz_cpr;
|
||||||
@@ -98,25 +123,24 @@ PackMachPPC32::buildMachLoader(
|
|||||||
memcpy(cprLoader, &h, sizeof(h));
|
memcpy(cprLoader, &h, sizeof(h));
|
||||||
|
|
||||||
// This adds the definition to the "library", to be used later.
|
// This adds the definition to the "library", to be used later.
|
||||||
linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + h.sz_cpr);
|
linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + h.sz_cpr, 0);
|
||||||
delete [] cprLoader;
|
delete [] cprLoader;
|
||||||
|
|
||||||
int const GAP = 128; // must match stub/l_mac_ppc.S
|
int const GAP = 128; // must match stub/l_mac_ppc.S
|
||||||
segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + 64;
|
segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + 64;
|
||||||
|
|
||||||
linker->addSection("MACOS000", proto, szproto);
|
addStubEntrySections(ft);
|
||||||
|
|
||||||
addLoader("MACOS000", NULL);
|
defineSymbols(ft);
|
||||||
addLoader("FOLDEXEC", NULL);
|
relocateLoader();
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
PackMachPPC32::buildLoader(const Filter *ft)
|
PackMachPPC32::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
return buildMachLoader(
|
buildMachLoader(
|
||||||
l_mac_ppc32_loader, sizeof(l_mac_ppc32_loader),
|
stub_powerpc_darwin_macho_entry, sizeof(stub_powerpc_darwin_macho_entry),
|
||||||
fold_machppc32, sizeof(fold_machppc32), ft );
|
stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft );
|
||||||
}
|
}
|
||||||
void PackMachPPC32::patchLoader() { }
|
void PackMachPPC32::patchLoader() { }
|
||||||
void PackMachPPC32::updateLoader(OutputFile *) {}
|
void PackMachPPC32::updateLoader(OutputFile *) {}
|
||||||
@@ -124,7 +148,7 @@ void PackMachPPC32::updateLoader(OutputFile *) {}
|
|||||||
void
|
void
|
||||||
PackMachPPC32::patchLoaderChecksum()
|
PackMachPPC32::patchLoaderChecksum()
|
||||||
{
|
{
|
||||||
unsigned char *const ptr = const_cast<unsigned char *>(getLoader());
|
unsigned char *const ptr = getLoader();
|
||||||
l_info *const lp = &linfo;
|
l_info *const lp = &linfo;
|
||||||
// checksum for loader; also some PackHeader info
|
// checksum for loader; also some PackHeader info
|
||||||
lp->l_checksum = 0;
|
lp->l_checksum = 0;
|
||||||
@@ -225,13 +249,13 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
|||||||
unsigned k;
|
unsigned k;
|
||||||
|
|
||||||
// count passes, set ptload vars
|
// count passes, set ptload vars
|
||||||
ui_total_passes = 0;
|
uip->ui_total_passes = 0;
|
||||||
for (k = 0; k < n_segment; ++k) {
|
for (k = 0; k < n_segment; ++k) {
|
||||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
||||||
&& 0!=msegcmd[k].filesize ) {
|
&& 0!=msegcmd[k].filesize ) {
|
||||||
ui_total_passes++;
|
uip->ui_total_passes++;
|
||||||
if (find_SEGMENT_gap(k)) {
|
if (find_SEGMENT_gap(k)) {
|
||||||
ui_total_passes++;
|
uip->ui_total_passes++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,9 +264,9 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
|||||||
unsigned total_in = 0;
|
unsigned total_in = 0;
|
||||||
unsigned total_out = 0;
|
unsigned total_out = 0;
|
||||||
|
|
||||||
unsigned hdr_ulen = mhdri.sizeofcmds;
|
unsigned hdr_u_len = mhdri.sizeofcmds;
|
||||||
|
|
||||||
ui_pass = 0;
|
uip->ui_pass = 0;
|
||||||
ft.addvalue = 0;
|
ft.addvalue = 0;
|
||||||
|
|
||||||
int nx = 0;
|
int nx = 0;
|
||||||
@@ -258,8 +282,8 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
|||||||
}
|
}
|
||||||
packExtent(x, total_in, total_out,
|
packExtent(x, total_in, total_out,
|
||||||
((Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
((Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
||||||
? &ft : 0 ), fo, hdr_ulen );
|
? &ft : 0 ), fo, hdr_u_len );
|
||||||
hdr_ulen = 0;
|
hdr_u_len = 0;
|
||||||
++nx;
|
++nx;
|
||||||
}
|
}
|
||||||
for (k = 0; k < n_segment; ++k) {
|
for (k = 0; k < n_segment; ++k) {
|
||||||
|
|||||||
+8
-5
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -180,16 +180,19 @@ public:
|
|||||||
virtual unsigned find_SEGMENT_gap(unsigned const k);
|
virtual unsigned find_SEGMENT_gap(unsigned const k);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
virtual void patchLoaderChecksum();
|
virtual void patchLoaderChecksum();
|
||||||
virtual void updateLoader(OutputFile *);
|
virtual void updateLoader(OutputFile *);
|
||||||
virtual int buildMachLoader(
|
virtual void buildMachLoader(
|
||||||
upx_byte const *const proto,
|
upx_byte const *const proto,
|
||||||
unsigned const szproto,
|
unsigned const szproto,
|
||||||
upx_byte const *const fold,
|
upx_byte const *const fold,
|
||||||
unsigned const szfold,
|
unsigned const szfold,
|
||||||
Filter const *ft );
|
Filter const *ft );
|
||||||
|
virtual void defineSymbols(Filter const *);
|
||||||
|
virtual void addStubEntrySections(Filter const *);
|
||||||
|
|
||||||
unsigned n_segment;
|
unsigned n_segment;
|
||||||
unsigned sz_segment;
|
unsigned sz_segment;
|
||||||
|
|||||||
+382
-164
@@ -35,30 +35,31 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_ps1.h"
|
#include "p_ps1.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_ps1b.h"
|
#include "stub/mipsel.r3000-ps1.h"
|
||||||
static const
|
|
||||||
#include "stub/l_ps1c.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define MIPS_HI(a) ((a) >> 16)
|
|
||||||
#define MIPS_LO(a) ((a) & 0xffff)
|
|
||||||
#define MIPS_JP(a) ((0x08 << 24) | (((a) & 0x0fffffff) >> 2))
|
|
||||||
#define TIL_ALIGNED(a,b) (((b) - ((a) & ((b) - 1))) & (b) - 1)
|
|
||||||
|
|
||||||
#define CD_SEC 2048
|
#define CD_SEC 2048
|
||||||
#define PS_HDR_SIZE CD_SEC
|
#define PS_HDR_SIZE CD_SEC
|
||||||
#define PS_RAM_SIZE 0x200000
|
#define PS_RAM_SIZE ram_size
|
||||||
#define PS_MIN_SIZE (PS_HDR_SIZE*3)
|
#define PS_MIN_SIZE (PS_HDR_SIZE*3)
|
||||||
#define PS_MAX_SIZE 0x1e8000
|
#define PS_MAX_SIZE ((PS_RAM_SIZE*95) / 100)
|
||||||
|
#define PS_STACK_SIZE (PS_RAM_SIZE / 256)
|
||||||
|
|
||||||
#define SZ_IH_BKUP (10 * sizeof(LE32))
|
#define SZ_IH_BKUP (10 * sizeof(LE32))
|
||||||
#define HD_CODE_OFS (sizeof(ps1_exe_t))
|
#define HD_CODE_OFS (sizeof(ps1_exe_t) + sz_cbh)
|
||||||
|
|
||||||
#define K0_BS (0x80000000)
|
#define K0_BS (0x80000000)
|
||||||
#define K1_BS (0xa0000000)
|
#define K1_BS (0xa0000000)
|
||||||
#define FIX_PSVR (K1_BS - (ih.epc & K0_BS)) + (PS_HDR_SIZE - HD_CODE_OFS)
|
#define EXE_BS (ih.epc & K0_BS)
|
||||||
|
#define FIX_PSVR (K1_BS - EXE_BS) + (PS_HDR_SIZE - HD_CODE_OFS)
|
||||||
|
|
||||||
|
// lui / addiu
|
||||||
|
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
|
||||||
|
#define MIPS_LO(a) ((a) & 0xffff)
|
||||||
|
#define MIPS_PC16(a) ((a) >> 2)
|
||||||
|
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -78,21 +79,24 @@ static const
|
|||||||
PackPs1::PackPs1(InputFile *f) :
|
PackPs1::PackPs1(InputFile *f) :
|
||||||
super(f),
|
super(f),
|
||||||
isCon(!opt->ps1_exe.boot_only), is32Bit(!opt->ps1_exe.do_8bit),
|
isCon(!opt->ps1_exe.boot_only), is32Bit(!opt->ps1_exe.do_8bit),
|
||||||
overlap(0), sa_cnt(0)
|
buildPart2(0), foundBss(0), sa_cnt(0), overlap(0), sz_lunc(0), sz_lcpr(0),
|
||||||
|
pad_code(0), bss_start(0), bss_end(0)
|
||||||
{
|
{
|
||||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 188);
|
bele = &N_BELE_RTP::le_policy;
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 136);
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(ps1_exe_hb_t) == 44);
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(ps1_exe_chb_t) == 5);
|
||||||
|
|
||||||
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t));
|
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t));
|
||||||
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40);
|
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40);
|
||||||
#if 1 || defined(WITH_NRV)
|
#if 0 // 1 || defined(WITH_NRV)
|
||||||
COMPILE_TIME_ASSERT(sizeof(nrv_boot_loader) == 3935);
|
COMPILE_TIME_ASSERT(sizeof(nrv_loader) == 14812);
|
||||||
COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0x0ac25782);
|
COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0x0);
|
||||||
COMPILE_TIME_ASSERT(sizeof(nrv_con_loader) == 2829);
|
|
||||||
COMPILE_TIME_ASSERT(NRV_CON_LOADER_CRC32 == 0x923b55c4);
|
|
||||||
#endif
|
#endif
|
||||||
fdata_size = file_size - PS_HDR_SIZE;
|
fdata_size = file_size - PS_HDR_SIZE;
|
||||||
|
ram_size = !opt->ps1_exe.do_8mb ? 0x200000 : 0x800000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int *PackPs1::getCompressionMethods(int method, int level) const
|
const int *PackPs1::getCompressionMethods(int method, int level) const
|
||||||
{
|
{
|
||||||
if (is32Bit)
|
if (is32Bit)
|
||||||
@@ -101,12 +105,16 @@ const int *PackPs1::getCompressionMethods(int method, int level) const
|
|||||||
return Packer::getDefaultCompressionMethods_8(method, level);
|
return Packer::getDefaultCompressionMethods_8(method, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int *PackPs1::getFilters() const
|
const int *PackPs1::getFilters() const
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker* PackPs1::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerMipsLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// util
|
// util
|
||||||
@@ -126,6 +134,78 @@ int PackPs1::readFileHeader()
|
|||||||
return UPX_F_PS1_EXE;
|
return UPX_F_PS1_EXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PackPs1::readBkupHeader()
|
||||||
|
{
|
||||||
|
fi->seek(sizeof(ps1_exe_t)+8, SEEK_SET);
|
||||||
|
fi->readx(&bh, sizeof(bh));
|
||||||
|
|
||||||
|
if (bh.ih_csum != upx_adler32(&bh, SZ_IH_BKUP))
|
||||||
|
{
|
||||||
|
unsigned char buf[sizeof(bh)];
|
||||||
|
fi->seek(sizeof(ps1_exe_t), SEEK_SET);
|
||||||
|
fi->readx(buf, sizeof(bh));
|
||||||
|
if (!getBkupHeader(buf, (unsigned char *)&bh))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INIT_BH_BKUP(p, l) {(p)->id = '1'; (p)->len = l;}
|
||||||
|
#define ADLER16(a) ((a) >> 16 ^ ((a) & 0xffff))
|
||||||
|
|
||||||
|
void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len)
|
||||||
|
{
|
||||||
|
unsigned sz_cbh = MemBuffer::getSizeForCompression(SZ_IH_BKUP);
|
||||||
|
|
||||||
|
if (src && dst)
|
||||||
|
{
|
||||||
|
unsigned char *cpr_bh = new unsigned char[sz_cbh];
|
||||||
|
|
||||||
|
memset(cpr_bh, 0, sizeof(bh));
|
||||||
|
ps1_exe_chb_t * p = (ps1_exe_chb_t * )cpr_bh;
|
||||||
|
|
||||||
|
int r = upx_compress(src, SZ_IH_BKUP,
|
||||||
|
&p->ih_bkup, &sz_cbh, NULL, M_NRV2E_8, 10, NULL, NULL );
|
||||||
|
if (r != UPX_E_OK || sz_cbh >= SZ_IH_BKUP)
|
||||||
|
throwInternalError("header compression failed");
|
||||||
|
INIT_BH_BKUP(p, sz_cbh);
|
||||||
|
*len = ALIGN_UP(sz_cbh + sizeof(ps1_exe_chb_t) - 1, 4);
|
||||||
|
p->ih_csum = ADLER16(upx_adler32(&ih.epc, SZ_IH_BKUP));
|
||||||
|
memcpy(dst, cpr_bh, SZ_IH_BKUP);
|
||||||
|
delete [] cpr_bh;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throwInternalError("header compression failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ADLER16_HI(a, b) ((((a) & 0xffff) ^ (b)) << 16)
|
||||||
|
#define ADLER16_LO(a, b) (((a) >> 16) ^ (b))
|
||||||
|
#define RE_ADLER16(a, b) (ADLER16_HI(a,b) | ADLER16_LO(a,b))
|
||||||
|
|
||||||
|
bool PackPs1::getBkupHeader(unsigned char *p, unsigned char *dst)
|
||||||
|
{
|
||||||
|
ps1_exe_chb_t *src = (ps1_exe_chb_t*)p;
|
||||||
|
|
||||||
|
if (src && (src->id == '1' && src->len < SZ_IH_BKUP) && dst)
|
||||||
|
{
|
||||||
|
unsigned char *unc_bh = new unsigned char[MemBuffer::getSizeForUncompression(SZ_IH_BKUP)];
|
||||||
|
|
||||||
|
unsigned sz_bh = SZ_IH_BKUP;
|
||||||
|
int r = upx_decompress((const unsigned char *)&src->ih_bkup, src->len,
|
||||||
|
unc_bh, &sz_bh, M_NRV2E_8, NULL );
|
||||||
|
if (r != UPX_E_OK || sz_bh != SZ_IH_BKUP)
|
||||||
|
throwInternalError("header decompression failed");
|
||||||
|
unsigned ad = upx_adler32(unc_bh, SZ_IH_BKUP);
|
||||||
|
unsigned ch = src->ih_csum;
|
||||||
|
if (ad != RE_ADLER16(ad,ch))
|
||||||
|
throwInternalError("backup header damaged");
|
||||||
|
memcpy(dst, unc_bh, SZ_IH_BKUP);
|
||||||
|
delete [] unc_bh;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool PackPs1::checkFileHeader()
|
bool PackPs1::checkFileHeader()
|
||||||
{
|
{
|
||||||
@@ -148,57 +228,24 @@ bool PackPs1::checkFileHeader()
|
|||||||
infoWarning("unsupported header field entry");
|
infoWarning("unsupported header field entry");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!opt->force && ih.is_ptr == 0)
|
if (ih.is_ptr < (EXE_BS | (PS_RAM_SIZE - PS_STACK_SIZE)))
|
||||||
{
|
{
|
||||||
infoWarning("stack pointer field empty");
|
if (!opt->force)
|
||||||
return false;
|
return false;
|
||||||
|
else
|
||||||
|
infoWarning("%s: stack pointer offset low", fi->getName());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// patch util
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
void PackPs1::patch_mips_le(void *b, int blen, const void *old, unsigned new_)
|
|
||||||
{
|
|
||||||
size_t patch_len = strlen((const char*)old);
|
|
||||||
|
|
||||||
if (patch_len == 2)
|
|
||||||
{
|
|
||||||
unsigned char w[2];
|
|
||||||
|
|
||||||
set_le16(w, get_be16(old));
|
|
||||||
patch_le16(b, blen, w, MIPS_LO(new_));
|
|
||||||
}
|
|
||||||
else if (patch_len == 4)
|
|
||||||
{
|
|
||||||
unsigned char w[4];
|
|
||||||
|
|
||||||
set_le32(w, get_be32(old));
|
|
||||||
int boff = find(b, blen, w, 4);
|
|
||||||
|
|
||||||
if (boff == -1)
|
|
||||||
{
|
|
||||||
patch_le16(b, blen, &w[0], MIPS_LO(new_));
|
|
||||||
patch_le16(b, blen, &w[2], MIPS_HI(new_));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
patch_le32((unsigned char *)b + boff, (blen-boff), &w, new_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throwInternalError("bad marker length");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackPs1::canPack()
|
bool PackPs1::canPack()
|
||||||
{
|
{
|
||||||
unsigned char buf[PS_HDR_SIZE-HD_CODE_OFS];
|
unsigned char buf[PS_HDR_SIZE - sizeof(ps1_exe_t)];
|
||||||
|
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
@@ -221,7 +268,7 @@ bool PackPs1::canPack()
|
|||||||
throwCantPack("unsupported header flags (try --force)");
|
throwCantPack("unsupported header flags (try --force)");
|
||||||
if (!opt->force && file_size < PS_MIN_SIZE)
|
if (!opt->force && file_size < PS_MIN_SIZE)
|
||||||
throwCantPack("file is too small (try --force)");
|
throwCantPack("file is too small (try --force)");
|
||||||
if (!opt->force && file_size > PS_MAX_SIZE)
|
if (!opt->force && file_size > (off_t) PS_MAX_SIZE)
|
||||||
throwCantPack("file is too big (try --force)");
|
throwCantPack("file is too big (try --force)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -231,44 +278,184 @@ bool PackPs1::canPack()
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int PackPs1::buildLoader(const Filter *)
|
void PackPs1::buildLoader(const Filter *)
|
||||||
{
|
{
|
||||||
if (isCon)
|
const char *method = NULL;
|
||||||
initLoader(nrv_con_loader,sizeof(nrv_con_loader));
|
|
||||||
else
|
|
||||||
initLoader(nrv_boot_loader,sizeof(nrv_boot_loader));
|
|
||||||
|
|
||||||
addLoader("PS1START",
|
|
||||||
isCon ? ph.c_len & 3 ? "PS1PADCD" : "" : "PS1ENTRY",
|
|
||||||
ih.tx_ptr & 0xffff ? "PS1CONHL" : "PS1CONHI",
|
|
||||||
isCon ? "PS1ENTRY" : "",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (ph.method == M_NRV2B_8)
|
if (ph.method == M_NRV2B_8)
|
||||||
addLoader("PS1N2B08", NULL);
|
method = isCon ? "nrv2b.small,8bit.sub,nrv.done" :
|
||||||
|
"nrv2b.8bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2D_8)
|
else if (ph.method == M_NRV2D_8)
|
||||||
addLoader("PS1N2D08", NULL);
|
method = isCon ? "nrv2d.small,8bit.sub,nrv.done" :
|
||||||
|
"nrv2d.8bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2E_8)
|
else if (ph.method == M_NRV2E_8)
|
||||||
addLoader("PS1N2E08", NULL);
|
method = isCon ? "nrv2e.small,8bit.sub,nrv.done" :
|
||||||
|
"nrv2e.8bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2B_LE32)
|
else if (ph.method == M_NRV2B_LE32)
|
||||||
addLoader("PS1N2B32", NULL);
|
method = isCon ? "nrv2b.small,32bit.sub,nrv.done" :
|
||||||
|
"nrv2b.32bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2D_LE32)
|
else if (ph.method == M_NRV2D_LE32)
|
||||||
addLoader("PS1N2D32", NULL);
|
method = isCon ? "nrv2d.small,32bit.sub,nrv.done" :
|
||||||
|
"nrv2d.32bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2E_LE32)
|
else if (ph.method == M_NRV2E_LE32)
|
||||||
addLoader("PS1N2E32", NULL);
|
method = isCon ? "nrv2e.small,32bit.sub,nrv.done" :
|
||||||
|
"nrv2e.32bit,nrv.done";
|
||||||
|
else if (ph.method == M_LZMA)
|
||||||
|
method = "nrv2b.small,8bit.sub,nrv.done,lzma.prep";
|
||||||
else
|
else
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
|
|
||||||
if (sa_cnt)
|
unsigned sa_tmp = sa_cnt;
|
||||||
addLoader(sa_cnt > (0x10000 << 2) ? "PS1MSETB" : "PS1MSETS",
|
if (ph.overlap_overhead > sa_cnt)
|
||||||
ih.tx_len & 3 ? "PS1MSETU" : "PS1MSETA",
|
{
|
||||||
NULL);
|
if (!opt->force)
|
||||||
|
{
|
||||||
|
infoWarning("not in-place decompressible");
|
||||||
|
throwCantPack("packed data overlap (try --force)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp),4);
|
||||||
|
}
|
||||||
|
|
||||||
addLoader("PS1EXITC", "IDENTSTR", "PS1PAHDR",
|
foundBss = findBssSection();
|
||||||
isCon ? "PS1SREGS" : "",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
return getLoaderSize();
|
if (ph.method == M_LZMA && !buildPart2)
|
||||||
|
{
|
||||||
|
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
|
||||||
|
addLoader("decompressor.start",
|
||||||
|
isCon ? "LZMA_DEC20" : "LZMA_DEC10", "lzma.init", NULL);
|
||||||
|
addLoader(sa_tmp > (0x10000 << 2) ? "memset.long" : "memset.short",
|
||||||
|
!foundBss ? "con.exit" : "bss.exit", NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ph.method == M_LZMA && buildPart2)
|
||||||
|
{
|
||||||
|
sz_lcpr = MemBuffer::getSizeForCompression(sz_lunc);
|
||||||
|
unsigned char *cprLoader = new unsigned char[sz_lcpr];
|
||||||
|
int r = upx_compress(getLoader(), sz_lunc, cprLoader, &sz_lcpr,
|
||||||
|
NULL, M_NRV2B_8, 10, NULL, NULL );
|
||||||
|
if (r != UPX_E_OK || sz_lcpr >= sz_lunc)
|
||||||
|
throwInternalError("loader compression failed");
|
||||||
|
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1),
|
||||||
|
(ph.method != M_LZMA || isCon) ? 0 : 1);
|
||||||
|
linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0);
|
||||||
|
delete [] cprLoader;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
|
||||||
|
|
||||||
|
pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4);
|
||||||
|
assert(pad_code < 4);
|
||||||
|
static const unsigned char pad_buffer[4] = { 0, 0, 0, 0 };
|
||||||
|
linker->addSection("pad.code", pad_buffer, pad_code, 0);
|
||||||
|
|
||||||
|
if (isCon)
|
||||||
|
{
|
||||||
|
if (ph.method == M_LZMA)
|
||||||
|
addLoader(!foundBss ? "con.start" : "bss.con.start",
|
||||||
|
method,
|
||||||
|
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||||
|
"con.entry", "pad.code", "lzma.exec", NULL);
|
||||||
|
else
|
||||||
|
addLoader(!foundBss ? "con.start" : "bss.con.start", "con.mcpy",
|
||||||
|
ph.c_len & 3 ? "con.padcd" : "",
|
||||||
|
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||||
|
"con.entry", method,
|
||||||
|
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
|
||||||
|
!foundBss ? "con.exit" : "bss.exit",
|
||||||
|
"pad.code", NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ph.method == M_LZMA)
|
||||||
|
addLoader("cdb.start.lzma", "pad.code", "cdb.entry.lzma", method, "cdb.lzma.cpr",
|
||||||
|
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||||
|
"lzma.exec", NULL);
|
||||||
|
else
|
||||||
|
addLoader("cdb.start", "pad.code", "cdb.entry",
|
||||||
|
ih.tx_ptr & 0xffff ? "cdb.dec.ptr" : "cdb.dec.ptr.hi",
|
||||||
|
method,
|
||||||
|
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
|
||||||
|
!foundBss ? "cdb.exit" : "bss.exit",
|
||||||
|
"pad.code", NULL);
|
||||||
|
}
|
||||||
|
addLoader("UPX1HEAD", "IDENTSTR", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OPTYPE(x) (((x) >> 13) & 0x7)
|
||||||
|
#define OPCODE(x) (((x) >> 10) & 0x7)
|
||||||
|
#define REG1(x) (((x) >> 5) & 0x1f)
|
||||||
|
#define REG2(x) ((x) & 0x1f)
|
||||||
|
|
||||||
|
#define MIPS_IMM(a,b) (((a) - (((b) & 0x8000) >> 15) << 16) | (b))
|
||||||
|
|
||||||
|
// Type
|
||||||
|
#define REGIMM 1
|
||||||
|
#define STORE 5
|
||||||
|
// Op
|
||||||
|
#define LUI 7
|
||||||
|
#define ADDIU 1
|
||||||
|
#define SW 3
|
||||||
|
|
||||||
|
#define IS_LUI(a) ((OPTYPE(a) == REGIMM && OPCODE(a) == LUI))
|
||||||
|
#define IS_ADDIU(a) ((OPTYPE(a) == REGIMM && OPCODE(a) == ADDIU))
|
||||||
|
#define IS_SW_ZERO(a) ((OPTYPE(a) == STORE && OPCODE(a) == SW) && REG2(a) == 0)
|
||||||
|
|
||||||
|
#define BSS_CHK_LIMIT (18)
|
||||||
|
|
||||||
|
bool PackPs1::findBssSection()
|
||||||
|
{
|
||||||
|
unsigned char reg;
|
||||||
|
LE32 *p1 = (LE32 *)(ibuf + (ih.epc - ih.tx_ptr));
|
||||||
|
|
||||||
|
if ((ih.epc - ih.tx_ptr + (BSS_CHK_LIMIT * 4)) > fdata_size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check 18 opcodes for sw zero,0(x)
|
||||||
|
for (signed i = BSS_CHK_LIMIT; i >= 0; i--)
|
||||||
|
{
|
||||||
|
unsigned short op = p1[i] >> 16;
|
||||||
|
if (IS_SW_ZERO(op))
|
||||||
|
{
|
||||||
|
// found! get reg (x) for bss_start
|
||||||
|
reg = REG1(op);
|
||||||
|
for (; i >= 0; i--)
|
||||||
|
{
|
||||||
|
bss_nfo *p = (bss_nfo *)&p1[i];
|
||||||
|
unsigned short op1 = p->op1, op2 = p->op2;
|
||||||
|
|
||||||
|
// check for la (x),bss_start
|
||||||
|
if ((IS_LUI(op1) && REG2(op1) == reg) &&
|
||||||
|
(IS_ADDIU(op2) && REG1(op2) == reg))
|
||||||
|
{
|
||||||
|
op1 = p->op3, op2 = p->op4;
|
||||||
|
|
||||||
|
// check for la (y),bss_end
|
||||||
|
if (IS_LUI(op1) && IS_ADDIU(op2))
|
||||||
|
{
|
||||||
|
// bss section info found!
|
||||||
|
bss_start = MIPS_IMM(p->hi1, p->lo1);
|
||||||
|
bss_end = MIPS_IMM(p->hi2, p->lo2);
|
||||||
|
|
||||||
|
if (0 < ALIGN_DOWN(bss_end - bss_start, 4) )
|
||||||
|
{
|
||||||
|
unsigned wkmem_sz = (ph.method == M_LZMA) ? 32768 : 800;
|
||||||
|
unsigned end_offs = ih.tx_ptr + fdata_size + overlap;
|
||||||
|
if (bss_end > (end_offs + wkmem_sz))
|
||||||
|
return (isCon || (!isCon && (ph.method == M_LZMA)));
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -301,29 +488,47 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
|
|
||||||
// compress (max_match = 65535)
|
// compress (max_match = 65535)
|
||||||
compressWithFilters(&ft, 512, 0, NULL, 0, 65535);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
cconf.conf_ucl.max_match = 65535;
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||||
|
compressWithFilters(&ft, sa_cnt, 0, NULL, &cconf);
|
||||||
|
|
||||||
if (ph.overlap_overhead > sa_cnt)
|
if (overlap)
|
||||||
{
|
{
|
||||||
if (!opt->force)
|
|
||||||
{
|
|
||||||
infoWarning("not in-place decompressible");
|
|
||||||
throwCantPack("packed data overlap (try --force)");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
overlap = ALIGN_UP((ph.overlap_overhead-sa_cnt),4);
|
|
||||||
opt->info_mode += !opt->info_mode ? 1 : 0;
|
opt->info_mode += !opt->info_mode ? 1 : 0;
|
||||||
infoWarning("%s: memory overlap %d bytes",fi->getName(),overlap);
|
infoWarning("overlap - relocating load address (+%d bytes)", overlap);
|
||||||
|
sa_cnt += overlap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (bss_start && bss_end && !foundBss)
|
||||||
|
infoWarning("%s: .bss section too small - use stack", fi->getName());
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned lzma_init = 0;
|
||||||
|
|
||||||
|
if (ph.method == M_LZMA)
|
||||||
|
{
|
||||||
|
sz_lunc = getLoaderSize();
|
||||||
|
|
||||||
|
lzma_init = 0u - (sz_lunc - linker->getSymbolOffset("lzma.init"));
|
||||||
|
defineDecompressorSymbols();
|
||||||
|
linker->defineSymbol("entry", ih.epc);
|
||||||
|
linker->defineSymbol("SC",
|
||||||
|
sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2);
|
||||||
|
relocateLoader();
|
||||||
|
|
||||||
|
buildPart2 = true;
|
||||||
|
buildLoader(&ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&oh, &ih, sizeof(ih));
|
memcpy(&oh, &ih, sizeof(ih));
|
||||||
memcpy(&oh.ih_bkup, &ih.epc, SZ_IH_BKUP);
|
|
||||||
oh.ih_csum = upx_adler32(&ih.epc, SZ_IH_BKUP);
|
|
||||||
|
|
||||||
if (ih.is_ptr == 0)
|
unsigned sz_cbh;
|
||||||
oh.is_ptr = PS_RAM_SIZE-0x10;
|
putBkupHeader((const unsigned char *)&ih.epc, (unsigned char *)&bh, &sz_cbh);
|
||||||
|
|
||||||
|
if (ih.is_ptr < (EXE_BS | (PS_RAM_SIZE - PS_STACK_SIZE)))
|
||||||
|
oh.is_ptr = (EXE_BS | (PS_RAM_SIZE - 16));
|
||||||
|
|
||||||
if (ih.da_ptr != 0 || ih.da_len != 0 ||
|
if (ih.da_ptr != 0 || ih.da_len != 0 ||
|
||||||
ih.bs_ptr != 0 || ih.bs_len != 0)
|
ih.bs_ptr != 0 || ih.bs_len != 0)
|
||||||
@@ -331,47 +536,46 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
oh.bs_ptr = oh.bs_len = 0;
|
oh.bs_ptr = oh.bs_len = 0;
|
||||||
|
|
||||||
const int lsize = getLoaderSize();
|
const int lsize = getLoaderSize();
|
||||||
MemBuffer loader(lsize);
|
|
||||||
memcpy(loader, getLoader(), lsize);
|
|
||||||
|
|
||||||
patchPackHeader(loader,lsize);
|
|
||||||
|
|
||||||
unsigned pad = 0;
|
|
||||||
unsigned filelen = ALIGN_UP(ih.tx_len, 4);
|
unsigned filelen = ALIGN_UP(ih.tx_len, 4);
|
||||||
unsigned pad_code = TIL_ALIGNED(ph.c_len, 4);
|
|
||||||
|
|
||||||
const unsigned decomp_data_start = ih.tx_ptr;
|
const unsigned decomp_data_start = ih.tx_ptr;
|
||||||
const unsigned comp_data_start = ((decomp_data_start + filelen + overlap) - ph.c_len);
|
const unsigned comp_data_start = (decomp_data_start + filelen + overlap) - ph.c_len;
|
||||||
|
|
||||||
const int h_len = lsize - getLoaderSectionStart("IDENTSTR");
|
const int h_len = lsize - getLoaderSectionStart("UPX1HEAD");
|
||||||
const int c_len = lsize - h_len;
|
|
||||||
int d_len = 0;
|
int d_len = 0;
|
||||||
int e_len = 0;
|
int e_len = 0;
|
||||||
|
|
||||||
if (isCon)
|
if (isCon)
|
||||||
{
|
{
|
||||||
e_len = lsize - h_len;
|
e_len = lsize - h_len;
|
||||||
d_len = e_len - getLoaderSectionStart("PS1ENTRY");
|
d_len = e_len - getLoaderSectionStart("con.entry");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_len = (lsize - h_len) - getLoaderSectionStart("PS1ENTRY");
|
d_len = (lsize - h_len) - getLoaderSectionStart((ph.method == M_LZMA) ? "cdb.entry.lzma" : "cdb.entry");
|
||||||
e_len = (lsize - d_len) - h_len;
|
e_len = (lsize - d_len) - h_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
patch_mips_le(loader,c_len,"JPEP",MIPS_JP(ih.epc));
|
linker->defineSymbol("entry", ih.epc);
|
||||||
if (sa_cnt)
|
linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ?
|
||||||
patch_mips_le(loader,c_len,"SC",
|
sa_cnt >> 5 : sa_cnt >> 2));
|
||||||
MIPS_LO(sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2));
|
linker->defineSymbol("DECO", decomp_data_start);
|
||||||
if (ih.tx_ptr & 0xffff)
|
linker->defineSymbol("ldr_sz", (ph.method == M_LZMA ? sz_lunc + 16 : (d_len-pad_code)));
|
||||||
patch_mips_le(loader,c_len,"DECO",decomp_data_start);
|
|
||||||
else
|
|
||||||
patch_mips_le(loader,c_len,"DE",MIPS_HI(decomp_data_start));
|
|
||||||
|
|
||||||
const unsigned entry = comp_data_start - e_len - pad_code;
|
if (foundBss)
|
||||||
oh.tx_ptr = entry;
|
if (ph.method == M_LZMA)
|
||||||
oh.tx_len = ph.c_len + e_len + pad_code;
|
linker->defineSymbol("wrkmem", bss_end - 160 - getDecompressorWrkmemSize()
|
||||||
oh.epc = comp_data_start - e_len - pad_code;
|
- (sz_lunc + 16));
|
||||||
|
else
|
||||||
|
linker->defineSymbol("wrkmem", bss_end - 16 - (d_len - pad_code));
|
||||||
|
|
||||||
|
|
||||||
|
const unsigned entry = comp_data_start - e_len;
|
||||||
|
oh.epc = oh.tx_ptr = entry;
|
||||||
|
oh.tx_len = ph.c_len + e_len;
|
||||||
|
|
||||||
|
unsigned pad = 0;
|
||||||
|
|
||||||
if (!opt->ps1_exe.no_align)
|
if (!opt->ps1_exe.no_align)
|
||||||
{
|
{
|
||||||
@@ -384,43 +588,53 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
ibuf.clear(0,fdata_size);
|
ibuf.clear(0,fdata_size);
|
||||||
upx_bytep paddata = ibuf;
|
upx_bytep paddata = ibuf;
|
||||||
|
|
||||||
|
if (ph.method == M_LZMA)
|
||||||
|
{
|
||||||
|
linker->defineSymbol("lzma_init_off", lzma_init);
|
||||||
|
linker->defineSymbol("gb_e", linker->getSymbolOffset("gb8_e"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (isCon)
|
||||||
|
linker->defineSymbol("gb_e", linker->getSymbolOffset(is32Bit ? "gb32_e" : "gb8_e"));
|
||||||
|
|
||||||
if (isCon)
|
if (isCon)
|
||||||
{
|
{
|
||||||
if (pad_code)
|
linker->defineSymbol("PAD", pad_code);
|
||||||
patch_mips_le(loader, c_len, "PC", pad_code);
|
if (ph.method == M_LZMA)
|
||||||
patch_mips_le(loader, c_len, "DCRT", entry + (e_len - d_len));
|
linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec")));
|
||||||
patch_mips_le(loader, c_len, "LS",
|
else
|
||||||
d_len + get_le32(&loader[getLoaderSectionStart("PS1SREGS")]));
|
linker->defineSymbol("DCRT", (entry + (e_len - d_len)));
|
||||||
|
|
||||||
// ps1_exe_t structure 188 bytes
|
|
||||||
fo->write(&oh,sizeof(oh));
|
|
||||||
// id & upx header
|
|
||||||
fo->write(loader + e_len,h_len);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
patch_mips_le(loader, c_len, "CPDO", comp_data_start);
|
linker->defineSymbol("PSVR", FIX_PSVR);
|
||||||
patch_mips_le(loader, e_len, "PSVR", FIX_PSVR);
|
linker->defineSymbol("CPDO", comp_data_start);
|
||||||
|
if (ph.method == M_LZMA)
|
||||||
// ps1_exe_t structure 188 bytes
|
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec")
|
||||||
fo->write(&oh,sizeof(oh));
|
- getLoaderSectionStart("cdb.entry.lzma"));
|
||||||
// decompressor
|
|
||||||
fo->write(loader + e_len, d_len);
|
|
||||||
// id & upx header
|
|
||||||
fo->write(loader + e_len + d_len, h_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// header size is 2048 bytes
|
relocateLoader();
|
||||||
fo->write(paddata, PS_HDR_SIZE - fo->getBytesWritten());
|
//linker->dumpSymbols();
|
||||||
// sector alignment
|
MemBuffer loader(lsize);
|
||||||
if (pad)
|
assert(lsize == getLoaderSize());
|
||||||
fo->write(paddata, pad);
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
patchPackHeader(loader, lsize);
|
||||||
|
|
||||||
|
if (!isCon && ph.method == M_LZMA && (HD_CODE_OFS + d_len + h_len) > CD_SEC)
|
||||||
|
throwInternalError("lzma --boot-only loader > 2048");
|
||||||
|
|
||||||
|
// ps1_exe_t structure
|
||||||
|
fo->write(&oh, sizeof(oh));
|
||||||
|
fo->write(&bh, sz_cbh);
|
||||||
|
// decompressor
|
||||||
|
fo->write(loader + e_len, isCon ? h_len : (d_len + h_len));
|
||||||
|
|
||||||
|
// header size is 2048 bytes + sector alignment
|
||||||
|
fo->write(paddata, (pad + PS_HDR_SIZE) - fo->getBytesWritten());
|
||||||
// entry
|
// entry
|
||||||
fo->write(loader, e_len);
|
fo->write(loader, e_len);
|
||||||
// code must be aligned to 4!
|
// compressed body
|
||||||
if (pad_code)
|
|
||||||
fo->write(paddata, pad_code);
|
|
||||||
// compressed binary / data
|
|
||||||
fo->write(obuf, ph.c_len);
|
fo->write(obuf, ph.c_len);
|
||||||
|
|
||||||
verifyOverlappingDecompression();
|
verifyOverlappingDecompression();
|
||||||
@@ -430,13 +644,21 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
#if 0
|
#if 0
|
||||||
printf("%-13s: uncompressed : %8ld bytes\n", getName(), (long) ph.u_len);
|
printf("%-13s: uncompressed : %8ld bytes\n", getName(), (long) ph.u_len);
|
||||||
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len);
|
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len);
|
||||||
printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) lsize - h_len);
|
printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) lsize - h_len - pad_code);
|
||||||
printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc);
|
printf("%-13s: header comp : %8ld bytes\n", getName(), (long) sz_cbh);
|
||||||
|
printf("%-13s: overlap : %8ld bytes\n", getName(), (long) overlap);
|
||||||
printf("%-13s: load address : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr);
|
printf("%-13s: load address : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr);
|
||||||
|
printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc);
|
||||||
|
printf("%-13s: bbs start : %08X bytes\n", getName(), (unsigned int) bss_start);
|
||||||
|
printf("%-13s: bbs end : %08X bytes\n", getName(), (unsigned int) bss_end);
|
||||||
printf("%-13s: eof in mem IF : %08X bytes\n", getName(), (unsigned int) ih.tx_ptr + ih.tx_len);
|
printf("%-13s: eof in mem IF : %08X bytes\n", getName(), (unsigned int) ih.tx_ptr + ih.tx_len);
|
||||||
printf("%-13s: eof in mem OF : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr + oh.tx_len);
|
printf("%-13s: eof in mem OF : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr + oh.tx_len);
|
||||||
|
unsigned char i = 0;
|
||||||
|
if (isCon) { if (foundBss) i = 1; }
|
||||||
|
else { i = 2; if (ph.method == M_LZMA) { if (!foundBss) i = 3; else i = 4; } }
|
||||||
|
const char *loader_method[] = { "con/stack", "con/bss", "cdb", "cdb/stack", "cdb/bss" };
|
||||||
char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);
|
char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);
|
||||||
printf("%-13s: compressor : %s\n", getName(), method_name);
|
printf("%-13s: methods : %s, %s\n", getName(), method_name, loader_method[i]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,11 +671,10 @@ int PackPs1::canUnpack()
|
|||||||
{
|
{
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
if (!readPackHeader(1024))
|
if (!readPackHeader(CD_SEC))
|
||||||
return false;
|
return false;
|
||||||
// check header as set by packer
|
// check header as set by packer
|
||||||
if (ih.ih_csum != upx_adler32(&ih.ih_bkup, SZ_IH_BKUP) &&
|
if (!readBkupHeader() || ph.c_len >= fdata_size)
|
||||||
(ph.c_len >= fdata_size))
|
|
||||||
throwCantUnpack("header damaged");
|
throwCantUnpack("header damaged");
|
||||||
// generic check
|
// generic check
|
||||||
if (!checkFileHeader())
|
if (!checkFileHeader())
|
||||||
@@ -470,7 +691,7 @@ void PackPs1::unpack(OutputFile *fo)
|
|||||||
{
|
{
|
||||||
// restore orig exec hdr
|
// restore orig exec hdr
|
||||||
memcpy(&oh, &ih, sizeof(ih));
|
memcpy(&oh, &ih, sizeof(ih));
|
||||||
memcpy(&oh.epc, &ih.ih_bkup, SZ_IH_BKUP);
|
memcpy(&oh.epc, &bh, SZ_IH_BKUP);
|
||||||
|
|
||||||
// check for removed sector alignment
|
// check for removed sector alignment
|
||||||
assert(oh.tx_len >= ph.u_len);
|
assert(oh.tx_len >= ph.u_len);
|
||||||
@@ -482,9 +703,6 @@ void PackPs1::unpack(OutputFile *fo)
|
|||||||
fi->seek(PS_HDR_SIZE, SEEK_SET);
|
fi->seek(PS_HDR_SIZE, SEEK_SET);
|
||||||
fi->readx(ibuf, fdata_size);
|
fi->readx(ibuf, fdata_size);
|
||||||
|
|
||||||
// clear backup and checksum of header
|
|
||||||
memset(&oh.ih_bkup, 0, SZ_IH_BKUP+4);
|
|
||||||
|
|
||||||
// decompress
|
// decompress
|
||||||
decompress(ibuf + (fdata_size - ph.c_len), obuf);
|
decompress(ibuf + (fdata_size - ph.c_len), obuf);
|
||||||
|
|
||||||
@@ -495,14 +713,14 @@ void PackPs1::unpack(OutputFile *fo)
|
|||||||
fo->write(&oh, sizeof(oh));
|
fo->write(&oh, sizeof(oh));
|
||||||
// align the ps exe header (mode 2 sector data size)
|
// align the ps exe header (mode 2 sector data size)
|
||||||
ibuf.clear();
|
ibuf.clear();
|
||||||
|
fo->write(ibuf, PS_HDR_SIZE - fo->getBytesWritten());
|
||||||
// write uncompressed data + pad
|
// write uncompressed data + pad
|
||||||
fo->write(ibuf, PS_HDR_SIZE - sizeof(oh));
|
|
||||||
obuf.clear(ph.u_len, pad);
|
obuf.clear(ph.u_len, pad);
|
||||||
fo->write(obuf, ph.u_len + pad);
|
fo->write(obuf, ph.u_len + pad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et:nowrap
|
vi:ts=4:et:nowrap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
+40
-14
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2002-2004 Jens Medoch
|
Copyright (C) 2002-2006 Jens Medoch
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -56,8 +56,12 @@ public:
|
|||||||
virtual int canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void patch_mips_le(void *b, int blen, const void *old, unsigned new_);
|
virtual void putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len);
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual bool getBkupHeader(unsigned char *src, unsigned char * dst);
|
||||||
|
virtual bool readBkupHeader();
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual bool findBssSection();
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
virtual bool checkFileHeader();
|
virtual bool checkFileHeader();
|
||||||
@@ -84,24 +88,48 @@ protected:
|
|||||||
LE32 sp, fp, gp0, ra, k0;
|
LE32 sp, fp, gp0, ra, k0;
|
||||||
// origin Jap/USA/Europe
|
// origin Jap/USA/Europe
|
||||||
char origin[60];
|
char origin[60];
|
||||||
|
|
||||||
// some safety space after that
|
|
||||||
char pad[8];
|
|
||||||
// backup of the original header (epc - is_len)
|
// backup of the original header (epc - is_len)
|
||||||
|
// id & the upx header ...
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
// for unpack
|
||||||
|
struct ps1_exe_hb_t
|
||||||
|
{
|
||||||
LE32 ih_bkup[10];
|
LE32 ih_bkup[10];
|
||||||
// plus checksum for the backup
|
// plus checksum for the backup
|
||||||
LE32 ih_csum;
|
LE32 ih_csum;
|
||||||
// id & the upx header.
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
struct ps1_exe_chb_t
|
||||||
|
{
|
||||||
|
unsigned char id;
|
||||||
|
unsigned char len;
|
||||||
|
LE16 ih_csum;
|
||||||
|
unsigned char ih_bkup;
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
typedef struct bss_nfo
|
||||||
|
{
|
||||||
|
LE16 hi1, op1, lo1, op2;
|
||||||
|
LE16 hi2, op3, lo2, op4;
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
ps1_exe_t ih, oh;
|
ps1_exe_t ih, oh;
|
||||||
|
ps1_exe_hb_t bh;
|
||||||
|
|
||||||
bool isCon;
|
bool isCon;
|
||||||
bool is32Bit;
|
bool is32Bit;
|
||||||
unsigned overlap;
|
bool buildPart2;
|
||||||
unsigned sa_cnt;
|
bool foundBss;
|
||||||
|
unsigned ram_size;
|
||||||
|
unsigned sa_cnt, overlap;
|
||||||
|
unsigned sz_lunc, sz_lcpr;
|
||||||
|
unsigned pad_code;
|
||||||
|
unsigned bss_start, bss_end;
|
||||||
// filesize-PS_HDR_SIZE
|
// filesize-PS_HDR_SIZE
|
||||||
unsigned fdata_size;
|
unsigned fdata_size;
|
||||||
};
|
};
|
||||||
@@ -113,5 +141,3 @@ protected:
|
|||||||
/*
|
/*
|
||||||
vi:ts=4:et
|
vi:ts=4:et
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+22
-25
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -32,9 +32,10 @@
|
|||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_com.h"
|
#include "p_com.h"
|
||||||
#include "p_sys.h"
|
#include "p_sys.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_sys.h"
|
#include "stub/i086-dos16.sys.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -67,34 +68,31 @@ void PackSys::patchLoader(OutputFile *fo,
|
|||||||
upx_byte *loader, int lsize,
|
upx_byte *loader, int lsize,
|
||||||
unsigned calls)
|
unsigned calls)
|
||||||
{
|
{
|
||||||
const int filter_id = ph.filter;
|
|
||||||
const int e_len = getLoaderSectionStart("SYSCUTPO");
|
const int e_len = getLoaderSectionStart("SYSCUTPO");
|
||||||
const int d_len = lsize - e_len;
|
const int d_len = lsize - e_len;
|
||||||
assert(e_len > 0 && e_len < 256);
|
assert(e_len > 0 && e_len < 128);
|
||||||
assert(d_len > 0 && d_len < 256);
|
assert(d_len > 0 && d_len < 256);
|
||||||
|
|
||||||
if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe)
|
if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe)
|
||||||
throwNotCompressible();
|
throwNotCompressible();
|
||||||
|
|
||||||
memcpy(loader,ibuf,6); // copy from orig. header
|
// use some fields of the original file
|
||||||
memcpy(loader+8,ibuf+8,2); // opendos wants this word too
|
linker->defineSymbol("attribute", get_le16(ibuf + 4));
|
||||||
|
linker->defineSymbol("interrupt", get_le16(ibuf + 8));
|
||||||
|
|
||||||
unsigned copy_to = ph.u_len + d_len + ph.overlap_overhead;
|
unsigned copy_to = ph.u_len + d_len + ph.overlap_overhead;
|
||||||
|
|
||||||
patch_le16(loader,lsize,"JO",get_le16(ibuf+6)-copy_to-1);
|
linker->defineSymbol("calltrick_calls", calls);
|
||||||
if (filter_id)
|
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
||||||
{
|
linker->defineSymbol("copy_destination", copy_to);
|
||||||
assert(calls > 0);
|
linker->defineSymbol("neg_e_len", 0 - e_len);
|
||||||
patch_le16(loader,lsize,"CT",calls);
|
linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead + 1);
|
||||||
}
|
linker->defineSymbol("original_strategy", get_le16(ibuf + 6));
|
||||||
|
|
||||||
|
relocateLoader();
|
||||||
|
loader = getLoader();
|
||||||
|
|
||||||
patchPackHeader(loader,e_len);
|
patchPackHeader(loader,e_len);
|
||||||
|
|
||||||
const unsigned jmp_pos = find_le16(loader,e_len,get_le16("JM"));
|
|
||||||
patch_le16(loader,e_len,"JM",ph.u_len+ph.overlap_overhead+2-jmp_pos-2);
|
|
||||||
loader[getLoaderSectionStart("SYSSUBSI") - 1] = (upx_byte) -e_len;
|
|
||||||
patch_le16(loader,e_len,"DI",copy_to);
|
|
||||||
patch_le16(loader,e_len,"SI",ph.c_len+e_len+d_len-1);
|
|
||||||
|
|
||||||
// write loader + compressed file
|
// write loader + compressed file
|
||||||
fo->write(loader,e_len); // entry
|
fo->write(loader,e_len); // entry
|
||||||
fo->write(obuf,ph.c_len);
|
fo->write(obuf,ph.c_len);
|
||||||
@@ -102,17 +100,17 @@ void PackSys::patchLoader(OutputFile *fo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackSys::buildLoader(const Filter *ft)
|
void PackSys::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
initLoader(stub_i086_dos16_sys, sizeof(stub_i086_dos16_sys));
|
||||||
addLoader("SYSMAIN1",
|
addLoader("SYSMAIN1",
|
||||||
opt->cpu == opt->CPU_8086 ? "SYSI0861" : "SYSI2861",
|
opt->cpu == opt->CPU_8086 ? "SYSI0861" : "SYSI2861",
|
||||||
"SYSMAIN2,SYSSUBSI",
|
"SYSMAIN2",
|
||||||
ph.first_offset_found == 1 ? "SYSSBBBP" : "",
|
ph.first_offset_found == 1 ? "SYSSBBBP" : "",
|
||||||
ft->id ? "SYSCALLT" : "",
|
ft->id ? "SYSCALLT" : "",
|
||||||
"SYSMAIN3,UPX1HEAD,SYSCUTPO,NRV2B160,NRVDDONE,NRVDECO1",
|
"SYSMAIN3,UPX1HEAD,SYSCUTPO,NRV2B160,NRVDDONE,NRVDECO1",
|
||||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
||||||
"NRVDECO2,NRV2B169",
|
"NRVDECO2",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
@@ -125,7 +123,6 @@ int PackSys::buildLoader(const Filter *ft)
|
|||||||
"SYSJUMP1",
|
"SYSJUMP1",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ protected:
|
|||||||
virtual unsigned getCallTrickOffset() const { return 0; }
|
virtual unsigned getCallTrickOffset() const { return 0; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
|
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+48
-25
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -31,9 +31,10 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_tmt.h"
|
#include "p_tmt.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_tmt.h"
|
#include "stub/i386-dos32.tmt.h"
|
||||||
|
|
||||||
#define EXTRA_INFO 4 // original entry point
|
#define EXTRA_INFO 4 // original entry point
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ static const
|
|||||||
|
|
||||||
PackTmt::PackTmt(InputFile *f) : super(f)
|
PackTmt::PackTmt(InputFile *f) : super(f)
|
||||||
{
|
{
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
COMPILE_TIME_ASSERT(sizeof(tmt_header_t) == 44);
|
COMPILE_TIME_ASSERT(sizeof(tmt_header_t) == 44);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,17 +76,25 @@ unsigned PackTmt::findOverlapOverhead(const upx_bytep buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackTmt::buildLoader(const Filter *ft)
|
Linker* PackTmt::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PackTmt::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
initLoader(stub_i386_dos32_tmt, sizeof(stub_i386_dos32_tmt));
|
||||||
addLoader("IDENTSTR,TMTMAIN1",
|
addLoader("IDENTSTR,TMTMAIN1",
|
||||||
ft->id ? "TMTCALT1" : "",
|
ft->id ? "TMTCALT1" : "",
|
||||||
"TMTMAIN2,UPX1HEAD,TMTCUTPO,+0XXXXXX",
|
"TMTMAIN2,UPX1HEAD,TMTCUTPO",
|
||||||
getDecompressor(),
|
NULL);
|
||||||
"TMTMAIN5",
|
|
||||||
NULL
|
// fake alignment for the start of the decompressor
|
||||||
);
|
linker->defineSymbol("TMTCUTPO", 0x1000);
|
||||||
|
|
||||||
|
addLoader(getDecompressorSections(), "TMTMAIN5", NULL);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
{
|
{
|
||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
@@ -96,7 +106,6 @@ int PackTmt::buildLoader(const Filter *ft)
|
|||||||
"RELOC32J,TMTJUMP1",
|
"RELOC32J,TMTJUMP1",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -175,6 +184,19 @@ bool PackTmt::canPack()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||||
|
{
|
||||||
|
if (ft->id == 0)
|
||||||
|
return false;
|
||||||
|
assert(ft->calls > 0);
|
||||||
|
|
||||||
|
linker->defineSymbol("filter_cto", ft->cto);
|
||||||
|
linker->defineSymbol("filter_length",
|
||||||
|
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||||
|
ft->lastcall - ft->calls * 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -230,30 +252,31 @@ void PackTmt::pack(OutputFile *fo)
|
|||||||
compressWithFilters(&ft, 512);
|
compressWithFilters(&ft, 512);
|
||||||
|
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
MemBuffer loader(lsize);
|
|
||||||
memcpy(loader,getLoader(),lsize);
|
|
||||||
|
|
||||||
const unsigned s_point = getLoaderSection("TMTMAIN1");
|
const unsigned s_point = getLoaderSection("TMTMAIN1");
|
||||||
int e_len = getLoaderSectionStart("TMTCUTPO");
|
int e_len = getLoaderSectionStart("TMTCUTPO");
|
||||||
const unsigned d_len = lsize - e_len;
|
const unsigned d_len = lsize - e_len;
|
||||||
assert(e_len > 0 && s_point > 0);
|
assert(e_len > 0 && s_point > 0);
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
patch_le32(loader,lsize,"JMPO",ih.entry-(ph.u_len+ph.overlap_overhead+d_len));
|
linker->defineSymbol("original_entry", ih.entry);
|
||||||
patchFilter32(loader, lsize, &ft);
|
defineFilterSymbols(linker, &ft);
|
||||||
patchPackHeader(loader,e_len);
|
defineDecompressorSymbols();
|
||||||
|
|
||||||
const unsigned jmp_pos = find_le32(loader,e_len,get_le32("JMPD"));
|
linker->defineSymbol("bytes_to_copy", ph.c_len + d_len);
|
||||||
patch_le32(loader,e_len,"JMPD",ph.u_len+ph.overlap_overhead-jmp_pos-4);
|
linker->defineSymbol("copy_dest", ph.u_len + ph.overlap_overhead + d_len - 1);
|
||||||
|
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
||||||
patch_le32(loader,e_len,"ECX0",ph.c_len+d_len);
|
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x c_len=%x \n\n",
|
||||||
patch_le32(loader,e_len,"EDI0",ph.u_len+ph.overlap_overhead+d_len-1);
|
|
||||||
patch_le32(loader,e_len,"ESI0",ph.c_len+e_len+d_len-1);
|
|
||||||
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x clen=%x \n\n",
|
|
||||||
// e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len);
|
// e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len);
|
||||||
|
|
||||||
|
linker->defineSymbol("TMTCUTPO", ph.u_len + ph.overlap_overhead);
|
||||||
|
relocateLoader();
|
||||||
|
|
||||||
|
MemBuffer loader(lsize);
|
||||||
|
memcpy(loader,getLoader(),lsize);
|
||||||
|
patchPackHeader(loader,e_len);
|
||||||
|
|
||||||
memcpy(&oh,&ih,sizeof(oh));
|
memcpy(&oh,&ih,sizeof(oh));
|
||||||
oh.imagesize = ph.c_len+e_len+d_len; // new size
|
oh.imagesize = ph.c_len + lsize; // new size
|
||||||
oh.entry = s_point; // new entry point
|
oh.entry = s_point; // new entry point
|
||||||
oh.relocsize = 4;
|
oh.relocsize = 4;
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -57,7 +57,8 @@ protected:
|
|||||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
||||||
unsigned range = 0,
|
unsigned range = 0,
|
||||||
unsigned upper_limit = ~0u) const;
|
unsigned upper_limit = ~0u) const;
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
unsigned adam_offset;
|
unsigned adam_offset;
|
||||||
int big_relocs;
|
int big_relocs;
|
||||||
|
|||||||
+311
-218
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -32,21 +32,12 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_tos.h"
|
#include "p_tos.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_t_n2b.h"
|
#include "stub/m68k-atari.tos.h"
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2bs.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2d.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2ds.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2e.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2es.h"
|
|
||||||
|
|
||||||
// #define TESTING
|
//#define TESTING 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -58,6 +49,7 @@ static const
|
|||||||
PackTos::PackTos(InputFile *f) :
|
PackTos::PackTos(InputFile *f) :
|
||||||
super(f)
|
super(f)
|
||||||
{
|
{
|
||||||
|
bele = &N_BELE_RTP::be_policy;
|
||||||
COMPILE_TIME_ASSERT(FH_SIZE == 28);
|
COMPILE_TIME_ASSERT(FH_SIZE == 28);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,30 +67,180 @@ const int *PackTos::getFilters() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const upx_byte *PackTos::getLoader() const
|
Linker* PackTos::newLinker() const
|
||||||
{
|
{
|
||||||
if (M_IS_NRV2B(ph.method))
|
return new ElfLinkerM68k;
|
||||||
return opt->small ? nrv2b_loader_small : nrv2b_loader;
|
|
||||||
if (M_IS_NRV2D(ph.method))
|
|
||||||
return opt->small ? nrv2d_loader_small : nrv2d_loader;
|
|
||||||
if (M_IS_NRV2E(ph.method))
|
|
||||||
return opt->small ? nrv2e_loader_small : nrv2e_loader;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackTos::getLoaderSize() const
|
void PackTos::LinkerSymbols::LoopInfo::init(unsigned count_, bool allow_dbra)
|
||||||
{
|
{
|
||||||
if (M_IS_NRV2B(ph.method))
|
count = value = count_;
|
||||||
return opt->small ? sizeof(nrv2b_loader_small) : sizeof(nrv2b_loader);
|
if (count == 0)
|
||||||
if (M_IS_NRV2D(ph.method))
|
mode = LOOP_NONE;
|
||||||
return opt->small ? sizeof(nrv2d_loader_small) : sizeof(nrv2d_loader);
|
else if (count <= 65536 && allow_dbra)
|
||||||
if (M_IS_NRV2E(ph.method))
|
{
|
||||||
return opt->small ? sizeof(nrv2e_loader_small) : sizeof(nrv2e_loader);
|
mode = LOOP_DBRA;
|
||||||
|
value -= 1;
|
||||||
|
value &= 0xffff;
|
||||||
|
}
|
||||||
|
else if (count <= 65536)
|
||||||
|
{
|
||||||
|
mode = LOOP_SUBQ_W;
|
||||||
|
value &= 0xffff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mode = LOOP_SUBQ_L;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned PackTos::getDecomprOffset(int method, int small) const
|
||||||
|
{
|
||||||
|
UNUSED(small);
|
||||||
|
if (M_IS_NRV2B(method))
|
||||||
|
return 2; // FIXME: do not hardcode this value
|
||||||
|
else if (M_IS_NRV2D(method))
|
||||||
|
return 2; // FIXME: do not hardcode this value
|
||||||
|
else if (M_IS_NRV2E(method))
|
||||||
|
return 2; // FIXME: do not hardcode this value
|
||||||
|
else if (M_IS_LZMA(method))
|
||||||
|
return linker->getSectionSize("__mulsi3");
|
||||||
|
else
|
||||||
|
throwBadLoader();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PackTos::buildLoader(const Filter *ft)
|
||||||
|
{
|
||||||
|
assert(ft->id == 0);
|
||||||
|
|
||||||
|
initLoader(stub_m68k_atari_tos, sizeof(stub_m68k_atari_tos));
|
||||||
|
//linker->dumpSymbols();
|
||||||
|
|
||||||
|
//
|
||||||
|
// part 1a
|
||||||
|
//
|
||||||
|
|
||||||
|
addLoader("entry");
|
||||||
|
|
||||||
|
if (symbols.up21_a6 <= 32767)
|
||||||
|
addLoader("set_up21_a6.w");
|
||||||
|
else if (symbols.up21_d4 <= 32767)
|
||||||
|
addLoader("set_up21_d4.w");
|
||||||
|
else
|
||||||
|
addLoader("set_up21_d4.l");
|
||||||
|
|
||||||
|
assert(symbols.loop1.count || symbols.loop2.count);
|
||||||
|
if (symbols.loop1.count)
|
||||||
|
{
|
||||||
|
if (symbols.loop1.value <= 127)
|
||||||
|
addLoader("loop1_set_count.b");
|
||||||
|
else if (symbols.loop1.value <= 65535)
|
||||||
|
addLoader("loop1_set_count.w");
|
||||||
|
else
|
||||||
|
addLoader("loop1_set_count.l");
|
||||||
|
addLoader("loop1_label");
|
||||||
|
addLoader(opt->small ? "loop1.small" : "loop1.fast");
|
||||||
|
if (symbols.loop1.mode == symbols.LOOP_SUBQ_L)
|
||||||
|
addLoader("loop1_subql");
|
||||||
|
else if (symbols.loop1.mode == symbols.LOOP_SUBQ_W)
|
||||||
|
addLoader("loop1_subqw");
|
||||||
|
else if (symbols.loop1.mode == symbols.LOOP_DBRA)
|
||||||
|
addLoader("loop1_dbra");
|
||||||
|
else
|
||||||
|
throwBadLoader();
|
||||||
|
}
|
||||||
|
if (symbols.loop2.count)
|
||||||
|
{
|
||||||
|
assert(symbols.loop2.mode == symbols.LOOP_DBRA);
|
||||||
|
addLoader(opt->small ? "loop2.small" : "loop2.fast");
|
||||||
|
}
|
||||||
|
|
||||||
|
addLoader("copy_to_stack");
|
||||||
|
|
||||||
|
if (M_IS_NRV2B(ph.method))
|
||||||
|
addLoader("nrv2b.init");
|
||||||
|
else if (M_IS_NRV2D(ph.method))
|
||||||
|
addLoader("nrv2d.init");
|
||||||
|
else if (M_IS_NRV2E(ph.method))
|
||||||
|
addLoader("nrv2e.init");
|
||||||
|
else if (M_IS_LZMA(ph.method))
|
||||||
|
addLoader("lzma.init");
|
||||||
|
else
|
||||||
|
throwBadLoader();
|
||||||
|
|
||||||
|
symbols.up31_d4 = symbols.up31_base_d4 + getDecomprOffset(ph.method, opt->small);
|
||||||
|
symbols.up31_a6 = symbols.up31_base_a6 + getDecomprOffset(ph.method, opt->small);
|
||||||
|
if (symbols.up31_a6 <= 32767)
|
||||||
|
addLoader("jmp_decompressor_a6.w");
|
||||||
|
else if (symbols.up31_d4 <= 32767)
|
||||||
|
addLoader("jmp_decompressor_d4.w");
|
||||||
|
else if (symbols.up31_a6 <= 65534)
|
||||||
|
addLoader("jmp_decompressor_a6.w2");
|
||||||
|
else
|
||||||
|
addLoader("jmp_decompressor_d4.l");
|
||||||
|
|
||||||
|
//
|
||||||
|
// part 1b
|
||||||
|
//
|
||||||
|
|
||||||
|
addLoader("code_on_stack");
|
||||||
|
|
||||||
|
addLoader("clear_dirty_bss");
|
||||||
|
addLoader("loop3_label");
|
||||||
|
addLoader(opt->small ? "loop3.small" : "loop3.fast");
|
||||||
|
if (symbols.loop3.mode == symbols.LOOP_SUBQ_L)
|
||||||
|
addLoader("loop3_subql");
|
||||||
|
else if (symbols.loop3.mode == symbols.LOOP_SUBQ_W)
|
||||||
|
addLoader("loop3_subqw");
|
||||||
|
else if (symbols.loop3.mode == symbols.LOOP_DBRA)
|
||||||
|
addLoader("loop3_dbra");
|
||||||
|
else
|
||||||
|
throwBadLoader();
|
||||||
|
|
||||||
|
addLoader("flush_cache");
|
||||||
|
addLoader("restore_stack");
|
||||||
|
#if 0
|
||||||
|
addLoader("clear_dirty_stack");
|
||||||
|
#endif
|
||||||
|
addLoader("start_program");
|
||||||
|
|
||||||
|
addLoader("IDENTSTR,+40D,UPX1HEAD,CUTPOINT");
|
||||||
|
|
||||||
|
//
|
||||||
|
// part 2
|
||||||
|
//
|
||||||
|
|
||||||
|
if (M_IS_NRV2B(ph.method)) {
|
||||||
|
addLoader(opt->small ? "nrv2b_8.small" : "nrv2b_8.fast");
|
||||||
|
} else if (M_IS_NRV2D(ph.method)) {
|
||||||
|
addLoader(opt->small ? "nrv2d_8.small" : "nrv2d_8.fast");
|
||||||
|
} else if (M_IS_NRV2E(ph.method)) {
|
||||||
|
addLoader(opt->small ? "nrv2e_8.small" : "nrv2e_8.fast");
|
||||||
|
} else if (M_IS_LZMA(ph.method)) {
|
||||||
|
addLoader("__mulsi3");
|
||||||
|
addLoader(opt->small ? "lzma.small" : "lzma.fast");
|
||||||
|
addLoader("lzma.finish");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throwBadLoader();
|
||||||
|
|
||||||
|
if (symbols.need_reloc)
|
||||||
|
addLoader("reloc");
|
||||||
|
|
||||||
|
assert(symbols.loop3.count);
|
||||||
|
if (symbols.loop3.value <= 127)
|
||||||
|
addLoader("loop3_set_count.b");
|
||||||
|
else if (symbols.loop3.value <= 65535)
|
||||||
|
addLoader("loop3_set_count.w");
|
||||||
|
else
|
||||||
|
addLoader("loop3_set_count.l");
|
||||||
|
|
||||||
|
addLoader("jmp_stack");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -184,123 +326,6 @@ bool PackTos::checkFileHeader()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// some 68000 opcodes for patching
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
enum m68k_reg_t {
|
|
||||||
REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7,
|
|
||||||
REG_A0, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned OP_DBRA(int d_reg)
|
|
||||||
{
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
return 0x51c8 | (d_reg & 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned OP_JMP(int a_reg)
|
|
||||||
{
|
|
||||||
// jmp (a0)
|
|
||||||
assert(a_reg >= REG_A0 && a_reg <= REG_A7);
|
|
||||||
return 0x4ed0 | (a_reg & 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned OP_MOVEI_L(int d_reg)
|
|
||||||
{
|
|
||||||
// movei.l #XXXXXXXX,d0
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
return 0x203c | ((d_reg & 7) << 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned OP_MOVEQ(int value, int d_reg)
|
|
||||||
{
|
|
||||||
// moveq.l #0,d0
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
assert(value >= -128 && value <= 127);
|
|
||||||
return 0x7000 | ((d_reg & 7) << 9) | (value & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned OP_SUBQ_L(int value, int d_reg)
|
|
||||||
{
|
|
||||||
// subq.l #X,d0
|
|
||||||
assert(value >= 1 && value <= 8);
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
return 0x5180 | ((value & 7) << 9) | (d_reg & 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned OP_SUBQ_W(int value, int d_reg)
|
|
||||||
{
|
|
||||||
// subq.w #X,d0
|
|
||||||
assert(value >= 1 && value <= 8);
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
return 0x5140 | ((value & 7) << 9) | (d_reg & 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
unsigned PackTos::patch_d_subq(void *b, int blen,
|
|
||||||
int d_reg, unsigned d_value,
|
|
||||||
const char *subq_marker)
|
|
||||||
{
|
|
||||||
// patch a "subq.l #1,d0" or "subq.w #1,d0".
|
|
||||||
// also convert into "dbra" if possible
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
assert((int)d_value > 0);
|
|
||||||
|
|
||||||
int boff = find_be16(b, blen, get_be16(subq_marker));
|
|
||||||
if (boff < 0)
|
|
||||||
throwBadLoader();
|
|
||||||
|
|
||||||
upx_byte *p = (upx_byte *)b + boff;
|
|
||||||
if (p[2] == 0x66) // bne.b XXX
|
|
||||||
checkPatch(b, blen, boff, 4);
|
|
||||||
else
|
|
||||||
checkPatch(b, blen, boff, 2);
|
|
||||||
|
|
||||||
if (d_value > 65536)
|
|
||||||
{
|
|
||||||
set_be16(p, OP_SUBQ_L(1, d_reg)); // subq.l #1,d0
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (p[2] == 0x66) // bne.b XXX
|
|
||||||
{
|
|
||||||
set_be16(p, OP_DBRA(d_reg)); // dbra d0,XXX
|
|
||||||
// adjust and extend branch from 8 to 16 bits
|
|
||||||
int branch = (signed char) p[3];
|
|
||||||
set_be16(p+2, branch+2);
|
|
||||||
// adjust d0
|
|
||||||
d_value -= 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
set_be16(p, OP_SUBQ_W(1, d_reg)); // subq.w #1,d0
|
|
||||||
}
|
|
||||||
d_value &= 0xffff;
|
|
||||||
}
|
|
||||||
return d_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned PackTos::patch_d_loop(void *b, int blen,
|
|
||||||
int d_reg, unsigned d_value,
|
|
||||||
const char *d_marker, const char *subq_marker)
|
|
||||||
{
|
|
||||||
d_value = patch_d_subq(b, blen, d_reg, d_value, subq_marker);
|
|
||||||
|
|
||||||
int boff = find_be32(b, blen, get_be32(d_marker));
|
|
||||||
checkPatch(b, blen, boff, 4);
|
|
||||||
upx_byte *p = (upx_byte *)b + boff;
|
|
||||||
assert(get_be16(p - 2) == OP_MOVEI_L(d_reg)); // move.l #XXXXXXXX,d0
|
|
||||||
set_be32(p, d_value);
|
|
||||||
return d_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// relocs
|
// relocs
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -354,18 +379,6 @@ static int check_relocs(const upx_byte *relocs, unsigned rsize, unsigned isize,
|
|||||||
|
|
||||||
bool PackTos::canPack()
|
bool PackTos::canPack()
|
||||||
{
|
{
|
||||||
#if 0 // debug
|
|
||||||
# define p(x) printf("%-30s 0x%04x\n", #x, x)
|
|
||||||
p(OP_DBRA(REG_D0));
|
|
||||||
p(OP_MOVEI_L(REG_D0));
|
|
||||||
p(OP_MOVEQ(-1, REG_D0));
|
|
||||||
p(OP_MOVEQ(1, REG_D2));
|
|
||||||
p(OP_MOVEQ(1, REG_D3));
|
|
||||||
p(OP_SUBQ_W(1, REG_D0));
|
|
||||||
p(OP_SUBQ_L(1, REG_D0));
|
|
||||||
# undef p
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -386,10 +399,8 @@ void PackTos::fileInfo()
|
|||||||
{
|
{
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return;
|
return;
|
||||||
#if !defined(WITH_GUI)
|
|
||||||
con_fprintf(stdout, " text: %d, data: %d, sym: %d, bss: %d, flags=0x%x\n",
|
con_fprintf(stdout, " text: %d, data: %d, sym: %d, bss: %d, flags=0x%x\n",
|
||||||
(int)ih.fh_text, (int)ih.fh_data, (int)ih.fh_sym, (int)ih.fh_bss, (int)ih.fh_flag);
|
(int)ih.fh_text, (int)ih.fh_data, (int)ih.fh_sym, (int)ih.fh_bss, (int)ih.fh_flag);
|
||||||
#endif /* !defined(WITH_GUI) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -409,6 +420,17 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
const unsigned i_sym = ih.fh_sym;
|
const unsigned i_sym = ih.fh_sym;
|
||||||
const unsigned i_bss = ih.fh_bss;
|
const unsigned i_bss = ih.fh_bss;
|
||||||
|
|
||||||
|
symbols.reset();
|
||||||
|
symbols.need_reloc = false;
|
||||||
|
// prepare symbols for buildLoader() - worst case
|
||||||
|
symbols.loop1.init(65536 + 1);
|
||||||
|
symbols.loop2.init((160 - 1) / 4);
|
||||||
|
symbols.loop3.init(65536 + 1);
|
||||||
|
symbols.up21_d4 = 65536 + 1;
|
||||||
|
symbols.up21_a6 = 65536 + 1;
|
||||||
|
symbols.up31_base_d4 = 65536 + 1;
|
||||||
|
symbols.up31_base_a6 = 65536 + 1;
|
||||||
|
|
||||||
// read file
|
// read file
|
||||||
const unsigned isize = file_size - i_sym;
|
const unsigned isize = file_size - i_sym;
|
||||||
ibuf.alloc(isize);
|
ibuf.alloc(isize);
|
||||||
@@ -417,6 +439,8 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
t = i_text + i_data;
|
t = i_text + i_data;
|
||||||
fi->readx(ibuf,t);
|
fi->readx(ibuf,t);
|
||||||
// skip symbols
|
// skip symbols
|
||||||
|
if (i_sym && opt->exact)
|
||||||
|
throwCantPackExact();
|
||||||
fi->seek(i_sym,SEEK_CUR);
|
fi->seek(i_sym,SEEK_CUR);
|
||||||
// read relocations + overlay
|
// read relocations + overlay
|
||||||
overlay = file_size - (FH_SIZE + i_text + i_data + i_sym);
|
overlay = file_size - (FH_SIZE + i_text + i_data + i_sym);
|
||||||
@@ -430,7 +454,6 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
|
|
||||||
// Check relocs (see load_and_reloc() in freemint/sys/memory.c).
|
// Check relocs (see load_and_reloc() in freemint/sys/memory.c).
|
||||||
// Must work around TOS bugs and lots of broken programs.
|
// Must work around TOS bugs and lots of broken programs.
|
||||||
int r = 0;
|
|
||||||
if (overlay < 4)
|
if (overlay < 4)
|
||||||
{
|
{
|
||||||
// Bug workaround: Whatever this is, silently keep it in
|
// Bug workaround: Whatever this is, silently keep it in
|
||||||
@@ -446,15 +469,17 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
else if (ih.fh_reloc != 0)
|
else if (ih.fh_reloc != 0)
|
||||||
relocsize = 0;
|
relocsize = 0;
|
||||||
else
|
else {
|
||||||
r = check_relocs(ibuf+t, overlay, t, &nrelocs, &relocsize, &overlay);
|
int r = check_relocs(ibuf+t, overlay, t, &nrelocs, &relocsize, &overlay);
|
||||||
|
if (r != 0)
|
||||||
|
throwCantPack("bad relocation table");
|
||||||
|
symbols.need_reloc = true;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0 || defined(TESTING)
|
#if 0 || defined(TESTING)
|
||||||
printf("xx2: %d relocs: %d, overlay: %d, t: %d\n", nrelocs, relocsize, overlay, t);
|
printf("xx2: %d relocs: %d, overlay: %d, t: %d\n", nrelocs, relocsize, overlay, t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (r != 0)
|
|
||||||
throwCantPack("bad relocation table");
|
|
||||||
checkOverlay(overlay);
|
checkOverlay(overlay);
|
||||||
|
|
||||||
// Append original fileheader.
|
// Append original fileheader.
|
||||||
@@ -472,29 +497,43 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
// After compression this will become the first part of the
|
// After compression this will become the first part of the
|
||||||
// data segement. The second part will be the decompressor.
|
// data segement. The second part will be the decompressor.
|
||||||
|
|
||||||
// alloc buffer (2048 is for decompressor and the various alignments)
|
// alloc buffer (4096 is for decompressor and the various alignments)
|
||||||
obuf.allocForCompression(t, 2048);
|
obuf.allocForCompression(t, 4096);
|
||||||
|
|
||||||
// prepare packheader
|
// prepare packheader
|
||||||
ph.u_len = t;
|
ph.u_len = t;
|
||||||
// prepare filter
|
// prepare filter
|
||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
// compress (max_match = 65535)
|
// compress (max_match = 65535)
|
||||||
compressWithFilters(&ft, 512, 0, NULL, 0, 65535);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
cconf.conf_ucl.max_match = 65535;
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||||
|
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||||
|
|
||||||
// get loader
|
//
|
||||||
const unsigned lsize = getLoaderSize();
|
// multipass buildLoader()
|
||||||
const unsigned e_len = get_be16(getLoader()+lsize-6);
|
//
|
||||||
const unsigned d_len = get_be16(getLoader()+lsize-4);
|
|
||||||
const unsigned decomp_offset = get_be16(getLoader()+lsize-2);
|
|
||||||
assert(e_len + d_len == lsize - 6);
|
|
||||||
assert((e_len & 3) == 0 && (d_len & 1) == 0);
|
|
||||||
|
|
||||||
|
// save initial loader
|
||||||
|
const unsigned initial_lsize = getLoaderSize();
|
||||||
|
unsigned last_lsize = initial_lsize;
|
||||||
|
MemBuffer last_loader(last_lsize);
|
||||||
|
memcpy(last_loader, getLoader(), last_lsize);
|
||||||
|
|
||||||
|
unsigned o_text, o_data, o_bss;
|
||||||
|
unsigned e_len, d_len, d_off;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
// The decompressed data will now get placed at this offset:
|
// The decompressed data will now get placed at this offset:
|
||||||
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
|
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
|
||||||
|
|
||||||
// compute addresses
|
// get loader
|
||||||
unsigned o_text, o_data, o_bss;
|
const unsigned lsize = getLoaderSize();
|
||||||
|
e_len = getLoaderSectionStart("CUTPOINT");
|
||||||
|
d_len = lsize - e_len;
|
||||||
|
assert((e_len & 3) == 0 && (d_len & 1) == 0);
|
||||||
|
|
||||||
|
// compute section sizes
|
||||||
o_text = e_len;
|
o_text = e_len;
|
||||||
o_data = ph.c_len;
|
o_data = ph.c_len;
|
||||||
o_bss = i_bss;
|
o_bss = i_bss;
|
||||||
@@ -507,8 +546,8 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// append decompressor (part 2 of loader)
|
// append decompressor (part 2 of loader)
|
||||||
const unsigned d_off = o_data;
|
d_off = o_data;
|
||||||
memcpy(obuf+d_off, getLoader()+e_len, d_len);
|
////memcpy(obuf + d_off, getLoader() + e_len, d_len); // must be done after relocation
|
||||||
o_data += d_len;
|
o_data += d_len;
|
||||||
|
|
||||||
// dword align the len of the final data segment
|
// dword align the len of the final data segment
|
||||||
@@ -533,53 +572,98 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
while (dirty_bss & (dirty_bss_align - 1))
|
while (dirty_bss & (dirty_bss_align - 1))
|
||||||
dirty_bss++;
|
dirty_bss++;
|
||||||
// adjust bss, assert room for some stack
|
// adjust bss, assert room for some stack
|
||||||
if (dirty_bss + 512 > o_bss)
|
unsigned stack = 512 + getDecompressorWrkmemSize();
|
||||||
o_bss = dirty_bss + 512;
|
if (dirty_bss + stack > o_bss)
|
||||||
|
o_bss = dirty_bss + stack;
|
||||||
|
|
||||||
// dword align the len of the final bss segment
|
// dword align the len of the final bss segment
|
||||||
while (o_bss & 3)
|
while (o_bss & 3)
|
||||||
o_bss++;
|
o_bss++;
|
||||||
|
|
||||||
// prepare loader
|
// update symbols for buildLoader()
|
||||||
MemBuffer loader(o_text);
|
|
||||||
memcpy(loader, getLoader(), o_text);
|
|
||||||
|
|
||||||
// patch loader
|
|
||||||
int tmp = patchPackHeader(loader, o_text);
|
|
||||||
assert(tmp + 32 == (int)o_text); UNUSED(tmp);
|
|
||||||
patchVersionYear(loader, o_text);
|
|
||||||
if (!opt->small)
|
|
||||||
patchVersion(loader, o_text);
|
|
||||||
// patch "subq.l #1,d6" or "subq.w #1,d6" - see "up41" below
|
|
||||||
const unsigned dirty_bss_d6 =
|
|
||||||
patch_d_subq(loader, o_text, REG_D6, dirty_bss / dirty_bss_align, "u4");
|
|
||||||
patch_be32(loader, o_text, "up31", d_off + offset + decomp_offset);
|
|
||||||
if (opt->small)
|
if (opt->small)
|
||||||
patch_d_loop(loader, o_text, REG_D0, o_data/4, "up22", "u1");
|
{
|
||||||
|
symbols.loop1.init(o_data / 4);
|
||||||
|
symbols.loop2.init(0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (o_data <= 160)
|
symbols.loop1.init(o_data / 160);
|
||||||
throwNotCompressible();
|
symbols.loop2.init((o_data % 160) / 4);
|
||||||
unsigned loop1 = o_data / 160;
|
|
||||||
unsigned loop2 = o_data % 160;
|
|
||||||
if (loop2 == 0)
|
|
||||||
{
|
|
||||||
loop1--;
|
|
||||||
loop2 = 160;
|
|
||||||
}
|
}
|
||||||
patch_be16(loader, o_text, "u2", OP_MOVEQ(loop2/4-1, REG_D0)); // moveq.l #X,d0
|
symbols.loop3.init(dirty_bss / dirty_bss_align);
|
||||||
patch_d_loop(loader, o_text, REG_D0, loop1, "up22", "u1");
|
|
||||||
}
|
|
||||||
patch_be32(loader,o_text,"up21",o_data + offset);
|
|
||||||
patch_be32(loader,o_text,"up13",i_bss); // p_blen
|
|
||||||
patch_be32(loader,o_text,"up12",i_data); // p_dlen
|
|
||||||
patch_be32(loader,o_text,"up11",i_text); // p_tlen
|
|
||||||
|
|
||||||
// patch decompressor
|
symbols.up21_d4 = o_data + offset;
|
||||||
upx_byte *p = obuf + d_off;
|
symbols.up31_base_d4 = d_off + offset;
|
||||||
// patch "moveq.l #1,d5" or "jmp (ASTACK)"
|
symbols.up21_a6 = symbols.up21_d4 - (i_text + i_data);
|
||||||
patch_be16(p, d_len, "u3", (nrelocs > 0) ? OP_MOVEQ(1, REG_D5) : OP_JMP(REG_A7));
|
symbols.up31_base_a6 = symbols.up31_base_d4 - (i_text + i_data);
|
||||||
patch_be32(p, d_len, "up41", dirty_bss_d6);
|
assert((int)symbols.up21_a6 > 0);
|
||||||
|
assert((int)symbols.up31_base_a6 > 0);
|
||||||
|
|
||||||
|
const unsigned c = linker->getSymbolOffset("code_on_stack");
|
||||||
|
unsigned d;
|
||||||
|
d = linker->getSymbolOffset("flush_cache_rts") - c;
|
||||||
|
symbols.flush_cache_rts_offset = d;
|
||||||
|
d = linker->getSymbolOffset("clear_dirty_stack_loop") - c;
|
||||||
|
symbols.clear_dirty_stack_len = (d + 3) / 4 + 32 - 1;
|
||||||
|
d = linker->getSymbolOffset("code_on_stack_end") - c;
|
||||||
|
symbols.copy_to_stack_len = d / 2 - 1;
|
||||||
|
|
||||||
|
// now re-build loader
|
||||||
|
buildLoader(&ft);
|
||||||
|
unsigned new_lsize = getLoaderSize();
|
||||||
|
//printf("buildLoader %d %d\n", new_lsize, initial_lsize);
|
||||||
|
assert(new_lsize <= initial_lsize);
|
||||||
|
if (new_lsize == last_lsize && memcmp(getLoader(), last_loader, last_lsize) == 0)
|
||||||
|
break;
|
||||||
|
last_lsize = new_lsize;
|
||||||
|
memcpy(last_loader, getLoader(), last_lsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// define symbols and reloc
|
||||||
|
//
|
||||||
|
|
||||||
|
defineDecompressorSymbols();
|
||||||
|
|
||||||
|
linker->defineSymbol("loop1_count", symbols.loop1.value);
|
||||||
|
linker->defineSymbol("loop2_count", symbols.loop2.value);
|
||||||
|
linker->defineSymbol("loop3_count", symbols.loop3.value);
|
||||||
|
|
||||||
|
linker->defineSymbol("orig_p_tlen", i_text);
|
||||||
|
linker->defineSymbol("orig_p_dlen", i_data);
|
||||||
|
linker->defineSymbol("orig_p_blen", i_bss);
|
||||||
|
|
||||||
|
if (symbols.up21_a6 <= 32767)
|
||||||
|
linker->defineSymbol("up21_a6", symbols.up21_a6);
|
||||||
|
else
|
||||||
|
linker->defineSymbol("up21_d4", symbols.up21_d4);
|
||||||
|
|
||||||
|
if (symbols.up31_a6 <= 32767)
|
||||||
|
linker->defineSymbol("up31_a6", symbols.up31_a6);
|
||||||
|
else if (symbols.up31_d4 <= 32767)
|
||||||
|
linker->defineSymbol("up31_d4", symbols.up31_d4);
|
||||||
|
else if (symbols.up31_a6 <= 65534)
|
||||||
|
linker->defineSymbol("up31_a6", symbols.up31_a6 - 32767);
|
||||||
|
else
|
||||||
|
linker->defineSymbol("up31_d4", symbols.up31_d4);
|
||||||
|
#if 0
|
||||||
|
printf("relocsize = %d\n", relocsize);
|
||||||
|
printf("upx21(d4) = %d\n", symbols.up21_d4);
|
||||||
|
printf("upx21(a6) = %d\n", symbols.up21_a6);
|
||||||
|
printf("upx31(d4) = %d\n", symbols.up31_d4);
|
||||||
|
printf("upx31(a6) = %d\n", symbols.up31_a6);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
linker->defineSymbol("flush_cache_rts_offset", symbols.flush_cache_rts_offset);
|
||||||
|
linker->defineSymbol("copy_to_stack_len", symbols.copy_to_stack_len);
|
||||||
|
linker->defineSymbol("clear_dirty_stack_len", symbols.clear_dirty_stack_len);
|
||||||
|
|
||||||
|
relocateLoader();
|
||||||
|
|
||||||
|
//
|
||||||
|
// write
|
||||||
|
//
|
||||||
|
|
||||||
// set new file_hdr
|
// set new file_hdr
|
||||||
memcpy(&oh, &ih, FH_SIZE);
|
memcpy(&oh, &ih, FH_SIZE);
|
||||||
@@ -605,13 +689,22 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
#if 0 || defined(TESTING)
|
#if 0 || defined(TESTING)
|
||||||
printf("old text: %6d, data: %6d, bss: %6d, reloc: %d, overlay: %d\n",
|
printf("old text: %6d, data: %6d, bss: %6d, reloc: %d, overlay: %d\n",
|
||||||
i_text, i_data, i_bss, relocsize, overlay);
|
i_text, i_data, i_bss, relocsize, overlay);
|
||||||
printf("new text: %6d, data: %6d, bss: %6d, dirty_bss: %d, flag=0x%x\n",
|
printf("new text: %6d, data: %6d, bss: %6d, flag=0x%x\n",
|
||||||
o_text, o_data, o_bss, dirty_bss, (int)oh.fh_flag);
|
o_text, o_data, o_bss, (int)oh.fh_flag);
|
||||||
|
linker->dumpSymbols();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// prepare loader
|
||||||
|
MemBuffer loader(o_text);
|
||||||
|
memcpy(loader, getLoader(), o_text);
|
||||||
|
patchPackHeader(loader, o_text);
|
||||||
|
|
||||||
// write new file header, loader and compressed file
|
// write new file header, loader and compressed file
|
||||||
fo->write(&oh, FH_SIZE);
|
fo->write(&oh, FH_SIZE);
|
||||||
fo->write(loader, o_text); // entry
|
fo->write(loader, o_text); // entry
|
||||||
|
if (opt->debug.dump_stub_loader)
|
||||||
|
OutputFile::dump(opt->debug.dump_stub_loader, loader, o_text);
|
||||||
|
memcpy(obuf + d_off, getLoader() + e_len, d_len); // copy decompressor
|
||||||
fo->write(obuf, o_data); // compressed + decompressor
|
fo->write(obuf, o_data); // compressed + decompressor
|
||||||
|
|
||||||
// write empty relocation fixup
|
// write empty relocation fixup
|
||||||
|
|||||||
+33
-7
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -54,8 +54,9 @@ public:
|
|||||||
virtual void fileInfo();
|
virtual void fileInfo();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual const upx_byte *getLoader() const;
|
virtual Linker* newLinker() const;
|
||||||
virtual int getLoaderSize() const;
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
unsigned getDecomprOffset(int method, int small) const;
|
||||||
|
|
||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
virtual bool checkFileHeader();
|
virtual bool checkFileHeader();
|
||||||
@@ -75,9 +76,34 @@ protected:
|
|||||||
|
|
||||||
tos_header_t ih, oh;
|
tos_header_t ih, oh;
|
||||||
|
|
||||||
protected:
|
// symbols for buildLoader()
|
||||||
unsigned patch_d_subq(void *l, int llen, int, unsigned, const char*);
|
struct LinkerSymbols
|
||||||
unsigned patch_d_loop(void *l, int llen, int, unsigned, const char*, const char*);
|
{
|
||||||
|
enum { LOOP_NONE, LOOP_SUBQ_L, LOOP_SUBQ_W, LOOP_DBRA };
|
||||||
|
struct LoopInfo {
|
||||||
|
unsigned mode; unsigned count; unsigned value;
|
||||||
|
void init(unsigned count, bool allow_dbra=true);
|
||||||
|
};
|
||||||
|
// buildLoader() input
|
||||||
|
bool need_reloc;
|
||||||
|
LoopInfo loop1;
|
||||||
|
LoopInfo loop2;
|
||||||
|
LoopInfo loop3;
|
||||||
|
unsigned up21_d4;
|
||||||
|
unsigned up21_a6;
|
||||||
|
unsigned up31_base_d4;
|
||||||
|
unsigned up31_base_a6;
|
||||||
|
// buildLoader() output
|
||||||
|
unsigned up31_d4;
|
||||||
|
unsigned up31_a6;
|
||||||
|
// currently not used by buildLoader()
|
||||||
|
unsigned flush_cache_rts_offset;
|
||||||
|
unsigned clear_dirty_stack_len;
|
||||||
|
unsigned copy_to_stack_len;
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
LinkerSymbols symbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+29
-30
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -225,7 +225,7 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
|
|||||||
void
|
void
|
||||||
PackUnix::patchLoaderChecksum()
|
PackUnix::patchLoaderChecksum()
|
||||||
{
|
{
|
||||||
unsigned char *const ptr = const_cast<unsigned char *>(getLoader());
|
unsigned char *const ptr = getLoader();
|
||||||
l_info *const lp = &linfo;
|
l_info *const lp = &linfo;
|
||||||
// checksum for loader; also some PackHeader info
|
// checksum for loader; also some PackHeader info
|
||||||
lp->l_magic = UPX_MAGIC_LE32; // LE32 always
|
lp->l_magic = UPX_MAGIC_LE32; // LE32 always
|
||||||
@@ -236,11 +236,10 @@ PackUnix::patchLoaderChecksum()
|
|||||||
lp->l_checksum = upx_adler32(ptr, lsize);
|
lp->l_checksum = upx_adler32(ptr, lsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackUnix::pack3(OutputFile *fo, Filter &ft)
|
void PackUnix::pack3(OutputFile *fo, Filter &/*ft*/)
|
||||||
{
|
{
|
||||||
upx_byte const *p = getLoader();
|
upx_byte *p = getLoader();
|
||||||
lsize = getLoaderSize();
|
lsize = getLoaderSize();
|
||||||
patchFilter32(const_cast<upx_byte *>(p), lsize, &ft);
|
|
||||||
updateLoader(fo);
|
updateLoader(fo);
|
||||||
patchLoaderChecksum();
|
patchLoaderChecksum();
|
||||||
fo->write(p, lsize);
|
fo->write(p, lsize);
|
||||||
@@ -305,16 +304,16 @@ void PackUnix::packExtent(
|
|||||||
unsigned &total_out,
|
unsigned &total_out,
|
||||||
Filter *ft,
|
Filter *ft,
|
||||||
OutputFile *fo,
|
OutputFile *fo,
|
||||||
unsigned hdr_ulen
|
unsigned hdr_u_len
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned const init_u_adler = ph.u_adler;
|
unsigned const init_u_adler = ph.u_adler;
|
||||||
unsigned const init_c_adler = ph.c_adler;
|
unsigned const init_c_adler = ph.c_adler;
|
||||||
MemBuffer hdr_ibuf;
|
MemBuffer hdr_ibuf;
|
||||||
if (hdr_ulen) {
|
if (hdr_u_len) {
|
||||||
hdr_ibuf.alloc(hdr_ulen);
|
hdr_ibuf.alloc(hdr_u_len);
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
int l = fi->readx(hdr_ibuf, hdr_ulen);
|
int l = fi->readx(hdr_ibuf, hdr_u_len);
|
||||||
(void)l;
|
(void)l;
|
||||||
}
|
}
|
||||||
fi->seek(x.offset, SEEK_SET);
|
fi->seek(x.offset, SEEK_SET);
|
||||||
@@ -347,8 +346,8 @@ void PackUnix::packExtent(
|
|||||||
ft->cto = 0;
|
ft->cto = 0;
|
||||||
|
|
||||||
compressWithFilters(ft, OVERHEAD, strategy,
|
compressWithFilters(ft, OVERHEAD, strategy,
|
||||||
NULL, 0, 0, 0, 0, // those 5 args are the defaults
|
NULL, NULL, 0, 0, // those 4 args are the defaults
|
||||||
hdr_ibuf, hdr_ulen);
|
hdr_ibuf, hdr_u_len);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(void) compress(ibuf, obuf); // ignore return value
|
(void) compress(ibuf, obuf); // ignore return value
|
||||||
@@ -371,31 +370,31 @@ void PackUnix::packExtent(
|
|||||||
|
|
||||||
// write block sizes
|
// write block sizes
|
||||||
b_info tmp;
|
b_info tmp;
|
||||||
if (hdr_ulen) {
|
if (hdr_u_len) {
|
||||||
unsigned hdr_clen;
|
unsigned hdr_c_len = 0;
|
||||||
MemBuffer hdr_obuf;
|
MemBuffer hdr_obuf;
|
||||||
unsigned result[16];
|
hdr_obuf.allocForCompression(hdr_u_len);
|
||||||
upx_compress_config_t conf;
|
int r = upx_compress(hdr_ibuf, hdr_u_len, hdr_obuf, &hdr_c_len, 0,
|
||||||
memset(&conf, 0xff, sizeof(conf));
|
ph.method, 10, NULL, NULL);
|
||||||
hdr_obuf.allocForCompression(hdr_ulen);
|
if (r != UPX_E_OK)
|
||||||
int r = upx_compress(hdr_ibuf, hdr_ulen, hdr_obuf, &hdr_clen, 0,
|
throwInternalError("header compression failed");
|
||||||
ph.method, 10, &conf, result);
|
if (hdr_c_len >= hdr_u_len)
|
||||||
(void)r;
|
throwInternalError("header compression size increase");
|
||||||
ph.saved_u_adler = upx_adler32(hdr_ibuf, hdr_ulen, init_u_adler);
|
ph.saved_u_adler = upx_adler32(hdr_ibuf, hdr_u_len, init_u_adler);
|
||||||
ph.saved_c_adler = upx_adler32(hdr_obuf, hdr_clen, init_c_adler);
|
ph.saved_c_adler = upx_adler32(hdr_obuf, hdr_c_len, init_c_adler);
|
||||||
ph.u_adler = upx_adler32(ibuf, ph.u_len, ph.saved_u_adler);
|
ph.u_adler = upx_adler32(ibuf, ph.u_len, ph.saved_u_adler);
|
||||||
ph.c_adler = upx_adler32(obuf, ph.c_len, ph.saved_c_adler);
|
ph.c_adler = upx_adler32(obuf, ph.c_len, ph.saved_c_adler);
|
||||||
end_u_adler = ph.u_adler;
|
end_u_adler = ph.u_adler;
|
||||||
memset(&tmp, 0, sizeof(tmp));
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
set_native32(&tmp.sz_unc, hdr_ulen);
|
set_native32(&tmp.sz_unc, hdr_u_len);
|
||||||
set_native32(&tmp.sz_cpr, hdr_clen);
|
set_native32(&tmp.sz_cpr, hdr_c_len);
|
||||||
tmp.b_method = (unsigned char) ph.method;
|
tmp.b_method = (unsigned char) ph.method;
|
||||||
fo->write(&tmp, sizeof(tmp));
|
fo->write(&tmp, sizeof(tmp));
|
||||||
b_len += sizeof(b_info);
|
b_len += sizeof(b_info);
|
||||||
fo->write(hdr_obuf, hdr_clen);
|
fo->write(hdr_obuf, hdr_c_len);
|
||||||
total_out += hdr_clen;
|
total_out += hdr_c_len;
|
||||||
total_in += hdr_ulen;
|
total_in += hdr_u_len;
|
||||||
hdr_ulen = 0; // compress hdr one time only
|
hdr_u_len = 0; // compress hdr one time only
|
||||||
}
|
}
|
||||||
memset(&tmp, 0, sizeof(tmp));
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
set_native32(&tmp.sz_unc, ph.u_len);
|
set_native32(&tmp.sz_unc, ph.u_len);
|
||||||
|
|||||||
+7
-7
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -111,9 +111,9 @@ protected:
|
|||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
struct l_info { // 12-byte trailer in header for loader
|
struct l_info { // 12-byte trailer in header for loader
|
||||||
unsigned l_checksum;
|
LE32 l_checksum;
|
||||||
unsigned l_magic;
|
LE32 l_magic;
|
||||||
unsigned short l_lsize;
|
LE16 l_lsize;
|
||||||
unsigned char l_version;
|
unsigned char l_version;
|
||||||
unsigned char l_format;
|
unsigned char l_format;
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ class PackUnixBe32 : public PackUnix
|
|||||||
{
|
{
|
||||||
typedef PackUnix super;
|
typedef PackUnix super;
|
||||||
protected:
|
protected:
|
||||||
PackUnixBe32(InputFile *f) : super(f) { }
|
PackUnixBe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::be_policy; }
|
||||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
|
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
|
||||||
virtual unsigned get_native32(const void *b) const { return get_be32(b); }
|
virtual unsigned get_native32(const void *b) const { return get_be32(b); }
|
||||||
virtual unsigned get_native16(const void *b) const { return get_be16(b); }
|
virtual unsigned get_native16(const void *b) const { return get_be16(b); }
|
||||||
@@ -182,7 +182,7 @@ class PackUnixLe32 : public PackUnix
|
|||||||
{
|
{
|
||||||
typedef PackUnix super;
|
typedef PackUnix super;
|
||||||
protected:
|
protected:
|
||||||
PackUnixLe32(InputFile *f) : super(f) { }
|
PackUnixLe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
||||||
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
||||||
virtual unsigned get_native16(const void *b) const { return get_le16(b); }
|
virtual unsigned get_native16(const void *b) const { return get_le16(b); }
|
||||||
|
|||||||
+171
-79
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 2004 John Reiser
|
Copyright (C) 2004-2006 John Reiser
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -36,21 +36,24 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_vmlinx.h"
|
#include "p_vmlinx.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_vmlinx.h"
|
#include "stub/i386-linux.kernel.vmlinux.h"
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
PackVmlinuxI386::PackVmlinuxI386(InputFile *f) :
|
PackVmlinuxI386::PackVmlinuxI386(InputFile *f) :
|
||||||
super(f), n_ptload(0), phdri(NULL), shdri(NULL)
|
super(f), n_ptload(0), phdri(NULL), shdri(NULL), shstrtab(NULL)
|
||||||
{
|
{
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
PackVmlinuxI386::~PackVmlinuxI386()
|
PackVmlinuxI386::~PackVmlinuxI386()
|
||||||
{
|
{
|
||||||
|
delete [] shstrtab;
|
||||||
delete [] phdri;
|
delete [] phdri;
|
||||||
delete [] shdri;
|
delete [] shdri;
|
||||||
}
|
}
|
||||||
@@ -64,11 +67,50 @@ const int *PackVmlinuxI386::getCompressionMethods(int method, int level) const
|
|||||||
const int *PackVmlinuxI386::getFilters() const
|
const int *PackVmlinuxI386::getFilters() const
|
||||||
{
|
{
|
||||||
static const int filters[] = {
|
static const int filters[] = {
|
||||||
0x49,
|
0x49, 0x46,
|
||||||
-1 };
|
-1 };
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copied from PackUnix 2006-10-13.
|
||||||
|
int PackVmlinuxI386::getStrategy(Filter &/*ft*/)
|
||||||
|
{
|
||||||
|
// Called just before reading and compressing each block.
|
||||||
|
// Might want to adjust blocksize, etc.
|
||||||
|
|
||||||
|
// If user specified the filter, then use it (-2==strategy).
|
||||||
|
// Else try the first two filters, and pick the better (2==strategy).
|
||||||
|
return (opt->no_filter ? -3 : ((opt->filter > 0) ? -2 : 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Elf_LE32_Shdr const *
|
||||||
|
PackVmlinuxI386::getElfSections()
|
||||||
|
{
|
||||||
|
Elf_LE32_Shdr const *p, *shstrsec=0;
|
||||||
|
shdri = new Elf_LE32_Shdr[(unsigned) ehdri.e_shnum];
|
||||||
|
fi->seek(ehdri.e_shoff, SEEK_SET);
|
||||||
|
fi->readx(shdri, ehdri.e_shnum * sizeof(*shdri));
|
||||||
|
int j;
|
||||||
|
for (p = shdri, j= ehdri.e_shnum; --j>=0; ++p) {
|
||||||
|
if (Elf32_Shdr::SHT_STRTAB==p->sh_type
|
||||||
|
&& (p->sh_size + p->sh_offset) <= (unsigned) file_size
|
||||||
|
&& (10+ p->sh_name) <= p->sh_size // 1+ strlen(".shstrtab")
|
||||||
|
) {
|
||||||
|
delete [] shstrtab;
|
||||||
|
shstrtab = new char[1+ p->sh_size];
|
||||||
|
fi->seek(p->sh_offset, SEEK_SET);
|
||||||
|
fi->readx(shstrtab, p->sh_size);
|
||||||
|
shstrtab[p->sh_size] = '\0';
|
||||||
|
if (0==strcmp(".shstrtab", shstrtab + p->sh_name)) {
|
||||||
|
shstrsec = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shstrsec;
|
||||||
|
}
|
||||||
|
|
||||||
static int __acc_cdecl_qsort
|
static int __acc_cdecl_qsort
|
||||||
compare_Phdr(void const *aa, void const *bb)
|
compare_Phdr(void const *aa, void const *bb)
|
||||||
{
|
{
|
||||||
@@ -101,6 +143,12 @@ compare_Phdr(void const *aa, void const *bb)
|
|||||||
// LOAD 0x249000 0x02348000 0x02348000 0x81800 0xcb0fc RWE 0x1000
|
// LOAD 0x249000 0x02348000 0x02348000 0x81800 0xcb0fc RWE 0x1000
|
||||||
// STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
|
// STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
|
||||||
//
|
//
|
||||||
|
//----- kernel-2.6.18-1.2778 Fedora Core 6 test 3
|
||||||
|
//Program Headers(3)
|
||||||
|
// Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
|
||||||
|
// LOAD 0x001000 0xc0400000 0x00400000 0x279820 0x279820 R E 0x1000
|
||||||
|
// LOAD 0x27b000 0xc067a000 0x0067a000 0x10ee64 0x1b07e8 RWE 0x1000
|
||||||
|
// NOTE 0x000000 0x00000000 0x00000000 0x00000 0x00000 R 0x4
|
||||||
|
|
||||||
bool PackVmlinuxI386::canPack()
|
bool PackVmlinuxI386::canPack()
|
||||||
{
|
{
|
||||||
@@ -120,12 +168,29 @@ bool PackVmlinuxI386::canPack()
|
|||||||
|| ehdri.e_phoff != sizeof(ehdri) // Phdrs not contiguous with Ehdr
|
|| ehdri.e_phoff != sizeof(ehdri) // Phdrs not contiguous with Ehdr
|
||||||
|| ehdri.e_phentsize!=sizeof(Elf32_Phdr)
|
|| ehdri.e_phentsize!=sizeof(Elf32_Phdr)
|
||||||
|| ehdri.e_type!=Elf32_Ehdr::ET_EXEC
|
|| ehdri.e_type!=Elf32_Ehdr::ET_EXEC
|
||||||
|| 0x00100000!=(0x001fffff & ehdri.e_entry) // entry not an odd 1MB
|
|| 0!=(0x000fffff & ehdri.e_entry) // entry not on whole 1MB
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
phdri = new Elf32_Phdr[(unsigned) ehdri.e_phnum];
|
// A Linux kernel must have a __ksymtab section. [??]
|
||||||
|
Elf_LE32_Shdr const *p, *const shstrsec = getElfSections();
|
||||||
|
if (0==shstrsec) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (p = shdri, j= ehdri.e_shnum; --j>=0; ++p) {
|
||||||
|
if (Elf32_Shdr::SHT_PROGBITS==p->sh_type
|
||||||
|
&& 0==strcmp("__ksymtab", p->sh_name + shstrtab)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j < 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
phdri = new Elf_LE32_Phdr[(unsigned) ehdri.e_phnum];
|
||||||
fi->seek(ehdri.e_phoff, SEEK_SET);
|
fi->seek(ehdri.e_phoff, SEEK_SET);
|
||||||
fi->readx(phdri, ehdri.e_phnum * sizeof(*phdri));
|
fi->readx(phdri, ehdri.e_phnum * sizeof(*phdri));
|
||||||
|
|
||||||
@@ -153,14 +218,21 @@ bool PackVmlinuxI386::canPack()
|
|||||||
return 0 < n_ptload;
|
return 0 < n_ptload;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PackVmlinuxI386::buildLoader(const Filter *ft)
|
|
||||||
|
Linker* PackVmlinuxI386::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PackVmlinuxI386::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
initLoader(stub_i386_linux_kernel_vmlinux, sizeof(stub_i386_linux_kernel_vmlinux));
|
||||||
addLoader("LINUX000",
|
addLoader("LINUX000",
|
||||||
(0x40==(0xf0 & ft->id)) ? "LXCKLLT1" : (ft->id ? "LXCALLT1" : ""),
|
(0x40==(0xf0 & ft->id)) ? "LXCKLLT1" : (ft->id ? "LXCALLT1" : ""),
|
||||||
"LXMOVEUP",
|
"LXMOVEUP",
|
||||||
getDecompressor(),
|
getDecompressorSections(),
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
@@ -175,10 +247,27 @@ int PackVmlinuxI386::buildLoader(const Filter *ft)
|
|||||||
addFilter32(ft->id);
|
addFilter32(ft->id);
|
||||||
}
|
}
|
||||||
addLoader("LINUX990,IDENTSTR,UPX1HEAD", NULL);
|
addLoader("LINUX990,IDENTSTR,UPX1HEAD", NULL);
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||||
|
{
|
||||||
|
if (ft->id == 0) {
|
||||||
|
linker->defineSymbol("filter_length", 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
assert(ft->calls > 0);
|
||||||
|
|
||||||
|
linker->defineSymbol("filter_cto", ft->cto);
|
||||||
|
linker->defineSymbol("filter_length",
|
||||||
|
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||||
|
ft->lastcall - ft->calls * 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const
|
||||||
|
#include "stub/i386-linux.kernel.vmlinux-head.h"
|
||||||
|
|
||||||
void PackVmlinuxI386::pack(OutputFile *fo)
|
void PackVmlinuxI386::pack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
unsigned fo_off = 0;
|
unsigned fo_off = 0;
|
||||||
@@ -190,8 +279,6 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
|||||||
// .shstrtab /* .symtab .strtab */
|
// .shstrtab /* .symtab .strtab */
|
||||||
Elf32_Shdr shdro[1+3+1/*+2*/];
|
Elf32_Shdr shdro[1+3+1/*+2*/];
|
||||||
memset(shdro, 0, sizeof(shdro));
|
memset(shdro, 0, sizeof(shdro));
|
||||||
char const shstrtab[]= "\0.text\0.note\0.shstrtab\0.symtab\0.strtab";
|
|
||||||
char const *p = shstrtab;
|
|
||||||
|
|
||||||
ibuf.alloc(file_size);
|
ibuf.alloc(file_size);
|
||||||
obuf.allocForCompression(file_size);
|
obuf.allocForCompression(file_size);
|
||||||
@@ -219,27 +306,45 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
|||||||
ft.buf_len = ph.u_len;
|
ft.buf_len = ph.u_len;
|
||||||
ft.addvalue = 0; // we are independent of actual runtime address; see ckt32
|
ft.addvalue = 0; // we are independent of actual runtime address; see ckt32
|
||||||
|
|
||||||
compressWithFilters(&ft, 1 << 20);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
// limit stack size needed for runtime decompression
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||||
|
compressWithFilters(&ft, 512, getStrategy(ft), getFilters(), &cconf);
|
||||||
|
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
|
|
||||||
|
defineFilterSymbols(linker, &ft);
|
||||||
|
if (0x40==(0xf0 & ft.id)) {
|
||||||
|
linker->defineSymbol("filter_length", ph.u_len); // redefine
|
||||||
|
}
|
||||||
|
defineDecompressorSymbols();
|
||||||
|
relocateLoader();
|
||||||
|
|
||||||
MemBuffer loader(lsize);
|
MemBuffer loader(lsize);
|
||||||
memcpy(loader, getLoader(), lsize);
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
|
||||||
patchPackHeader(loader, lsize);
|
patchPackHeader(loader, lsize);
|
||||||
patch_le32(loader, lsize, "ULEN", ph.u_len);
|
|
||||||
patchFilter32(loader, lsize, &ft);
|
|
||||||
|
|
||||||
|
#define shstrtab local_shstrtab // avoid -Wshadow warning
|
||||||
|
char const shstrtab[]= "\0.text\0.note\0.shstrtab\0.symtab\0.strtab";
|
||||||
|
char const *p = shstrtab;
|
||||||
while (0!=*p++) ;
|
while (0!=*p++) ;
|
||||||
shdro[1].sh_name = ptr_diff(p, shstrtab);
|
shdro[1].sh_name = ptr_diff(p, shstrtab);
|
||||||
shdro[1].sh_type = Elf32_Shdr::SHT_PROGBITS;
|
shdro[1].sh_type = Elf32_Shdr::SHT_PROGBITS;
|
||||||
shdro[1].sh_flags = Elf32_Shdr::SHF_ALLOC | Elf32_Shdr::SHF_EXECINSTR;
|
shdro[1].sh_flags = Elf32_Shdr::SHF_ALLOC | Elf32_Shdr::SHF_EXECINSTR;
|
||||||
shdro[1].sh_offset = fo_off;
|
shdro[1].sh_offset = fo_off;
|
||||||
shdro[1].sh_size = 1+ 4+ ph.c_len + lsize;
|
shdro[1].sh_size = sizeof(stub_i386_linux_kernel_vmlinux_head) + ph.c_len + lsize;
|
||||||
shdro[1].sh_addralign = 1;
|
shdro[1].sh_addralign = 1;
|
||||||
|
|
||||||
unsigned char const call = 0xE8; // opcode for CALL d32
|
// ENTRY_POINT
|
||||||
fo->write(&call, 1); fo_off+=1;
|
fo->write(&stub_i386_linux_kernel_vmlinux_head[0], sizeof(stub_i386_linux_kernel_vmlinux_head)-2*(1+ 4) +1);
|
||||||
tmp_le32 = ph.c_len; fo->write(&tmp_le32, 4); fo_off += 4;
|
tmp_le32 = ehdri.e_entry; fo->write(&tmp_le32, 4);
|
||||||
|
|
||||||
|
// COMPRESSED_LENGTH
|
||||||
|
fo->write(&stub_i386_linux_kernel_vmlinux_head[sizeof(stub_i386_linux_kernel_vmlinux_head)-(1+ 4)], 1);
|
||||||
|
tmp_le32 = ph.c_len; fo->write(&tmp_le32, 4);
|
||||||
|
|
||||||
|
fo_off += sizeof(stub_i386_linux_kernel_vmlinux_head);
|
||||||
|
|
||||||
fo->write(obuf, ph.c_len); fo_off += ph.c_len;
|
fo->write(obuf, ph.c_len); fo_off += ph.c_len;
|
||||||
fo->write(loader, lsize); fo_off += lsize;
|
fo->write(loader, lsize); fo_off += lsize;
|
||||||
|
|
||||||
@@ -278,7 +383,7 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
|||||||
ph.level = 1;
|
ph.level = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compress(ibuf, obuf);
|
compress(ibuf, obuf, &cconf);
|
||||||
ph.level = old_level;
|
ph.level = old_level;
|
||||||
|
|
||||||
// while (0!=*p++) ; // name is the same
|
// while (0!=*p++) ; // name is the same
|
||||||
@@ -294,7 +399,7 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
|||||||
shdro[4].sh_name = ptr_diff(p, shstrtab);
|
shdro[4].sh_name = ptr_diff(p, shstrtab);
|
||||||
shdro[4].sh_type = Elf32_Shdr::SHT_STRTAB;
|
shdro[4].sh_type = Elf32_Shdr::SHT_STRTAB;
|
||||||
shdro[4].sh_offset = fo_off;
|
shdro[4].sh_offset = fo_off;
|
||||||
shdro[4].sh_size = 1+ sizeof(shstrtab); // 1+: terminating '\0'
|
shdro[4].sh_size = sizeof(shstrtab); // already includes terminating '\0'
|
||||||
shdro[4].sh_addralign = 1;
|
shdro[4].sh_addralign = 1;
|
||||||
fo->write(shstrtab, shdro[4].sh_size); fo_off += shdro[4].sh_size;
|
fo->write(shstrtab, shdro[4].sh_size); fo_off += shdro[4].sh_size;
|
||||||
|
|
||||||
@@ -330,6 +435,7 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
|||||||
|
|
||||||
if (!checkFinalCompressionRatio(fo))
|
if (!checkFinalCompressionRatio(fo))
|
||||||
throwNotCompressible();
|
throwNotCompressible();
|
||||||
|
#undef shstrtab
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -354,35 +460,18 @@ int PackVmlinuxI386::canUnpack()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// find the .shstrtab section
|
// find the .shstrtab section
|
||||||
char shstrtab[40];
|
Elf_LE32_Shdr const *const shstrsec = getElfSections();
|
||||||
Elf32_Shdr *p, *p_shstrtab=0;
|
if (0==shstrsec) {
|
||||||
shdri = new Elf32_Shdr[(unsigned) ehdri.e_shnum];
|
|
||||||
fi->seek(ehdri.e_shoff, SEEK_SET);
|
|
||||||
fi->readx(shdri, ehdri.e_shnum * sizeof(*shdri));
|
|
||||||
int j;
|
|
||||||
for (p = shdri, j= ehdri.e_shnum; --j>=0; ++p) {
|
|
||||||
if (Elf32_Shdr::SHT_STRTAB==p->sh_type
|
|
||||||
&& p->sh_size <= sizeof(shstrtab)
|
|
||||||
&& (p->sh_size + p->sh_offset) <= (unsigned) file_size
|
|
||||||
&& (10+ p->sh_name) <= p->sh_size // 1+ strlen(".shstrtab")
|
|
||||||
) {
|
|
||||||
fi->seek(p->sh_offset, SEEK_SET);
|
|
||||||
fi->readx(shstrtab, p->sh_size);
|
|
||||||
if (0==strcmp(".shstrtab", shstrtab + p->sh_name)) {
|
|
||||||
p_shstrtab = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (0==p_shstrtab) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for .text .note .note and sane (.sh_size + .sh_offset)
|
// check for .text .note .note and sane (.sh_size + .sh_offset)
|
||||||
p_note0 = p_note1 = p_text = 0;
|
p_note0 = p_note1 = p_text = 0;
|
||||||
|
int j;
|
||||||
|
Elf_LE32_Shdr *p;
|
||||||
for (p= shdri, j= ehdri.e_shnum; --j>=0; ++p) {
|
for (p= shdri, j= ehdri.e_shnum; --j>=0; ++p) {
|
||||||
if ((unsigned)file_size < (p->sh_size + p->sh_offset)
|
if ((unsigned)file_size < (p->sh_size + p->sh_offset)
|
||||||
|| p_shstrtab->sh_size < (5+ p->sh_name) ) {
|
|| shstrsec->sh_size < (5+ p->sh_name) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (0==strcmp(".text", shstrtab + p->sh_name)) {
|
if (0==strcmp(".text", shstrtab + p->sh_name)) {
|
||||||
@@ -429,7 +518,7 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
|||||||
ibuf.dealloc();
|
ibuf.dealloc();
|
||||||
|
|
||||||
ph = ph_tmp;
|
ph = ph_tmp;
|
||||||
fi->seek(p_text->sh_offset, SEEK_SET);
|
fi->seek(p_text->sh_offset + sizeof(stub_i386_linux_kernel_vmlinux_head) -5, SEEK_SET);
|
||||||
fi->readx(&buf[0], 5);
|
fi->readx(&buf[0], 5);
|
||||||
if (0xE8!=buf[0] || get_le32(&buf[1]) != ph.c_len)
|
if (0xE8!=buf[0] || get_le32(&buf[1]) != ph.c_len)
|
||||||
{
|
{
|
||||||
@@ -464,7 +553,7 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Example usage within build system of Linux kernel-2.6.7:
|
// Example usage within build system of Linux kernel-2.6.18:
|
||||||
//
|
//
|
||||||
//----- arch/i386/boot/compressed/Makefile
|
//----- arch/i386/boot/compressed/Makefile
|
||||||
//#
|
//#
|
||||||
@@ -484,41 +573,43 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
|||||||
//$(obj)/upx-piggy.o: vmlinux FORCE
|
//$(obj)/upx-piggy.o: vmlinux FORCE
|
||||||
// rm -f $@
|
// rm -f $@
|
||||||
// upx --best -o $@ $<
|
// upx --best -o $@ $<
|
||||||
|
// touch $@
|
||||||
|
//
|
||||||
|
//#
|
||||||
|
//# The ORIGINAL build sequence using gzip is:
|
||||||
|
//# vmlinux Elf executable at top level in tree
|
||||||
|
//# (in same directory as MAINTAINERS)
|
||||||
|
//# In arch/i386:
|
||||||
|
//# boot/compressed/vmlinux.bin by objcopy -O binary
|
||||||
|
//# boot/compressed/vmlinux.bin.gz by gzip
|
||||||
|
//# boot/compressed/piggy.o by ld --format binary --oformat elf32-i386
|
||||||
|
//#
|
||||||
|
//# The 3 steps above create a linkable
|
||||||
|
//# compressed blob.
|
||||||
|
//# In arch/i386:
|
||||||
|
//# boot/compressed/vmlinux by ld head.o misc.o piggy.o
|
||||||
|
//# boot/vmlinux.bin by objcopy
|
||||||
|
//# boot/bzImage by arch/i386/boot/tools/build with
|
||||||
|
//# bootsect and setup
|
||||||
|
//#
|
||||||
|
//#
|
||||||
|
//# The MODIFIED build sequence using upx is:
|
||||||
|
//# vmlinux Elf executable at top level in tree
|
||||||
|
//# (in same directory as MAINTAINERS)
|
||||||
|
//# In arch/i386:
|
||||||
|
//# boot/compressed/upx-piggy.o by upx format vmlinux/386
|
||||||
|
//#
|
||||||
|
//# In arch/i386/boot:
|
||||||
|
//# boot/compressed/vmlinux by ld upx-head.o upx-piggy.o
|
||||||
|
//# boot/vmlinux.bin by objcopy
|
||||||
|
//# boot/bzImage by arch/i386/boot/tools/build with
|
||||||
|
//# bootsect and setup
|
||||||
|
//#
|
||||||
//-----
|
//-----
|
||||||
//
|
//
|
||||||
//----- arch/i386/boot/compressed/upx-head.S
|
//----- arch/i386/boot/compressed/upx-head.S
|
||||||
// .text
|
|
||||||
//startup_32: .globl startup_32 # In: %esi=0x90000 setup data "real_mode pointer"
|
//startup_32: .globl startup_32 # In: %esi=0x90000 setup data "real_mode pointer"
|
||||||
// #cli # this must be true already
|
// /* All code is in stub/src/i386-linux.kernel.vmlinux-head.S */
|
||||||
//
|
|
||||||
// /* The only facts about segments here, that are true for all kernels:
|
|
||||||
// * %cs is a valid "flat" code segment; no other segment reg is valid;
|
|
||||||
// * the next segment after %cs is a valid "flat" data segment, but
|
|
||||||
// * no segment register designates it yet.
|
|
||||||
// */
|
|
||||||
// movl %cs,%eax; addl $1<<3,%eax # the next segment after %cs
|
|
||||||
// movl %eax,%ds
|
|
||||||
// movl %eax,%es
|
|
||||||
// leal 0x9000(%esi),%ecx # 0x99000 typical
|
|
||||||
// movl %ecx,-8(%ecx) # 32-bit offset for stack pointer
|
|
||||||
// movl %eax,-4(%ecx) # segment for stack pointer
|
|
||||||
// lss -8(%ecx),%esp # %ss:%esp= %ds:0x99000
|
|
||||||
// /* Linux Documentation/i386/boot.txt "SAMPLE BOOT CONFIGURATION" says
|
|
||||||
// 0x8000-0x8FFF Stack and heap [inside the "real mode segment",
|
|
||||||
// just below the command line at offset 0x9000].
|
|
||||||
//
|
|
||||||
// arch/i386/boot/compressed/head.S "Do the decompression ..." says
|
|
||||||
// %esi contains the "real mode pointer" [as a 32-bit addr].
|
|
||||||
//
|
|
||||||
// In any case, avoid EBDA (Extended BIOS Data Area) below 0xA0000.
|
|
||||||
// boot.txt says 0x9A000 is the limit. LILO goes up to 0x9B000.
|
|
||||||
// */
|
|
||||||
//
|
|
||||||
// pushl $0; popf # subsumes "cli; cld"; also clears NT for buggy BIOS
|
|
||||||
//
|
|
||||||
// movl $ 0x100000,%eax # destination of uncompression (and entry point)
|
|
||||||
// push %cs
|
|
||||||
/* Fall into .text of upx-compressed vmlinux. */
|
|
||||||
//-----
|
//-----
|
||||||
|
|
||||||
// Approximate translation for Linux 2.4.x:
|
// Approximate translation for Linux 2.4.x:
|
||||||
@@ -558,6 +649,7 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
|||||||
//upx-piggy.o: $(SYSTEM)
|
//upx-piggy.o: $(SYSTEM)
|
||||||
// $(RM) -f $@
|
// $(RM) -f $@
|
||||||
// upx --best -o $@ $<
|
// upx --best -o $@ $<
|
||||||
|
// touch $@
|
||||||
//
|
//
|
||||||
//clean:
|
//clean:
|
||||||
// rm -f vmlinux bvmlinux _tmp_*
|
// rm -f vmlinux bvmlinux _tmp_*
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user