Compare commits
1480 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8dd810c41d | |||
| d9d0dc5201 | |||
| 72880d9e03 | |||
| 6c7ec6eb1b | |||
| 705fc5d116 | |||
| d20b575b9b | |||
| c949beab9c | |||
| 3fb857c435 | |||
| 0a4f999ade | |||
| f0b7147881 | |||
| b36a42cd0a | |||
| 000309b47f | |||
| 5cb12988f0 | |||
| 50c4b749ec | |||
| 5db2734e6f | |||
| e9e5507483 | |||
| d63dc7adfb | |||
| 27db44a8db | |||
| 1a035e2866 | |||
| 887aa20116 | |||
| 5e03d86695 | |||
| 95075aa28e | |||
| 0260f0790a | |||
| 34d65ba292 | |||
| 27a77a15ed | |||
| 76025bfae1 | |||
| 4957faf482 | |||
| 0d8e16d5c8 | |||
| 07baed1581 | |||
| eab5da075a | |||
| 0d1bbb19ce | |||
| 58d6cbc6ac | |||
| 4d3b627839 | |||
| 49455c99ad | |||
| 31bb6bedbd | |||
| 8d54678ea1 | |||
| 590767c299 | |||
| ec1bd342b8 | |||
| b031c9e7f6 | |||
| ea0dfe83b7 | |||
| bdd90f2c57 | |||
| 288dac5d70 | |||
| 9d22e1c35e | |||
| ace2359e7b | |||
| 617e6510a5 | |||
| 26024770b8 | |||
| d556f58e34 | |||
| b6f302dfc0 | |||
| 8e9b5f14af | |||
| 3635c00143 | |||
| abc71baaa6 | |||
| 959aaebede | |||
| d17f8c5049 | |||
| 42a7201a70 | |||
| 1f1744a49a | |||
| fd7dbe5bd9 | |||
| 984549400d | |||
| cf0c49277e | |||
| 16c3f9fa9c | |||
| 2f2539cf34 | |||
| e66823d017 | |||
| 881c32a3df | |||
| ea0a361c35 | |||
| dc60f8bb7b | |||
| 9e92c9ea12 | |||
| a503a54240 | |||
| 265957712a | |||
| c26962bb71 | |||
| a428eddf93 | |||
| dc4f7eb2f9 | |||
| d54ac1ba91 | |||
| a3d46b18ac | |||
| e81dd05666 | |||
| 29394935e3 | |||
| df8acc4ed7 | |||
| 81928d4ab1 | |||
| 3ebf93e03d | |||
| 59e4032f1f | |||
| 8f15777427 | |||
| 748c4bf780 | |||
| befcf6d2b3 | |||
| 48236ecd3c | |||
| f340f84de7 | |||
| 40e19293f9 | |||
| f252f824a4 | |||
| 1d7e5a8130 | |||
| cb2ff92c2f | |||
| ef373ab54f | |||
| 9141a78c29 | |||
| 10a6370738 | |||
| 573009eeb6 | |||
| c3363712d9 | |||
| faa33d89a2 | |||
| f347458c53 | |||
| 530e6d9196 | |||
| b398e18e12 | |||
| 747e8370e0 | |||
| 2c67875781 | |||
| c96e8a8c19 | |||
| 5f203fc082 | |||
| b943c9b471 | |||
| 1a90a1daa8 | |||
| 72dfc743fd | |||
| 465307655b | |||
| 6ce71e6694 | |||
| 7f01b3b92a | |||
| 76950d56b9 | |||
| c11e0d02b3 | |||
| 4c798c1718 | |||
| 450d7e9ad4 | |||
| b8ab79c83e | |||
| 6934bdd533 | |||
| 84dedb73a5 | |||
| 8964aa5221 | |||
| 3481ae236c | |||
| 46adc5f8a4 | |||
| 5296df5899 | |||
| 13dad4be16 | |||
| b5d0c343b4 | |||
| b00b945264 | |||
| 3bda09e105 | |||
| 32d32c4e4a | |||
| 497441b54e | |||
| 9c564fd4c7 | |||
| 0c2263d0e9 | |||
| 3d4d30766d | |||
| 99d84d44fc | |||
| 41ba7077ad | |||
| 8a929a91c3 | |||
| 0604f06841 | |||
| 229924adf9 | |||
| df988b7c69 | |||
| e8106e2e34 | |||
| c21d3e24f8 | |||
| 2d87aa0753 | |||
| b2ad4dc9a0 | |||
| 370f2ea98f | |||
| a05ca565ff | |||
| 52255637f2 | |||
| 0fcaa3a2f5 | |||
| 0e2fa6eb9d | |||
| 1aac462c83 | |||
| 2a0edfd8f7 | |||
| 1f59a9f846 | |||
| 80c20a90ea | |||
| 56a35649fe | |||
| f07cea0b79 | |||
| 4c1b08a281 | |||
| 117f9eddcd | |||
| 7bbbfce482 | |||
| f37a7811f9 | |||
| 9173c10239 | |||
| 318b31550d | |||
| c18ebc63a6 | |||
| d704694272 | |||
| 1cfec3bdf7 | |||
| fe6ea6bc10 | |||
| d29c8df45e | |||
| 71f996af95 | |||
| d9722ad6b3 | |||
| 398fd8028c | |||
| 1345a3cfd3 | |||
| 7eb0b195b8 | |||
| 009caee82d | |||
| 3bdc805a22 | |||
| ac457792b4 | |||
| 1377b54b9e | |||
| 66418ffc8c | |||
| b4c4b1fb70 | |||
| ffe4a4b047 | |||
| 753ce45310 | |||
| fece0d73e7 | |||
| edce076e68 | |||
| 675d0a009a | |||
| 5d41b5a4db | |||
| fe53b135eb | |||
| 5b1c154ee2 | |||
| 816d882611 | |||
| 12bcb09051 | |||
| c59c69a85f | |||
| bdd0daaf6f | |||
| cfad7c8356 | |||
| b2b8a128d0 | |||
| 1cfad80ca2 | |||
| a5a80e41b8 | |||
| 152f8e92bf | |||
| 0323560b49 | |||
| d3bc84a2f7 | |||
| 8a82c259bd | |||
| 46009c7658 | |||
| 6f760308bd | |||
| c346f8f17d | |||
| af1d059fff | |||
| 5562b21a20 | |||
| 8f68f31877 | |||
| ce7e94030c | |||
| ccf5a1b972 | |||
| 0d5ae77efc | |||
| 1695096d18 | |||
| 6db0b7cf18 | |||
| 575b43b0d4 | |||
| 7b39b05894 | |||
| 8bea9e0a5e | |||
| 2255b32e45 | |||
| b62573ae8f | |||
| 44ed84f5cf | |||
| d008c834be | |||
| 2d3a914aee | |||
| 7324f4c3d1 | |||
| 50c8860a50 | |||
| 6456de7188 | |||
| 23c629f2aa | |||
| 2bf154f74f | |||
| b598ad1bc0 | |||
| ace24ad68e | |||
| 750c1a0f27 | |||
| 52d89bd66b | |||
| 8cfb9d35e9 | |||
| 2f529158a0 | |||
| 6e68ab6d9e | |||
| 7a3c55af35 | |||
| fb39d6304a | |||
| 4cb57d9059 | |||
| 42d69bd0e5 | |||
| f27b399f81 | |||
| a545a3938f | |||
| d1e352c9ee | |||
| 99be1e798b | |||
| 2132a28a17 | |||
| 8b1cc28783 | |||
| 78364ac830 | |||
| 6e5f5732b5 | |||
| 87844254d1 | |||
| 08ef9f69fb | |||
| 5fbd1b78e7 | |||
| 39f5eb753f | |||
| f4cbe3f300 | |||
| 70632e5541 | |||
| 0bba700105 | |||
| b71aaccff3 | |||
| 7271ae9611 | |||
| 6e32dff2ad | |||
| 8f7c898c08 | |||
| f4a9815f48 | |||
| 0f8d5c7e98 | |||
| 5e83596a1b | |||
| 6361213e07 | |||
| 9c59a5d9b6 | |||
| bb04844bd5 | |||
| 0b988176fa | |||
| a354f18a2d | |||
| a7ca0fec88 | |||
| 06eec508df | |||
| 10dc580a3a | |||
| 2f6ae3ef01 | |||
| 392e803905 | |||
| 83a5fb585b | |||
| c6205ffbe0 | |||
| c04737ce20 | |||
| 11b92172fe | |||
| 3a6c574376 | |||
| b21ce925fb | |||
| de9dcc4ed6 | |||
| 9e77dbfe20 | |||
| 4cee0676a4 | |||
| 8ad9d21db3 | |||
| 8ba8317eea | |||
| d221187f24 | |||
| db54ec294f | |||
| 1d39796e3f | |||
| cd6a318903 | |||
| 73090b98ab | |||
| 745de1abab | |||
| 961031efc1 | |||
| 2487595778 | |||
| 5c4863d504 | |||
| 5e3a658932 | |||
| cb4704c821 | |||
| cc0b7d1492 | |||
| f8ebbf8b08 | |||
| 8795f60bf1 | |||
| f00c0a9436 | |||
| 767bc71870 | |||
| 4c068e3e00 | |||
| 277d862172 | |||
| dbed6a47bb | |||
| 94f3749784 | |||
| 728e6d851e | |||
| 11e863545f | |||
| dde49f0bb4 | |||
| a37a75aecc | |||
| e43e3aeb1c | |||
| a8fe529814 | |||
| d9f5e2bb08 | |||
| dfa83b0ac8 | |||
| bd5cef1411 | |||
| cd70b48831 | |||
| 50ebf8088a | |||
| c5cfb7eb40 | |||
| bccaafda6d | |||
| bf0086d7b5 | |||
| 7e65938ca6 | |||
| 112eff2509 | |||
| d7837d9179 | |||
| 6cdd057f80 | |||
| 5a03b213fb | |||
| f270213246 | |||
| 2e1795c5ba | |||
| 732d6710d3 | |||
| edf384d2ee | |||
| c307640826 | |||
| a77b598f82 | |||
| 217420cfa5 | |||
| f2b9dff596 | |||
| ae945ed315 | |||
| 770c153c76 | |||
| 29c4a7e606 | |||
| 8875470b37 | |||
| 6e52364bcb | |||
| 7015d616b4 | |||
| 92e6da3260 | |||
| 9220b6f1d5 | |||
| 1d0d538d0c | |||
| 83052eafae | |||
| fa95c3c4a2 | |||
| 665dcf221b | |||
| 8f73dbd253 | |||
| 826312cbad | |||
| 72a18f2b3f | |||
| a6b5e3d0ae | |||
| 1b321f4fa3 | |||
| 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 | |||
| 08c0796719 | |||
| edc7994ce5 | |||
| bcfcfbd064 | |||
| 9e79b3258d | |||
| 243873cd2d | |||
| c7b8a4b0c1 | |||
| e39e0c7140 | |||
| d4a3f11dbb | |||
| 0962f266b3 | |||
| 69e4d3fdad | |||
| c0908f463a | |||
| b00a61a17b | |||
| 553c2f886a | |||
| 4fd9c5772a | |||
| 04e0e06d85 | |||
| 4d7829d72b | |||
| 6b751aac57 | |||
| 813349fd23 | |||
| 16a2744782 | |||
| 7b6870db22 | |||
| 3e38e7d52c | |||
| 8142d3474d | |||
| 8773649de6 | |||
| c117920ff9 | |||
| c8dd2a3eb8 | |||
| 90b1817e92 | |||
| d6c3ff5997 | |||
| 984ec25132 | |||
| a7bff34784 | |||
| a6e7afbc91 | |||
| 33f1d63b64 | |||
| f95e171e11 | |||
| c82b50b212 | |||
| 2b402b77f1 | |||
| adcb551020 | |||
| 2680aabe06 | |||
| d5c0533b74 | |||
| 609307668b | |||
| cdaf36572a | |||
| 033c8d5d51 | |||
| 6216ec1d6a | |||
| 6c9c67f6c5 | |||
| 5bd32b5521 | |||
| 549336f75b | |||
| f0e75f30b3 | |||
| 144c09f175 | |||
| ee50c0f97c | |||
| ade921bf02 | |||
| 676cacff04 | |||
| a3097d5e25 | |||
| fd78148558 | |||
| a4d79d7375 | |||
| df04e8183d | |||
| c43c484a62 | |||
| 0608c35669 | |||
| 7dd4d06e26 | |||
| 1ee0310b86 | |||
| cc0a52038f | |||
| 6aed1fe231 | |||
| 680608fe18 | |||
| ec6acbc602 | |||
| cb7ee4c5d2 | |||
| 88d5798f45 | |||
| fcc22a0aa3 | |||
| aabefff298 | |||
| ed25c64e97 | |||
| b7dc870c2d | |||
| 9bea608843 | |||
| 9db1732c36 | |||
| 39f1a70174 | |||
| 1810440355 | |||
| 37ac8f179e | |||
| 626a09328f | |||
| 8d489d0d77 | |||
| 776f3db0d7 | |||
| 6046057b88 | |||
| 7e85d9e549 | |||
| 01c8a8b1c2 | |||
| c9bf6ac9ae | |||
| 62e4d69be9 | |||
| 62ac733b09 | |||
| c3b3e1b1b9 | |||
| a791e96e00 | |||
| e87f5521c1 | |||
| 366a708f3a | |||
| 70ba662574 | |||
| b389abd99f | |||
| 4aa2d14fe3 | |||
| af7de75ad4 | |||
| d461ebbda1 | |||
| 55ef94abcd | |||
| afaf489d99 | |||
| 20e4cbfd13 | |||
| f3b8c9f34e | |||
| 45e8ff25a5 | |||
| 268e322e1c | |||
| d3bcba6a05 | |||
| cc4ef1944d | |||
| 5aa8486265 | |||
| fd181673cd | |||
| 62c9547c4e | |||
| cdd117bfb9 | |||
| 304ba57dad | |||
| 69eaaa4177 | |||
| 452ac52fcb | |||
| 40cf489290 | |||
| 891d6be4a6 | |||
| 5d45ce5cf7 | |||
| a0f2241f3a | |||
| aa513bf7d3 | |||
| b2d65febc8 | |||
| 23a6d326e8 | |||
| 5b2f1b6d8b | |||
| b4e9ad031b | |||
| 8b7ebcf040 | |||
| af05296631 | |||
| 29d693de2d | |||
| 51ac5172f5 | |||
| 24ce1ef5e7 | |||
| f6d1e269d1 | |||
| 62c2f5228d | |||
| 9882d9683b | |||
| 45ce89ee1f | |||
| bfb9df1553 | |||
| a5f79204ce | |||
| e322613d84 | |||
| fbb60f5191 | |||
| 899e7d2f39 | |||
| 8e2aa07747 | |||
| a0d262cd76 | |||
| b43a7edee4 | |||
| 7760bbd77c | |||
| 9c0f1b02a7 | |||
| 4ecfff4d8d | |||
| ac03b89f38 | |||
| 620174aea9 | |||
| ab50d28bc4 | |||
| b5318602d1 | |||
| bff2a63ea2 | |||
| aacfb8820e | |||
| 98e8c031d0 | |||
| beb4319d1e | |||
| 2558243c83 | |||
| b670e8d1ac | |||
| 68f8358f06 | |||
| db5a099097 | |||
| ce33ffb62a | |||
| 59a2fb9cfd | |||
| 75bba319de | |||
| f78e9261f3 | |||
| 5f77562333 | |||
| 5c4f01a68d | |||
| 35f6f998e6 | |||
| 6737a3ae09 | |||
| 09559bee8c | |||
| f487ea27a8 | |||
| a3d95f239a | |||
| 023c06e178 | |||
| 414a6c1c9e | |||
| 910e18fb22 | |||
| ac441fd1cf | |||
| 0c328372b5 | |||
| 55ef60a6d4 | |||
| c33584e683 | |||
| ee8c7453bd | |||
| 0330369603 | |||
| 3f7b642c7d | |||
| eb6c51426a | |||
| 0337bdb9fd | |||
| 7aedc62058 | |||
| bfc835cbbf | |||
| 5c6ba30c48 | |||
| 8fe4824ed2 | |||
| d40cb3bd55 | |||
| 4bcd3ac5d7 | |||
| e2b8e9dea9 | |||
| 572314bf3f | |||
| 14d303d331 | |||
| 24ffaa0738 | |||
| 5d9b6d056d | |||
| 5c28ff15ba | |||
| 06ceb2f2a1 | |||
| 7373e1dd8b | |||
| 4b1a9e714d | |||
| 9d76136358 | |||
| b3502420ad | |||
| dd7ac7cca9 | |||
| 31dfa18e9b | |||
| 3e785008d3 | |||
| 6b7c7f755c | |||
| c55a8a8703 | |||
| 64c97308ac | |||
| 3551b0b95a | |||
| 9f16b5c4af | |||
| 9777e549cb | |||
| fbfced1b93 | |||
| 1a84b4681c | |||
| 4bf81b8e1c | |||
| c282e7fdb4 | |||
| d339ee3135 | |||
| 1de95de299 | |||
| 96c998a1d7 | |||
| b5413c0156 | |||
| 7371c195ff | |||
| 0866a1996b | |||
| 41f44c4e78 | |||
| 131712c3bd | |||
| bae12aaab7 | |||
| 74d5844d8c | |||
| c87908266a | |||
| f788d76b8c | |||
| 41031e572e | |||
| f8a0864c1b | |||
| 949587334c | |||
| 0bc6a1a7f1 | |||
| 0d9cbfe927 | |||
| 8742a524c3 | |||
| 79bf2297b5 | |||
| 32e9e23630 | |||
| 7f1cecba92 | |||
| efd30c61c3 | |||
| 4c97b11207 | |||
| 58ea0ab745 | |||
| 3547c71ad5 | |||
| 044d6b2ce2 | |||
| a0b26b6c06 | |||
| 8e3bfde439 | |||
| 6507de959b | |||
| 56d09bf3b5 | |||
| 232754b978 | |||
| 75ef603308 | |||
| a5a2fcee4d | |||
| f86d57bfe3 | |||
| 615615b1df | |||
| aeba0ce170 | |||
| 5ce60aad53 | |||
| dbc01de9a0 | |||
| dfaf3f24fc | |||
| 14b0527e79 | |||
| f0148c3161 | |||
| 6a5e3d924d | |||
| 664a82e7c9 | |||
| e2763b4826 | |||
| afb29b19c2 | |||
| 8d60343940 | |||
| 67a77f1880 | |||
| c933974174 | |||
| 19715903fb | |||
| c88f72fd15 | |||
| 7818596271 | |||
| 9cb8d7bca6 | |||
| 46f9256114 | |||
| c26ef87202 | |||
| 89fee5b835 | |||
| f5795eb01b | |||
| dbf0c9f016 | |||
| 586b43048f | |||
| 63b9ee61d2 | |||
| 3b9eff7f34 | |||
| 59668c5fc1 | |||
| 3ed786fb5c | |||
| 0cd5eb5472 | |||
| ff571b96cb | |||
| 36b852e6bf | |||
| f0c21c7203 | |||
| 0516d8260c | |||
| 1418f57b96 | |||
| b24fb59c94 | |||
| 8fcf2bcd59 | |||
| 079b808a56 | |||
| a4e01e28db | |||
| ec1ef9099f | |||
| ac724c7e6c | |||
| ec25835525 | |||
| d4841a641c | |||
| 5612460720 | |||
| 465ea6429f | |||
| ed9057ca83 | |||
| 14ced962db | |||
| 1aff6b862d | |||
| ef490c4220 | |||
| 0dda83cbbc | |||
| fa4efec3b5 | |||
| 814eabb88e | |||
| 95021e4977 | |||
| d17fb7ebf0 | |||
| df9aa9ac32 | |||
| 9110517893 | |||
| 8204c7deb6 | |||
| 6662f8985e | |||
| a2b305ed3b | |||
| ce3d3a850c | |||
| 212b674bc2 | |||
| 2980a6b4bb | |||
| 435c0a9e82 | |||
| 4102cd7c91 | |||
| b4b603819d | |||
| 20e3707e69 | |||
| fc6eeaaea8 | |||
| 41799955ce | |||
| efb4ec9cb8 | |||
| 4dbda29f82 | |||
| befaa3c501 | |||
| f41edf9e21 | |||
| 754f10f0b0 | |||
| 5d331fdf69 | |||
| cbf1dbe2cb | |||
| 3177de92fb | |||
| 3878890783 | |||
| 61594f7873 | |||
| f412b5e0cd | |||
| f14d594a1a | |||
| f0279d23d3 | |||
| 18ef55ac14 | |||
| 0010c50de6 | |||
| 130699a33b | |||
| 5a8d60d3e0 | |||
| 603dc83c1a | |||
| 51106e730b | |||
| 23ec864130 | |||
| 5349bd0b2a | |||
| 74d70fe1d9 | |||
| 041865c320 | |||
| 6a7d555ad7 | |||
| 18262f79c7 | |||
| 9769599f1d | |||
| aee150474c | |||
| 0e45021a5a | |||
| 241abcc89c | |||
| 90fc32a56e | |||
| 7ce85ab712 | |||
| 55cde23f10 | |||
| a19e6cd4f5 | |||
| 06f8c55908 | |||
| b10f68d20a | |||
| ed8a71bba1 | |||
| fee6f17caf | |||
| 767e4e2ce6 | |||
| 23f5370dcf | |||
| 37ae689328 | |||
| 123b33efd4 | |||
| 736ec9d9e5 | |||
| 5a94136764 | |||
| 1555be40b7 | |||
| 60b7a3c33b | |||
| a5d8e575bd | |||
| 23db1d375c | |||
| e06722d121 | |||
| 81e77a8b2b | |||
| 5c567c5a76 | |||
| b8e698bde3 | |||
| 440b5b2608 | |||
| 8b2e7ffe0b | |||
| 1018a96b31 | |||
| 5f87e9891b | |||
| 19564ed27e | |||
| f4022af48a | |||
| 2d1de8b9e9 | |||
| cdbfdee725 | |||
| ac64126a66 | |||
| 97153e8e09 | |||
| b9c976304a | |||
| 670b67cc98 | |||
| ccecaa741c | |||
| 07230edec0 | |||
| de1a4b4da4 | |||
| aba5c40b17 | |||
| a55b3480ef | |||
| bcb5e7d852 | |||
| e4f6378dfe | |||
| f616d2edf1 | |||
| bffb138b9c | |||
| b49fc6c081 | |||
| 570b195ed6 | |||
| b0e961b90b | |||
| 919a899c39 | |||
| 655094239c | |||
| 8eda698a9c | |||
| d1753c6df9 | |||
| 3db0b0e8fe | |||
| 8d5d6bd1a5 | |||
| 05f6f4d2ff | |||
| 9e154e33c3 | |||
| 5125f4d4ac | |||
| 365a3c0432 | |||
| ab37b5ea0c | |||
| 20ddd8590d | |||
| 69d9aa6c69 | |||
| 2163231401 | |||
| f513373693 | |||
| ed0e3b9af4 | |||
| 4205c699ac | |||
| 4e64cdac15 | |||
| bbbea34d74 | |||
| 66565f7238 | |||
| 9cb922425e | |||
| 268e13c572 | |||
| 03f1f615e5 | |||
| 94152391b1 | |||
| 2d403e07bb | |||
| 48ec581539 | |||
| f9054529c1 | |||
| 67d9ff987c | |||
| a3bb8f00fd | |||
| 48846c7226 | |||
| ad8648f668 | |||
| c7224c7727 | |||
| b2949259c5 | |||
| 757bdd1264 | |||
| ec1e5849eb | |||
| 1752fab911 | |||
| b0748388b2 | |||
| 175899013e | |||
| c448d15a8f | |||
| 5c7bca5b3e | |||
| 390cdbba2d | |||
| 256b8f066f | |||
| 30915862cd | |||
| eeb1dfaf8f | |||
| 90161bc3a7 | |||
| a1064dc2cb | |||
| b8a9b321fa | |||
| a3e80b1628 | |||
| 350ebfc47d | |||
| b9b75c536c | |||
| 8b74704bbf | |||
| bead894e49 | |||
| 502f9b5a00 | |||
| cd15b7d5af | |||
| 0c1d544e98 | |||
| 728be1867f | |||
| 09578df46b | |||
| b29f5b7c09 | |||
| 10f602fca7 | |||
| 2f8917f450 | |||
| b57f48d543 | |||
| 87a4d8455d | |||
| b14df392fa | |||
| 437c34a68c | |||
| b218cec3d7 | |||
| f19c91243a | |||
| 882e1be2db | |||
| 8e21c1e965 | |||
| f3970eaed9 | |||
| ac4b8f8617 | |||
| 51c28020de | |||
| fd525ae7df | |||
| a282171318 | |||
| c3040d1636 | |||
| c76c07aea0 | |||
| 1282ed333a | |||
| 32e76e88cf | |||
| fc0d3ff118 | |||
| 0bd05c0d67 | |||
| ff2c5300b8 | |||
| a38989dfbf | |||
| e387c6bc56 | |||
| 5eb81c0ec4 | |||
| f92b617c43 | |||
| 8f25c72085 | |||
| 7860e7a249 | |||
| a2e3ceb8c8 | |||
| e96ad21db1 | |||
| 888ac8a220 | |||
| 29db8bca3a | |||
| 63d49f0143 | |||
| 378224c6ba | |||
| 2f3e7a82b5 | |||
| 960f020277 | |||
| 6962da718c | |||
| 42575d9f57 | |||
| 03fb0d95c6 | |||
| beb766b005 | |||
| 29c1f67057 | |||
| a709b38065 | |||
| ec5840fb2a | |||
| 9511e3c9b1 | |||
| 9190e7d51a | |||
| cff830c43b | |||
| e31c45dc10 | |||
| e1da733810 | |||
| b8c34036a5 | |||
| d771f219f0 | |||
| d8280343f9 | |||
| c7b9395866 | |||
| 992ceee52b | |||
| 2162a01848 | |||
| 102e0f0a98 | |||
| 4e0967e0a1 | |||
| 73dc4eede0 | |||
| 5e5ea9f6e4 | |||
| e537f25857 | |||
| 47aea88c27 | |||
| 0237bf8915 | |||
| 3a7032f21c | |||
| 54d01790b5 | |||
| fb3375112e | |||
| 554f22a14f | |||
| eb6a6e3909 | |||
| 041947507f | |||
| ff03ac17b2 | |||
| 12c6cd8021 | |||
| de6e8c8020 | |||
| f3b64cfe78 |
@@ -1,4 +0,0 @@
|
||||
.cvsignore
|
||||
ChangeLog.cvs*
|
||||
build
|
||||
maint
|
||||
@@ -0,0 +1,52 @@
|
||||
syntax: regexp
|
||||
|
||||
^\.bzr
|
||||
^ChangeLog
|
||||
^Makevars.global
|
||||
^build
|
||||
^maint
|
||||
|
||||
syntax: glob
|
||||
|
||||
.depend
|
||||
Makevars.local
|
||||
|
||||
*.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,18 @@
|
||||
140415ffbcef86a42b4d672249927364430d3d38 RELEASE_111
|
||||
1931f4f28074970ec53b4cd21c7fc181b4da8e5e RELEASE_301
|
||||
223ac5b23f9731ceac9ff8d65167df4900776e36 RELEASE_190
|
||||
2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194
|
||||
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
|
||||
396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291
|
||||
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
|
||||
a1c61174f54aac714f59ac20fcba839d71e64c5c RELEASE_292
|
||||
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
|
||||
ef9c7f2c9658d73a9b5ab2ed291483d2bbcd8bc7 RELEASE_300
|
||||
efa52753e366300c0e0ebe20631adcb24ed3c15b RELEASE_293
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2002 Markus Oberhumer & Laszlo Molnar
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
Limitations and other things which are not (yet) supported:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@@ -225,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
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; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
@@ -1,33 +1,48 @@
|
||||
# Toplevel Makefile for UPX
|
||||
#
|
||||
# UPX toplevel Makefile - needs GNU make 3.81 or better
|
||||
#
|
||||
|
||||
SHELL = /bin/sh
|
||||
MAKEFLAGS += -rR
|
||||
.SUFFIXES:
|
||||
export SHELL = /bin/sh
|
||||
|
||||
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.77 3.78 3.78.1 3.79 3.79.1 3.80),)
|
||||
$(error GNU make 3.81 or better is required)
|
||||
endif
|
||||
|
||||
srcdir = .
|
||||
top_srcdir = .
|
||||
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||
|
||||
|
||||
# info: src/stub needs 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
|
||||
|
||||
|
||||
default:
|
||||
@echo "UPX info: please choose a target for 'make'"
|
||||
|
||||
all mostlyclean clean distclean maintainer-clean:
|
||||
$(MAKE) -C src/stub/util/sstrip $@
|
||||
ifeq ($(BUILD_STUB),1)
|
||||
$(MAKE) -C src/stub $@
|
||||
endif
|
||||
$(MAKE) -C src $@
|
||||
$(MAKE) -C doc $@
|
||||
|
||||
dist: distclean
|
||||
false
|
||||
|
||||
zip:
|
||||
cd .. && rm -f upx-current.zip && zip -r upx-current.zip upx
|
||||
|
||||
cvs-admin-ko:
|
||||
cvs admin -ko .
|
||||
cvs update
|
||||
|
||||
ifneq ($(wildcard .hg/.),)
|
||||
# automatically generate ChangeLog from local Mercurial repo
|
||||
ChangeLog:
|
||||
perl $(srcdir)/scripts/cvs2cl.pl --utc -f ChangeLog.cvs
|
||||
hg log --style=changelog > $@
|
||||
.PHONY: ChangeLog
|
||||
endif
|
||||
|
||||
|
||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||
.PHONY: dist cvs-admin-ko ChangeLog
|
||||
|
||||
.NOEXPORT:
|
||||
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
||||
|
||||
|
||||
@@ -2,19 +2,136 @@
|
||||
User visible changes for UPX
|
||||
==================================================================
|
||||
|
||||
[ BETA VERSION - please see README.1ST for some more info ]
|
||||
Changes in 3.02 (16 Dec 2007):
|
||||
* fix unmapping on arm-linux.elf
|
||||
* fix error checking in mmap for i386-linux.elf [triggered by -fPIE]
|
||||
* bug fixes
|
||||
|
||||
Changes in 3.01 (31 Jul 2007):
|
||||
* new options --no-mode, --no-owner and --no-time to disable preservation
|
||||
of mode (file permissions), file ownership and timestamps.
|
||||
* dos/exe: fixed an incorrect error message caused by a bug in
|
||||
relocation handling
|
||||
* new format linux/mipsel supports ELF on [32-bit] R3000
|
||||
* fix argv[0] on PowerPC with --lzma
|
||||
* bug fixes
|
||||
|
||||
Changes in 3.00 (27 Apr 2007):
|
||||
* watcom/le & tmt/adam: fixed a problem when using certain filters
|
||||
|
||||
Changes in 2.93 beta (08 Mar 2007):
|
||||
* new formats Mach/i386 and Mach/fat support Mac OS X i686 and
|
||||
Universal binaries [i686 and PowerPC only]
|
||||
* dos/exe: LZMA is now also supported for 16-bit dos/exe. Please note that
|
||||
you have to explicitly use '--lzma' even for '--ultra-brute' here
|
||||
because runtime decompression is about 30 times slower than NRV -
|
||||
which is really noticeable on old machines.
|
||||
* dos/exe: fixed a rarely occuring bug in relocation handling
|
||||
* win32/pe & arm/pe: better icon compression handling
|
||||
|
||||
Changes in 2.92 beta (23 Jan 2007):
|
||||
* new option '--ultra-brute' which tries even more variants
|
||||
* slightly improved compression ratio for some files when
|
||||
using '--brute' or '--ultra-brute'
|
||||
* bug fixes
|
||||
|
||||
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):
|
||||
* arm/pe: added DLL support
|
||||
* arm/pe: added thumb mode stub support
|
||||
* arm/pe: added unpacking support
|
||||
* win32/pe: really worked around R6002 runtime errors
|
||||
|
||||
Changes in 1.94 beta (11 Mar 2006):
|
||||
* new format: added support for arm/pe (ARM executables running on WinCE)
|
||||
* new format: added support for linux elf/amd64
|
||||
* new format: added support for linux elf/ppc32
|
||||
* new format: added support for mach/ppc32 (Apple Mac OS X)
|
||||
* win32/pe: hopefully working "load config" support
|
||||
* win32/pe: R6002 runtime errors worked around
|
||||
* win32/pe: the stub now clears the dirty stack
|
||||
|
||||
Changes in 1.93 beta (07 Feb 2005):
|
||||
* vmlinuz/386: fixes to support more kernels
|
||||
|
||||
Changes in 1.92 beta (20 Jul 2004):
|
||||
* win32/pe: added option '--strip-loadconf' to strip the SEH load
|
||||
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]
|
||||
* vmlinux/386: new format that directly supports building Linux kernels
|
||||
* source code: now compiles cleanly under Win64
|
||||
|
||||
Changes in 1.91 beta (30 Jun 2004):
|
||||
* djgpp2/coff: added support for recent binutils versions
|
||||
* linux/elf386, linux/sh386: lots of improvements
|
||||
* vmlinuz/386: added support for recent kernels
|
||||
* watcom/le: don't crash on files without relocations
|
||||
* win32/pe: stricter checks of some PE values
|
||||
* option '--brute' now implies '--crp-ms=999999'.
|
||||
* source code: much improved portability using ACC, the
|
||||
Automatic Compiler Configuration
|
||||
* source code: compile fixes for strict ISO C++ compilers
|
||||
* source code: compile fixes for Win64
|
||||
* re-synced with upx 1.25 branch
|
||||
|
||||
Changes in 1.90 beta (11 Nov 2002):
|
||||
* UNSTABLE BETA VERSION - DO NOT USE EXCEPT FOR TESTING
|
||||
* 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
|
||||
* linux/386: added the option `--force-execve'
|
||||
* linux/386: added the option '--force-execve'
|
||||
* vmlinuz/386: better kernel detection and sanity checks
|
||||
* re-synced with upx 1.24 branch
|
||||
* documentation updates
|
||||
|
||||
Changes in 1.11 beta (20 Dec 2000):
|
||||
* UNSTABLE BETA VERSION - DO NOT USE EXCEPT FOR TESTING
|
||||
* vmlinuz/386: new format - UPX now supports bootable linux kernels
|
||||
* linux/elf386: added the new ELF direct-to-memory executable format - no
|
||||
more temp files are needed for decompression!
|
||||
@@ -25,6 +142,15 @@ Changes in 1.11 beta (20 Dec 2000):
|
||||
|
||||
==================================================================
|
||||
|
||||
Changes in 1.25 (29 Jun 2004)
|
||||
* INFO: http://upx.sourceforge.net is the permanent UPX home page
|
||||
* watcom/le: don't crash on files without relocations
|
||||
* win32/pe: stricter checks of some PE values
|
||||
* source code: much improved portability using ACC, the
|
||||
Automatic Compiler Configuration
|
||||
* source code: compile fixes for strict ISO C++ compilers
|
||||
* source code: compile fixes for Win64
|
||||
|
||||
Changes in 1.24 (07 Nov 2002)
|
||||
* djgpp2/coff: stricter check of the COFF header to work around a
|
||||
problem with certain binutils versions
|
||||
@@ -41,13 +167,13 @@ Changes in 1.23 (05 Sep 2002)
|
||||
Changes in 1.22 (27 Jun 2002)
|
||||
* atari/tos: the stub now flushes the CPU cache to avoid
|
||||
problems on 68030+ machines
|
||||
* source code: additional compiler support for Borland C++ 5.5.1,
|
||||
Digital Mars C++ 8.28 and Watcom C++ 11.0c
|
||||
* source code: additional compiler support for Borland C++,
|
||||
Digital Mars C++ and Watcom C++
|
||||
|
||||
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.
|
||||
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: compile fixes for g++ 3.0 and g++ 3.1
|
||||
|
||||
@@ -61,7 +187,6 @@ Changes in 1.20 (23 May 2001)
|
||||
our unstable development releases 1.1x and 1.9x]
|
||||
|
||||
Changes in 1.08 (30 Apr 2001)
|
||||
* INFO: http://upx.sourceforge.net now is the new permanent UPX home page
|
||||
* new native port to atari/tos
|
||||
* win32/pe: shortened the identstring
|
||||
* source code: portability fixes - UPX now builds cleanly under m68k CPUs
|
||||
@@ -86,7 +211,7 @@ Changes in 1.05 (24 Jan 2001)
|
||||
at the unstable UPX 1.1x beta versions for that)
|
||||
|
||||
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
|
||||
* some tunings for the default compression level
|
||||
|
||||
@@ -94,7 +219,7 @@ Changes in 1.03 (30 Nov 2000)
|
||||
* linked with a new version of the NRV compression library:
|
||||
- improved compression ratio a little bit
|
||||
- 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
|
||||
* atari/tos: added support for FreeMiNT
|
||||
* the 32-bit DOS version now uses the new CWSDSTUB extender
|
||||
@@ -102,7 +227,7 @@ Changes in 1.03 (30 Nov 2000)
|
||||
Changes in 1.02 (13 Sep 2000)
|
||||
* watcom/le: fixed a problem with the Causeway extender
|
||||
* 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
|
||||
|
||||
Changes in 1.01 (09 Apr 2000)
|
||||
@@ -130,7 +255,7 @@ Changes in 0.99.1 (29 Feb 2000)
|
||||
|
||||
Changes in 0.99 (25 Feb 2000)
|
||||
* 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
|
||||
* linux/386: the counter for the progress indicator was off by one
|
||||
|
||||
@@ -153,7 +278,7 @@ Changes in 0.91 (13 Nov 1999)
|
||||
* dos/exe: correctly restore cs when uncompressing
|
||||
|
||||
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
|
||||
* win32/pe: uncompression is finally supported
|
||||
* win32/pe: never compress REGISTRY resources
|
||||
@@ -163,7 +288,7 @@ Changes in 0.90 (10 Nov 1999)
|
||||
* win32/pe: somewhat less memory is required during compression
|
||||
* linux/386: fixed compression of scripts which was broken since 0.71
|
||||
* 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)
|
||||
|
||||
Changes in 0.84 (04 Oct 1999)
|
||||
@@ -179,7 +304,7 @@ Changes in 0.83 (17 Sep 1999)
|
||||
Changes in 0.82 (16 Aug 1999)
|
||||
* 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
|
||||
`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
|
||||
* win32/pe: removed some unneeded data
|
||||
|
||||
@@ -188,32 +313,32 @@ Changes in 0.81 (04 Aug 1999)
|
||||
* dos/com: fixed an internal error that could happen with very small files
|
||||
|
||||
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/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
|
||||
* 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: support files which do not contain their stack in the last object
|
||||
* wc/le: fixed a bug which could cause a crash, improved relocation
|
||||
handling
|
||||
* wc/le: new option `--copy-overlay'
|
||||
* win32/pe: `--compress-icons=2' is now the default
|
||||
* wc/le: new option '--copy-overlay'
|
||||
* win32/pe: '--compress-icons=2' is now the default
|
||||
* win32/pe: even better TLS support
|
||||
* win32/pe: versioninfo works on NT
|
||||
* win32/pe: import by ordinal from kernel32.dll works
|
||||
* win32/pe: other import improvements: importing a nonexistant DLL
|
||||
results in a usual Windows message, importing a nonexistant function
|
||||
* win32/pe: other import improvements: importing a nonexistent DLL
|
||||
results in a usual Windows message, importing a nonexistent function
|
||||
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
|
||||
files might even require LESS memory when they're compressed
|
||||
* win32/pe: TYPELIBs should work now
|
||||
* 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 `--copy-overlay'
|
||||
* win32/pe: new option '--strip-relocs' (only if you know what you are doing)
|
||||
* win32/pe: new option '--copy-overlay'
|
||||
* important internal changes: now the stubs are built at runtime
|
||||
|
||||
Changes in 0.72 (12 May 1999)
|
||||
@@ -227,20 +352,20 @@ Changes in 0.72 (12 May 1999)
|
||||
* linux/386: minor decompressor stub updates, nicer progress bar
|
||||
|
||||
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
|
||||
overhead for an extra cleanup process has been removed
|
||||
* win32/pe: added support for export forwarders
|
||||
* win32/pe: added support for DLLs without entry point or imports
|
||||
* 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
|
||||
* win32/pe: rearranged stub to avoid false alerts from some virus scanners
|
||||
|
||||
Changes in 0.70 (30 Mar 1999)
|
||||
* added support for linux/386 executables
|
||||
* 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: --compress-icons=0 should now work as well
|
||||
* the usual minor fixes for win32/pe
|
||||
@@ -257,7 +382,7 @@ Changes in 0.60 (06 Mar 1999)
|
||||
* win32/pe: fixed file corruption when the size of the export data is invalid
|
||||
* win32/pe: fixed a problem with empty resource data
|
||||
* win32/pe: compressed file alignment set to minimum value
|
||||
* win32/pe: made all compressed sections writeable
|
||||
* win32/pe: made all compressed sections writable
|
||||
* fixed some other win32/pe bugs
|
||||
* fixed an address optimization problem for some not Watcom LE files
|
||||
* fixed a bug which could make UPX hang when an exe header contained
|
||||
@@ -281,7 +406,7 @@ Changes in 0.40 (05 Oct 1998)
|
||||
* fixed a small but fatal bug in dos/sys introduced in 0.30
|
||||
* fixed a rare bug in dos/exe
|
||||
* worked around a bug in djgpp's strip 2.8
|
||||
* Allegro packfile support should work now
|
||||
* djgpp/coff: Allegro packfile support should work now
|
||||
* added dos/exeh compression method (works on 386+)
|
||||
|
||||
Changes in 0.30 (27 Jul 1998)
|
||||
@@ -298,3 +423,5 @@ Changes in 0.20 (05 Jul 1998)
|
||||
Changes in 0.05 (26 May 1998)
|
||||
* first public beta release
|
||||
|
||||
|
||||
# vim:set syntax=off tw=0 ts=4 sw=4 et: -*- coding: utf-8 -*-
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2002 Markus Oberhumer & Laszlo Molnar
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
Here are some possible projects from which you can choose if you'd like to
|
||||
@@ -42,8 +42,6 @@ More formats:
|
||||
- freebsd/386 (generic), freebsd/elf386 (specialized).
|
||||
Probably could share most of the linux code.
|
||||
|
||||
- Windows CE
|
||||
|
||||
- add support for self-extracting HTML pages using a Javascript stub
|
||||
(like the AlgART HTML Packer "AHP")
|
||||
|
||||
@@ -58,8 +56,6 @@ Existing formats:
|
||||
|
||||
- dos/exe: implement filter support
|
||||
|
||||
- dos/sys: add support for sys/exe combos
|
||||
|
||||
- linux/i386:
|
||||
- use the new assembly preprocessor stuff (ie. process the file
|
||||
headers internally)
|
||||
@@ -70,8 +66,7 @@ Existing formats:
|
||||
|
||||
- win32/pe: display a nice dialog box in the stub in case
|
||||
of problems (like importing a DLL or function fails)
|
||||
- win32/pe: finer control over resource compression, per section
|
||||
compression
|
||||
- win32/pe: per section compression
|
||||
|
||||
|
||||
Compression ratio:
|
||||
|
||||
@@ -8,26 +8,11 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2002 Markus Oberhumer & Laszlo Molnar
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
|
||||
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.22, and the next stable release
|
||||
will be called version 2.00.
|
||||
|
||||
The main news since 1.22 are support for bootable Linux kernels ("vmlinuz/386")
|
||||
and direct Linux ELF-to-memory decompression ("linux/elf386"), so there's
|
||||
no reason to use the unstable versions unless you want to try the new formats.
|
||||
|
||||
|
||||
WELCOME
|
||||
=======
|
||||
|
||||
@@ -52,7 +37,7 @@ and run exactly as before, with no runtime or memory penalty for most
|
||||
of the supported formats.
|
||||
|
||||
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.
|
||||
|
||||
UPX is free software distributed under the term of the GNU General
|
||||
@@ -70,8 +55,8 @@ UPX aims to be Commercial Quality Freeware.
|
||||
SHORT DOCUMENTATION
|
||||
===================
|
||||
|
||||
`upx program.exe' will compress a program or DLL. For best compression
|
||||
results try `upx --best program.exe'.
|
||||
'upx program.exe' will compress a program or DLL. For best compression
|
||||
results try 'upx --brute program.exe'.
|
||||
|
||||
Please see the file UPX.DOC for the full documentation. The files
|
||||
NEWS and BUGS also contain various tidbits of information.
|
||||
@@ -85,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
|
||||
have compressed lots of files without any problems. Also, the
|
||||
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
|
||||
releases will be backward compatible with this version.
|
||||
@@ -111,7 +96,7 @@ THE FUTURE
|
||||
- We will *NOT* add any sort of protection and/or encryption.
|
||||
This only gives people a false feeling of security because
|
||||
by definition all protectors/compressors can be broken.
|
||||
And don't trust any advertisment of authors of other executable
|
||||
And don't trust any advertisement of authors of other executable
|
||||
compressors about this topic - just do a websearch on "unpackers"...
|
||||
|
||||
- Fix all remaining bugs - keep your reports coming ;-)
|
||||
@@ -123,8 +108,9 @@ THE FUTURE
|
||||
COPYRIGHT
|
||||
=========
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
|
||||
This program may be used freely, and you are welcome to
|
||||
redistribute it under certain conditions.
|
||||
@@ -143,7 +129,7 @@ Markus & Laszlo
|
||||
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
|
||||
|
||||
|
||||
|
||||
+7
-15
@@ -8,24 +8,16 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
MAJOR NEWS IN UPX 3
|
||||
===================
|
||||
|
||||
WARNING - UNSTABLE BETA VERSION
|
||||
===============================
|
||||
The main news since UPX 2 are:
|
||||
|
||||
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.
|
||||
* new format: added support for linux elf/arm
|
||||
|
||||
The current stable release is 1.24, and the next stable release
|
||||
will be called version 2.00.
|
||||
|
||||
The main news since 1.24 are:
|
||||
- slightly better compression using the new NRV2E algorithm
|
||||
- new options for compression tuining (e.g. `--brute')
|
||||
- support for bootable Linux kernels ("vmlinuz/386")
|
||||
- direct Linux ELF-to-memory decompression ("linux/elf386")
|
||||
- support for playstation exes ("ps1/exe")
|
||||
- lots of new bugs ;-) take care
|
||||
* better compression using the LZMA algorithm (option '--lzma')
|
||||
|
||||
|
||||
+22
-30
@@ -66,49 +66,42 @@ Prerequisites
|
||||
Tools needed to build/modify the UPX sources
|
||||
--------------------------------------------
|
||||
|
||||
- A modern C++ compiler like gcc 2.95.3 or Visual C++ 6
|
||||
- A C++ compiler supporting inner classes, templates, exceptions
|
||||
and RTTI.
|
||||
|
||||
- GNU make for Win32
|
||||
http://upx.sourceforge.net/download/tools/
|
||||
|
||||
- GNU make for DOS
|
||||
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/
|
||||
- GNU make 3.80 or better (GNU make 3.81 recommened).
|
||||
|
||||
|
||||
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.01 (DOS / Windows)
|
||||
export UCLDIR=$HOME/local/src/ucl-1.01 (Unix)
|
||||
set UPX_UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
|
||||
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 # on linux
|
||||
make target=djgpp2 # for djgpp2
|
||||
make target=mingw32 # for mingw32
|
||||
make target=cygwin # cygwin 1.3.x
|
||||
make target=no-cygwin # for mingw32 as included in cygwin
|
||||
make target=vc6 # for Visual C++ 6.0
|
||||
export UPX_LZMADIR=$HOME/local/src/lzma-4.43 (Unix)
|
||||
|
||||
Finally type
|
||||
|
||||
make
|
||||
|
||||
|
||||
If you want to modify the stub sources you'll also need
|
||||
-------------------------------------------------------
|
||||
|
||||
- Nasm 0.98.34 - the Netwide Assembler
|
||||
http://upx.sourceforge.net/download/tools/
|
||||
http://nasm.sourceforge.net/
|
||||
- GNU make 3.81 or better
|
||||
http://savannah.gnu.org/projects/make/
|
||||
|
||||
- A68K - a 68000 macro assembler
|
||||
http://upx.sourceforge.net/download/tools/
|
||||
- Perl & Python
|
||||
|
||||
- djasm - an assembler for the djgpp stub
|
||||
http://upx.sourceforge.net/download/tools/
|
||||
|
||||
- Perl 5.004 or better
|
||||
|
||||
- Linux (for the linux/386 stubs)
|
||||
- A number of cross-assemblers and cross-compilers - precompiled
|
||||
binaries for i386-linux hosts are available from
|
||||
http://sourceforge.net/project/showfiles.php?group_id=2331
|
||||
|
||||
|
||||
Misc. notes
|
||||
@@ -123,9 +116,6 @@ Misc. notes
|
||||
stream.
|
||||
- Use gcc extensions and other compiler specific stuff only through
|
||||
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.
|
||||
|
||||
***
|
||||
|
||||
@@ -150,3 +140,5 @@ Patches/Contributions
|
||||
|
||||
diff -uNr olddirectory newdirectory
|
||||
|
||||
|
||||
# vi:ts=4:et
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2002 Markus Oberhumer & Laszlo Molnar
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
.___.. .
|
||||
@@ -39,12 +39,12 @@ Ice
|
||||
for debugging the PE headersize problem down
|
||||
Joergen Ibsen <jibz@hotmail.com> and d'b
|
||||
for the relocation & address optimization ideas
|
||||
John F. Reiser <jreiser@BitWagon.com>
|
||||
for the new Linux executable formats
|
||||
John S. Fine <johnfine@erols.com>
|
||||
for the new version of the dos/exe decompressor
|
||||
Lukundoo <Lukundoo@softhome.net>
|
||||
for beta testing
|
||||
Michael Devore
|
||||
for initial dos/exe device driver support
|
||||
Oleg V. Volkov <rover@lglobus.ru>
|
||||
for various FreeBSD specific informations
|
||||
The Owl & G-RoM
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
UPX TODO list. Last updated 2002-11-11.
|
||||
UPX TODO list. Last updated 2006-12-08.
|
||||
|
||||
|
||||
IMPORTANT PROBLEMS THAT SHOULD BE FIXED SOON:
|
||||
|
||||
- [None]
|
||||
|
||||
|
||||
OTHER:
|
||||
|
||||
- docs: convert docs from upx.pod to use AsciiDoc
|
||||
|
||||
- check all <const_cast> to make sure they are not invalid
|
||||
|
||||
@@ -6,6 +16,8 @@ UPX TODO list. Last updated 2002-11-11.
|
||||
(info: bla bla). Also ui.cpp (total_*).
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
||||
IMPROVED COMPRESSION RATIO
|
||||
==========================
|
||||
@@ -29,8 +41,6 @@ ALL FORMATS
|
||||
- implement `--cpu=486' option to use bswap on the 32-bit formats
|
||||
(if cpu >= 486)
|
||||
|
||||
- consider removing "or ebp,-1" when not needed
|
||||
|
||||
|
||||
FORMAT DJGPP2/COFF
|
||||
==================
|
||||
@@ -65,6 +75,8 @@ FORMAT TMT/ADAM
|
||||
FORMAT WATCOM/LE
|
||||
================
|
||||
|
||||
- handle files without relocations
|
||||
|
||||
- the decompressors are already aligned, no need for an
|
||||
extra alignment
|
||||
|
||||
@@ -72,10 +84,6 @@ FORMAT WATCOM/LE
|
||||
|
||||
- handle holes in the file
|
||||
|
||||
- implement compressWithFilters()
|
||||
|
||||
- add a call to verifyOverlappingDecompression()
|
||||
|
||||
|
||||
FORMAT WIN16/NE
|
||||
===============
|
||||
@@ -91,11 +99,6 @@ FORMAT WIN32/PE
|
||||
|
||||
- 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 - medium - ml) rebuild exports
|
||||
|
||||
3 - difficult) don't compress the BSS section and other holes.
|
||||
|
||||
4 - medium - ml) fix when objectalign < 0x1000
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
upx.1
|
||||
upx.doc
|
||||
upx.html
|
||||
upx.man
|
||||
upx.ps
|
||||
upx.tex
|
||||
+53
-36
@@ -1,34 +1,51 @@
|
||||
#
|
||||
# UPX doc Makefile - needs GNU make 3.80 or better
|
||||
#
|
||||
|
||||
MAKEFLAGS += -rR
|
||||
.SUFFIXES:
|
||||
SHELL = /bin/sh
|
||||
|
||||
top_srcdir = ..
|
||||
# internal make variables
|
||||
comma := ,
|
||||
empty :=
|
||||
space := $(empty) $(empty)
|
||||
tab := $(empty) $(empty)
|
||||
|
||||
PACKAGE = upx
|
||||
VERSION_DATE = 11 Nov 2002
|
||||
VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||
# 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
|
||||
|
||||
TRIMSPACE = cat
|
||||
TRIMSPACE = sed -e 's/ *$$//'
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
||||
top_srcdir ?= ..
|
||||
|
||||
PACKAGE = upx
|
||||
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)
|
||||
|
||||
RTRIM := sed -e 's/[ $(tab)]*$$//'
|
||||
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
|
||||
|
||||
|
||||
###
|
||||
###
|
||||
### targets
|
||||
###
|
||||
|
||||
all: $(BUILT_SOURCES)
|
||||
|
||||
mostlyclean:
|
||||
-rm -f $(BUILT_SOURCES) pod2htm*
|
||||
|
||||
clean: mostlyclean
|
||||
|
||||
distclean: clean
|
||||
|
||||
maintainer-clean: distclean
|
||||
|
||||
.SUFFIXES: .1 .doc .html .man .pod .ps .tex .texi
|
||||
mostlyclean clean distclean maintainer-clean:
|
||||
rm -f $(BUILT_SOURCES) pod2htm*
|
||||
|
||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||
|
||||
@@ -37,32 +54,32 @@ maintainer-clean: distclean
|
||||
### rules
|
||||
###
|
||||
|
||||
.pod.1:
|
||||
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(TRIMSPACE) > $@
|
||||
.SUFFIXES: .1 .doc .html .man .pod .ps .tex
|
||||
|
||||
.pod.html:
|
||||
### pod2html $< | $(TRIMSPACE) > $@
|
||||
pod2html --noindex $< | $(TRIMSPACE) > $@
|
||||
@-rm -f pod2htm*
|
||||
%.1 : %.pod
|
||||
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(RTRIM) > $@
|
||||
|
||||
.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 $<
|
||||
|
||||
.pod.doc:
|
||||
pod2text < $< | $(TRIMSPACE) > $@
|
||||
|
||||
.1.man:
|
||||
nroff -man $< | $(TRIMSPACE) > $@
|
||||
|
||||
.1.ps:
|
||||
groff -man $< | $(TRIMSPACE) > $@
|
||||
|
||||
|
||||
###
|
||||
### dependencies
|
||||
###
|
||||
|
||||
$(BUILT_SOURCES): $(top_srcdir)/src/version.h Makefile
|
||||
|
||||
.NOEXPORT:
|
||||
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
||||
.DELETE_ON_ERROR: $(BUILT_SOURCES)
|
||||
|
||||
|
||||
+19
-3
@@ -1,5 +1,5 @@
|
||||
Decompressing ELF Directly to Memory on Linux/x86
|
||||
Copyright 2000 John F. Reiser jreiser@BitWagon.com
|
||||
Copyright (C) 2000-2007 John F. Reiser jreiser@BitWagon.com
|
||||
|
||||
References:
|
||||
<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
|
||||
brk() as the original executable. So, the second PT_LOAD
|
||||
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
|
||||
of the original executable, reside in the first PT_LOAD of the
|
||||
decompressor program.
|
||||
@@ -57,9 +57,25 @@ Subroutine do_xmap() of src/stub/l_lx_elf.c performs the
|
||||
"virtual execve()" using the compressed data as source, and stores
|
||||
the decompressed bytes directly into the appropriate virtual addresses.
|
||||
|
||||
Before transfering control to the PT_INTERP "program interpreter",
|
||||
Before transferring control to the PT_INTERP "program interpreter",
|
||||
minor tricks are required to setup the Elf32_auxv_t entries,
|
||||
clear the free portion of the stack (to compensate for ld-linux.so.2
|
||||
assuming that its automatic stack variables are initialized to zero),
|
||||
and remove (all but 4 bytes of) the decompression program (and
|
||||
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.
|
||||
|
||||
+26
-65
@@ -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
|
||||
that do the runtime decompression when a compressed program is started.
|
||||
|
||||
So, how the runtime stub/loader generation works?
|
||||
|
||||
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 (they are all 8 character length strings):
|
||||
If you look at the C++ source files, you can find code fragments like
|
||||
this:
|
||||
|
||||
addLoader("PEMAIN20",
|
||||
ih.entry ? "PEDOJUMP" : "PERETURN",
|
||||
@@ -19,71 +11,40 @@ in the following way (they are all 8 character length strings):
|
||||
NULL
|
||||
);
|
||||
|
||||
Basically that's all you have to know: when you want to add a section
|
||||
of assembly code to the runtime loader, you just write
|
||||
linker->defineSymbol("original_entry", ih.entry);
|
||||
|
||||
l_foo.asm
|
||||
---------
|
||||
;__FOOBAR00__
|
||||
and in the assembly files fragments like this:
|
||||
|
||||
xor eax, eax
|
||||
label1:
|
||||
jmps label1
|
||||
section PEISDLL1
|
||||
cmpb [esp + 8], 1
|
||||
jnz reloc_end_jmp
|
||||
|
||||
;__FOOBARZZ__
|
||||
section PEMAIN21
|
||||
reloc_end_jmp:
|
||||
|
||||
p_foo.cpp
|
||||
---------
|
||||
section PERETURN
|
||||
xor eax, eax
|
||||
inc eax
|
||||
ret 0x0C
|
||||
section PEDOJUMP
|
||||
jmp original_entry
|
||||
|
||||
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.)
|
||||
Everything works as you would expect. If you want to add the code
|
||||
fragment which is in `section PERETURN' to the runtime stub, then
|
||||
simply use `addLoader("PERETURN")' in the C++ source.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
assembly preprocessor (src/stub/scripts/app.pl) and a little C++ module
|
||||
(src/linker.cpp). And of course NASM - the Netwide Assembler. You can
|
||||
see what's going on behind the scenes - just do:
|
||||
You can also use (undefined) symbols in the assembly for values that
|
||||
can only be computed during compression time (like `original_entry').
|
||||
These symbols can be defined later in C++ using
|
||||
|
||||
cd src/stubs
|
||||
make maintainer-clean
|
||||
make all
|
||||
linker->defineSymbol("xx", yy)
|
||||
|
||||
This will rebuild all the loaders - and keep the temporary files (*.as[xy])
|
||||
which are seen by the assembler.
|
||||
|
||||
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.
|
||||
This functionality (we could say it's a simple linker) is achieved by
|
||||
compiling the assembly into an ELF object file which a little C++
|
||||
module (src/linker.cpp) can interpret and work with.
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
UPX and SELinux
|
||||
March 6, 2006
|
||||
|
||||
|
||||
When a program that has been compressed by UPX is run, the decompressor
|
||||
must create and write new memory pages of executable instructions.
|
||||
SELinux (Security Enhanced Linux) directly controls the conditions
|
||||
under which generating and/or executing new instructions is allowed,
|
||||
so the configuration settings of SELinux affect the running of programs
|
||||
that have been compressed by UPX.
|
||||
|
||||
In SELinux "strict enforcing" mode (the most restrictive), generating
|
||||
new instructions at runtime is not allowed at all: any page with
|
||||
PROT_EXEC permission must be mapped from a file in a mounted filesystem
|
||||
that has 'x' [eXecute] permission, and the generation of such files is
|
||||
also tightly controlled. A program that was compressed by UPX will not
|
||||
run in SELinux strict enforcing mode. Attempts will fail with exit
|
||||
code 127, and a record will be added to the history file
|
||||
/var/log/audit/audit.log.
|
||||
|
||||
In "targeted enforcing" mode, SELinux pays close attention mostly to
|
||||
designated processes that run with elevated privileges: web server,
|
||||
print server, login server, etc. Ordinary user excutables receive
|
||||
much less scrutiny. However, one of the eventual goals of SELinux is to
|
||||
eradicate runtime generation of instructions because of the possibility
|
||||
for exploitation by malware (virus, trojan, key logger, privilege
|
||||
elevation exploit, etc.) Thus targeted enforcing mode notices and
|
||||
logs the use of "execmem" capability that is used by a program which
|
||||
was compressed by UPX. In keeping with the goal of eventual prohibition,
|
||||
SELinux ordinarily would deny execmem. However, most current SELinux
|
||||
systems, including Fedora Core 5 [set for release March 15, 2006],
|
||||
override this with "allow_exemem=1" in /etc/selinux/targeted/booleans.
|
||||
Thus a program compressed by UPX will run in the default installed
|
||||
configuration (targeted enforcing, allow_execmem=1) of SELinux under
|
||||
Fedora Core 5. Each invocation will add a few lines to the log file
|
||||
/var/log/audit/audit.log, one line for each use of execmem. If the
|
||||
SELinux policy becomes more restrictive in the future, then a special
|
||||
SELinux class or other mechanism must be created for compressed programs,
|
||||
or else UPX-compressed executables will not run then.
|
||||
|
||||
In its "permissive" modes, SELinux just logs the potential problems,
|
||||
but otherwise does not interfere. A program compressed by UPX will run
|
||||
in any permissive mode.
|
||||
+114
-74
@@ -12,15 +12,16 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
|
||||
|
||||
=head1 ABSTRACT
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2002 Markus Oberhumer & Laszlo Molnar
|
||||
http://upx.sourceforge.net
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2007 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
B<UPX> is a portable, extendable, high-performance executable packer for
|
||||
several different executable formats. It achieves an excellent compression
|
||||
ratio and offers I<*very*> fast decompression. Your executables suffer
|
||||
no memory overhead or other drawbacks for most of the formats supported.
|
||||
no memory overhead or other drawbacks for most of the formats supported,
|
||||
because of in-place decompression.
|
||||
|
||||
While you may use B<UPX> freely for both non-commercial and commercial
|
||||
executables (for details see the file LICENSE), we would highly
|
||||
@@ -36,11 +37,6 @@ is considered not politically correct ;-) ]
|
||||
|
||||
B<UPX> comes with ABSOLUTELY NO WARRANTY; for details see the file LICENSE.
|
||||
|
||||
Having said that, we think that B<UPX> is quite stable now. Indeed we
|
||||
have compressed lots of files without any problems. Also, the
|
||||
current version has undergone several months of beta testing -
|
||||
actually it's more than 4 years since our first public beta back in 1998.
|
||||
|
||||
This is the first production quality release, and we plan that future 1.xx
|
||||
releases will be backward compatible with this version.
|
||||
|
||||
@@ -55,7 +51,8 @@ B<UPX> is a versatile executable packer with the following features:
|
||||
- excellent compression ratio: compresses better than zip/gzip,
|
||||
use UPX to decrease the size of your distribution !
|
||||
|
||||
- very fast decompression: about 10 MB/sec even on my old Pentium 133
|
||||
- very fast decompression: about 10 MB/sec on an ancient Pentium 133,
|
||||
about 200 MB/sec on an Athlon XP 2000+.
|
||||
|
||||
- no memory overhead for your compressed executables for most of the
|
||||
supported formats
|
||||
@@ -78,8 +75,13 @@ B<UPX> is a versatile executable packer with the following features:
|
||||
* rtm32/pe
|
||||
* tmt/adam
|
||||
* vmlinuz/386 [bootable Linux kernel]
|
||||
* vmlinux/386
|
||||
* watcom/le (supporting DOS4G, PMODE/W, DOS32a and CauseWay)
|
||||
* win32/pe
|
||||
* win32/pe (exe and dll)
|
||||
* arm/pe (exe and dll)
|
||||
* linux/elfamd64
|
||||
* linux/elfppc32
|
||||
* mach/elfppc32
|
||||
|
||||
- portable: UPX is written in portable endian-neutral C++
|
||||
|
||||
@@ -136,6 +138,13 @@ B<--help>: prints the help
|
||||
|
||||
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>. [NOTE: this is work in progress and is
|
||||
not supported for all formats yet. If you do care, as a workaround you can
|
||||
compress and then decompress your program a first time - any further
|
||||
compress-decompress steps should then yield byte-identical results
|
||||
as compared to the first decompressed version.]
|
||||
|
||||
[ ...to be written... - type `B<upx --help>' for now ]
|
||||
|
||||
|
||||
@@ -166,29 +175,17 @@ Compression level B<--best> may take a long time.
|
||||
|
||||
=back
|
||||
|
||||
Note that compression level B<-9> can be somewhat slow for large
|
||||
Note that compression level B<--best> can be somewhat slow for large
|
||||
files, but you definitely should use it when releasing a final version
|
||||
of your program.
|
||||
|
||||
Since UPX 0.70 there is also an extra compression level B<--best> which
|
||||
squeezes out even some more compression ratio. While it is usually fine
|
||||
to use this option with your favorite .com file it may take a long time
|
||||
to compress a multi-megabyte program. You have been warned.
|
||||
|
||||
Tips for achieving the best compression ratio:
|
||||
Quick info for achieving the best compression ratio:
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
Use the compression level B<--best>.
|
||||
|
||||
=item *
|
||||
|
||||
Try one or both of the options B<--all-methods> and B<--all-filters>.
|
||||
|
||||
Info: the option B<--brute> is an abbrevation for all the options
|
||||
B<S<--best> S<--all-methods> S<--all-filters>>.
|
||||
Try B<upx --brute myfile.exe> or even B<upx --ultra-brute myfile.exe>.
|
||||
|
||||
=item *
|
||||
|
||||
@@ -204,12 +201,15 @@ For win32/pe programs there's B<--strip-relocs=0>. See notes below.
|
||||
|
||||
=head1 OVERLAY HANDLING OPTIONS
|
||||
|
||||
Info: An "overlay" means auxiliary data attached after the logical end of
|
||||
an executable, and it often contains application specific data
|
||||
(this is a common practice to avoid an extra data file, though
|
||||
it would be better to use resource sections).
|
||||
|
||||
B<UPX> handles overlays like many other executable packers do: it simply
|
||||
copies the overlay after the compressed image. This works with some
|
||||
files, but doesn't work with others.
|
||||
|
||||
Since version 0.90 UPX defaults to B<--overlay=copy> for
|
||||
all executable formats.
|
||||
files, but doesn't work with others, depending on how an application
|
||||
actually accesses this overlayed data.
|
||||
|
||||
--overlay=copy Copy any extra data attached to the file. [DEFAULT]
|
||||
|
||||
@@ -238,7 +238,8 @@ environment variable because of a COMMAND.COM limitation.
|
||||
Not all of the options are valid in the environment variable -
|
||||
B<UPX> will tell you.
|
||||
|
||||
You can use the B<--no-env> option to turn this support off.
|
||||
You can explicitly use the B<--no-env> option to ignore the
|
||||
environment variable.
|
||||
|
||||
|
||||
|
||||
@@ -250,6 +251,7 @@ This is the executable format used by the Atari ST/TT, a Motorola 68000
|
||||
based personal computer which was popular in the late '80s. Support
|
||||
of this format is only because of nostalgic feelings of one of
|
||||
the authors and serves no practical purpose :-).
|
||||
See http://www.freemint.de for more info.
|
||||
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
All debug information will be stripped, though.
|
||||
@@ -320,9 +322,6 @@ Extra options available for this executable format:
|
||||
|
||||
=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+.
|
||||
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
@@ -350,11 +349,11 @@ Extra options available for this executable format:
|
||||
First of all, it is recommended to use B<UPX> *instead* of B<strip>. strip has
|
||||
the very bad habit of replacing your stub with its own (outdated) version.
|
||||
Additionally B<UPX> corrects a bug/feature in strip v2.8.x: it
|
||||
will fix the 4 KByte aligment of the stub.
|
||||
will fix the 4 KByte alignment of the stub.
|
||||
|
||||
B<UPX> includes the full functionality of stubify. This means it will
|
||||
automatically stubify your COFF files. Use the option B<--coff> to
|
||||
disable this behaviour (see below).
|
||||
disable this functionality (see below).
|
||||
|
||||
B<UPX> automatically handles Allegro packfiles.
|
||||
|
||||
@@ -385,7 +384,7 @@ Extra options available for this executable format:
|
||||
Introduction
|
||||
|
||||
Linux/386 support in UPX consists of 3 different executable formats,
|
||||
one optimized for ELF excutables ("linux/elf386"), one optimized
|
||||
one optimized for ELF executables ("linux/elf386"), one optimized
|
||||
for shell scripts ("linux/sh386"), and one generic format
|
||||
("linux/386").
|
||||
|
||||
@@ -413,14 +412,14 @@ General user's overview
|
||||
or network I/O.
|
||||
|
||||
Depending on the statistics of usage and access, and the relative
|
||||
speeds of CPU, RAM, swap space, /tmp, and filesystem storage, then
|
||||
speeds of CPU, RAM, swap space, /tmp, and file system storage, then
|
||||
invoking and running a compressed executable can be faster than
|
||||
directly running the corresponding uncompressed program.
|
||||
The operating system might perfrom fewer expensive I/O operations
|
||||
The operating system might perform fewer expensive I/O operations
|
||||
to invoke the compressed program. Paging to or from swap space
|
||||
or /tmp might be faster than paging from the general filesystem.
|
||||
or /tmp might be faster than paging from the general file system.
|
||||
``Medium-sized'' programs which access about 1/3 to 1/2 of their
|
||||
stored program bytes can do particulary well with compression.
|
||||
stored program bytes can do particularly well with compression.
|
||||
Small programs tend not to benefit as much because the absolute
|
||||
savings is less. Big programs tend not to benefit proportionally
|
||||
because each invocation may use only a small fraction of the program,
|
||||
@@ -429,7 +428,7 @@ General user's overview
|
||||
then compression may win anyway.
|
||||
|
||||
Currently, executables compressed by UPX do not share RAM at runtime
|
||||
in the way that executables mapped from a filesystem do. As a
|
||||
in the way that executables mapped from a file system do. As a
|
||||
result, if the same program is run simultaneously by more than one
|
||||
process, then using the compressed version will require more RAM and/or
|
||||
swap space. So, shell programs (bash, csh, etc.) and ``make''
|
||||
@@ -518,7 +517,7 @@ The linux/elf386 format decompresses directly into RAM,
|
||||
uses only one exec, does not use space in /tmp,
|
||||
and does not use /proc.
|
||||
|
||||
Linux/elf386 is automatically selected for Linux ELF exectuables.
|
||||
Linux/elf386 is automatically selected for Linux ELF executables.
|
||||
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
|
||||
@@ -607,7 +606,7 @@ Extra options available for this executable format:
|
||||
Please read the general Linux description first.
|
||||
|
||||
The generic linux/386 format decompresses to /tmp and needs
|
||||
/proc filesystem support. It starts the decompressed program
|
||||
/proc file system support. It starts the decompressed program
|
||||
via the execve() syscall.
|
||||
|
||||
Linux/386 is only selected if the specialized linux/elf386
|
||||
@@ -619,11 +618,11 @@ How it works:
|
||||
|
||||
For files which are not ELF and not a script for a known "-c" shell,
|
||||
UPX uses kernel execve(), which first requires decompressing to a
|
||||
temporary file in the filesystem. Interestingly -
|
||||
temporary file in the file system. Interestingly -
|
||||
because of the good memory management of the Linux kernel - this
|
||||
often does not introduce a noticable delay, and in fact there
|
||||
often does not introduce a noticeable delay, and in fact there
|
||||
will be no disk access at all if you have enough free memory as
|
||||
the entire process takes places within the filesystem buffers.
|
||||
the entire process takes places within the file system buffers.
|
||||
|
||||
A compressed executable consists of the UPX stub and an overlay
|
||||
which contains the original program in a compressed form.
|
||||
@@ -649,7 +648,7 @@ Specific drawbacks:
|
||||
decompression, but you still need it for the full execution time
|
||||
of the program.
|
||||
|
||||
- You must have /proc filesystem support as the stub wants to open
|
||||
- You must have /proc file system support as the stub wants to open
|
||||
/proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you
|
||||
cannot compress programs that are used during the boot sequence
|
||||
before /proc is mounted.
|
||||
@@ -661,7 +660,7 @@ Specific drawbacks:
|
||||
|
||||
- Because of temporary decompression to disk the decompression speed
|
||||
is not as fast as with the other executable formats. Still, I can see
|
||||
no noticable delay when starting programs like my ~3 MB emacs (which
|
||||
no noticeable delay when starting programs like my ~3 MB emacs (which
|
||||
is less than 1 MB when compressed :-).
|
||||
|
||||
Extra options available for this executable format:
|
||||
@@ -677,21 +676,28 @@ Extra options available for this executable format:
|
||||
This is the executable format used by the Sony PlayStation (PSone),
|
||||
a Mips R3000 based gaming console which is popular since the late '90s.
|
||||
Support of this format is very similar to the Atari one, because of
|
||||
nostalgic feelings of one of the authors, but this format maybe serves
|
||||
a practical purpose ;-).
|
||||
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.
|
||||
|
||||
Maximum uncompressed size: ~1998848 bytes.
|
||||
Maximum uncompressed size: ~1.89 / ~7.60 Mbytes.
|
||||
|
||||
Notes:
|
||||
|
||||
- UPX creates as default a suitable executable for CD-Mastering
|
||||
and console transfer. For a CD-Master main executable you could also try
|
||||
the special option "--boot-only" as described below.
|
||||
It has been reported that upx packed executables are fully compatible with
|
||||
the Sony PlayStation 2 (PS2, PStwo) and Sony PlayStation Portable (PSP) in
|
||||
Sony PlayStation (PSone) emulation mode.
|
||||
|
||||
- Normally the packed files use the same memory areas like the uncompressed
|
||||
versions, so they will not override other memory areas while unpacking.
|
||||
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
|
||||
offset for the packed file, but this isn't a real problem if it is a
|
||||
single or boot-only executable.
|
||||
error. With the "--force" option UPX will relocate the loading address
|
||||
for the packed file, but this isn't a real problem if it is a single or
|
||||
the main executable.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
@@ -700,14 +706,23 @@ Extra options available for this executable format:
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--8-bit Uses 8 bit size compression [default: 32 bit]
|
||||
|
||||
--8mb-ram PSone has 8 MB ram available [default: 2 MB]
|
||||
|
||||
--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
|
||||
alignment. This will slightly increase the compression
|
||||
ratio, but the compressed executable will not work
|
||||
when started from a CD.
|
||||
alignment. May slightly improves the compression ratio,
|
||||
but the compressed executable will not boot from a CD.
|
||||
Use it for console transfer only !
|
||||
|
||||
|
||||
|
||||
=head2 NOTES FOR RTM32/PE
|
||||
=head2 NOTES FOR RTM32/PE and ARM/PE
|
||||
|
||||
Same as win32/pe.
|
||||
|
||||
@@ -751,15 +766,15 @@ Benefits:
|
||||
- Better compression (but note that the kernel was already compressed,
|
||||
so the improvement is not as large as with other formats).
|
||||
Still, the bytes saved may be essential for special needs like
|
||||
bootdisks.
|
||||
boot disks.
|
||||
|
||||
For example, this is what I get for my 2.2.16 kernel:
|
||||
1589708 vmlinux
|
||||
641073 bzImage [original]
|
||||
560755 bzImage.upx [compressed by "upx -9"]
|
||||
|
||||
- Much faster decompression at kernel boot time (but decompression
|
||||
speed is not really an issue these days).
|
||||
- Much faster decompression at kernel boot time (but kernel
|
||||
decompression speed is not really an issue these days).
|
||||
|
||||
Drawbacks:
|
||||
|
||||
@@ -798,13 +813,14 @@ Extra options available for this executable format:
|
||||
=head2 NOTES FOR WIN32/PE
|
||||
|
||||
The PE support in B<UPX> is quite stable now, but probably there are
|
||||
still some incompabilities with some files.
|
||||
still some incompatibilities with some files.
|
||||
|
||||
Because of the way B<UPX> (and other packers for this format) works, you
|
||||
can see increased memory usage of your compressed files. If you start
|
||||
several instances of huge compressed programs you're wasting memory
|
||||
because the common segements of the program won't get shared
|
||||
across the instances.
|
||||
can see increased memory usage of your compressed files because the whole
|
||||
program is loaded into memory at startup.
|
||||
If you start several instances of huge compressed programs you're
|
||||
wasting memory because the common segments of the program won't
|
||||
get shared across the instances.
|
||||
On the other hand if you're compressing only smaller programs, or
|
||||
running only one instance of larger programs, then this penalty is
|
||||
smaller, but it's still there.
|
||||
@@ -812,12 +828,19 @@ smaller, but it's still there.
|
||||
If you're running executables from network, then compressed programs
|
||||
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
|
||||
must end with ".scr" (as screensavers are handled slightly different
|
||||
than normal exe files).
|
||||
|
||||
UPX compressed PE files have 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:
|
||||
|
||||
--compress-exports=0 Don't compress the export section.
|
||||
@@ -834,9 +857,26 @@ Extra options available for this executable format:
|
||||
--compress-icons=1 Compress all but the first icon.
|
||||
--compress-icons=2 Compress all icons which are not in the
|
||||
first icon directory. [DEFAULT]
|
||||
--compress-icons=3 Compress all icons.
|
||||
|
||||
--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
|
||||
unexpected value in a header field.
|
||||
Use with care.
|
||||
@@ -847,7 +887,7 @@ Extra options available for this executable format:
|
||||
address greater or equal to 0x400000. Usually the
|
||||
compressed files becomes smaller, but some files
|
||||
may become larger. Note that the resulting file will
|
||||
not work under Win32s.
|
||||
not work under Windows 3.x (Win32s).
|
||||
UPX never strips relocations from a DLL
|
||||
regardless of this option.
|
||||
|
||||
@@ -893,13 +933,13 @@ Please report all bugs immediately to the authors.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
|
||||
Copyright (C) 2000-2002 John F. Reiser
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
|
||||
Copyright (C) 2002 Jens Medoch
|
||||
Copyright (C) 2002-2007 Jens Medoch
|
||||
|
||||
This program may be used freely, and you are welcome to
|
||||
redistribute it under certain conditions.
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
The GNU bfd binary file descriptor package, part of the GNU binutils package,
|
||||
contains code to recognize an Elf file by looking at fields in the file header.
|
||||
Many programs (such as gdb, size, objdump, objcopy, strip and others) use bfd.
|
||||
Unfortunately, bfd has been overly strict. In releases
|
||||
binutils-2.9.1.0.4, binutils-2.9.1.0.23, binutils-2.9.5.0.0,
|
||||
binutils-2.10.1,
|
||||
gdb-4.17, gdb-5.0,
|
||||
and probably others,
|
||||
bfd does not recognize a file with zero in Elf32_Ehdr.e_shoff, .e_shentsize,
|
||||
or .e_shnum, even though the operating system kernel does not care, and many
|
||||
bfd clients would work just fine in these cases.
|
||||
|
||||
Because of its desire to create small size compressed executables, UPX
|
||||
generates and uses Elf files with zero in .e_shoff, .e_shentsizes, and .e_shnum.
|
||||
As a result, many widely-distributed instances of gdb, size, objdump, etc.,
|
||||
refuse to work on UPX-packed executables.
|
||||
|
||||
Here is a patch to bfd/elfcode.h which enables many bfd clients to work
|
||||
with UPX-packed executables. The last two lines of the patch are
|
||||
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1)
|
||||
return -1;
|
||||
|
||||
|
||||
--- elfcode.h.orig Mon Jun 16 11:45:32 1997
|
||||
+++ elfcode.h Sat Apr 22 10:18:56 2000
|
||||
@@ -1,5 +1,5 @@
|
||||
/* ELF executable support for BFD.
|
||||
- Copyright 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
|
||||
+ Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
|
||||
|
||||
Written by Fred Fish @ Cygnus Support, from information published
|
||||
in "UNIX System V Release 4, Programmers Guide: ANSI C and
|
||||
@@ -517,14 +517,14 @@
|
||||
elf_debug_file (i_ehdrp);
|
||||
#endif
|
||||
|
||||
- /* If there is no section header table, we're hosed. */
|
||||
- if (i_ehdrp->e_shoff == 0)
|
||||
+ /* If there is no section header table, and relocatable, then we're hosed. */
|
||||
+ if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_type == ET_REL)
|
||||
goto got_wrong_format_error;
|
||||
|
||||
/* As a simple sanity check, verify that the what BFD thinks is the
|
||||
size of each section header table entry actually matches the size
|
||||
- recorded in the file. */
|
||||
- if (i_ehdrp->e_shentsize != sizeof (x_shdr))
|
||||
+ recorded in the file, but only if there are any sections. */
|
||||
+ if (i_ehdrp->e_shentsize != sizeof (x_shdr) && i_ehdrp->e_shnum != 0)
|
||||
goto got_wrong_format_error;
|
||||
|
||||
ebd = get_elf_backend_data (abfd);
|
||||
@@ -579,6 +579,7 @@
|
||||
/* Allocate space for a copy of the section header table in
|
||||
internal form, seek to the section header table in the file,
|
||||
read it in, and convert it to internal form. */
|
||||
+ if (i_ehdrp->e_shnum!=0) {
|
||||
i_shdrp = ((Elf_Internal_Shdr *)
|
||||
bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum));
|
||||
elf_elfsections (abfd) = ((Elf_Internal_Shdr **)
|
||||
@@ -609,6 +610,7 @@
|
||||
if (! bfd_section_from_shdr (abfd, i_ehdrp->e_shstrndx))
|
||||
goto got_no_match;
|
||||
}
|
||||
+ }
|
||||
|
||||
/* Read in the program headers. */
|
||||
if (i_ehdrp->e_phnum == 0)
|
||||
@@ -644,6 +646,7 @@
|
||||
bfd_section_from_shdr with it (since this particular strtab is
|
||||
used to find all of the ELF section names.) */
|
||||
|
||||
+ if (i_ehdrp->e_shstrndx != 0) {
|
||||
shstrtab = bfd_elf_get_str_section (abfd, i_ehdrp->e_shstrndx);
|
||||
if (!shstrtab)
|
||||
goto got_no_match;
|
||||
@@ -657,6 +660,7 @@
|
||||
if (! bfd_section_from_shdr (abfd, shindex))
|
||||
goto got_no_match;
|
||||
}
|
||||
+ }
|
||||
|
||||
/* Let the backend double check the format and override global
|
||||
information. */
|
||||
@@ -930,7 +934,7 @@
|
||||
{
|
||||
Elf_Internal_Shdr *hdr;
|
||||
Elf_Internal_Shdr *verhdr;
|
||||
- long symcount; /* Number of external ELF symbols */
|
||||
+ unsigned long symcount; /* Number of external ELF symbols */
|
||||
elf_symbol_type *sym; /* Pointer to current bfd symbol */
|
||||
elf_symbol_type *symbase; /* Buffer for generated bfd symbols */
|
||||
Elf_Internal_Sym i_sym;
|
||||
@@ -978,7 +982,7 @@
|
||||
sym = symbase = NULL;
|
||||
else
|
||||
{
|
||||
- long i;
|
||||
+ unsigned long i;
|
||||
|
||||
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1)
|
||||
return -1;
|
||||
-1865
File diff suppressed because it is too large
Load Diff
@@ -1,19 +0,0 @@
|
||||
GNUmakefile
|
||||
*.0??
|
||||
*.dat
|
||||
*.idb
|
||||
*.img
|
||||
*.map
|
||||
*.raw
|
||||
*.rel
|
||||
*.pdb
|
||||
*.upx
|
||||
.gdbinit
|
||||
.Attic
|
||||
.deps
|
||||
compress_nrv.*
|
||||
upx
|
||||
upx_nrv
|
||||
upx_nrv.*
|
||||
upx_ucl
|
||||
upx_ucl.*
|
||||
+90
-604
@@ -1,625 +1,111 @@
|
||||
#
|
||||
# UPX Makefile (GNU make) - works with unix/win32/djgpp2
|
||||
#
|
||||
# usage:
|
||||
# `make target=linux' # linux
|
||||
# `make target=djggp2' # dos32 - djggp2 2.03
|
||||
# `make target=cygwin' # win32 - cygwin 1.3.x
|
||||
# `make target=mingw32' # win32 - mingw32
|
||||
# `make target=no-cygwin' # win32 - mingw32 as included in cygwin 1.3.x
|
||||
# `make target=bcc' # win32 - Borland C++ 5.5.1
|
||||
# `make target=dmc' # win32 - Digital Mars C++ 8.30
|
||||
# `make target=vc6' # win32 - Visual C++ 6.0
|
||||
# `make target=wcc' # win32 - Watcom C++ 11.0c
|
||||
# `make target=cross-m68k-linux' # m68k-linux cross compiler
|
||||
# `make target=cross-mingw32' # i586-mingw32msvc cross compiler
|
||||
# `make target=cross-mint' # m68k-atari-mint cross compiler
|
||||
# UPX Makefile - needs GNU make 3.81 or better
|
||||
#
|
||||
|
||||
|
||||
# configuration section
|
||||
|
||||
ifeq ($(strip $(UCLDIR)),)
|
||||
# change this to reflect where the UCL library is
|
||||
UCLDIR = $(HOME)/local/src/ucl-1.01
|
||||
endif
|
||||
|
||||
##target =
|
||||
|
||||
DEBUG = 0
|
||||
|
||||
|
||||
# -------------------------------------------------------
|
||||
# You should not have to change anything below this line.
|
||||
# -------------------------------------------------------
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
|
||||
MAKEFLAGS += -rR
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .a .c .cpp .exe .lib .o .obj .rc .res .ttp
|
||||
export SHELL = /bin/sh
|
||||
override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1)
|
||||
|
||||
|
||||
srcdir = .
|
||||
top_srcdir = ..
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
|
||||
# auto-detect the target unless given on the commandline
|
||||
ifeq ($(strip $(target)),)
|
||||
##target = djgpp2
|
||||
ifneq ($(strip $(wildcard /usr/include/linux)),)
|
||||
target = linux
|
||||
endif
|
||||
##ifneq ($(strip $(wildcard /platform/sun4?/kernel/unix)),)
|
||||
##target = sparc
|
||||
##endif
|
||||
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.77 3.78 3.78.1 3.79 3.79.1 3.80),)
|
||||
$(error GNU make 3.81 or better is required)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(target)),)
|
||||
include please_specify_a_target
|
||||
ifndef srcdir
|
||||
srcdir := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
|
||||
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,')
|
||||
endif
|
||||
ifndef top_srcdir
|
||||
top_srcdir := $(srcdir)/..
|
||||
endif
|
||||
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||
ifneq ($(srcdir),.)
|
||||
##$(info Info: using VPATH . $(srcdir))
|
||||
VPATH := . $(srcdir)
|
||||
endif
|
||||
|
||||
|
||||
# util var for use in the rules - basename of the current target
|
||||
override T = $(basename $@)
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // object files
|
||||
# ************************************************************************/
|
||||
|
||||
# these use exceptions & RTTI
|
||||
OBJECTS1 = \
|
||||
compress$o except$o file$o lefile$o \
|
||||
filter$o linker$o mem$o msg$o stdcxx$o work$o ui$o \
|
||||
packer$o packerf$o packhead$o packmast$o \
|
||||
p_com$o p_djgpp2$o p_elks$o p_exe$o \
|
||||
p_lx_elf$o p_lx_exc$o p_lx_sep$o p_lx_sh$o \
|
||||
p_ps1$o p_sys$o p_tmt$o p_tos$o \
|
||||
p_unix$o p_vmlinz$o p_w16ne$o p_w32pe$o p_wcle$o
|
||||
|
||||
# no exceptions or RTTI
|
||||
OBJECTS2 = \
|
||||
filteri$o help$o main$o mygetopt$o snprintf$o util$o \
|
||||
c_init$o c_file$o c_none$o c_screen$o \
|
||||
s_object$o s_djgpp2$o s_vcsa$o s_win32$o
|
||||
|
||||
# pure C sources
|
||||
OBJECTS3 =
|
||||
|
||||
OBJECTS = $(OBJECTS1) $(OBJECTS2) $(OBJECTS3)
|
||||
LIBS =
|
||||
RESOURCES =
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // compiler settings
|
||||
# ************************************************************************/
|
||||
|
||||
###
|
||||
### default compiler (gcc under unix)
|
||||
###
|
||||
|
||||
o = .o
|
||||
a = .a
|
||||
e =
|
||||
|
||||
CC = gcc
|
||||
DEFS =
|
||||
INCLUDES =
|
||||
##INCLUDES = -I. -I$(srcdir)
|
||||
CFLAGS_OUTPUT = -o $@
|
||||
|
||||
LINK_EXE = $(CXXLD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
||||
STUBEDIT_EXE =
|
||||
STUBIFY_EXE =
|
||||
CHMOD_EXE =
|
||||
|
||||
# C++ defaults are set later
|
||||
CXX =
|
||||
CXXLD =
|
||||
CXXFLAGS_OUTPUT =
|
||||
|
||||
|
||||
###
|
||||
### gcc defaults
|
||||
###
|
||||
|
||||
##CFLAGS_WERROR = -Werror
|
||||
CFLAGS_WERROR =
|
||||
CFLAGS_W = $(CFLAGS_WERROR)
|
||||
CFLAGS_W += -Wall -W -Wcast-align -Wcast-qual -Wmissing-prototypes -Wpointer-arith -Wshadow -Wwrite-strings
|
||||
CFLAGS_M =
|
||||
##CFLAGS_M += -fno-builtin
|
||||
##CFLAGS_M += -malign-functions=0 -malign-jumps=0 -malign-loops=0
|
||||
##CFLAGS_O = -Os -fstrict-aliasing
|
||||
##CFLAGS_O = -O2 -fstrict-aliasing
|
||||
CFLAGS_O = -O2 -fno-strict-aliasing
|
||||
|
||||
CFLAGS = $(CFLAGS_W) $(CFLAGS_M) $(CFLAGS_O)
|
||||
CXXFLAGS = $(CFLAGS) -Wsynth -fconserve-space
|
||||
CXXFLAGS1 = $(CXXFLAGS)
|
||||
##CXXFLAGS1 += -fasynchronous-exceptions
|
||||
CXXFLAGS2 = $(CXXFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
ifeq ($(CXX),)
|
||||
CXX = g++
|
||||
endif
|
||||
ifneq ($(findstring $(firstword $(CXX)),g++),)
|
||||
USE_GNUC ?= 1
|
||||
endif
|
||||
ifeq ($(USE_GNUC),1)
|
||||
ifeq ($(DEBUG),1)
|
||||
DEFS += -DDEBUG
|
||||
## DEFS += -DTESTING
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
LDFLAGS = -g
|
||||
CXXFLAGS += -O0 -g
|
||||
else
|
||||
LDFLAGS = -s
|
||||
CXXFLAGS += -O2
|
||||
endif
|
||||
LDFLAGS += -Wl,-Map,$T.map
|
||||
LDLIBS = -lz
|
||||
LIBDIRS =
|
||||
DOS_LDLIBS =
|
||||
DOS_LIBDIRS =
|
||||
|
||||
|
||||
###
|
||||
### compression library
|
||||
###
|
||||
|
||||
UCLDIR:=$(strip $(subst \,/,$(UCLDIR)))
|
||||
NRVDIR:=$(strip $(subst \,/,$(NRVDIR)))
|
||||
u = ucl
|
||||
U = UCL
|
||||
upx_exe_tail =
|
||||
include $(srcdir)/Makefile.inc
|
||||
ifneq ($(strip $(wildcard $(NRVDIR)/include/nrv)),)
|
||||
u = nrv
|
||||
U = NRV
|
||||
upx_exe_tail = _$(u)
|
||||
include $(srcdir)/Makefile.inc
|
||||
CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wwrite-strings -Werror
|
||||
##CXXFLAGS += -Wshadow
|
||||
endif
|
||||
upx_exe = upx$(upx_exe_tail)$(e)
|
||||
CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
|
||||
CXXLD ?= $(CXX)
|
||||
|
||||
override tmp := -Wl,--rpath,
|
||||
LDRPATH := $(addprefix $(tmp),$(LIBDIRS))
|
||||
LIBDIRS += .
|
||||
LDLIBDIRS := $(addprefix -L,$(LIBDIRS))
|
||||
exeext ?= .out
|
||||
libext ?= .a
|
||||
objext ?= .o
|
||||
|
||||
##LDFLAGS += $(LDRPATH)
|
||||
LDFLAGS += $(LDLIBDIRS)
|
||||
upx_SOURCES := $(wildcard $(srcdir)/*.cpp)
|
||||
upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
|
||||
|
||||
|
||||
###
|
||||
### Linux
|
||||
###
|
||||
|
||||
ifeq ($(target),linux)
|
||||
override arch := $(shell uname -m | sed -e 's/^i[3456789]86$$/i386/')
|
||||
DEFS += '-DUPX_CONFIG_H="config_h/linux.h"'
|
||||
DEFS += -D_FILE_OFFSET_BITS=64
|
||||
LDLIBS += -lmcheck
|
||||
ifeq ($(arch),i386)
|
||||
CC += -march=i386 -mcpu=i586
|
||||
##CFLAGS_M += -mno-schedule-prologue
|
||||
# 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 LZMA SDK
|
||||
include $(top_srcdir)/src/stub/src/c/Makevars.lzma
|
||||
ifneq ($(UPX_LZMA_VERSION),)
|
||||
DEFS += -DWITH_LZMA=$(UPX_LZMA_VERSION)
|
||||
INCLUDES += -I$(UPX_LZMADIR)
|
||||
endif
|
||||
##CFLAGS_WERROR = -Werror
|
||||
|
||||
ifeq (1,2) # checkergcc
|
||||
CC = checkergcc
|
||||
CXX = checkerg++
|
||||
|
||||
all: upx$(exeext) | .depend
|
||||
.DELETE_ON_ERROR: upx$(exeext) $(upx_OBJECTS) .depend
|
||||
|
||||
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
||||
$($(notdir $@).PRE_LINK_STEP)
|
||||
$(strip $(CXXLD) $(call e,CPPFLAGS) $(call e,CXXFLAGS) $(call e,LDFLAGS) -o $@ $(upx_OBJECTS) $(call e,LDADD) $(call e,LIBS))
|
||||
$($(notdir $@).POST_LINK_STEP)
|
||||
|
||||
%.o : %.cpp | .depend
|
||||
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
||||
|
||||
.depend: $(wildcard $(srcdir)/*.cpp $(srcdir)/*.h) $(MAKEFILE_LIST)
|
||||
@rm -f $@
|
||||
ifeq ($(USE_GNUC),1)
|
||||
@echo "Updating $@"
|
||||
@$(strip $(CXX) $(call e,CPPFLAGS) -MM) $(filter %.cpp,$^) > $@
|
||||
else
|
||||
ifeq ($(DEBUG),1)
|
||||
##CFLAGS += -O0 -gstabs+3
|
||||
##CFLAGS += -O0 -gdwarf-2
|
||||
CFLAGS += -O0 -g
|
||||
touch $@
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(USE_GNUC),1)
|
||||
##compress_lzma$(objext) : CXXFLAGS += -O3 -fomit-frame-pointer
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-cast-qual
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-shadow
|
||||
ifeq ($(UPX_LZMA_VERSION),0x443)
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-non-virtual-dtor
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-unused
|
||||
endif
|
||||
# needed for gcc-4.3:
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-error
|
||||
endif
|
||||
|
||||
|
||||
mostlyclean clean distclean maintainer-clean:
|
||||
rm -f *.d *.map *.o *.obj *.res .depend upx.exe upx.out upx.ttp upx$(exeext)
|
||||
|
||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||
|
||||
ifeq ($(MAKECMDGOALS),mostlyclean)
|
||||
else ifeq ($(MAKECMDGOALS),clean)
|
||||
else ifeq ($(MAKECMDGOALS),distclean)
|
||||
else ifeq ($(MAKECMDGOALS),maintainer-clean)
|
||||
else
|
||||
##LDFLAGS += -static
|
||||
STUBEDIT_EXE = objcopy -S -R .comment -R .note $@
|
||||
ifeq ($(arch),i386)
|
||||
STUBIFY_EXE = perl $(srcdir)/stub/scripts/brandelf.pl $@
|
||||
CHMOD_EXE = chmod 755 $@
|
||||
endif
|
||||
-include .depend
|
||||
endif
|
||||
endif
|
||||
|
||||
endif # linux
|
||||
|
||||
|
||||
###
|
||||
### Linux cross compilers
|
||||
###
|
||||
|
||||
ifeq ($(target),cross-m68k-linux)
|
||||
CC = m68k-linux-gcc
|
||||
DEFS += '-DUPX_CONFIG_H="config_h/linux.h"'
|
||||
##LDLIBS += -lmcheck
|
||||
endif # cross-m68k-linux
|
||||
|
||||
|
||||
###
|
||||
### sparc-sun-solaris2.8
|
||||
###
|
||||
|
||||
ifeq ($(target),sparc)
|
||||
CC = gcc
|
||||
DEFS += '-DUPX_CONFIG_H="config_h/sparc_sun_solaris28.h"'
|
||||
endif # sparc
|
||||
|
||||
|
||||
ifeq ($(target),XXX-sparc)
|
||||
DEFS += '-DUPX_CONFIG_H="config_h/sparc_sun_solaris28.h"'
|
||||
INCLUDES += -I/home/ethmola/local/include
|
||||
|
||||
ifeq (1,2) # native compiler
|
||||
CFLAGS = -O0 -g
|
||||
CXXFLAGS1 =
|
||||
CXXFLAGS2 =
|
||||
DEFS += -DUSE_STDNAMESPACE
|
||||
else # gcc
|
||||
CFLAGS += -O0 -gstabs+
|
||||
endif
|
||||
|
||||
ifeq (1,2) # purify
|
||||
DEFS += -D__PURIFY__
|
||||
CXXLD := purify $(CXXLD)
|
||||
endif
|
||||
|
||||
endif # XXX-sparc
|
||||
|
||||
|
||||
###
|
||||
### Atari cross compiler
|
||||
###
|
||||
|
||||
ifeq ($(target),cross-mint)
|
||||
e = .ttp
|
||||
CC = m68k-atari-mint-gcc
|
||||
CC += -m68000
|
||||
endif
|
||||
|
||||
ifeq ($(target),cross-mint-m68040)
|
||||
e = .ttp
|
||||
CC = m68k-atari-mint-gcc
|
||||
CC += -m68040
|
||||
endif
|
||||
|
||||
ifeq ($(target),cross-mint-m68020-60)
|
||||
e = .ttp
|
||||
CC = m68k-atari-mint-gcc
|
||||
CC += -m68020-60 -m68881
|
||||
endif
|
||||
|
||||
|
||||
###
|
||||
### djgpp2
|
||||
###
|
||||
|
||||
ifeq ($(target),djgpp2)
|
||||
e = .exe
|
||||
CC += -march=i386 -mcpu=i586
|
||||
##CFLAGS_M += -mno-schedule-prologue
|
||||
CFLAGS_WERROR = -Werror
|
||||
STUBEDIT_EXE = stubedit $@ bufsize=0xfc00
|
||||
ifneq ($(strip $(wildcard $(DJDIR)/bin/mfxdjstubify.ex[eE])),)
|
||||
ifneq ($(strip $(wildcard $(DJDIR)/bin/cwsdstub.ex[eE])),)
|
||||
STUBIFY_EXE = mfxdjstubify -v -s $(DJDIR)/bin/cwsdstub.exe $(upx_exe)
|
||||
endif
|
||||
endif
|
||||
endif # djgpp2
|
||||
|
||||
|
||||
###
|
||||
### cygwin / mingw32
|
||||
###
|
||||
|
||||
ifeq ($(target),cygwin)
|
||||
e = .exe
|
||||
CC += -march=i386 -mcpu=i586
|
||||
CXXLD = g++
|
||||
##CFLAGS_M += -mno-schedule-prologue
|
||||
endif
|
||||
|
||||
ifeq ($(target),mingw32)
|
||||
e = .exe
|
||||
CC = gcc -mno-cygwin
|
||||
CC += -march=i386 -mcpu=i586
|
||||
CXXLD = g++ -mno-cygwin
|
||||
##CFLAGS_M += -mno-schedule-prologue
|
||||
endif
|
||||
|
||||
# mingw32 as included in cygwin
|
||||
ifeq ($(target),no-cygwin)
|
||||
e = .exe
|
||||
CC = gcc -mno-cygwin
|
||||
CC += -march=i386 -mcpu=i586
|
||||
CXXLD = g++ -mno-cygwin
|
||||
##CFLAGS_M += -mno-schedule-prologue
|
||||
endif
|
||||
|
||||
# mingw32 cross compiler
|
||||
ifeq ($(target),cross-mingw32)
|
||||
e = .exe
|
||||
CC = i586-mingw32msvc-gcc
|
||||
CC += -march=i386 -mcpu=i586
|
||||
CXXLD = i586-mingw32msvc-g++
|
||||
##CFLAGS_M += -mno-schedule-prologue
|
||||
endif
|
||||
|
||||
|
||||
###
|
||||
### Borland C++ 5.5.1
|
||||
###
|
||||
|
||||
ifeq ($(target),bcc)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = bcc32 -q
|
||||
CFLAGS = -w -w-aus -g1
|
||||
CXXFLAGS1 = $(CFLAGS)
|
||||
CXXFLAGS2 = $(CFLAGS) -x- -xd- -RT-
|
||||
CFLAGS_OUTPUT = -o$@
|
||||
LDFLAGS =
|
||||
LDLIBS = $(DOS_LDLIBS) zlib114.lib
|
||||
|
||||
ifneq ($(strip $(DOS_LIBDIRS)),)
|
||||
LIB := $(DOS_LIBDIRS);$(LIB)
|
||||
endif
|
||||
export LIB
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -Od -d
|
||||
else
|
||||
CFLAGS += -O2 -d
|
||||
endif
|
||||
|
||||
LINK_EXE = $(CXXLD) $(LDFLAGS) -e$@ $^ $(LDLIBS)
|
||||
|
||||
endif # bcc
|
||||
|
||||
|
||||
###
|
||||
### Digital Mars C++ 8.30
|
||||
###
|
||||
|
||||
ifeq ($(target),dmc)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = dmc -mn
|
||||
CFLAGS = -w- -wx
|
||||
CXXFLAGS1 = $(CFLAGS) -Aa -Ab -Ae -Ar
|
||||
CXXFLAGS2 = $(CFLAGS) -Aa -Ab
|
||||
CFLAGS_OUTPUT = -o$@
|
||||
LDFLAGS =
|
||||
LDLIBS = $(DOS_LDLIBS)
|
||||
|
||||
ifneq ($(strip $(DOS_LIBDIRS)),)
|
||||
LIB := $(DOS_LIBDIRS);$(LIB)
|
||||
endif
|
||||
export LIB
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -o- -g -s
|
||||
else
|
||||
CFLAGS += -o
|
||||
endif
|
||||
|
||||
LINK_EXE = $(CXXLD) $(LDFLAGS) -o$@ $^ $(LDLIBS)
|
||||
|
||||
endif # dmc
|
||||
|
||||
|
||||
###
|
||||
### Visual C++ 6 (aka Microsoft C/C++ Compiler 12.00)
|
||||
###
|
||||
|
||||
ifeq ($(target),vc6)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = cl -nologo
|
||||
CFLAGS = -W4 -WX
|
||||
CXXFLAGS1 = $(CFLAGS) -EHac -GR
|
||||
CXXFLAGS2 = $(CFLAGS)
|
||||
LDFLAGS =
|
||||
LINK_LDFLAGS = /link /map:$T.map
|
||||
|
||||
ifneq ($(strip $(DOS_LIBDIRS)),)
|
||||
LIB := $(DOS_LIBDIRS);$(LIB)
|
||||
endif
|
||||
export LIB
|
||||
|
||||
ifeq (1,2)
|
||||
# statically link libc.lib
|
||||
CC += -ML
|
||||
LDLIBS = $(u)_s.lib setargv.obj
|
||||
else
|
||||
# link against msvcrt.dll
|
||||
CC += -MD
|
||||
LDLIBS = $(DOS_LDLIBS) zlib114.lib setargv.obj
|
||||
endif
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -Od -ZI
|
||||
LINK_LDFLAGS += /debug
|
||||
else
|
||||
CFLAGS += -O2 -GF
|
||||
LINK_LDFLAGS += /release
|
||||
endif
|
||||
RESOURCES = upx.res
|
||||
|
||||
##LINK_LDFLAGS += /verbose
|
||||
LINK_EXE = $(CXXLD) $(LDFLAGS) -Fe$@ $^ $(LDLIBS) $(LINK_LDFLAGS)
|
||||
|
||||
endif # vc6
|
||||
|
||||
|
||||
###
|
||||
### Watcom C++ 11.0c
|
||||
###
|
||||
|
||||
ifeq ($(target),wcc)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = wcl386 -zq -bt=nt -mf -5r
|
||||
CFLAGS = -zc -w5 -we
|
||||
CXXFLAGS1 = $(CFLAGS) -xs -xr
|
||||
CXXFLAGS2 = $(CFLAGS)
|
||||
CFLAGS_OUTPUT = -fo=$@
|
||||
LDFLAGS = -k0x100000 -fm
|
||||
LDLIBS = $(DOS_LDLIBS)
|
||||
|
||||
INCLUDES:=$(strip $(subst /,\\,$(INCLUDES)))
|
||||
ifeq (1,2)
|
||||
WCL386:=$(INCLUDES)
|
||||
export WCL386
|
||||
INCLUDES:=
|
||||
endif
|
||||
|
||||
ifneq ($(strip $(DOS_LIBDIRS)),)
|
||||
LIB := $(DOS_LIBDIRS);$(LIB)
|
||||
endif
|
||||
export LIB
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS +=
|
||||
else
|
||||
# note: it seems that the optimizer is generating bad code with `-ox'
|
||||
CFLAGS += -olr
|
||||
endif
|
||||
|
||||
LINK_EXE = $(CXXLD) $(LDFLAGS) -fe=$@ $^ $(LDLIBS)
|
||||
|
||||
endif # wcc
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // malloc debuggers and memory checkers - somewhat obsolete, use valgrind
|
||||
# ************************************************************************/
|
||||
|
||||
ifeq (1,2)
|
||||
# compile in extra valgrind support
|
||||
CFLAGS += -DWITH_VALGRIND
|
||||
endif
|
||||
|
||||
ifeq (1,2)
|
||||
LDLIBS += -lefence
|
||||
endif
|
||||
|
||||
ifeq (1,2)
|
||||
CFLAGS += -DWITH_DMALLOC
|
||||
LDLIBS += -ldmalloc
|
||||
endif
|
||||
|
||||
ifeq (1,2)
|
||||
CFLAGS += -DWITH_GC -DLINUX_THREADS -D_REENTRANT
|
||||
LDLIBS += -lgc -lpthread
|
||||
# only needed when using -static:
|
||||
##LDFLAGS += -Wl,-defsym,_DYNAMIC=0
|
||||
endif
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // finish settings
|
||||
# ************************************************************************/
|
||||
|
||||
# C++ defaults
|
||||
ifeq ($(strip $(CXX)),)
|
||||
ifeq ($(strip $(CC)),gcc)
|
||||
CXX = g++
|
||||
else
|
||||
CXX = $(CC)
|
||||
endif
|
||||
endif
|
||||
ifeq ($(strip $(CXXLD)),)
|
||||
CXXLD = $(CXX)
|
||||
endif
|
||||
ifeq ($(strip $(CXXFLAGS_OUTPUT)),)
|
||||
CXXFLAGS_OUTPUT = $(CFLAGS_OUTPUT)
|
||||
endif
|
||||
|
||||
|
||||
# extra flags
|
||||
DEFS += $(EXTRA_DEFS)
|
||||
CFLAGS += $(EXTRA_CFLAGS)
|
||||
CFLAGS_W += $(EXTRA_CFLAGS_W)
|
||||
CFLAGS_M += $(EXTRA_CFLAGS_M)
|
||||
CFLAGS_O += $(EXTRA_CFLAGS_O)
|
||||
CXXFLAGS1 += $(EXTRA_CXXFLAGS1)
|
||||
CXXFLAGS2 += $(EXTRA_CXXFLAGS2)
|
||||
LDFLAGS += $(EXTRA_LDFLAGS)
|
||||
LDLIBS += $(EXTRA_LDLIBS)
|
||||
|
||||
|
||||
# To better deal with asynchronous exceptions we compile all source
|
||||
# files with exception handling and RTTI enabled - the size overhead
|
||||
# is negligible.
|
||||
CXXFLAGS2 = $(CXXFLAGS1)
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // main targets
|
||||
# ************************************************************************/
|
||||
|
||||
all: $(upx_exe)
|
||||
|
||||
.PHONY: all mostlyclean clean distclean maintainer-clean untabify tags
|
||||
|
||||
$(upx_exe): $(OBJECTS) $(LIBS) $(RESOURCES)
|
||||
$(LINK_EXE)
|
||||
$(STUBEDIT_EXE)
|
||||
$(STUBIFY_EXE)
|
||||
$(CHMOD_EXE)
|
||||
|
||||
|
||||
mostlyclean:
|
||||
-rm -f *.d *.err *.i *.log *.map *~ gdb-trans*
|
||||
|
||||
clean: mostlyclean
|
||||
-rm -f *.a *.lib *.o *.obj *.res *.tds tags TAGS ID
|
||||
-rm -f *.idb *.pdb
|
||||
-rm -f $(upx_exe) upx upx.exe upx.ttp upx_nrv upx_nrv.exe upx_nrv.ttp upx_ucl upx_ucl.exe upx_ucl.ttp
|
||||
-rm -rf .deps
|
||||
|
||||
distclean: clean
|
||||
|
||||
maintainer-clean: distclean
|
||||
|
||||
|
||||
untabify:
|
||||
mfxtu -d4 -t *.h *.cpp *.ch
|
||||
mfxtu -d8 -t stub/[ln]*.asm stub/*.ash stub/*.[cs]
|
||||
|
||||
tags TAGS:
|
||||
ctags *.h *.cpp *.ch
|
||||
|
||||
ID:
|
||||
mkid *.h *.cpp *.ch
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // rules
|
||||
# ************************************************************************/
|
||||
|
||||
%$o : %.c
|
||||
$(CC) $(DEFS) $(INCLUDES) $(CFLAGS) $(CFLAGS_OUTPUT) -c $<
|
||||
|
||||
%$o : %.cpp
|
||||
$(CXX) $(DEFS) $(INCLUDES) $(CXXFLAGS1) $(CXXFLAGS_OUTPUT) -c $<
|
||||
|
||||
ifneq ($(strip $(OBJECTS2)),)
|
||||
$(OBJECTS2): %$o : %.cpp
|
||||
$(CXX) $(DEFS) $(INCLUDES) $(CXXFLAGS2) $(CXXFLAGS_OUTPUT) -c $<
|
||||
endif
|
||||
|
||||
%.res : %.rc
|
||||
rc -l 0x409 -fo$@ $<
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // dependencies
|
||||
# ************************************************************************/
|
||||
|
||||
include $(srcdir)/Makefile.dep
|
||||
|
||||
# vi:nowrap
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
|
||||
# /***********************************************************************
|
||||
# // automated dependencies
|
||||
# ************************************************************************/
|
||||
|
||||
CFLAGS += -Wp,-MMD,.deps/$(*F).pp
|
||||
|
||||
ifeq ($(strip $(wildcard .deps)),)
|
||||
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
|
||||
else
|
||||
DEP_FILES := $(wildcard .deps/*.pp)
|
||||
ifneq ($(strip $(DEP_FILES)),)
|
||||
include $(DEP_FILES)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
UDIR := $($(U)DIR)
|
||||
|
||||
ifneq ($(strip $(wildcard $(UDIR)/include)),) # { include
|
||||
DEFS += -DWITH_$(U)
|
||||
INCLUDES += -I$(UDIR)/include
|
||||
|
||||
ifneq ($(strip $(wildcard $(UDIR)/build/$(target)/src/.libs)),)
|
||||
LIBDIRS += $(UDIR)/build/$(target)/src/.libs
|
||||
endif
|
||||
ifneq ($(strip $(wildcard $(UDIR)/src/.libs)),)
|
||||
LIBDIRS += $(UDIR)/src/.libs
|
||||
endif
|
||||
ifeq ($(DEBUG),1)
|
||||
ifneq ($(strip $(wildcard $(UDIR)/build/debug/src/.libs)),)
|
||||
LIBDIRS += $(UDIR)/build/debug/src/.libs
|
||||
endif
|
||||
endif
|
||||
ifneq ($(strip $(wildcard $(UDIR)/build/release/src/.libs)),)
|
||||
LIBDIRS += $(UDIR)/build/release/src/.libs
|
||||
endif
|
||||
ifneq ($(strip $(wildcard $(UDIR)/build/src/.libs)),)
|
||||
LIBDIRS += $(UDIR)/build/src/.libs
|
||||
endif
|
||||
ifneq ($(strip $(wildcard $(UDIR))),)
|
||||
LIBDIRS += $(UDIR)
|
||||
DOS_LIBDIRS := $(DOS_LIBDIRS);$(UDIR)
|
||||
endif
|
||||
|
||||
LDLIBS += -l$(u)
|
||||
DOS_LDLIBS += $(u).lib
|
||||
|
||||
|
||||
DEFS := $(DEFS)
|
||||
INCLUDES := $(INCLUDES)
|
||||
LIBDIRS := $(LIBDIRS)
|
||||
LDLIBS := $(LDLIBS)
|
||||
DOS_LDLIBS := $(DOS_LDLIBS)
|
||||
|
||||
endif # } include
|
||||
+484
-212
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -34,132 +34,147 @@
|
||||
// core
|
||||
**************************************************************************/
|
||||
|
||||
inline unsigned get_be16(const void *bb)
|
||||
inline unsigned get_be16(const void *p)
|
||||
{
|
||||
const upx_bytep b = (const upx_bytep) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[1] << 0;
|
||||
v |= (unsigned) b[0] << 8;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline void set_be16(void *bb, unsigned v)
|
||||
{
|
||||
upx_bytep b = (upx_bytep) bb;
|
||||
b[1] = (unsigned char) (v >> 0);
|
||||
b[0] = (unsigned char) (v >> 8);
|
||||
}
|
||||
|
||||
|
||||
inline unsigned get_be24(const void *bb)
|
||||
{
|
||||
const upx_bytep b = (const upx_bytep) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[2] << 0;
|
||||
v |= (unsigned) b[1] << 8;
|
||||
v |= (unsigned) b[0] << 16;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline void set_be24(void *bb, unsigned v)
|
||||
{
|
||||
upx_bytep b = (upx_bytep) bb;
|
||||
b[2] = (unsigned char) (v >> 0);
|
||||
b[1] = (unsigned char) (v >> 8);
|
||||
b[0] = (unsigned char) (v >> 16);
|
||||
}
|
||||
|
||||
|
||||
inline unsigned get_be32(const void *bb)
|
||||
{
|
||||
const upx_bytep b = (const upx_bytep) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[3] << 0;
|
||||
v |= (unsigned) b[2] << 8;
|
||||
v |= (unsigned) b[1] << 16;
|
||||
v |= (unsigned) b[0] << 24;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline void set_be32(void *bb, unsigned v)
|
||||
{
|
||||
upx_bytep b = (upx_bytep) bb;
|
||||
b[3] = (unsigned char) (v >> 0);
|
||||
b[2] = (unsigned char) (v >> 8);
|
||||
b[1] = (unsigned char) (v >> 16);
|
||||
b[0] = (unsigned char) (v >> 24);
|
||||
}
|
||||
|
||||
|
||||
inline unsigned get_le16(const void *bb)
|
||||
{
|
||||
#if defined(__i386__)
|
||||
return * (const unsigned short *) bb;
|
||||
#if defined(ACC_UA_GET_BE16)
|
||||
return ACC_UA_GET_BE16(p);
|
||||
#else
|
||||
const upx_bytep b = (const upx_bytep) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[0] << 0;
|
||||
v |= (unsigned) b[1] << 8;
|
||||
return v;
|
||||
return acc_ua_get_be16(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le16(void *bb, unsigned v)
|
||||
inline void set_be16(void *p, unsigned v)
|
||||
{
|
||||
#if defined(__i386__)
|
||||
(* (unsigned short *) bb) = (unsigned short) (v & 0xffff);
|
||||
#if defined(ACC_UA_SET_BE16)
|
||||
ACC_UA_SET_BE16(p, v);
|
||||
#else
|
||||
upx_bytep b = (upx_bytep) bb;
|
||||
b[0] = (unsigned char) (v >> 0);
|
||||
b[1] = (unsigned char) (v >> 8);
|
||||
acc_ua_set_be16(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline unsigned get_le24(const void *bb)
|
||||
inline unsigned get_be24(const void *p)
|
||||
{
|
||||
const upx_bytep b = (const upx_bytep) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[0] << 0;
|
||||
v |= (unsigned) b[1] << 8;
|
||||
v |= (unsigned) b[2] << 16;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline void set_le24(void *bb, unsigned v)
|
||||
{
|
||||
upx_bytep b = (upx_bytep) bb;
|
||||
b[0] = (unsigned char) (v >> 0);
|
||||
b[1] = (unsigned char) (v >> 8);
|
||||
b[2] = (unsigned char) (v >> 16);
|
||||
}
|
||||
|
||||
|
||||
inline unsigned get_le32(const void *bb)
|
||||
{
|
||||
#if defined(__i386__)
|
||||
return * (const unsigned *) bb;
|
||||
#if defined(ACC_UA_GET_BE24)
|
||||
return ACC_UA_GET_BE24(p);
|
||||
#else
|
||||
const upx_bytep b = (const upx_bytep) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[0] << 0;
|
||||
v |= (unsigned) b[1] << 8;
|
||||
v |= (unsigned) b[2] << 16;
|
||||
v |= (unsigned) b[3] << 24;
|
||||
return v;
|
||||
return acc_ua_get_be24(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le32(void *bb, unsigned v)
|
||||
inline void set_be24(void *p, unsigned v)
|
||||
{
|
||||
#if defined(__i386__)
|
||||
(* (unsigned *) bb) = v;
|
||||
#if defined(ACC_UA_SET_BE24)
|
||||
ACC_UA_SET_BE24(p, v);
|
||||
#else
|
||||
upx_bytep b = (upx_bytep) bb;
|
||||
b[0] = (unsigned char) (v >> 0);
|
||||
b[1] = (unsigned char) (v >> 8);
|
||||
b[2] = (unsigned char) (v >> 16);
|
||||
b[3] = (unsigned char) (v >> 24);
|
||||
acc_ua_set_be24(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned get_be32(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_BE32)
|
||||
return ACC_UA_GET_BE32(p);
|
||||
#else
|
||||
return acc_ua_get_be32(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_be32(void *p, unsigned v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_BE32)
|
||||
ACC_UA_SET_BE32(p, v);
|
||||
#else
|
||||
acc_ua_set_be32(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline acc_uint64l_t get_be64(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_BE64)
|
||||
return ACC_UA_GET_BE64(p);
|
||||
#else
|
||||
return acc_ua_get_be64(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_be64(void *p, acc_uint64l_t v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_BE64)
|
||||
ACC_UA_SET_BE64(p, v);
|
||||
#else
|
||||
acc_ua_set_be64(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned get_le16(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_LE16)
|
||||
return ACC_UA_GET_LE16(p);
|
||||
#else
|
||||
return acc_ua_get_le16(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le16(void *p, unsigned v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_LE16)
|
||||
ACC_UA_SET_LE16(p, v);
|
||||
#else
|
||||
acc_ua_set_le16(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned get_le24(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_LE24)
|
||||
return ACC_UA_GET_LE24(p);
|
||||
#else
|
||||
return acc_ua_get_le24(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le24(void *p, unsigned v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_LE24)
|
||||
ACC_UA_SET_LE24(p, v);
|
||||
#else
|
||||
acc_ua_set_le24(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned get_le32(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_LE32)
|
||||
return ACC_UA_GET_LE32(p);
|
||||
#else
|
||||
return acc_ua_get_le32(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le32(void *p, unsigned v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_LE32)
|
||||
ACC_UA_SET_LE32(p, v);
|
||||
#else
|
||||
acc_ua_set_le32(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline acc_uint64l_t get_le64(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_LE64)
|
||||
return ACC_UA_GET_LE64(p);
|
||||
#else
|
||||
return acc_ua_get_le64(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le64(void *p, acc_uint64l_t v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_LE64)
|
||||
ACC_UA_SET_LE64(p, v);
|
||||
#else
|
||||
acc_ua_set_le64(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -168,122 +183,270 @@ inline void set_le32(void *bb, unsigned v)
|
||||
// get signed values, i.e. sign-extend
|
||||
**************************************************************************/
|
||||
|
||||
inline int sign_extend(int v, int bits)
|
||||
inline int sign_extend(unsigned v, unsigned bits)
|
||||
{
|
||||
const int sign_bit = 1 << (bits - 1);
|
||||
v |= -(v & sign_bit);
|
||||
return v;
|
||||
const unsigned sign_bit = 1u << (bits - 1);
|
||||
v &= sign_bit | (sign_bit - 1);
|
||||
//v = (v ^ sign_bit) - sign_bit;
|
||||
v |= 0 - (v & sign_bit);
|
||||
return (int) v;
|
||||
}
|
||||
|
||||
inline int get_be16_signed(const void *bb)
|
||||
inline acc_int64l_t sign_extend(acc_uint64l_t v, unsigned bits)
|
||||
{
|
||||
int v = get_be16(bb);
|
||||
const acc_uint64l_t sign_bit = ACC_UINT64_C(1) << (bits - 1);
|
||||
v &= sign_bit | (sign_bit - 1);
|
||||
//v = (v ^ sign_bit) - sign_bit;
|
||||
v |= 0 - (v & sign_bit);
|
||||
return (acc_int64l_t) v;
|
||||
}
|
||||
|
||||
inline int get_be16_signed(const void *p)
|
||||
{
|
||||
unsigned v = get_be16(p);
|
||||
return sign_extend(v, 16);
|
||||
}
|
||||
|
||||
inline int get_be24_signed(const void *bb)
|
||||
inline int get_be24_signed(const void *p)
|
||||
{
|
||||
int v = get_be24(bb);
|
||||
unsigned v = get_be24(p);
|
||||
return sign_extend(v, 24);
|
||||
}
|
||||
|
||||
inline int get_be32_signed(const void *bb)
|
||||
inline int get_be32_signed(const void *p)
|
||||
{
|
||||
int v = get_be32(bb);
|
||||
unsigned v = get_be32(p);
|
||||
return sign_extend(v, 32);
|
||||
}
|
||||
|
||||
inline int get_le16_signed(const void *bb)
|
||||
inline acc_int64l_t get_be64_signed(const void *p)
|
||||
{
|
||||
int v = get_le16(bb);
|
||||
acc_uint64l_t v = get_be64(p);
|
||||
return sign_extend(v, 64);
|
||||
}
|
||||
|
||||
inline int get_le16_signed(const void *p)
|
||||
{
|
||||
unsigned v = get_le16(p);
|
||||
return sign_extend(v, 16);
|
||||
}
|
||||
|
||||
inline int get_le24_signed(const void *bb)
|
||||
inline int get_le24_signed(const void *p)
|
||||
{
|
||||
int v = get_le24(bb);
|
||||
unsigned v = get_le24(p);
|
||||
return sign_extend(v, 24);
|
||||
}
|
||||
|
||||
inline int get_le32_signed(const void *bb)
|
||||
inline int get_le32_signed(const void *p)
|
||||
{
|
||||
int v = get_le32(bb);
|
||||
unsigned v = get_le32(p);
|
||||
return sign_extend(v, 32);
|
||||
}
|
||||
|
||||
inline acc_int64l_t get_le64_signed(const void *p)
|
||||
{
|
||||
acc_uint64l_t v = get_le64(p);
|
||||
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
|
||||
//
|
||||
// Important: these classes must be PODs (Plain Old Data), i.e. no
|
||||
// constructor, no destructor, no virtual functions and no default
|
||||
// assignment operator, and all fields must be public(!).
|
||||
//
|
||||
// [Actually we _can_ use a safe non-POD subset, but for this we need
|
||||
// to have gcc bug 17519 fixed - see http://gcc.gnu.org/PR17519 ]
|
||||
**************************************************************************/
|
||||
|
||||
class BE16
|
||||
struct BE16
|
||||
{
|
||||
unsigned char d[2];
|
||||
|
||||
public:
|
||||
BE16& operator = (const BE16 &v) { memcpy(d, v.d, sizeof(d)); return *this; }
|
||||
//inline BE16() { }
|
||||
//BE16(unsigned v) { set_be16(d, v); }
|
||||
|
||||
BE16& operator = (unsigned v) { set_be16(d, v); return *this; }
|
||||
BE16& operator += (unsigned v) { set_be16(d, get_be16(d) + v); return *this; }
|
||||
BE16& operator -= (unsigned v) { set_be16(d, get_be16(d) - v); return *this; }
|
||||
BE16& operator &= (unsigned v) { set_be16(d, get_be16(d) & v); return *this; }
|
||||
BE16& operator |= (unsigned v) { set_be16(d, get_be16(d) | v); return *this; }
|
||||
BE16& operator = (unsigned v) { set_be16(d, v); return *this; }
|
||||
BE16& operator += (unsigned v) { set_be16(d, get_be16(d) + v); return *this; }
|
||||
BE16& operator -= (unsigned v) { set_be16(d, get_be16(d) - v); return *this; }
|
||||
BE16& operator *= (unsigned v) { set_be16(d, get_be16(d) * v); return *this; }
|
||||
BE16& operator /= (unsigned v) { set_be16(d, get_be16(d) / v); return *this; }
|
||||
BE16& operator &= (unsigned v) { set_be16(d, get_be16(d) & v); return *this; }
|
||||
BE16& operator |= (unsigned v) { set_be16(d, get_be16(d) | v); return *this; }
|
||||
BE16& operator ^= (unsigned v) { set_be16(d, get_be16(d) ^ v); return *this; }
|
||||
BE16& operator <<= (unsigned v) { set_be16(d, get_be16(d) << v); return *this; }
|
||||
BE16& operator >>= (unsigned v) { set_be16(d, get_be16(d) >> v); return *this; }
|
||||
|
||||
operator const unsigned () const { return get_be16(d); }
|
||||
operator unsigned () const { return get_be16(d); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
class BE32
|
||||
struct BE32
|
||||
{
|
||||
unsigned char d[4];
|
||||
|
||||
public:
|
||||
BE32& operator = (const BE32 &v) { memcpy(d, v.d, sizeof(d)); return *this; }
|
||||
//inline BE32() { }
|
||||
//BE32(unsigned v) { set_be32(d, v); }
|
||||
|
||||
BE32& operator = (unsigned v) { set_be32(d, v); return *this; }
|
||||
BE32& operator += (unsigned v) { set_be32(d, get_be32(d) + v); return *this; }
|
||||
BE32& operator -= (unsigned v) { set_be32(d, get_be32(d) - v); return *this; }
|
||||
BE32& operator &= (unsigned v) { set_be32(d, get_be32(d) & v); return *this; }
|
||||
BE32& operator |= (unsigned v) { set_be32(d, get_be32(d) | v); return *this; }
|
||||
BE32& operator = (unsigned v) { set_be32(d, v); return *this; }
|
||||
BE32& operator += (unsigned v) { set_be32(d, get_be32(d) + v); return *this; }
|
||||
BE32& operator -= (unsigned v) { set_be32(d, get_be32(d) - v); return *this; }
|
||||
BE32& operator *= (unsigned v) { set_be32(d, get_be32(d) * v); return *this; }
|
||||
BE32& operator /= (unsigned v) { set_be32(d, get_be32(d) / v); return *this; }
|
||||
BE32& operator &= (unsigned v) { set_be32(d, get_be32(d) & v); return *this; }
|
||||
BE32& operator |= (unsigned v) { set_be32(d, get_be32(d) | v); return *this; }
|
||||
BE32& operator ^= (unsigned v) { set_be32(d, get_be32(d) ^ v); return *this; }
|
||||
BE32& operator <<= (unsigned v) { set_be32(d, get_be32(d) << v); return *this; }
|
||||
BE32& operator >>= (unsigned v) { set_be32(d, get_be32(d) >> v); return *this; }
|
||||
|
||||
operator const unsigned () const { return get_be32(d); }
|
||||
operator unsigned () const { return get_be32(d); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
class LE16
|
||||
struct BE64
|
||||
{
|
||||
unsigned char d[8];
|
||||
|
||||
//inline BE64() { }
|
||||
//BE64(acc_uint64l_t v) { set_be64(d, v); }
|
||||
|
||||
BE64& operator = (acc_uint64l_t v) { set_be64(d, v); return *this; }
|
||||
BE64& operator += (acc_uint64l_t v) { set_be64(d, get_be64(d) + v); return *this; }
|
||||
BE64& operator -= (acc_uint64l_t v) { set_be64(d, get_be64(d) - v); return *this; }
|
||||
BE64& operator *= (acc_uint64l_t v) { set_be64(d, get_be64(d) * v); return *this; }
|
||||
BE64& operator /= (acc_uint64l_t v) { set_be64(d, get_be64(d) / v); return *this; }
|
||||
BE64& operator &= (acc_uint64l_t v) { set_be64(d, get_be64(d) & v); return *this; }
|
||||
BE64& operator |= (acc_uint64l_t v) { set_be64(d, get_be64(d) | v); return *this; }
|
||||
BE64& operator ^= (acc_uint64l_t v) { set_be64(d, get_be64(d) ^ v); return *this; }
|
||||
BE64& operator <<= (unsigned v) { set_be64(d, get_be64(d) << v); return *this; }
|
||||
BE64& operator >>= (unsigned v) { set_be64(d, get_be64(d) >> v); return *this; }
|
||||
|
||||
operator acc_uint64l_t () const { return get_be64(d); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
struct LE16
|
||||
{
|
||||
unsigned char d[2];
|
||||
|
||||
public:
|
||||
LE16& operator = (const LE16 &v) { memcpy(d, v.d, sizeof(d)); return *this; }
|
||||
//inline LE16() { }
|
||||
//LE16(unsigned v) { set_le16(d, v); }
|
||||
|
||||
LE16& operator = (unsigned v) { set_le16(d, v); return *this; }
|
||||
LE16& operator += (unsigned v) { set_le16(d, get_le16(d) + v); return *this; }
|
||||
LE16& operator -= (unsigned v) { set_le16(d, get_le16(d) - v); return *this; }
|
||||
LE16& operator &= (unsigned v) { set_le16(d, get_le16(d) & v); return *this; }
|
||||
LE16& operator |= (unsigned v) { set_le16(d, get_le16(d) | v); return *this; }
|
||||
LE16& operator = (unsigned v) { set_le16(d, v); return *this; }
|
||||
LE16& operator += (unsigned v) { set_le16(d, get_le16(d) + v); return *this; }
|
||||
LE16& operator -= (unsigned v) { set_le16(d, get_le16(d) - v); return *this; }
|
||||
LE16& operator *= (unsigned v) { set_le16(d, get_le16(d) * v); return *this; }
|
||||
LE16& operator /= (unsigned v) { set_le16(d, get_le16(d) / v); return *this; }
|
||||
LE16& operator &= (unsigned v) { set_le16(d, get_le16(d) & v); return *this; }
|
||||
LE16& operator |= (unsigned v) { set_le16(d, get_le16(d) | v); return *this; }
|
||||
LE16& operator ^= (unsigned v) { set_le16(d, get_le16(d) ^ v); return *this; }
|
||||
LE16& operator <<= (unsigned v) { set_le16(d, get_le16(d) << v); return *this; }
|
||||
LE16& operator >>= (unsigned v) { set_le16(d, get_le16(d) >> v); return *this; }
|
||||
|
||||
operator const unsigned () const { return get_le16(d); }
|
||||
operator unsigned () const { return get_le16(d); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
class LE32
|
||||
struct LE32
|
||||
{
|
||||
unsigned char d[4];
|
||||
|
||||
public:
|
||||
LE32& operator = (const LE32 &v) { memcpy(d, v.d, sizeof(d)); return *this; }
|
||||
//inline LE32() { }
|
||||
//LE32(unsigned v) { set_le32(d, v); }
|
||||
|
||||
LE32& operator = (unsigned v) { set_le32(d, v); return *this; }
|
||||
LE32& operator += (unsigned v) { set_le32(d, get_le32(d) + v); return *this; }
|
||||
LE32& operator -= (unsigned v) { set_le32(d, get_le32(d) - v); return *this; }
|
||||
LE32& operator &= (unsigned v) { set_le32(d, get_le32(d) & v); return *this; }
|
||||
LE32& operator |= (unsigned v) { set_le32(d, get_le32(d) | v); return *this; }
|
||||
LE32& operator = (unsigned v) { set_le32(d, v); return *this; }
|
||||
LE32& operator += (unsigned v) { set_le32(d, get_le32(d) + v); return *this; }
|
||||
LE32& operator -= (unsigned v) { set_le32(d, get_le32(d) - v); return *this; }
|
||||
LE32& operator *= (unsigned v) { set_le32(d, get_le32(d) * v); return *this; }
|
||||
LE32& operator /= (unsigned v) { set_le32(d, get_le32(d) / v); return *this; }
|
||||
LE32& operator &= (unsigned v) { set_le32(d, get_le32(d) & v); return *this; }
|
||||
LE32& operator |= (unsigned v) { set_le32(d, get_le32(d) | v); return *this; }
|
||||
LE32& operator ^= (unsigned v) { set_le32(d, get_le32(d) ^ v); return *this; }
|
||||
LE32& operator <<= (unsigned v) { set_le32(d, get_le32(d) << v); return *this; }
|
||||
LE32& operator >>= (unsigned v) { set_le32(d, get_le32(d) >> v); return *this; }
|
||||
|
||||
operator const unsigned () const { return get_le32(d); }
|
||||
operator unsigned () const { return get_le32(d); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
struct LE64
|
||||
{
|
||||
unsigned char d[8];
|
||||
|
||||
//inline LE64() { }
|
||||
//LE64(acc_uint64l_t v) { set_le64(d, v); }
|
||||
|
||||
LE64& operator = (acc_uint64l_t v) { set_le64(d, v); return *this; }
|
||||
LE64& operator += (acc_uint64l_t v) { set_le64(d, get_le64(d) + v); return *this; }
|
||||
LE64& operator -= (acc_uint64l_t v) { set_le64(d, get_le64(d) - v); return *this; }
|
||||
LE64& operator *= (acc_uint64l_t v) { set_le64(d, get_le64(d) * v); return *this; }
|
||||
LE64& operator /= (acc_uint64l_t v) { set_le64(d, get_le64(d) / v); return *this; }
|
||||
LE64& operator &= (acc_uint64l_t v) { set_le64(d, get_le64(d) & v); return *this; }
|
||||
LE64& operator |= (acc_uint64l_t v) { set_le64(d, get_le64(d) | v); return *this; }
|
||||
LE64& operator ^= (acc_uint64l_t v) { set_le64(d, get_le64(d) ^ v); return *this; }
|
||||
LE64& operator <<= (unsigned v) { set_le64(d, get_le64(d) << v); return *this; }
|
||||
LE64& operator >>= (unsigned v) { set_le64(d, get_le64(d) >> v); return *this; }
|
||||
|
||||
operator acc_uint64l_t () const { return get_le64(d); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
@@ -292,46 +455,78 @@ __attribute_packed;
|
||||
// global operators
|
||||
**************************************************************************/
|
||||
|
||||
inline bool operator < (const BE16& v1, const BE16& v2)
|
||||
{
|
||||
return (const unsigned)v1 < (const unsigned)v2;
|
||||
}
|
||||
|
||||
inline bool operator < (const BE32& v1, const BE32& v2)
|
||||
{
|
||||
return (const unsigned)v1 < (const unsigned)v2;
|
||||
}
|
||||
|
||||
inline bool operator < (const LE16& v1, const LE16& v2)
|
||||
{
|
||||
return (const unsigned)v1 < (const unsigned)v2;
|
||||
}
|
||||
|
||||
inline bool operator < (const LE32& v1, const LE32& v2)
|
||||
{
|
||||
return (const unsigned)v1 < (const unsigned)v2;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T* operator + (T* ptr, const BE16& v) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator + (const BE16& v, T* ptr) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const BE16& v) { return ptr - (unsigned) v; }
|
||||
|
||||
template <class T>
|
||||
inline T* operator + (T* ptr, const BE16& v) { return ptr + (const unsigned) v; }
|
||||
inline T* operator + (T* ptr, const BE32& v) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const BE16& v) { return ptr - (const unsigned) v; }
|
||||
inline T* operator + (const BE32& v, T* ptr) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const BE32& v) { return ptr - (unsigned) v; }
|
||||
|
||||
// these are not implemented on purpose and will cause link-time errors
|
||||
template <class T> T* operator + (T* ptr, const BE64& v);
|
||||
template <class T> T* operator + (const BE64& v, T* ptr);
|
||||
template <class T> T* operator - (T* ptr, const BE64& v);
|
||||
|
||||
template <class T>
|
||||
inline T* operator + (T* ptr, const BE32& v) { return ptr + (const unsigned) v; }
|
||||
inline T* operator + (T* ptr, const LE16& v) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const BE32& v) { return ptr - (const unsigned) v; }
|
||||
inline T* operator + (const LE16& v, T* ptr) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const LE16& v) { return ptr - (unsigned) v; }
|
||||
|
||||
template <class T>
|
||||
inline T* operator + (T* ptr, const LE16& v) { return ptr + (const unsigned) v; }
|
||||
inline T* operator + (T* ptr, const LE32& v) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const LE16& v) { return ptr - (const unsigned) v; }
|
||||
inline T* operator + (const LE32& v, T* ptr) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const LE32& v) { return ptr - (unsigned) v; }
|
||||
|
||||
template <class T>
|
||||
inline T* operator + (T* ptr, const LE32& v) { return ptr + (const unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const LE32& v) { return ptr - (const unsigned) v; }
|
||||
// these are not implemented on purpose and will cause link-time errors
|
||||
template <class T> T* operator + (T* ptr, const LE64& v);
|
||||
template <class T> T* operator + (const LE64& v, T* ptr);
|
||||
template <class T> T* operator - (T* ptr, const LE64& v);
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// global overloads
|
||||
**************************************************************************/
|
||||
|
||||
#if 1 && !defined(ALIGN_DOWN)
|
||||
inline unsigned ALIGN_DOWN(unsigned a, const LE32& b) { return ALIGN_DOWN(a, (unsigned) b); }
|
||||
inline unsigned ALIGN_DOWN(const LE32& a, unsigned b) { return ALIGN_DOWN((unsigned) a, b); }
|
||||
inline unsigned ALIGN_UP (unsigned a, const LE32& b) { return ALIGN_UP (a, (unsigned) b); }
|
||||
inline unsigned ALIGN_UP (const LE32& a, unsigned b) { return ALIGN_UP ((unsigned) a, b); }
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(UPX_MAX)
|
||||
inline unsigned UPX_MAX(unsigned a, const BE16& b) { return UPX_MAX(a, (unsigned) b); }
|
||||
inline unsigned UPX_MAX(const BE16& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
|
||||
inline unsigned UPX_MIN(unsigned a, const BE16& b) { return UPX_MIN(a, (unsigned) b); }
|
||||
inline unsigned UPX_MIN(const BE16& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
|
||||
|
||||
inline unsigned UPX_MAX(unsigned a, const BE32& b) { return UPX_MAX(a, (unsigned) b); }
|
||||
inline unsigned UPX_MAX(const BE32& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
|
||||
inline unsigned UPX_MIN(unsigned a, const BE32& b) { return UPX_MIN(a, (unsigned) b); }
|
||||
inline unsigned UPX_MIN(const BE32& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
|
||||
|
||||
inline unsigned UPX_MAX(unsigned a, const LE16& b) { return UPX_MAX(a, (unsigned) b); }
|
||||
inline unsigned UPX_MAX(const LE16& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
|
||||
inline unsigned UPX_MIN(unsigned a, const LE16& b) { return UPX_MIN(a, (unsigned) b); }
|
||||
inline unsigned UPX_MIN(const LE16& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
|
||||
|
||||
inline unsigned UPX_MAX(unsigned a, const LE32& b) { return UPX_MAX(a, (unsigned) b); }
|
||||
inline unsigned UPX_MAX(const LE32& a, unsigned b) { return UPX_MAX((unsigned) a, b); }
|
||||
inline unsigned UPX_MIN(unsigned a, const LE32& b) { return UPX_MIN(a, (unsigned) b); }
|
||||
inline unsigned UPX_MIN(const LE32& a, unsigned b) { return UPX_MIN((unsigned) a, b); }
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -339,29 +534,106 @@ inline T* operator - (T* ptr, const LE32& v) { return ptr - (const unsigned) v;
|
||||
**************************************************************************/
|
||||
|
||||
// for use with qsort()
|
||||
int be16_compare(const void *e1, const void *e2);
|
||||
int be24_compare(const void *e1, const void *e2);
|
||||
int be32_compare(const void *e1, const void *e2);
|
||||
int le16_compare(const void *e1, const void *e2);
|
||||
int le24_compare(const void *e1, const void *e2);
|
||||
int le32_compare(const void *e1, const void *e2);
|
||||
int be16_compare_signed(const void *e1, const void *e2);
|
||||
int be24_compare_signed(const void *e1, const void *e2);
|
||||
int be32_compare_signed(const void *e1, const void *e2);
|
||||
int le16_compare_signed(const void *e1, const void *e2);
|
||||
int le24_compare_signed(const void *e1, const void *e2);
|
||||
int le32_compare_signed(const void *e1, const void *e2);
|
||||
extern "C" {
|
||||
int __acc_cdecl_qsort be16_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be24_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be32_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be64_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le16_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le24_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le32_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le64_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be16_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be24_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be32_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be64_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le16_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le24_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
||||
} // extern "C"
|
||||
|
||||
|
||||
// just for testing...
|
||||
#if 0 && defined(__i386__) && defined(__GNUC_VERSION_HEX__)
|
||||
# if (__GNUC_VERSION_HEX__ >= 0x030100)
|
||||
typedef unsigned short LE16_unaligned __attribute__((__packed__,__aligned__(1)));
|
||||
typedef unsigned int LE32_unaligned __attribute__((__packed__,__aligned__(1)));
|
||||
# define LE16 LE16_unaligned
|
||||
# define LE32 LE32_unaligned
|
||||
# endif
|
||||
#if !defined(ACC_CFG_NO_UNALIGNED)
|
||||
#if 0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386) && (ACC_CC_GNUC >= 0x030200)
|
||||
typedef acc_uint16e_t LE16_unaligned __attribute__((__aligned__(1)));
|
||||
typedef acc_uint32e_t LE32_unaligned __attribute__((__aligned__(1)));
|
||||
# ifndef LE16
|
||||
# define LE16 LE16_unaligned
|
||||
# endif
|
||||
# ifndef LE32
|
||||
# define LE32 LE32_unaligned
|
||||
# endif
|
||||
#endif
|
||||
#if 0 && (ACC_ARCH_I386) && (ACC_CC_INTELC)
|
||||
typedef __declspec(align(1)) acc_uint16e_t LE16_unaligned;
|
||||
typedef __declspec(align(1)) acc_uint32e_t LE32_unaligned;
|
||||
# ifndef LE16
|
||||
# define LE16 LE16_unaligned
|
||||
# endif
|
||||
# ifndef LE32
|
||||
# define LE32 LE32_unaligned
|
||||
# endif
|
||||
#endif
|
||||
#if 0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386) && (ACC_CC_MSC) && (_MSC_VER >= 1200)
|
||||
typedef __declspec(align(1)) acc_uint16e_t LE16_unaligned;
|
||||
typedef __declspec(align(1)) acc_uint32e_t LE32_unaligned;
|
||||
# ifndef LE16
|
||||
# define LE16 LE16_unaligned
|
||||
# endif
|
||||
# ifndef LE32
|
||||
# define LE32 LE32_unaligned
|
||||
# endif
|
||||
# pragma warning(disable: 4244) // Wx: conversion, possible loss of data
|
||||
#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;
|
||||
extern const BEPolicy be_policy;
|
||||
extern const LEPolicy le_policy;
|
||||
}
|
||||
namespace N_BELE_RTP {
|
||||
class AbstractPolicy;
|
||||
class BEPolicy; class LEPolicy;
|
||||
extern const BEPolicy be_policy;
|
||||
extern const LEPolicy le_policy;
|
||||
}
|
||||
|
||||
namespace N_BELE_CTP {
|
||||
#define BELE_CTP 1
|
||||
#include "bele_policy.h"
|
||||
#undef BELE_CTP
|
||||
}
|
||||
|
||||
namespace N_BELE_RTP {
|
||||
#define BELE_RTP 1
|
||||
#include "bele_policy.h"
|
||||
#undef BELE_RTP
|
||||
}
|
||||
|
||||
namespace N_BELE_CTP {
|
||||
|
||||
template <class T>
|
||||
inline const N_BELE_RTP::AbstractPolicy* getRTP();
|
||||
template <>
|
||||
inline const N_BELE_RTP::AbstractPolicy* getRTP<BEPolicy>()
|
||||
{ return &N_BELE_RTP::be_policy; }
|
||||
template <>
|
||||
inline const N_BELE_RTP::AbstractPolicy* getRTP<LEPolicy>()
|
||||
{ return &N_BELE_RTP::le_policy; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
/* bele_policy.h -- access memory in BigEndian and LittleEndian byte order
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 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
|
||||
{
|
||||
inline 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
|
||||
{
|
||||
inline BEPolicy() { }
|
||||
#if defined(BELE_CTP)
|
||||
typedef N_BELE_RTP::BEPolicy RTP_Policy;
|
||||
#elif defined(BELE_RTP)
|
||||
typedef N_BELE_CTP::BEPolicy CTP_Policy;
|
||||
#endif
|
||||
V bool isBE() C { return true; }
|
||||
V bool isLE() C { return false; }
|
||||
|
||||
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_ALIGNED1(U16)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U32)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||
}
|
||||
|
||||
// disable dynamic allocation
|
||||
DISABLE_NEW_DELETE
|
||||
};
|
||||
|
||||
|
||||
struct LEPolicy
|
||||
#if defined(BELE_RTP)
|
||||
: public AbstractPolicy
|
||||
#endif
|
||||
{
|
||||
inline LEPolicy() { }
|
||||
#if defined(BELE_CTP)
|
||||
typedef N_BELE_RTP::LEPolicy RTP_Policy;
|
||||
#elif defined(BELE_RTP)
|
||||
typedef N_BELE_CTP::LEPolicy CTP_Policy;
|
||||
#endif
|
||||
V bool isBE() C { return false; }
|
||||
V bool isLE() C { return true; }
|
||||
|
||||
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_ALIGNED1(U16)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U32)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(U64)
|
||||
}
|
||||
|
||||
// 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
|
||||
*/
|
||||
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/* bptr.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 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_BPTR_H
|
||||
#define __UPX_BPTR_H
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// BoundedPtr
|
||||
**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
class BoundedPtr
|
||||
{
|
||||
// typedef BoundedPtr<T> Self;
|
||||
public:
|
||||
typedef T* StoredType;
|
||||
typedef T* PointerType;
|
||||
typedef T& ReferenceType;
|
||||
|
||||
~BoundedPtr() { }
|
||||
|
||||
explicit BoundedPtr(void* base, unsigned size, T* ptr=0)
|
||||
: ptr_(ptr), base_(base), size_(size) { check(); }
|
||||
BoundedPtr& operator= (const BoundedPtr& other) {
|
||||
assert(base_ == other.base_); assert(size_ == other.size_);
|
||||
ptr_ = other.ptr_; check(); return *this;
|
||||
}
|
||||
BoundedPtr& operator= (T* other) {
|
||||
ptr_ = other; check(); return *this;
|
||||
}
|
||||
|
||||
operator T* () { check(); return ptr_; }
|
||||
operator const T* () const { check(); return ptr_; }
|
||||
|
||||
BoundedPtr& operator += (size_t n) {
|
||||
checkStrict(); ptr_ += n; checkStrict(); return *this;
|
||||
}
|
||||
BoundedPtr& operator -= (size_t n) {
|
||||
checkStrict(); ptr_ -= n; checkStrict(); return *this;
|
||||
}
|
||||
BoundedPtr& operator ++ (void) {
|
||||
checkStrict(); ptr_ += 1; checkStrict(); return *this;
|
||||
}
|
||||
// T* operator ++ (int) {
|
||||
// T* p = ptr_; checkStrict(); ptr_ += 1; checkStrict(); return p;
|
||||
// }
|
||||
// BoundedPtr& operator -- (void) {
|
||||
// checkStrict(); ptr_ -= 1; checkStrict(); return *this;
|
||||
// }
|
||||
|
||||
|
||||
private:
|
||||
void checkNULL() const {
|
||||
if (!ptr_)
|
||||
throwCantUnpack("unexpected NULL pointer; take care!");
|
||||
}
|
||||
void checkRange(size_t extra=0) const {
|
||||
size_t off = (const char *) ptr_ - (const char *) base_;
|
||||
if (off > size_ || off + extra > size_)
|
||||
throwCantUnpack("pointer out of range; take care!");
|
||||
}
|
||||
void checkStrict(size_t extra=0) const {
|
||||
checkNULL();
|
||||
checkRange(extra);
|
||||
}
|
||||
void check(size_t extra=0) const {
|
||||
if (ptr_) checkRange(extra);
|
||||
}
|
||||
|
||||
T* ptr_;
|
||||
void* base_;
|
||||
size_t size_;
|
||||
|
||||
// disable copy
|
||||
BoundedPtr(const BoundedPtr&); // {}
|
||||
// BoundedPtr& operator= (const BoundedPtr&); // { return *this; }
|
||||
|
||||
// disable dynamic allocation
|
||||
DISABLE_NEW_DELETE
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
+3
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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);
|
||||
return 0;
|
||||
|
||||
+5
-5
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -81,7 +81,7 @@ static int do_init(FILE *f)
|
||||
if (opt->console == CON_NONE || opt->to_stdout)
|
||||
return con_mode;
|
||||
try_init(&console_file,f);
|
||||
if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO))
|
||||
if (!acc_isatty(STDIN_FILENO) || !acc_isatty(STDOUT_FILENO) || !acc_isatty(STDERR_FILENO))
|
||||
return con_mode;
|
||||
|
||||
#if defined(USE_ANSI)
|
||||
@@ -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)
|
||||
init(f,-1,-1);
|
||||
@@ -142,7 +142,7 @@ console_t console_init =
|
||||
};
|
||||
|
||||
|
||||
void con_fprintf(FILE *f, const char *format, ...)
|
||||
void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[80*25];
|
||||
|
||||
+3
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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);
|
||||
return 0;
|
||||
|
||||
+5
-5
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -88,7 +88,7 @@ static screen_t *do_construct(screen_t *s, int fd)
|
||||
|
||||
static screen_t *screen = NULL;
|
||||
|
||||
static void do_destroy(void)
|
||||
static void __acc_cdecl_atexit do_destroy(void)
|
||||
{
|
||||
if (screen)
|
||||
{
|
||||
@@ -130,7 +130,7 @@ static int init(FILE *f, int o, int now)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_djgpp2_construct(),fd);
|
||||
#endif
|
||||
#if defined(__MFX_WIN32)
|
||||
#if defined(USE_SCREEN_WIN32)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_win32_construct(),fd);
|
||||
#endif
|
||||
@@ -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);
|
||||
#if defined(USE_FRAMES)
|
||||
|
||||
-242
@@ -1,242 +0,0 @@
|
||||
/* compress.ch --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 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>
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_adler32)
|
||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
||||
{
|
||||
if (len == 0)
|
||||
return adler;
|
||||
assert(buf != NULL);
|
||||
return ucl_adler32(adler, (const ucl_bytep)buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(upx_crc32)
|
||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||
{
|
||||
if (len == 0)
|
||||
return crc;
|
||||
assert(buf != NULL);
|
||||
return ucl_crc32(crc, (const ucl_bytep)buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_compress)
|
||||
|
||||
int upx_compress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
upx_progress_callback_t *cb,
|
||||
int method, int level,
|
||||
const struct upx_compress_config_t *conf_parm,
|
||||
upx_uintp result )
|
||||
{
|
||||
struct upx_compress_config_t conf;
|
||||
upx_uint result_buffer[16];
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
assert(level > 0);
|
||||
memset(&conf, 0xff, sizeof(conf));
|
||||
if (conf_parm)
|
||||
conf = *conf_parm; // struct copy
|
||||
if (!result)
|
||||
result = result_buffer;
|
||||
|
||||
// assume no info available - fill in worst case results
|
||||
//result[0] = 1; // min_offset_found - NOT USED
|
||||
result[1] = src_len - 1; // max_offset_found
|
||||
//result[2] = 2; // min_match_found - NOT USED
|
||||
result[3] = src_len - 1; // max_match_found
|
||||
//result[4] = 1; // min_run_found - NOT USED
|
||||
result[5] = src_len; // max_run_found
|
||||
result[6] = 1; // first_offset_found
|
||||
//result[7] = 999999; // same_match_offsets_found - NOT USED
|
||||
|
||||
// prepare bit-buffer settings
|
||||
conf.bb_endian = 0;
|
||||
conf.bb_size = 0;
|
||||
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
|
||||
{
|
||||
int n = (method - M_NRV2B_LE32) % 3;
|
||||
if (n == 0)
|
||||
conf.bb_size = 32;
|
||||
else if (n == 1)
|
||||
conf.bb_size = 8;
|
||||
else
|
||||
conf.bb_size = 16;
|
||||
}
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
|
||||
// optimize compression parms
|
||||
if (level <= 3 && conf.max_offset == UPX_UINT_MAX)
|
||||
conf.max_offset = 8*1024-1;
|
||||
else if (level == 4 && conf.max_offset == UPX_UINT_MAX)
|
||||
conf.max_offset = 32*1024-1;
|
||||
|
||||
if M_IS_NRV2B(method)
|
||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
else if M_IS_NRV2D(method)
|
||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
#if defined(ALG_NRV2E)
|
||||
else if M_IS_NRV2E(method)
|
||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
#endif
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* upx_compress */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_decompress)
|
||||
|
||||
int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
int method )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
#if defined(ALG_NRV2E)
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* upx_decompress */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_test_overlap)
|
||||
|
||||
int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
||||
upx_uint src_len, upx_uintp dst_len,
|
||||
int method )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
#if defined(ALG_NRV2E)
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* upx_test_overlap */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
+188
-13
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -27,23 +27,198 @@
|
||||
|
||||
|
||||
#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)
|
||||
# define upx_adler32 upx_adler32
|
||||
//# define upx_crc32 upx_crc32
|
||||
# define upx_compress upx_compress
|
||||
# define upx_decompress upx_decompress
|
||||
# if (UPX_VERSION_HEX >= 0x019000)
|
||||
# define ALG_NRV2E
|
||||
# define upx_test_overlap upx_test_overlap
|
||||
# endif
|
||||
# include "compress.ch"
|
||||
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
||||
#else
|
||||
# error
|
||||
#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,
|
||||
const upx_bytep tbuf,
|
||||
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, tbuf, 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, tbuf, 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, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown decompression method");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/* compress.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 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,
|
||||
const upx_bytep tbuf,
|
||||
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,
|
||||
const upx_bytep tbuf,
|
||||
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,
|
||||
const upx_bytep tbuf,
|
||||
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,
|
||||
const upx_bytep tbuf,
|
||||
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,563 @@
|
||||
/* compress_lzma.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 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"
|
||||
#include "mem.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
|
||||
#if (WITH_LZMA >= 0x449)
|
||||
# define INITGUID 1
|
||||
//# include "CPP/7zip/Compress/LZMA/LZMADecoder.h"
|
||||
# include "CPP/7zip/Compress/LZMA/LZMAEncoder.h"
|
||||
#else
|
||||
# include "C/Common/MyInitGuid.h"
|
||||
//# include "C/7zip/Compress/LZMA/LZMADecoder.h"
|
||||
# include "C/7zip/Compress/LZMA/LZMAEncoder.h"
|
||||
#endif
|
||||
|
||||
namespace MyLzma {
|
||||
|
||||
struct InStream: public ISequentialInStream, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
const Byte *b_buf; size_t b_size; size_t b_pos;
|
||||
void Init(const Byte *data, size_t size) {
|
||||
b_buf = data; b_size = size; b_pos = 0;
|
||||
}
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
size_t remain = b_size - b_pos;
|
||||
if (size > remain) size = (UInt32) remain;
|
||||
memcpy(data, b_buf + b_pos, size);
|
||||
b_pos += size;
|
||||
if (processedSize != NULL) *processedSize = size;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct OutStream : public ISequentialOutStream, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
Byte *b_buf; size_t b_size; size_t b_pos; bool overflow;
|
||||
void Init(Byte *data, size_t size) {
|
||||
b_buf = data; b_size = size; b_pos = 0; overflow = false;
|
||||
}
|
||||
HRESULT WriteByte(Byte c) {
|
||||
if (b_pos >= b_size) { overflow = true; return E_FAIL; }
|
||||
b_buf[b_pos++] = c;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
size_t remain = b_size - b_pos;
|
||||
if (size > remain) size = (UInt32) remain, overflow = true;
|
||||
memcpy(b_buf + b_pos, data, size);
|
||||
b_pos += size;
|
||||
if (processedSize != NULL) *processedSize = size;
|
||||
return overflow ? E_FAIL : 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
|
||||
|
||||
|
||||
#if (ACC_CC_INTELC) && defined(__linux__)
|
||||
# pragma warning(disable: 424) // #424: extra ";" ignored
|
||||
#endif
|
||||
|
||||
#if (WITH_LZMA >= 0x449)
|
||||
# include "C/Alloc.c"
|
||||
# include "C/7zCrc.c"
|
||||
# include "C/Compress/Lz/MatchFinder.c"
|
||||
//# include "CPP/7zip/Common/InBuffer.cpp"
|
||||
# include "CPP/7zip/Common/OutBuffer.cpp"
|
||||
# include "CPP/7zip/Common/StreamUtils.cpp"
|
||||
//# include "CPP/7zip/Compress/LZ/LZOutWindow.cpp"
|
||||
//# include "CPP/7zip/Compress/LZMA/LZMADecoder.cpp"
|
||||
# include "CPP/7zip/Compress/LZMA/LZMAEncoder.cpp"
|
||||
# include "CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp"
|
||||
#else
|
||||
# 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"
|
||||
#endif
|
||||
#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(M_IS_LZMA(method));
|
||||
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::InStream is; is.AddRef();
|
||||
MyLzma::OutStream 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;
|
||||
unsigned nprops = 7;
|
||||
|
||||
// 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";
|
||||
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
|
||||
pr[nprops].vt = VT_BSTR;
|
||||
pr[nprops].bstrVal = matchfinder;
|
||||
nprops++;
|
||||
#endif
|
||||
#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
|
||||
// method overrides
|
||||
if (method >= 0x100) {
|
||||
pr[0].uintVal = (method >> 16) & 15;
|
||||
pr[1].uintVal = (method >> 12) & 15;
|
||||
pr[2].uintVal = (method >> 8) & 15;
|
||||
}
|
||||
#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, nprops) != 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.b_pos == 5);
|
||||
#if defined(USE_LZMA_PROPERTIES)
|
||||
os.b_pos = 1;
|
||||
#else
|
||||
os.b_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 (...) { rh = E_OUTOFMEMORY; }
|
||||
#endif
|
||||
|
||||
assert(is.b_pos <= src_len);
|
||||
assert(os.b_pos <= *dst_len);
|
||||
if (rh == E_OUTOFMEMORY)
|
||||
r = UPX_E_OUT_OF_MEMORY;
|
||||
else if (os.overflow)
|
||||
{
|
||||
assert(os.b_pos == *dst_len);
|
||||
//r = UPX_E_OUTPUT_OVERRUN;
|
||||
r = UPX_E_NOT_COMPRESSIBLE;
|
||||
}
|
||||
else if (rh == S_OK)
|
||||
{
|
||||
assert(is.b_pos == src_len);
|
||||
r = UPX_E_OK;
|
||||
}
|
||||
|
||||
error:
|
||||
*dst_len = os.b_pos;
|
||||
//printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len);
|
||||
//printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// decompress
|
||||
**************************************************************************/
|
||||
|
||||
#undef _LZMA_IN_CB
|
||||
#undef _LZMA_OUT_READ
|
||||
#undef _LZMA_PROB32
|
||||
#undef _LZMA_LOC_OPT
|
||||
#if (WITH_LZMA >= 0x449)
|
||||
# include "C/Compress/Lzma/LzmaDecode.h"
|
||||
# include "C/Compress/Lzma/LzmaDecode.c"
|
||||
#else
|
||||
# include "C/7zip/Compress/LZMA_C/LzmaDecode.h"
|
||||
# include "C/7zip/Compress/LZMA_C/LzmaDecode.c"
|
||||
#endif
|
||||
|
||||
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(M_IS_LZMA(method));
|
||||
// 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 - see <ucl/ucl.h> for semantics
|
||||
**************************************************************************/
|
||||
|
||||
int upx_lzma_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(M_IS_LZMA(method));
|
||||
|
||||
MemBuffer b(src_off + src_len);
|
||||
memcpy(b + src_off, buf + src_off, src_len);
|
||||
unsigned saved_dst_len = *dst_len;
|
||||
int r = upx_lzma_decompress(b + src_off, src_len, b, dst_len, method, cresult);
|
||||
if (r != UPX_E_OK)
|
||||
return r;
|
||||
if (*dst_len != saved_dst_len)
|
||||
return UPX_E_ERROR;
|
||||
// NOTE: there is a very tiny possibility that decompression has
|
||||
// succeeded but the data is not restored correctly because of
|
||||
// in-place buffer overlapping.
|
||||
if (tbuf != NULL && memcmp(tbuf, b, *dst_len) != 0)
|
||||
return UPX_E_ERROR;
|
||||
return UPX_E_OK;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
const char *upx_lzma_version_string(void)
|
||||
{
|
||||
#if (WITH_LZMA == 0x449)
|
||||
return "4.49";
|
||||
#elif (WITH_LZMA == 0x443)
|
||||
return "4.43";
|
||||
#else
|
||||
# error "unknown version"
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_LZMA */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
/* compress_ucl.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 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"
|
||||
#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)
|
||||
# include <ucl/ucl_asm.h>
|
||||
# define ucl_nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8
|
||||
# define ucl_nrv2b_decompress_safe_le16 ucl_nrv2b_decompress_asm_safe_le16
|
||||
# define ucl_nrv2b_decompress_safe_le32 ucl_nrv2b_decompress_asm_safe_le32
|
||||
# define ucl_nrv2d_decompress_safe_8 ucl_nrv2d_decompress_asm_safe_8
|
||||
# define ucl_nrv2d_decompress_safe_le16 ucl_nrv2d_decompress_asm_safe_le16
|
||||
# define ucl_nrv2d_decompress_safe_le32 ucl_nrv2d_decompress_asm_safe_le32
|
||||
# define ucl_nrv2e_decompress_safe_8 ucl_nrv2e_decompress_asm_safe_8
|
||||
# define ucl_nrv2e_decompress_safe_le16 ucl_nrv2e_decompress_asm_safe_le16
|
||||
# define ucl_nrv2e_decompress_safe_le32 ucl_nrv2e_decompress_asm_safe_le32
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int convert_errno_from_ucl(int r)
|
||||
{
|
||||
switch (r)
|
||||
{
|
||||
case UCL_E_OK: return UPX_E_OK;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
static void wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
|
||||
{
|
||||
if (state != -1 && state != 3) return;
|
||||
upx_callback_p cb = (upx_callback_p) user;
|
||||
if (cb && cb->nprogress)
|
||||
cb->nprogress(cb, a, b);
|
||||
}}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_ucl_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 )
|
||||
{
|
||||
int r;
|
||||
assert(level > 0); assert(cresult != NULL);
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
|
||||
|
||||
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
|
||||
//res[0] = 1; // min_offset_found - NOT USED
|
||||
res[1] = src_len - 1; // max_offset_found
|
||||
//res[2] = 2; // min_match_found - NOT USED
|
||||
res[3] = src_len - 1; // max_match_found
|
||||
//res[4] = 1; // min_run_found - NOT USED
|
||||
res[5] = src_len; // max_run_found
|
||||
res[6] = 1; // first_offset_found
|
||||
//res[7] = 999999; // same_match_offsets_found - NOT USED
|
||||
|
||||
// prepare bit-buffer settings
|
||||
cconf.bb_endian = 0;
|
||||
cconf.bb_size = 0;
|
||||
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
|
||||
{
|
||||
static const unsigned char sizes[3] = {32, 8, 16};
|
||||
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
||||
}
|
||||
else {
|
||||
throwInternalError("unknown compression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
// optimize compression parms
|
||||
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
||||
cconf.max_offset = 8*1024-1;
|
||||
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
||||
cconf.max_offset = 32*1024-1;
|
||||
|
||||
if M_IS_NRV2B(method)
|
||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
||||
&cb, level, &cconf, res);
|
||||
else if M_IS_NRV2D(method)
|
||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
||||
&cb, level, &cconf, res);
|
||||
else if M_IS_NRV2E(method)
|
||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
||||
&cb, level, &cconf, res);
|
||||
else {
|
||||
throwInternalError("unknown compression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
// make sure first_offset_found is set
|
||||
if (res[6] == 0)
|
||||
res[6] = 1;
|
||||
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
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 r;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
UNUSED(cresult);
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_ucl_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
int r;
|
||||
UNUSED(tbuf); // not needed for UCL
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
UNUSED(cresult);
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
const char *upx_ucl_version_string(void)
|
||||
{
|
||||
return ucl_version_string();
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_UCL */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
/* compress_zlib.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 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"
|
||||
#include "mem.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 - see <ucl/ucl.h> for semantics
|
||||
**************************************************************************/
|
||||
|
||||
int upx_zlib_test_overlap ( const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned src_off, unsigned src_len,
|
||||
unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_DEFLATE);
|
||||
|
||||
MemBuffer b(src_off + src_len);
|
||||
memcpy(b + src_off, buf + src_off, src_len);
|
||||
unsigned saved_dst_len = *dst_len;
|
||||
int r = upx_zlib_decompress(b + src_off, src_len, b, dst_len, method, cresult);
|
||||
if (r != UPX_E_OK)
|
||||
return r;
|
||||
if (*dst_len != saved_dst_len)
|
||||
return UPX_E_ERROR;
|
||||
// NOTE: there is a very tiny possibility that decompression has
|
||||
// succeeded but the data is not restored correctly because of
|
||||
// in-place buffer overlapping.
|
||||
if (tbuf != NULL && memcmp(tbuf, b, *dst_len) != 0)
|
||||
return UPX_E_ERROR;
|
||||
return UPX_E_OK;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
const char *upx_zlib_version_string(void)
|
||||
{
|
||||
return zlibVersion();
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_ZLIB */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
+522
-338
File diff suppressed because it is too large
Load Diff
@@ -1,229 +0,0 @@
|
||||
/* pseudo <config.h> for Linux */
|
||||
|
||||
#ifndef __UPX_CONFIG_H
|
||||
#define __UPX_CONFIG_H
|
||||
|
||||
/* $TOP$ */
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Define if your memcmp is broken. */
|
||||
/* #undef NO_MEMCMP */
|
||||
|
||||
/* Define to `long' if <stddef.h> doesn't define. */
|
||||
/* #undef ptrdiff_t */
|
||||
|
||||
/* Define when using the dmalloc package. */
|
||||
/* #undef WITH_DMALLOC */
|
||||
|
||||
/* Define if you have the access function. */
|
||||
#define HAVE_ACCESS 1
|
||||
|
||||
/* Define if you have the atoi function. */
|
||||
#define HAVE_ATOI 1
|
||||
|
||||
/* Define if you have the chmod function. */
|
||||
#define HAVE_CHMOD 1
|
||||
|
||||
/* Define if you have the chown function. */
|
||||
#define HAVE_CHOWN 1
|
||||
|
||||
/* Define if you have the ctime function. */
|
||||
#define HAVE_CTIME 1
|
||||
|
||||
/* Define if you have the difftime function. */
|
||||
#define HAVE_DIFFTIME 1
|
||||
|
||||
/* Define if you have the fchmod function. */
|
||||
#define HAVE_FCHMOD 1
|
||||
|
||||
/* Define if you have the fileno function. */
|
||||
#define HAVE_FILENO 1
|
||||
|
||||
/* Define if you have the fstat function. */
|
||||
#define HAVE_FSTAT 1
|
||||
|
||||
/* Define if you have the XXX function. */
|
||||
#define HAVE_GETPID 1
|
||||
|
||||
/* Define if you have the XXX function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define if you have the getumask function. */
|
||||
/* #undef HAVE_GETUMASK */
|
||||
|
||||
/* Define if you have the gmtime function. */
|
||||
#define HAVE_GMTIME 1
|
||||
|
||||
/* Define if you have the index function. */
|
||||
#define HAVE_INDEX 1
|
||||
|
||||
/* Define if you have the isatty function. */
|
||||
#define HAVE_ISATTY 1
|
||||
|
||||
/* Define if you have the lstat function. */
|
||||
#define HAVE_LSTAT 1
|
||||
|
||||
/* Define if you have the localtime function. */
|
||||
#define HAVE_LOCALTIME 1
|
||||
|
||||
/* Define if you have the memcmp function. */
|
||||
#define HAVE_MEMCMP 1
|
||||
|
||||
/* Define if you have the memcpy function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define if you have the memmove function. */
|
||||
#define HAVE_MEMMOVE 1
|
||||
|
||||
/* Define if you have the memset function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define if you have the mktime function. */
|
||||
#define HAVE_MKTIME 1
|
||||
|
||||
/* Define if you have the setmode function. */
|
||||
/* #undef HAVE_SETMODE */
|
||||
|
||||
/* Define if you have the stat function. */
|
||||
#define HAVE_STAT 1
|
||||
|
||||
/* Define if you have the strcasecmp function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define if you have the strchr function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define if you have the strdup function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define if you have the stricmp function. */
|
||||
/* #undef HAVE_STRICMP */
|
||||
|
||||
/* Define if you have the strncasecmp function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
|
||||
/* Define if you have the strnicmp function. */
|
||||
/* #undef HAVE_STRNICMP */
|
||||
|
||||
/* Define if you have the strstr function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define if you have the tzset function. */
|
||||
#define HAVE_TZSET 1
|
||||
|
||||
/* Define if you have the umask function. */
|
||||
#define HAVE_UMASK 1
|
||||
|
||||
/* Define if you have the utime function. */
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Define if you have the vsnprintf function. */
|
||||
#define HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define if you have the <ctype.h> header file. */
|
||||
#define HAVE_CTYPE_H 1
|
||||
|
||||
/* Define if you have the <curses.h> header file. */
|
||||
#define HAVE_CURSES_H 1
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define if you have the <linux/kd.h> header file. */
|
||||
#define HAVE_LINUX_KD_H 1
|
||||
|
||||
/* Define if you have the <linux/kdev_t.h> header file. */
|
||||
#define HAVE_LINUX_KDEV_T_H 1
|
||||
|
||||
/* Define if you have the <linux/major.h> header file. */
|
||||
#define HAVE_LINUX_MAJOR_H 1
|
||||
|
||||
/* Define if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define if you have the <ncurses.h> header file. */
|
||||
#define HAVE_NCURSES_H 1
|
||||
|
||||
/* Define if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define if you have the <stddef.h> header file. */
|
||||
#define HAVE_STDDEF_H 1
|
||||
|
||||
/* Define if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define if you have the <sys/resource.h> header file. */
|
||||
#define HAVE_SYS_RESOURCE_H 1
|
||||
|
||||
/* Define if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define if you have the <sys/times.h> header file. */
|
||||
#define HAVE_SYS_TIMES_H 1
|
||||
|
||||
/* Define if you have the <sys/utime.h> header file. */
|
||||
/* #undef HAVE_SYS_UTIME_H */
|
||||
|
||||
/* Define if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define if you have the <utime.h> header file. */
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
/* $BOTTOM$ */
|
||||
|
||||
#if defined(HAVE_GMTIME) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_GMTIME
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LOCALTIME) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_LOCALTIME
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_STRFTIME) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_STRFTIME
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_RESOURCE_H) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_SYS_RESOURCE_H
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_TIMES_H) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_SYS_TIMES_H
|
||||
#endif
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/*
|
||||
vi:ts=4
|
||||
*/
|
||||
@@ -1,226 +0,0 @@
|
||||
/* pseudo <config.h> for sparc-sun-solaris2.8 */
|
||||
|
||||
#ifndef __UPX_CONFIG_H
|
||||
#define __UPX_CONFIG_H
|
||||
|
||||
/* $TOP$ */
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Define if your memcmp is broken. */
|
||||
/* #undef NO_MEMCMP */
|
||||
|
||||
/* Define to `long' if <stddef.h> doesn't define. */
|
||||
/* #undef ptrdiff_t */
|
||||
|
||||
/* Define when using the dmalloc package. */
|
||||
/* #undef WITH_DMALLOC */
|
||||
|
||||
/* Define if you have the access function. */
|
||||
#define HAVE_ACCESS 1
|
||||
|
||||
/* Define if you have the atoi function. */
|
||||
#define HAVE_ATOI 1
|
||||
|
||||
/* Define if you have the chmod function. */
|
||||
#define HAVE_CHMOD 1
|
||||
|
||||
/* Define if you have the chown function. */
|
||||
#define HAVE_CHOWN 1
|
||||
|
||||
/* Define if you have the ctime function. */
|
||||
#define HAVE_CTIME 1
|
||||
|
||||
/* Define if you have the difftime function. */
|
||||
#define HAVE_DIFFTIME 1
|
||||
|
||||
/* Define if you have the fchmod function. */
|
||||
#define HAVE_FCHMOD 1
|
||||
|
||||
/* Define if you have the fileno function. */
|
||||
#define HAVE_FILENO 1
|
||||
|
||||
/* Define if you have the fstat function. */
|
||||
#define HAVE_FSTAT 1
|
||||
|
||||
/* Define if you have the XXX function. */
|
||||
#define HAVE_GETPID 1
|
||||
|
||||
/* Define if you have the XXX function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define if you have the getumask function. */
|
||||
/* #undef HAVE_GETUMASK */
|
||||
|
||||
/* Define if you have the gmtime function. */
|
||||
#define HAVE_GMTIME 1
|
||||
|
||||
/* Define if you have the index function. */
|
||||
#define HAVE_INDEX 1
|
||||
|
||||
/* Define if you have the isatty function. */
|
||||
#define HAVE_ISATTY 1
|
||||
|
||||
/* Define if you have the lstat function. */
|
||||
#define HAVE_LSTAT 1
|
||||
|
||||
/* Define if you have the localtime function. */
|
||||
#define HAVE_LOCALTIME 1
|
||||
|
||||
/* Define if you have the memcmp function. */
|
||||
#define HAVE_MEMCMP 1
|
||||
|
||||
/* Define if you have the memcpy function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define if you have the memmove function. */
|
||||
#define HAVE_MEMMOVE 1
|
||||
|
||||
/* Define if you have the memset function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define if you have the mktime function. */
|
||||
#define HAVE_MKTIME 1
|
||||
|
||||
/* Define if you have the setmode function. */
|
||||
/* #undef HAVE_SETMODE */
|
||||
|
||||
/* Define if you have the stat function. */
|
||||
#define HAVE_STAT 1
|
||||
|
||||
/* Define if you have the strcasecmp function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define if you have the strchr function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define if you have the strdup function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define if you have the stricmp function. */
|
||||
/* #undef HAVE_STRICMP */
|
||||
|
||||
/* Define if you have the strncasecmp function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
|
||||
/* Define if you have the strnicmp function. */
|
||||
/* #undef HAVE_STRNICMP */
|
||||
|
||||
/* Define if you have the strstr function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define if you have the tzset function. */
|
||||
#define HAVE_TZSET 1
|
||||
|
||||
/* Define if you have the umask function. */
|
||||
#define HAVE_UMASK 1
|
||||
|
||||
/* Define if you have the utime function. */
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Define if you have the vsnprintf function. */
|
||||
#define HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define if you have the <ctype.h> header file. */
|
||||
#define HAVE_CTYPE_H 1
|
||||
|
||||
/* Define if you have the <curses.h> header file. */
|
||||
#define HAVE_CURSES_H 1
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define if you have the <linux/kd.h> header file. */
|
||||
#define HAVE_LINUX_KD_H 1
|
||||
|
||||
/* Define if you have the <linux/kdev_t.h> header file. */
|
||||
#define HAVE_LINUX_KDEV_T_H 1
|
||||
|
||||
/* Define if you have the <linux/major.h> header file. */
|
||||
#define HAVE_LINUX_MAJOR_H 1
|
||||
|
||||
/* Define if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define if you have the <ncurses.h> header file. */
|
||||
#define HAVE_NCURSES_H 1
|
||||
|
||||
/* Define if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define if you have the <stddef.h> header file. */
|
||||
#define HAVE_STDDEF_H 1
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define if you have the <sys/resource.h> header file. */
|
||||
#define HAVE_SYS_RESOURCE_H 1
|
||||
|
||||
/* Define if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define if you have the <sys/times.h> header file. */
|
||||
#define HAVE_SYS_TIMES_H 1
|
||||
|
||||
/* Define if you have the <sys/utime.h> header file. */
|
||||
/* #undef HAVE_SYS_UTIME_H */
|
||||
|
||||
/* Define if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define if you have the <utime.h> header file. */
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
/* $BOTTOM$ */
|
||||
|
||||
#if defined(HAVE_GMTIME) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_GMTIME
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LOCALTIME) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_LOCALTIME
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_STRFTIME) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_STRFTIME
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_RESOURCE_H) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_SYS_RESOURCE_H
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_TIMES_H) && !defined(TIME_WITH_SYS_TIME)
|
||||
# undef /**/ HAVE_SYS_TIMES_H
|
||||
#endif
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/*
|
||||
vi:ts=4
|
||||
*/
|
||||
+13
-10
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -34,8 +34,9 @@
|
||||
#undef USE_CONSOLE
|
||||
#undef USE_ANSI
|
||||
#undef USE_SCREEN
|
||||
#undef USE_SCREEN_VCSA
|
||||
#undef USE_SCREEN_CURSES
|
||||
#undef USE_SCREEN_VCSA
|
||||
#undef USE_SCREEN_WIN32
|
||||
#undef USE_FRAMES
|
||||
|
||||
#if defined(WITH_GUI) && !defined(NO_CONSOLE)
|
||||
@@ -57,10 +58,12 @@
|
||||
|
||||
#if 1 && defined(__DJGPP__)
|
||||
# define USE_SCREEN
|
||||
#endif
|
||||
|
||||
#if 1 && defined(__MFX_WIN32)
|
||||
#elif 1 && (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||
# define USE_SCREEN
|
||||
# define USE_SCREEN_WIN32
|
||||
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
|
||||
# define USE_SCREEN
|
||||
# define USE_SCREEN_WIN32
|
||||
#endif
|
||||
|
||||
|
||||
@@ -114,16 +117,16 @@ typedef struct
|
||||
int (*init)(FILE *f, int, int);
|
||||
int (*set_fg)(FILE *f, int fg);
|
||||
void (*print0)(FILE *f, const char *s);
|
||||
upx_bool (*intro)(FILE *f);
|
||||
bool (*intro)(FILE *f);
|
||||
}
|
||||
console_t;
|
||||
|
||||
|
||||
#if defined(__GNUC__)
|
||||
void con_fprintf(FILE *f, const char *format, ...)
|
||||
__attribute__((format(printf,2,3)));
|
||||
void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...)
|
||||
__attribute__((__format__(printf,2,3)));
|
||||
#else
|
||||
void con_fprintf(FILE *f, const char *format, ...);
|
||||
void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+30
-15
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
long Throwable::counter = 0;
|
||||
|
||||
Throwable::Throwable(const char *m, int e, bool w)
|
||||
Throwable::Throwable(const char *m, int e, bool w) NOTHROW
|
||||
: super(), msg(NULL), err(e), is_warning(w)
|
||||
{
|
||||
if (m)
|
||||
@@ -47,7 +47,7 @@ Throwable::Throwable(const char *m, int e, bool w)
|
||||
}
|
||||
|
||||
|
||||
Throwable::Throwable(Throwable const &other)
|
||||
Throwable::Throwable(const Throwable &other) NOTHROW
|
||||
: super(other), msg(NULL), err(other.err), is_warning(other.is_warning)
|
||||
{
|
||||
if (other.msg)
|
||||
@@ -85,6 +85,11 @@ void throwCantPack(const char *msg)
|
||||
throw CantUnpackException(msg);
|
||||
}
|
||||
|
||||
void throwCantPackExact()
|
||||
{
|
||||
throwCantPack("option '--exact' does not work with this file");
|
||||
}
|
||||
|
||||
void throwFilterException()
|
||||
{
|
||||
throwCantPack("filter problem");
|
||||
@@ -156,6 +161,14 @@ void throwBadLoader()
|
||||
}
|
||||
|
||||
|
||||
void throwOutOfMemoryException(const char *msg)
|
||||
{
|
||||
if (msg == NULL)
|
||||
msg = "out of memory";
|
||||
throw OutOfMemoryException(msg);
|
||||
}
|
||||
|
||||
|
||||
void throwIOException(const char *msg, int e)
|
||||
{
|
||||
throw IOException(msg, e);
|
||||
@@ -174,22 +187,24 @@ void throwEOFException(const char *msg, int e)
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
const char *prettyName(const char *n)
|
||||
const char *prettyName(const char *n) NOTHROW
|
||||
{
|
||||
if (n == NULL)
|
||||
return "";
|
||||
while (*n >= '0' && *n <= '9') // gcc
|
||||
n++;
|
||||
if (strncmp(n, "class ", 6) == 0) // Visual C++
|
||||
n += 6;
|
||||
return "(null)";
|
||||
while (*n)
|
||||
{
|
||||
if (*n >= '0' && *n <= '9') // Linux ABI
|
||||
n++;
|
||||
else if (*n == ' ')
|
||||
n++;
|
||||
else if (strncmp(n, "class ", 6) == 0) // Visual C++
|
||||
n += 6;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
const char *prettyName(const std::type_info &ti)
|
||||
{
|
||||
return prettyName(ti.name());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
|
||||
+27
-29
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -31,8 +31,7 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
const char *prettyName(const char *n);
|
||||
const char *prettyName(const std::type_info &ti);
|
||||
const char *prettyName(const char *n) NOTHROW;
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -43,13 +42,13 @@ class Throwable : public std::exception
|
||||
{
|
||||
typedef std::exception super;
|
||||
protected:
|
||||
Throwable(const char *m = 0, int e = 0, bool w = false);
|
||||
Throwable(const char *m = 0, int e = 0, bool w = false) NOTHROW;
|
||||
public:
|
||||
Throwable(Throwable const &);
|
||||
Throwable(const Throwable &) NOTHROW;
|
||||
virtual ~Throwable() NOTHROW;
|
||||
const char *getMsg() const { return msg; }
|
||||
int getErrno() const { return err; }
|
||||
bool isWarning() const { return is_warning; }
|
||||
const char *getMsg() const NOTHROW { return msg; }
|
||||
int getErrno() const NOTHROW { return err; }
|
||||
bool isWarning() const NOTHROW { return is_warning; }
|
||||
private:
|
||||
char *msg;
|
||||
int err;
|
||||
@@ -58,12 +57,9 @@ protected:
|
||||
|
||||
private:
|
||||
// disable assignment
|
||||
Throwable& operator= (Throwable const &);
|
||||
Throwable& operator= (const Throwable &);
|
||||
// disable dynamic allocation
|
||||
#ifndef new
|
||||
static void *operator new (size_t); // {}
|
||||
static void *operator new[] (size_t); // {}
|
||||
#endif
|
||||
DISABLE_NEW_DELETE
|
||||
|
||||
private:
|
||||
static long counter; // for debugging
|
||||
@@ -75,7 +71,7 @@ class Exception : public Throwable
|
||||
{
|
||||
typedef Throwable super;
|
||||
public:
|
||||
Exception(const char *m = 0, int e = 0, bool w = false) : super(m,e,w) { }
|
||||
Exception(const char *m = 0, int e = 0, bool w = false) NOTHROW : super(m,e,w) { }
|
||||
};
|
||||
|
||||
|
||||
@@ -84,7 +80,7 @@ class Error : public Throwable
|
||||
{
|
||||
typedef Throwable super;
|
||||
public:
|
||||
Error(const char *m = 0, int e = 0) : super(m,e) { }
|
||||
Error(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
};
|
||||
|
||||
|
||||
@@ -96,7 +92,7 @@ class OutOfMemoryException : public Exception
|
||||
{
|
||||
typedef Exception super;
|
||||
public:
|
||||
OutOfMemoryException(const char *m = 0, int e = 0) : super(m,e) { }
|
||||
OutOfMemoryException(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
};
|
||||
|
||||
|
||||
@@ -104,7 +100,7 @@ class IOException : public Exception
|
||||
{
|
||||
typedef Exception super;
|
||||
public:
|
||||
IOException(const char *m = 0, int e = 0) : super(m,e) { }
|
||||
IOException(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
};
|
||||
|
||||
|
||||
@@ -112,7 +108,7 @@ class EOFException : public IOException
|
||||
{
|
||||
typedef IOException super;
|
||||
public:
|
||||
EOFException(const char *m = 0, int e = 0) : super(m,e) { }
|
||||
EOFException(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
};
|
||||
|
||||
|
||||
@@ -120,7 +116,7 @@ class FileNotFoundException : public IOException
|
||||
{
|
||||
typedef IOException super;
|
||||
public:
|
||||
FileNotFoundException(const char *m = 0, int e = 0) : super(m,e) { }
|
||||
FileNotFoundException(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
};
|
||||
|
||||
|
||||
@@ -128,7 +124,7 @@ class FileAlreadyExistsException : public IOException
|
||||
{
|
||||
typedef IOException super;
|
||||
public:
|
||||
FileAlreadyExistsException(const char *m = 0, int e = 0) : super(m,e) { }
|
||||
FileAlreadyExistsException(const char *m = 0, int e = 0) NOTHROW : super(m,e) { }
|
||||
};
|
||||
|
||||
|
||||
@@ -140,35 +136,35 @@ class OverlayException : public Exception
|
||||
{
|
||||
typedef Exception super;
|
||||
public:
|
||||
OverlayException(const char *m = 0, bool w = false) : super(m,0,w) { }
|
||||
OverlayException(const char *m = 0, bool w = false) NOTHROW : super(m,0,w) { }
|
||||
};
|
||||
|
||||
class CantPackException : public Exception
|
||||
{
|
||||
typedef Exception super;
|
||||
public:
|
||||
CantPackException(const char *m = 0, bool w = false) : super(m,0,w) { }
|
||||
CantPackException(const char *m = 0, bool w = false) NOTHROW : super(m,0,w) { }
|
||||
};
|
||||
|
||||
class UnknownExecutableFormatException : public CantPackException
|
||||
{
|
||||
typedef CantPackException super;
|
||||
public:
|
||||
UnknownExecutableFormatException(const char *m = 0, bool w = false) : super(m,w) { }
|
||||
UnknownExecutableFormatException(const char *m = 0, bool w = false) NOTHROW : super(m,w) { }
|
||||
};
|
||||
|
||||
class AlreadyPackedException : public CantPackException
|
||||
{
|
||||
typedef CantPackException super;
|
||||
public:
|
||||
AlreadyPackedException(const char *m = 0) : super(m) { is_warning = true; }
|
||||
AlreadyPackedException(const char *m = 0) NOTHROW : super(m) { is_warning = true; }
|
||||
};
|
||||
|
||||
class NotCompressibleException : public CantPackException
|
||||
{
|
||||
typedef CantPackException super;
|
||||
public:
|
||||
NotCompressibleException(const char *m = 0) : super(m) { }
|
||||
NotCompressibleException(const char *m = 0) NOTHROW : super(m) { }
|
||||
};
|
||||
|
||||
|
||||
@@ -176,14 +172,14 @@ class CantUnpackException : public Exception
|
||||
{
|
||||
typedef Exception super;
|
||||
public:
|
||||
CantUnpackException(const char *m = 0, bool w = false) : super(m,0,w) { }
|
||||
CantUnpackException(const char *m = 0, bool w = false) NOTHROW : super(m,0,w) { }
|
||||
};
|
||||
|
||||
class NotPackedException : public CantUnpackException
|
||||
{
|
||||
typedef CantUnpackException super;
|
||||
public:
|
||||
NotPackedException(const char *m = 0) : super(m,true) { }
|
||||
NotPackedException(const char *m = 0) NOTHROW : super(m,true) { }
|
||||
};
|
||||
|
||||
|
||||
@@ -195,7 +191,7 @@ class InternalError : public Error
|
||||
{
|
||||
typedef Error super;
|
||||
public:
|
||||
InternalError(const char *m = 0) : super(m,0) { }
|
||||
InternalError(const char *m = 0) NOTHROW : super(m,0) { }
|
||||
};
|
||||
|
||||
|
||||
@@ -212,6 +208,7 @@ public:
|
||||
#endif
|
||||
|
||||
void throwCantPack(const char *msg) NORET;
|
||||
void throwCantPackExact() NORET;
|
||||
void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET;
|
||||
void throwNotCompressible(const char *msg = NULL) NORET;
|
||||
void throwAlreadyPacked(const char *msg = NULL) NORET;
|
||||
@@ -223,6 +220,7 @@ void throwBadLoader() NORET;
|
||||
void throwChecksumError() NORET;
|
||||
void throwCompressedDataViolation() NORET;
|
||||
void throwInternalError(const char *msg) NORET;
|
||||
void throwOutOfMemoryException(const char *msg = NULL) NORET;
|
||||
void throwIOException(const char *msg = NULL, int e = 0) NORET;
|
||||
void throwEOFException(const char *msg = NULL, int e = 0) NORET;
|
||||
|
||||
|
||||
+127
-76
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -40,13 +40,15 @@ void File::chmod(const char *name, int mode)
|
||||
#if defined(HAVE_CHMOD)
|
||||
if (::chmod(name,mode) != 0)
|
||||
throwIOException(name,errno);
|
||||
#else
|
||||
UNUSED(name); UNUSED(mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void File::rename(const char *old_, const char *new_)
|
||||
{
|
||||
#if 1 && defined(__DJGPP__)
|
||||
#if defined(__DJGPP__)
|
||||
if (::_rename(old_,new_) != 0)
|
||||
#else
|
||||
if (::rename(old_,new_) != 0)
|
||||
@@ -67,7 +69,7 @@ void File::unlink(const char *name)
|
||||
**************************************************************************/
|
||||
|
||||
FileBase::FileBase() :
|
||||
_fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL)
|
||||
_fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL), _offset(0), _length(0)
|
||||
{
|
||||
memset(&st,0,sizeof(st));
|
||||
}
|
||||
@@ -86,7 +88,7 @@ FileBase::~FileBase()
|
||||
}
|
||||
|
||||
|
||||
void FileBase::sopen()
|
||||
bool FileBase::do_sopen()
|
||||
{
|
||||
if (_shflags < 0)
|
||||
_fd = ::open(_name, _flags, _mode);
|
||||
@@ -99,9 +101,15 @@ void FileBase::sopen()
|
||||
#elif defined(SH_DENYRW)
|
||||
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
||||
#else
|
||||
assert(0);
|
||||
throwInternalError("bad usage of do_sopen()");
|
||||
#endif
|
||||
}
|
||||
if (_fd < 0)
|
||||
return false;
|
||||
if (::fstat(_fd, &st) != 0)
|
||||
throwIOException(_name, errno);
|
||||
_length = st.st_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +123,8 @@ bool FileBase::close()
|
||||
_flags = 0;
|
||||
_mode = 0;
|
||||
_name = NULL;
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -128,29 +138,13 @@ void FileBase::closex()
|
||||
|
||||
int FileBase::read(void *buf, int len)
|
||||
{
|
||||
int l;
|
||||
if (!isOpen() || len < 0)
|
||||
throwIOException("bad read");
|
||||
if (len == 0)
|
||||
return 0;
|
||||
for (;;)
|
||||
{
|
||||
#if 1 && defined(__DJGPP__)
|
||||
l = ::_read(_fd, buf, len);
|
||||
#else
|
||||
l = ::read(_fd, buf, len);
|
||||
#endif
|
||||
if (l < 0)
|
||||
{
|
||||
#if defined(EINTR)
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
#endif
|
||||
throwIOException("read error",errno);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return l;
|
||||
errno = 0;
|
||||
long l = acc_safe_hread(_fd, buf, len);
|
||||
if (errno)
|
||||
throwIOException("read error",errno);
|
||||
return (int) l;
|
||||
}
|
||||
|
||||
|
||||
@@ -165,26 +159,12 @@ int FileBase::readx(void *buf, int len)
|
||||
|
||||
void FileBase::write(const void *buf, int len)
|
||||
{
|
||||
int l;
|
||||
if (!isOpen() || len < 0)
|
||||
throwIOException("bad write");
|
||||
if (len == 0)
|
||||
return;
|
||||
for (;;)
|
||||
{
|
||||
#if 1 && defined(__DJGPP__)
|
||||
l = ::_write(_fd,buf,len);
|
||||
#else
|
||||
l = ::write(_fd,buf,len);
|
||||
#endif
|
||||
#if defined(EINTR)
|
||||
if (l < 0 && errno == EINTR)
|
||||
continue;
|
||||
#endif
|
||||
if (l != len)
|
||||
throwIOException("write error",errno);
|
||||
break;
|
||||
}
|
||||
errno = 0;
|
||||
long l = acc_safe_hwrite(_fd, buf, len);
|
||||
if (l != len)
|
||||
throwIOException("write error",errno);
|
||||
}
|
||||
|
||||
|
||||
@@ -192,10 +172,17 @@ void FileBase::seek(off_t off, int whence)
|
||||
{
|
||||
if (!isOpen())
|
||||
throwIOException("bad seek 1");
|
||||
if (whence == SEEK_SET && off < 0)
|
||||
throwIOException("bad seek 2");
|
||||
if (whence == SEEK_END && off > 0)
|
||||
throwIOException("bad seek 3");
|
||||
if (whence == SEEK_SET) {
|
||||
if (off < 0)
|
||||
throwIOException("bad seek 2");
|
||||
off += _offset;
|
||||
}
|
||||
if (whence == SEEK_END) {
|
||||
if (off > 0)
|
||||
throwIOException("bad seek 3");
|
||||
off += _offset + _length;
|
||||
whence = SEEK_SET;
|
||||
}
|
||||
if (::lseek(_fd,off,whence) < 0)
|
||||
throwIOException("seek error",errno);
|
||||
}
|
||||
@@ -208,7 +195,19 @@ off_t FileBase::tell() const
|
||||
off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
||||
if (l < 0)
|
||||
throwIOException("tell error",errno);
|
||||
return l;
|
||||
return l - _offset;
|
||||
}
|
||||
|
||||
|
||||
void FileBase::set_extent(off_t offset, off_t length)
|
||||
{
|
||||
_offset = offset;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
off_t FileBase::st_size() const
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
|
||||
@@ -233,8 +232,9 @@ void InputFile::sopen(const char *name, int flags, int shflags)
|
||||
_flags = flags;
|
||||
_shflags = shflags;
|
||||
_mode = 0;
|
||||
FileBase::sopen();
|
||||
if (!isOpen())
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
if (!FileBase::do_sopen())
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
throw FileNotFoundException(_name, errno);
|
||||
@@ -259,14 +259,16 @@ int InputFile::readx(void *buf, int len)
|
||||
|
||||
int InputFile::read(MemBuffer *buf, int len)
|
||||
{
|
||||
buf->checkState();
|
||||
assert((unsigned)len <= buf->getSize());
|
||||
return super::read(buf->getVoidPtr(), len);
|
||||
return read(buf->getVoidPtr(), len);
|
||||
}
|
||||
|
||||
int InputFile::readx(MemBuffer *buf, int len)
|
||||
{
|
||||
buf->checkState();
|
||||
assert((unsigned)len <= buf->getSize());
|
||||
return super::readx(buf->getVoidPtr(), len);
|
||||
return read(buf->getVoidPtr(), len);
|
||||
}
|
||||
|
||||
|
||||
@@ -315,8 +317,9 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
||||
_flags = flags;
|
||||
_shflags = shflags;
|
||||
_mode = mode;
|
||||
FileBase::sopen();
|
||||
if (!isOpen())
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
if (!FileBase::do_sopen())
|
||||
{
|
||||
#if 0
|
||||
// don't throw FileNotFound here -- this is confusing
|
||||
@@ -335,29 +338,18 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
||||
bool OutputFile::openStdout(int flags, bool force)
|
||||
{
|
||||
close();
|
||||
if (!force)
|
||||
{
|
||||
if (!isafile(STDOUT_FILENO))
|
||||
return false;
|
||||
}
|
||||
_fd = STDOUT_FILENO;
|
||||
int fd = STDOUT_FILENO;
|
||||
if (!force && acc_isatty(fd))
|
||||
return false;
|
||||
_name = "<stdout>";
|
||||
_flags = flags;
|
||||
_shflags = -1;
|
||||
_mode = 0;
|
||||
if (flags != 0)
|
||||
{
|
||||
assert(flags == O_BINARY);
|
||||
#if defined(__MINT__)
|
||||
__set_binmode(stdout, 1);
|
||||
#elif defined(HAVE_SETMODE) && defined(USE_SETMODE)
|
||||
if (setmode(_fd, O_BINARY) == -1)
|
||||
throwIOException(_name,errno);
|
||||
#if defined(__DJGPP__)
|
||||
__djgpp_set_ctrl_c(1);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
_offset = 0;
|
||||
_length = 0;
|
||||
if (flags && acc_set_binmode(fd, 1) == -1)
|
||||
throwIOException(_name, errno);
|
||||
_fd = fd;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -368,6 +360,65 @@ void OutputFile::write(const void *buf, int len)
|
||||
bytes_written += len;
|
||||
}
|
||||
|
||||
off_t OutputFile::st_size() const
|
||||
{
|
||||
if (opt->to_stdout) { // might be a pipe ==> .st_size is invalid
|
||||
return bytes_written; // too big if seek()+write() instead of rewrite()
|
||||
}
|
||||
struct stat my_st;
|
||||
if (::fstat(_fd, &my_st) != 0)
|
||||
throwIOException(_name, errno);
|
||||
return my_st.st_size;
|
||||
}
|
||||
|
||||
|
||||
void OutputFile::write(const MemBuffer *buf, int len)
|
||||
{
|
||||
buf->checkState();
|
||||
assert((unsigned)len <= buf->getSize());
|
||||
write(buf->getVoidPtr(), len);
|
||||
}
|
||||
|
||||
|
||||
void OutputFile::write(const MemBuffer &buf, int len)
|
||||
{
|
||||
write(&buf, len);
|
||||
}
|
||||
|
||||
void OutputFile::rewrite(const void *buf, int len)
|
||||
{
|
||||
assert(!opt->to_stdout);
|
||||
write(buf, len);
|
||||
bytes_written -= len; // restore
|
||||
}
|
||||
|
||||
void OutputFile::seek(off_t off, int whence)
|
||||
{
|
||||
assert(!opt->to_stdout);
|
||||
super::seek(off,whence);
|
||||
}
|
||||
|
||||
void OutputFile::set_extent(off_t offset, off_t length)
|
||||
{
|
||||
super::set_extent(offset, length);
|
||||
bytes_written = 0;
|
||||
if (0==offset && (off_t)~0u==length) {
|
||||
if (::fstat(_fd, &st) != 0)
|
||||
throwIOException(_name, errno);
|
||||
_length = st.st_size - offset;
|
||||
}
|
||||
}
|
||||
|
||||
off_t OutputFile::unset_extent()
|
||||
{
|
||||
off_t l = ::lseek(_fd, 0, SEEK_END);
|
||||
if (l < 0)
|
||||
throwIOException("lseek error", errno);
|
||||
_offset = 0;
|
||||
_length = l;
|
||||
bytes_written = _length;
|
||||
return _length;
|
||||
}
|
||||
|
||||
void OutputFile::dump(const char *name, const void *buf, int len, int flags)
|
||||
{
|
||||
@@ -375,7 +426,7 @@ void OutputFile::dump(const char *name, const void *buf, int len, int flags)
|
||||
flags = O_CREAT | O_BINARY | O_TRUNC;
|
||||
flags |= O_WRONLY;
|
||||
OutputFile f;
|
||||
f.open(name, flags, 0666);
|
||||
f.open(name, flags, 0600);
|
||||
f.write(buf, len);
|
||||
f.closex();
|
||||
}
|
||||
|
||||
+19
-18
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -38,6 +38,9 @@ class MemBuffer;
|
||||
|
||||
class File
|
||||
{
|
||||
protected:
|
||||
File() { }
|
||||
virtual ~File() { }
|
||||
public:
|
||||
static void chmod(const char *name, int mode);
|
||||
static void rename(const char *old_, const char *new_);
|
||||
@@ -56,9 +59,11 @@ public:
|
||||
virtual bool isOpen() const { return _fd >= 0; }
|
||||
int getFd() const { return _fd; }
|
||||
const char *getName() const { return _name; }
|
||||
virtual off_t st_size() const; // { return _length; }
|
||||
virtual void set_extent(off_t offset, off_t length);
|
||||
|
||||
protected:
|
||||
void sopen();
|
||||
bool do_sopen();
|
||||
virtual int read(void *buf, int len);
|
||||
virtual int readx(void *buf, int len);
|
||||
virtual void write(const void *buf, int len);
|
||||
@@ -70,6 +75,8 @@ protected:
|
||||
int _shflags;
|
||||
int _mode;
|
||||
const char *_name;
|
||||
off_t _offset;
|
||||
off_t _length;
|
||||
public:
|
||||
struct stat st;
|
||||
};
|
||||
@@ -123,23 +130,17 @@ public:
|
||||
virtual bool openStdout(int flags=0, bool force=false);
|
||||
|
||||
virtual void write(const void *buf, int len);
|
||||
virtual void write(const MemBuffer *buf, int len);
|
||||
virtual void write(const MemBuffer &buf, int len);
|
||||
virtual void set_extent(off_t offset, off_t length);
|
||||
virtual off_t unset_extent(); // returns actual length
|
||||
|
||||
off_t getBytesWritten() const { return bytes_written; }
|
||||
virtual off_t st_size() const; // { return _length; }
|
||||
|
||||
#if (UPX_VERSION_HEX >= 0x019000)
|
||||
// FIXME - these won't work when using the `--stdout' option
|
||||
virtual void seek(off_t off, int whence)
|
||||
{
|
||||
assert(!opt->to_stdout);
|
||||
super::seek(off,whence);
|
||||
}
|
||||
virtual void rewrite(const void *buf, int len)
|
||||
{
|
||||
assert(!opt->to_stdout);
|
||||
write(buf, len);
|
||||
bytes_written -= len; // restore
|
||||
}
|
||||
#endif
|
||||
// FIXME - these won't work when using the '--stdout' option
|
||||
virtual void seek(off_t off, int whence);
|
||||
virtual void rewrite(const void *buf, int len);
|
||||
|
||||
// util
|
||||
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
||||
@@ -153,7 +154,7 @@ protected:
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if 0
|
||||
#if 0 /* NOT USED */
|
||||
class MemoryOutputFile : public FileBase
|
||||
{
|
||||
typedef FileBase super;
|
||||
|
||||
+22
-8
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -21,8 +21,8 @@
|
||||
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
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
@@ -61,10 +61,10 @@ const FilterImp::FilterEntry *FilterImp::getFilter(int id)
|
||||
memset(filter_map, 0xff, sizeof(filter_map));
|
||||
for (int i = 0; i < n_filters; i++)
|
||||
{
|
||||
int fid = filters[i].id;
|
||||
assert(fid >= 0 && fid <= 255);
|
||||
assert(filter_map[fid] == 0xff);
|
||||
filter_map[fid] = (unsigned char) i;
|
||||
int filter_id = filters[i].id;
|
||||
assert(filter_id >= 0 && filter_id <= 255);
|
||||
assert(filter_map[filter_id] == 0xff);
|
||||
filter_map[filter_id] = (unsigned char) i;
|
||||
}
|
||||
done = true;
|
||||
}
|
||||
@@ -85,6 +85,20 @@ bool Filter::isValidFilter(int filter_id)
|
||||
return fe != NULL;
|
||||
}
|
||||
|
||||
bool Filter::isValidFilter(int filter_id, const int *allowed_filters)
|
||||
{
|
||||
if (!isValidFilter(filter_id))
|
||||
return false;
|
||||
if (filter_id == 0)
|
||||
return true;
|
||||
if (allowed_filters == NULL)
|
||||
return false;
|
||||
while (*allowed_filters != FT_END)
|
||||
if (*allowed_filters++ == filter_id)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// high level API
|
||||
|
||||
+4
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
bool scan(const upx_byte *buf, unsigned buf_len);
|
||||
|
||||
static bool isValidFilter(int filter_id);
|
||||
static bool isValidFilter(int filter_id, const int *allowed_filters);
|
||||
|
||||
public:
|
||||
// Will be set by each call to filter()/unfilter().
|
||||
|
||||
+77
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
|
||||
/*************************************************************************
|
||||
// 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
|
||||
|
||||
+20
-6
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -36,11 +36,11 @@ static int F(Filter *f)
|
||||
#ifdef U
|
||||
// filter
|
||||
upx_byte *b = f->buf;
|
||||
const unsigned addvalue = f->addvalue;
|
||||
#else
|
||||
// scan
|
||||
const upx_byte *b = f->buf;
|
||||
#endif
|
||||
const unsigned addvalue = f->addvalue;
|
||||
const unsigned size = f->buf_len;
|
||||
|
||||
unsigned ic, jc, kc;
|
||||
@@ -52,11 +52,24 @@ static int F(Filter *f)
|
||||
unsigned char buf[256];
|
||||
memset(buf,0,256);
|
||||
|
||||
// A call to a destination that is inside the buffer
|
||||
// will be rewritten and marked with cto8 as first byte.
|
||||
// So, a call to a destination that is outside the buffer
|
||||
// must not conflict with the mark.
|
||||
// Note that unsigned comparison checks both edges of buffer.
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
if (COND(b,ic) && get_le32(b+ic+1)+ic+1 >= size)
|
||||
{
|
||||
if (!COND(b,ic))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
if (jc < size)
|
||||
{
|
||||
buf[b[ic+1]] |= 1;
|
||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
buf[b[ic+1]] |= 1;
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0)
|
||||
return -1;
|
||||
@@ -74,6 +87,7 @@ static int F(Filter *f)
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size)
|
||||
{
|
||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||
#ifdef U
|
||||
set_be32(b+ic+1,jc+addvalue+cto);
|
||||
#endif
|
||||
@@ -112,7 +126,7 @@ static int F(Filter *f)
|
||||
f->noncalls = noncalls;
|
||||
f->lastcall = lastcall;
|
||||
|
||||
#ifdef TESTING
|
||||
#if 0 || defined(TESTING)
|
||||
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
+18
-10
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 2000-2002 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -40,11 +40,11 @@ static int F(Filter *f)
|
||||
#ifdef U
|
||||
// filter
|
||||
upx_byte *b = f->buf;
|
||||
const unsigned addvalue = f->addvalue;
|
||||
#else
|
||||
// scan
|
||||
const upx_byte *b = f->buf;
|
||||
#endif
|
||||
const unsigned addvalue = f->addvalue;
|
||||
const unsigned size = f->buf_len;
|
||||
|
||||
unsigned ic, jc, kc;
|
||||
@@ -57,10 +57,18 @@ static int F(Filter *f)
|
||||
memset(buf,0,256);
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
if (COND(b,ic,lastcall) && get_le32(b+ic+1)+ic+1 >= size)
|
||||
{
|
||||
if (!COND(b,ic,lastcall))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
if (jc < size)
|
||||
{
|
||||
buf[b[ic+1]] |= 1;
|
||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
buf[b[ic+1]] |= 1;
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0)
|
||||
return -1;
|
||||
@@ -78,6 +86,7 @@ static int F(Filter *f)
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size)
|
||||
{
|
||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||
#ifdef U
|
||||
set_be32(b+ic+1,jc+addvalue+cto);
|
||||
#endif
|
||||
@@ -116,7 +125,7 @@ static int F(Filter *f)
|
||||
f->noncalls = noncalls;
|
||||
f->lastcall = lastcall;
|
||||
|
||||
#ifdef TESTING
|
||||
#if 0 || defined(TESTING)
|
||||
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
||||
#endif
|
||||
return 0;
|
||||
@@ -134,8 +143,7 @@ static int U(Filter *f)
|
||||
const unsigned size5 = f->buf_len - 5;
|
||||
const unsigned addvalue = f->addvalue;
|
||||
const unsigned cto = (unsigned)f->cto << 24;
|
||||
unsigned lastcall = 0;
|
||||
|
||||
// unsigned lastcall = 0; // lastcall is not used in COND macro
|
||||
unsigned ic, jc;
|
||||
|
||||
for (ic = 0; ic < size5; ic++)
|
||||
@@ -147,7 +155,7 @@ static int U(Filter *f)
|
||||
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
|
||||
f->calls++;
|
||||
ic += 4;
|
||||
f->lastcall = lastcall = ic+1;
|
||||
f->lastcall = ic+1;
|
||||
}
|
||||
else
|
||||
f->noncalls++;
|
||||
|
||||
+10
-5
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 2000-2002 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -30,6 +30,10 @@
|
||||
*/
|
||||
|
||||
|
||||
#if (ACC_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1300))
|
||||
# pragma warning(disable: 4702) // W4: unreachable code
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// filter / scan
|
||||
@@ -131,6 +135,7 @@ static int F(Filter *f)
|
||||
{
|
||||
buf[b[ic+1]] |= 1;
|
||||
}
|
||||
UNUSED(which);
|
||||
|
||||
if (getcto(f, buf) < 0)
|
||||
return -1;
|
||||
@@ -244,11 +249,11 @@ static int F(Filter *f)
|
||||
f->noncalls = noncalls;
|
||||
f->lastcall = lastcall;
|
||||
|
||||
/*#ifdef TESTING*/
|
||||
#if 0 || defined(TESTING)
|
||||
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",
|
||||
calls,noncalls,noncalls2,size,cto8);
|
||||
printf("CALL/JMP/JCC %d %d %d\n",wtally[0],wtally[1],wtally[2]);
|
||||
/*#endif*/
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+16
-7
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 2000-2002 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -40,11 +40,11 @@ static int F(Filter *f)
|
||||
#ifdef U
|
||||
// filter
|
||||
upx_byte *b = f->buf;
|
||||
const unsigned addvalue = f->addvalue;
|
||||
#else
|
||||
// scan
|
||||
const upx_byte *b = f->buf;
|
||||
#endif
|
||||
const unsigned addvalue = f->addvalue;
|
||||
const unsigned size = f->buf_len;
|
||||
unsigned const id = f->id;
|
||||
|
||||
@@ -58,10 +58,18 @@ static int F(Filter *f)
|
||||
memset(buf,0,256);
|
||||
|
||||
for (ic = 0; ic < size - 5; ic++)
|
||||
if (COND(b,ic,lastcall,id) && get_le32(b+ic+1)+ic+1 >= size)
|
||||
{
|
||||
if (!COND(b,ic,lastcall,id))
|
||||
continue;
|
||||
jc = get_le32(b+ic+1)+ic+1;
|
||||
if (jc < size)
|
||||
{
|
||||
buf[b[ic+1]] |= 1;
|
||||
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
buf[b[ic+1]] |= 1;
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0)
|
||||
return -1;
|
||||
@@ -79,6 +87,7 @@ static int F(Filter *f)
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size)
|
||||
{
|
||||
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||
#ifdef U
|
||||
set_be32(b+ic+1,jc+addvalue+cto);
|
||||
#endif
|
||||
@@ -117,7 +126,7 @@ static int F(Filter *f)
|
||||
f->noncalls = noncalls;
|
||||
f->lastcall = lastcall;
|
||||
|
||||
#ifdef TESTING
|
||||
#if 0 || defined(TESTING)
|
||||
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/* ppcbxx.h -- PowerPC Branch trick
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2004-2007 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
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// filter / scan
|
||||
**************************************************************************/
|
||||
|
||||
#define W_CTO 4 /* width of cto; must match stub/ppc_bxx.S */
|
||||
|
||||
static int F(Filter *f)
|
||||
{
|
||||
#ifdef U
|
||||
// filter
|
||||
upx_byte *b = f->buf;
|
||||
const unsigned addvalue = f->addvalue;
|
||||
#else
|
||||
// scan
|
||||
const upx_byte *b = f->buf;
|
||||
#endif
|
||||
const unsigned size = umin(f->buf_len, -(~0u<<(32 - (6+ W_CTO))));
|
||||
const unsigned size4 = size -4;
|
||||
|
||||
unsigned ic;
|
||||
unsigned calls = 0, noncalls = 0;
|
||||
unsigned lastnoncall = size, lastcall = 0;
|
||||
|
||||
// find 26-2-W_CTO bits of displacements that contain no targets
|
||||
{
|
||||
unsigned char buf[256];
|
||||
unsigned short wbuf[256];
|
||||
const size_t WW = (size_t)0 - ((~(size_t)0) << W_CTO); // ???
|
||||
memset(wbuf, 0, sizeof(wbuf));
|
||||
memset(buf , 0, WW);
|
||||
memset(buf + WW, 1, 256 - WW);
|
||||
|
||||
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
|
||||
unsigned const off = (int)(get_be32(b+ic)<<6) >>6;
|
||||
if (size <= (off & (~0u<<2))+ic) {
|
||||
buf[(~(~0u<<W_CTO)) & (off>>(26 - W_CTO))] |= 1;
|
||||
++wbuf[0xff&(off>>18)];
|
||||
}
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0) {
|
||||
if (0!=W_CTO) // FIXME: what is this ???
|
||||
return -1;
|
||||
f->cto = 0;
|
||||
}
|
||||
}
|
||||
const unsigned char cto8 = f->cto;
|
||||
#ifdef U
|
||||
const unsigned cto = (unsigned)f->cto << (24+2 - W_CTO);
|
||||
#endif
|
||||
|
||||
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
|
||||
unsigned const word = get_be32(b+ic);
|
||||
unsigned const off = (int)(word<<6) >>6;
|
||||
unsigned const jc = (off & (~0u<<2))+ic;
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size) {
|
||||
#ifdef U
|
||||
set_be32(b+ic,(0xfc000003&word) | (jc+addvalue+cto));
|
||||
#endif
|
||||
calls++;
|
||||
lastcall = ic;
|
||||
}
|
||||
else {
|
||||
assert(0==W_CTO // FIXME: what is this ???
|
||||
|| (~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) != cto8); // this should not happen
|
||||
lastnoncall = ic;
|
||||
noncalls++;
|
||||
}
|
||||
}
|
||||
|
||||
f->calls = calls;
|
||||
f->noncalls = noncalls;
|
||||
f->lastcall = lastcall;
|
||||
|
||||
#if 0 || defined(TESTING)
|
||||
printf("\ncalls=%d noncalls=%d text_size=%x calltrickoffset=%x\n",
|
||||
calls,noncalls,size,cto8);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// unfilter
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef U
|
||||
static int U(Filter *f)
|
||||
{
|
||||
upx_byte *b = f->buf;
|
||||
const unsigned size4 = umin(f->buf_len - 4, -(~0u<<(32 - (6+ W_CTO))));
|
||||
const unsigned addvalue = f->addvalue;
|
||||
|
||||
unsigned ic;
|
||||
|
||||
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
|
||||
unsigned const word = get_be32(b+ic);
|
||||
if ((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) == f->cto) {
|
||||
unsigned const jc = word & (~(~0u<<(26 - W_CTO)) & (~0u<<2));
|
||||
set_be32(b+ic, (0xfc000003&word)|(0x03fffffc&(jc-ic-addvalue)));
|
||||
f->calls++;
|
||||
f->lastcall = ic;
|
||||
}
|
||||
else {
|
||||
f->noncalls++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef F
|
||||
#undef U
|
||||
|
||||
#undef W_CTO
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+31
-5
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,13 +22,19 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "filter.h"
|
||||
|
||||
static unsigned
|
||||
umin(unsigned const a, unsigned const b)
|
||||
{
|
||||
return (a<=b) ? a : b;
|
||||
}
|
||||
|
||||
|
||||
#define set_dummy(p, v) ((void)0)
|
||||
#define get_8(p) (*(p))
|
||||
@@ -103,7 +109,7 @@
|
||||
|
||||
#define COND1(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||
#define COND2(b,x,lc) (lc!=(x) && 0xf==b[(x)-1] && 0x80<=b[x] && b[x]<=0x8f)
|
||||
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
|
||||
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
|
||||
#define F f_ctok32_e8e9_bswap_le
|
||||
#define U u_ctok32_e8e9_bswap_le
|
||||
#include "filter/ctok.h"
|
||||
@@ -145,6 +151,19 @@
|
||||
#undef COND_CALL
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// PowerPC branch [incl. call] trick
|
||||
**************************************************************************/
|
||||
|
||||
#define COND(b,x) (18==(get_be32(b+x)>>26))
|
||||
#define F f_ppcbxx
|
||||
#define U u_ppcbxx
|
||||
#include "filter/ppcbxx.h"
|
||||
#define F s_ppcbxx
|
||||
#include "filter/ppcbxx.h"
|
||||
#undef COND
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// database for use in class Filter
|
||||
**************************************************************************/
|
||||
@@ -205,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 },
|
||||
{ 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
|
||||
{ 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 },
|
||||
@@ -230,9 +253,12 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
||||
{ 0xb1,99, 0, f_sub32_2, u_sub32_2, s_sub32_2 },
|
||||
{ 0xb2,99, 0, f_sub32_3, u_sub32_3, s_sub32_3 },
|
||||
{ 0xb3,99, 0, f_sub32_4, u_sub32_4, s_sub32_4 },
|
||||
|
||||
// PowerPC branch+call trick
|
||||
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
|
||||
};
|
||||
|
||||
const int FilterImp::n_filters = HIGH(filters);
|
||||
const int FilterImp::n_filters = TABLESIZE(filters);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
+157
-67
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -27,6 +27,9 @@
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
#include "packmast.h"
|
||||
#include "packer.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -47,12 +50,12 @@ void show_head(void)
|
||||
#define V(x) (strcmp(UPX_VERSION_STRING, UPX_VERSION_STRING4) ? UPX_VERSION_STRING : UPX_VERSION_STRING x)
|
||||
fg = con_fg(f,FG_GREEN);
|
||||
con_fprintf(f,
|
||||
" Ultimate Packer for eXecutables\n"
|
||||
" Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002\n"
|
||||
"UPX %-12s Markus F.X.J. Oberhumer & Laszlo Molnar %20s\n\n",
|
||||
#if defined(__MFX_DOS)
|
||||
" Ultimate Packer for eXecutables\n"
|
||||
" Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007\n"
|
||||
"UPX %-10s Markus Oberhumer, Laszlo Molnar & John Reiser %14s\n\n",
|
||||
#if (ACC_OS_DOS16 || ACC_OS_DOS32)
|
||||
V("d"),
|
||||
#elif defined(__MFX_WIN32)
|
||||
#elif (ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||
V("w"),
|
||||
#elif 0 && defined(__linux__)
|
||||
V("l"),
|
||||
@@ -62,6 +65,8 @@ void show_head(void)
|
||||
UPX_VERSION_DATE);
|
||||
fg = con_fg(f,fg);
|
||||
#undef V
|
||||
|
||||
UNUSED(fg);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +91,77 @@ void show_usage(void)
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void show_help(int x)
|
||||
struct PackerNames
|
||||
{
|
||||
struct Entry {
|
||||
const char* fname;
|
||||
const char* sname;
|
||||
};
|
||||
Entry names[64];
|
||||
size_t names_count;
|
||||
const options_t *o;
|
||||
PackerNames() : names_count(0), o(NULL) { }
|
||||
void add(const Packer *p)
|
||||
{
|
||||
p->assertPacker();
|
||||
assert(names_count < 64);
|
||||
names[names_count].fname = p->getFullName(o);
|
||||
names[names_count].sname = p->getName();
|
||||
names_count++;
|
||||
}
|
||||
static Packer* visit(Packer *p, void *user)
|
||||
{
|
||||
PackerNames *self = (PackerNames *) user;
|
||||
self->add(p);
|
||||
return NULL;
|
||||
}
|
||||
static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) {
|
||||
return strcmp(((const Entry *) a)->fname, ((const Entry *) b)->fname);
|
||||
}
|
||||
static int __acc_cdecl_qsort cmp_sname(const void *a, const void *b) {
|
||||
return strcmp(((const Entry *) a)->sname, ((const Entry *) b)->sname);
|
||||
}
|
||||
};
|
||||
|
||||
static void show_all_packers(FILE *f, int verbose)
|
||||
{
|
||||
options_t o; o.reset();
|
||||
PackerNames pn; pn.o = &o;
|
||||
PackMaster::visitAllPackers(pn.visit, NULL, &o, &pn);
|
||||
qsort(pn.names, pn.names_count, sizeof(PackerNames::Entry), pn.cmp_fname);
|
||||
size_t pos = 0;
|
||||
for (size_t i = 0; i < pn.names_count; ++i)
|
||||
{
|
||||
const char *fn = pn.names[i].fname;
|
||||
const char *sn = pn.names[i].sname;
|
||||
if (verbose)
|
||||
{
|
||||
con_fprintf(f, " %-32s %s\n", fn, sn);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pos == 0) {
|
||||
con_fprintf(f, " %s", fn);
|
||||
pos = 2 + strlen(fn);
|
||||
} else if (pos + 1 + strlen(fn) > 80) {
|
||||
con_fprintf(f, "\n %s", fn);
|
||||
pos = 2 + strlen(fn);
|
||||
} else {
|
||||
con_fprintf(f, " %s", fn);
|
||||
pos += 1 + strlen(fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!verbose && pn.names_count)
|
||||
con_fprintf(f, "\n");
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void show_help(int verbose)
|
||||
{
|
||||
FILE *f = con_term;
|
||||
int fg;
|
||||
@@ -103,8 +178,8 @@ void show_help(int x)
|
||||
" -d decompress -l list compressed file\n"
|
||||
" -t test compressed file -V display version number\n"
|
||||
" -h give %s help -L display software license\n%s",
|
||||
x == 0 ? "" : " --best compress best (can be very slow for big files)\n",
|
||||
x == 0 ? "more" : "this", x == 0 ? "" : "\n");
|
||||
verbose == 0 ? "" : " --best compress best (can be slow for big files)\n",
|
||||
verbose == 0 ? "more" : "this", verbose == 0 ? "" : "\n");
|
||||
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Options:\n");
|
||||
@@ -112,22 +187,29 @@ void show_help(int x)
|
||||
|
||||
con_fprintf(f,
|
||||
" -q be quiet -v be verbose\n"
|
||||
" -oFILE write output to `FILE'\n"
|
||||
" -oFILE write output to 'FILE'\n"
|
||||
//" -f force overwrite of output files and compression of suspicious files\n"
|
||||
" -f force compression of suspicious files\n"
|
||||
"%s%s"
|
||||
, (x == 0) ? " -k keep backup files\n" : ""
|
||||
, (verbose == 0) ? " -k keep backup files\n" : ""
|
||||
#if 1
|
||||
, (x > 0) ? " --no-color, --mono, --color, --no-progress change look\n" : ""
|
||||
, (verbose > 0) ? " --no-color, --mono, --color, --no-progress change look\n" : ""
|
||||
#else
|
||||
, ""
|
||||
#endif
|
||||
);
|
||||
|
||||
if (x > 0)
|
||||
if (verbose > 0)
|
||||
{
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"\nBackup options:\n");
|
||||
con_fprintf(f,"\nCompression tuning options:\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f,
|
||||
" --brute try all available compression methods & filters [slow]\n"
|
||||
" --ultra-brute try even more compression variants [very slow]\n"
|
||||
"\n");
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Backup options:\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f,
|
||||
" -k, --backup keep backup files\n"
|
||||
@@ -138,17 +220,15 @@ void show_help(int x)
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f,
|
||||
" --overlay=copy copy any extra data attached to the file [default]\n"
|
||||
" --overlay=strip strip any extra data attached to the file [dangerous]\n"
|
||||
" --overlay=strip strip any extra data attached to the file [DANGEROUS]\n"
|
||||
" --overlay=skip don't compress a file with an overlay\n"
|
||||
"\n");
|
||||
#if 1
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Options for atari/tos:\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f,
|
||||
" --all-methods try all available compression methods\n"
|
||||
"\n");
|
||||
#endif
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Options for djgpp2/coff:\n");
|
||||
fg = con_fg(f,fg);
|
||||
@@ -190,16 +270,16 @@ void show_help(int x)
|
||||
" --script=/path/upxX use path/upxX as decompressor\n"
|
||||
"\n");
|
||||
#endif
|
||||
#if 1
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Options for ps1/exe:\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f,
|
||||
" --all-methods try all available compression methods\n"
|
||||
" --no-align don't align to mode2 sector format\n"
|
||||
" --8-bit uses 8 bit size compression [default: 32 bit]\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"
|
||||
"\n");
|
||||
#endif
|
||||
#if 1
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Options for tmt/adam:\n");
|
||||
fg = con_fg(f,fg);
|
||||
@@ -207,16 +287,13 @@ void show_help(int x)
|
||||
" --all-methods try all available compression methods\n"
|
||||
" --all-filters try all available preprocessing filters\n"
|
||||
"\n");
|
||||
#endif
|
||||
#if 1
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Options for [b]vmlinuz/386\n");
|
||||
con_fprintf(f,"Options for vmlinuz/386\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f,
|
||||
" --all-methods try all available compression methods\n"
|
||||
" --all-filters try all available preprocessing filters\n"
|
||||
"\n");
|
||||
#endif
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Options for watcom/le:\n");
|
||||
fg = con_fg(f,fg);
|
||||
@@ -224,7 +301,7 @@ void show_help(int x)
|
||||
" --le produce LE output [default: EXE]\n"
|
||||
"\n");
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"Options for win32/pe & rtm32/pe:\n");
|
||||
con_fprintf(f,"Options for win32/pe, rtm32/pe & arm/pe:\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f,
|
||||
" --compress-exports=0 do not compress the export section\n"
|
||||
@@ -232,7 +309,9 @@ void show_help(int x)
|
||||
" --compress-icons=0 do not compress any icons\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=3 compress all icons\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=1 strip relocations [default]\n"
|
||||
" --all-methods try all available compression methods\n"
|
||||
@@ -240,34 +319,23 @@ void show_help(int x)
|
||||
"\n");
|
||||
}
|
||||
|
||||
con_fprintf(f,
|
||||
"file.. executables to (de)compress\n"
|
||||
"\n");
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"This version supports:\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f," "
|
||||
"atari/tos, "
|
||||
"bvmlinuz/386, "
|
||||
"djgpp2/coff, "
|
||||
"dos/com, "
|
||||
"dos/exe, "
|
||||
"dos/sys,\n "
|
||||
//"elks/8086, "
|
||||
"linux/386, "
|
||||
"linux/elf386, "
|
||||
"linux/sh386, "
|
||||
"ps1/exe, "
|
||||
"rtm32/pe, "
|
||||
"tmt/adam,\n "
|
||||
"vmlinuz/386, "
|
||||
"watcom/le, "
|
||||
//"win16/ne, "
|
||||
"win32/pe"
|
||||
"\n\nUPX comes with ABSOLUTELY NO WARRANTY; for details visit http://upx.sf.net\n"
|
||||
//"\n\nUPX comes with ABSOLUTELY NO WARRANTY; for details type `upx -L'.\n"
|
||||
"");
|
||||
con_fprintf(f, "file.. executables to (de)compress\n");
|
||||
|
||||
if (verbose > 0)
|
||||
{
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
con_fprintf(f,"\nThis version supports:\n");
|
||||
fg = con_fg(f,fg);
|
||||
show_all_packers(f, verbose);
|
||||
}
|
||||
else
|
||||
{
|
||||
con_fprintf(f,"\nType '%s --help' for more detailed help.\n", progname);
|
||||
}
|
||||
|
||||
con_fprintf(f,"\nUPX comes with ABSOLUTELY NO WARRANTY; for details visit http://upx.sf.net\n"
|
||||
// "\nUPX comes with ABSOLUTELY NO WARRANTY; for details type 'upx -L'.\n"
|
||||
"");
|
||||
|
||||
#if defined(DEBUG) || defined(TESTING)
|
||||
fg = con_fg(f,FG_RED);
|
||||
@@ -281,6 +349,8 @@ void show_help(int x)
|
||||
"\n");
|
||||
fg = con_fg(f,fg);
|
||||
#endif
|
||||
|
||||
UNUSED(fg);
|
||||
}
|
||||
|
||||
|
||||
@@ -320,6 +390,8 @@ void show_license(void)
|
||||
" <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>\n"
|
||||
);
|
||||
fg = con_fg(f,fg);
|
||||
|
||||
UNUSED(fg);
|
||||
}
|
||||
|
||||
|
||||
@@ -329,25 +401,43 @@ void show_license(void)
|
||||
|
||||
void show_version(int x)
|
||||
{
|
||||
FILE *f = stdout;
|
||||
FILE *fp = stdout;
|
||||
const char *v;
|
||||
UNUSED(x);
|
||||
UNUSED(v);
|
||||
|
||||
#if 0 && defined(__GNUC__)
|
||||
fprintf(f,"upx %s (gcc 0x%lx)\n", UPX_VERSION_STRING, __GNUC_VERSION_HEX__);
|
||||
#else
|
||||
fprintf(f,"upx %s\n", UPX_VERSION_STRING);
|
||||
#endif
|
||||
fprintf(fp, "upx %s\n", UPX_VERSION_STRING);
|
||||
#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
|
||||
#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
|
||||
fprintf(f,"Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer\n");
|
||||
fprintf(f,"Copyright (C) 1996-2002 Laszlo Molnar\n");
|
||||
fprintf(f,"Copyright (C) 2000-2002 John F. Reiser\n");
|
||||
fprintf(f,"Copyright (C) 2002 Jens Medoch\n");
|
||||
fprintf(f,"UPX comes with ABSOLUTELY NO WARRANTY; for details type `%s -L'.\n", progname);
|
||||
#if defined(WITH_ZLIB)
|
||||
v = upx_zlib_version_string();
|
||||
if (v != NULL && v[0])
|
||||
fprintf(fp, "zlib data compression library %s\n", v);
|
||||
#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-2007 Markus Franz Xaver Johannes Oberhumer\n");
|
||||
fprintf(fp, "Copyright (C) 1996-2007 Laszlo Molnar\n");
|
||||
fprintf(fp, "Copyright (C) 2000-2007 John F. Reiser\n");
|
||||
fprintf(fp, "Copyright (C) 2002-2007 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.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+4
-4
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -219,8 +219,8 @@ protected:
|
||||
|
||||
private:
|
||||
// disable copy and assignment
|
||||
LeFile(LeFile const &); // {}
|
||||
LeFile& operator= (LeFile const &); // { return *this; }
|
||||
LeFile(const LeFile &); // {}
|
||||
LeFile& operator= (const LeFile &); // { return *this; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
+855
-157
File diff suppressed because it is too large
Load Diff
+195
-46
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -30,64 +30,213 @@
|
||||
#define __UPX_LINKER_H
|
||||
|
||||
|
||||
class Linker
|
||||
/*************************************************************************
|
||||
// ElfLinker
|
||||
**************************************************************************/
|
||||
|
||||
class ElfLinker : private noncopyable
|
||||
{
|
||||
friend class Packer;
|
||||
public:
|
||||
Linker(const void *pdata, int plen, int pinfo);
|
||||
virtual ~Linker();
|
||||
int addSection(const char *sect);
|
||||
void addSection(const char *sname, const void *sdata, unsigned len);
|
||||
const char *getLoader(int *llen);
|
||||
int getSection(const char *name, int *slen) const;
|
||||
int getLoaderSize() const { return olen; }
|
||||
void setLoaderAlignOffset(int phase);
|
||||
const N_BELE_RTP::AbstractPolicy *bele;
|
||||
protected:
|
||||
struct Section;
|
||||
struct Symbol;
|
||||
struct Relocation;
|
||||
|
||||
upx_byte *input;
|
||||
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:
|
||||
// little endian
|
||||
virtual unsigned get32(const void *b) const { return get_le32(b); }
|
||||
virtual void set32(void *b, unsigned v) const { set_le32(b, v); }
|
||||
void preprocessSections(char *start, char *end);
|
||||
void preprocessSymbols(char *start, char *end);
|
||||
void preprocessRelocations(char *start, char *end);
|
||||
Section *findSection(const char *name, bool fatal=true) const;
|
||||
Symbol *findSymbol(const char *name, bool fatal=true) const;
|
||||
|
||||
private:
|
||||
struct section;
|
||||
struct jump;
|
||||
Symbol *addSymbol(const char *name, const char *section, unsigned offset);
|
||||
Relocation *addRelocation(const char *section, unsigned off, const char *type,
|
||||
const char *symbol, unsigned add);
|
||||
|
||||
char *iloader, *oloader;
|
||||
int ilen, olen;
|
||||
int info;
|
||||
jump *jumps;
|
||||
int njumps;
|
||||
section *sections;
|
||||
int nsections;
|
||||
int frozen;
|
||||
int align_hack;
|
||||
int align_offset;
|
||||
public:
|
||||
ElfLinker();
|
||||
virtual ~ElfLinker();
|
||||
|
||||
private:
|
||||
// disable copy and assignment
|
||||
Linker(Linker const &); // {}
|
||||
Linker& operator= (Linker const &); // { return *this; }
|
||||
virtual void init(const void *pdata, int plen);
|
||||
//virtual void setLoaderAlignOffset(int phase);
|
||||
virtual int addLoader(const char *sname);
|
||||
void addLoader(const char *s, va_list ap);
|
||||
#if 1 && (ACC_CC_GNUC >= 0x040100)
|
||||
void __acc_cdecl_va addLoaderVA(const char *s, ...) __attribute__((__sentinel__));
|
||||
#else
|
||||
void __acc_cdecl_va addLoaderVA(const char *s, ...);
|
||||
#endif
|
||||
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 noncopyable
|
||||
{
|
||||
typedef Linker super;
|
||||
public:
|
||||
BeLinker(const void *pdata, int plen, int pinfo) :
|
||||
super(pdata, plen, pinfo) { }
|
||||
char *name;
|
||||
void *input;
|
||||
upx_byte *output;
|
||||
unsigned size;
|
||||
unsigned offset;
|
||||
unsigned p2align; // log2
|
||||
Section *next;
|
||||
|
||||
protected:
|
||||
// big endian
|
||||
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(BeLinker const &); // {}
|
||||
BeLinker& operator= (BeLinker const &); // { return *this; }
|
||||
Section(const char *n, const void *i, unsigned s, unsigned a=0);
|
||||
~Section();
|
||||
};
|
||||
|
||||
|
||||
struct ElfLinker::Symbol : private noncopyable
|
||||
{
|
||||
char *name;
|
||||
Section *section;
|
||||
unsigned offset;
|
||||
|
||||
Symbol(const char *n, Section *s, unsigned o);
|
||||
~Symbol();
|
||||
};
|
||||
|
||||
|
||||
struct ElfLinker::Relocation : private noncopyable
|
||||
{
|
||||
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 ElfLinkerMipsBE : public ElfLinker
|
||||
{
|
||||
typedef ElfLinker super;
|
||||
public:
|
||||
ElfLinkerMipsBE() { bele = &N_BELE_RTP::be_policy; }
|
||||
protected:
|
||||
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 */
|
||||
|
||||
|
||||
|
||||
+493
-245
File diff suppressed because it is too large
Load Diff
+146
-41
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -34,11 +34,40 @@
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
MemBuffer::MemBuffer(unsigned size) :
|
||||
ptr(NULL), alloc_ptr(NULL), alloc_size(0)
|
||||
static int use_mcheck = -1;
|
||||
|
||||
static int mcheck_init()
|
||||
{
|
||||
if (size > 0)
|
||||
alloc(size, 0);
|
||||
if (use_mcheck < 0)
|
||||
{
|
||||
use_mcheck = 1;
|
||||
#if defined(WITH_VALGRIND) && defined(RUNNING_ON_VALGRIND)
|
||||
if (RUNNING_ON_VALGRIND)
|
||||
{
|
||||
//fprintf(stderr, "upx: detected RUNNING_ON_VALGRIND\n");
|
||||
use_mcheck = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return use_mcheck;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
MemBuffer::MemBuffer() :
|
||||
b(NULL), b_size(0)
|
||||
{
|
||||
if (use_mcheck < 0)
|
||||
mcheck_init();
|
||||
}
|
||||
|
||||
MemBuffer::MemBuffer(unsigned size) :
|
||||
b(NULL), b_size(0)
|
||||
{
|
||||
alloc(size);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,59 +78,135 @@ MemBuffer::~MemBuffer()
|
||||
|
||||
void MemBuffer::dealloc()
|
||||
{
|
||||
if (alloc_ptr)
|
||||
::free(alloc_ptr);
|
||||
alloc_ptr = ptr = NULL;
|
||||
alloc_size = 0;
|
||||
if (b)
|
||||
{
|
||||
checkState();
|
||||
if (use_mcheck)
|
||||
{
|
||||
// remove magic constants
|
||||
set_be32(b - 8, 0);
|
||||
set_be32(b - 4, 0);
|
||||
set_be32(b + b_size, 0);
|
||||
set_be32(b + b_size + 4, 0);
|
||||
//
|
||||
::free(b - 16);
|
||||
}
|
||||
else
|
||||
::free(b);
|
||||
b = NULL;
|
||||
b_size = 0;
|
||||
}
|
||||
else
|
||||
assert(b_size == 0);
|
||||
}
|
||||
|
||||
|
||||
unsigned MemBuffer::getSize() const
|
||||
unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned extra)
|
||||
{
|
||||
if (!alloc_ptr)
|
||||
return 0;
|
||||
unsigned size = alloc_size - (ptr - alloc_ptr);
|
||||
assert((int)size > 0);
|
||||
assert((int)uncompressed_size > 0);
|
||||
assert((int)extra >= 0);
|
||||
unsigned size = uncompressed_size + uncompressed_size/8 + 256 + extra;
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned MemBuffer::getSizeForUncompression(unsigned uncompressed_size, unsigned extra)
|
||||
{
|
||||
assert((int)uncompressed_size > 0);
|
||||
assert((int)extra >= 0);
|
||||
unsigned size = uncompressed_size + extra;
|
||||
// size += 512; // 512 safety bytes
|
||||
// INFO: 3 bytes are the allowed overrun for the i386 asm_fast decompressors
|
||||
#if (ACC_ARCH_I386)
|
||||
size += 3;
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
void MemBuffer::alloc(unsigned size, unsigned base_offset)
|
||||
void MemBuffer::allocForCompression(unsigned uncompressed_size, unsigned extra)
|
||||
{
|
||||
// NOTE: we don't automaticlly free a used buffer
|
||||
assert(alloc_ptr == NULL);
|
||||
assert((int)size > 0);
|
||||
size = base_offset + size;
|
||||
alloc_ptr = (unsigned char *) malloc(size);
|
||||
if (!alloc_ptr)
|
||||
unsigned size = getSizeForCompression(uncompressed_size, extra);
|
||||
alloc(size);
|
||||
}
|
||||
|
||||
|
||||
void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra)
|
||||
{
|
||||
unsigned size = getSizeForUncompression(uncompressed_size, extra);
|
||||
alloc(size);
|
||||
}
|
||||
|
||||
|
||||
void MemBuffer::fill(unsigned off, unsigned len, int value)
|
||||
{
|
||||
checkState();
|
||||
assert((int)off >= 0);
|
||||
assert((int)len >= 0);
|
||||
assert(off <= b_size);
|
||||
assert(len <= b_size);
|
||||
assert(off + len <= b_size);
|
||||
if (len > 0)
|
||||
memset(b + off, value, len);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#define PTR(p) ((unsigned) ((acc_uintptr_t)(p) & 0xffffffff))
|
||||
#define MAGIC1(p) (PTR(p) ^ 0xfefdbeeb)
|
||||
#define MAGIC2(p) (PTR(p) ^ 0xfefdbeeb ^ 0x80024001)
|
||||
|
||||
unsigned MemBuffer::global_alloc_counter = 0;
|
||||
|
||||
|
||||
void MemBuffer::checkState() const
|
||||
{
|
||||
if (!b)
|
||||
throwInternalError("block not allocated");
|
||||
if (use_mcheck)
|
||||
{
|
||||
//throw bad_alloc();
|
||||
throwCantPack("out of memory");
|
||||
//exit(1);
|
||||
if (get_be32(b - 4) != MAGIC1(b))
|
||||
throwInternalError("memory clobbered before allocated block 1");
|
||||
if (get_be32(b - 8) != b_size)
|
||||
throwInternalError("memory clobbered before allocated block 2");
|
||||
if (get_be32(b + b_size) != MAGIC2(b))
|
||||
throwInternalError("memory clobbered past end of allocated block");
|
||||
}
|
||||
alloc_size = size;
|
||||
ptr = alloc_ptr + base_offset;
|
||||
assert((int)b_size > 0);
|
||||
}
|
||||
|
||||
|
||||
void MemBuffer::alloc(unsigned size)
|
||||
{
|
||||
alloc(size, 0);
|
||||
}
|
||||
if (use_mcheck < 0)
|
||||
mcheck_init();
|
||||
|
||||
// NOTE: we don't automatically free a used buffer
|
||||
assert(b == NULL);
|
||||
assert(b_size == 0);
|
||||
//
|
||||
assert((int)size > 0);
|
||||
unsigned total = use_mcheck ? size + 32 : size;
|
||||
assert((int)total > 0);
|
||||
unsigned char *p = (unsigned char *) malloc(total);
|
||||
if (!p)
|
||||
throwOutOfMemoryException();
|
||||
b_size = size;
|
||||
if (use_mcheck)
|
||||
{
|
||||
b = p + 16;
|
||||
// store magic constants to detect buffer overruns
|
||||
set_be32(b - 8, b_size);
|
||||
set_be32(b - 4, MAGIC1(b));
|
||||
set_be32(b + b_size, MAGIC2(b));
|
||||
set_be32(b + b_size + 4, global_alloc_counter++);
|
||||
}
|
||||
else
|
||||
b = p ;
|
||||
|
||||
void MemBuffer::allocForCompression(unsigned uncompressed_size)
|
||||
{
|
||||
assert((int)uncompressed_size > 0);
|
||||
alloc(uncompressed_size + uncompressed_size/8 + 256, 0);
|
||||
}
|
||||
|
||||
|
||||
void MemBuffer::allocForUncompression(unsigned uncompressed_size)
|
||||
{
|
||||
assert((int)uncompressed_size > 0);
|
||||
//alloc(uncompressed_size + 3 + 512, 0); // 512 safety bytes
|
||||
alloc(uncompressed_size + 3, 0); // 3 bytes for asm_fast decompresion
|
||||
//fill(0, b_size, (rand() & 0xff) | 1); // debug
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -37,46 +37,44 @@
|
||||
class MemBuffer
|
||||
{
|
||||
public:
|
||||
MemBuffer(unsigned size=0);
|
||||
MemBuffer();
|
||||
explicit MemBuffer(unsigned size);
|
||||
~MemBuffer();
|
||||
|
||||
static unsigned getSizeForCompression(unsigned uncompressed_size, unsigned extra=0);
|
||||
static unsigned getSizeForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
||||
|
||||
void alloc(unsigned size);
|
||||
void allocForCompression(unsigned uncompressed_size);
|
||||
void allocForUncompression(unsigned uncompressed_size);
|
||||
void allocForCompression(unsigned uncompressed_size, unsigned extra=0);
|
||||
void allocForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
||||
|
||||
void dealloc();
|
||||
|
||||
const unsigned char *getBuf() const { return ptr; }
|
||||
unsigned getSize() const;
|
||||
void checkState() const;
|
||||
|
||||
operator unsigned char * () { return ptr; }
|
||||
//operator const unsigned char * () const { return ptr; }
|
||||
unsigned getSize() const { return b_size; }
|
||||
|
||||
void *getVoidPtr() { return (void *) ptr; }
|
||||
const void *getVoidPtr() const { return (const void *) ptr; }
|
||||
operator unsigned char * () { return b; }
|
||||
//operator const unsigned char * () const { return b; }
|
||||
void *getVoidPtr() { return (void *) b; }
|
||||
const void *getVoidPtr() const { return (const void *) b; }
|
||||
|
||||
void fill(unsigned off, unsigned len, int value);
|
||||
void clear(unsigned off, unsigned len) { fill(off, len, 0); }
|
||||
void clear() { fill(0, b_size, 0); }
|
||||
|
||||
private:
|
||||
void alloc(unsigned size, unsigned base_offset);
|
||||
unsigned char *b;
|
||||
unsigned b_size;
|
||||
|
||||
protected:
|
||||
unsigned char *ptr;
|
||||
unsigned char *alloc_ptr;
|
||||
unsigned alloc_size;
|
||||
static unsigned global_alloc_counter;
|
||||
|
||||
private:
|
||||
// disable copy and assignment
|
||||
MemBuffer(MemBuffer const &); // {}
|
||||
MemBuffer& operator= (MemBuffer const &); // { return *this; }
|
||||
MemBuffer(const MemBuffer &); // {}
|
||||
MemBuffer& operator= (const MemBuffer &); // { return *this; }
|
||||
|
||||
// disable dynamic allocation
|
||||
#ifndef new
|
||||
static void *operator new (size_t); // {}
|
||||
static void *operator new[] (size_t); // {}
|
||||
#endif
|
||||
#ifndef delete
|
||||
//static void operator delete (void *) {}
|
||||
//static void operator delete[] (void *) {}
|
||||
#endif
|
||||
DISABLE_NEW_DELETE
|
||||
};
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
+6713
File diff suppressed because it is too large
Load Diff
+27
-15
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -66,9 +66,9 @@ void printClearLine(FILE *f)
|
||||
static void pr_print(bool c, const char *msg)
|
||||
{
|
||||
if (c && !opt->to_stdout)
|
||||
con_fprintf(stderr,msg);
|
||||
con_fprintf(stderr, "%s", msg);
|
||||
else
|
||||
fprintf(stderr,msg);
|
||||
fprintf(stderr, "%s", msg);
|
||||
}
|
||||
|
||||
static void pr_error(const char *iname, const char *msg, bool is_warning)
|
||||
@@ -88,7 +88,7 @@ static void pr_error(const char *iname, const char *msg, bool is_warning)
|
||||
// This hack is needed, otherwise error messages may get lost
|
||||
// when the cursor is not yet at the bottom of the screen.
|
||||
// At least I can use some colors then...
|
||||
bool c = isatty(STDERR_FILENO) ? 1 : 0;
|
||||
bool c = acc_isatty(STDERR_FILENO) ? 1 : 0;
|
||||
|
||||
int fg = con_fg(stderr,FG_BRTRED);
|
||||
upx_snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),"%s: ", progname);
|
||||
@@ -103,23 +103,35 @@ static void pr_error(const char *iname, const char *msg, bool is_warning)
|
||||
fg = con_fg(stderr,fg);
|
||||
|
||||
UNUSED(is_warning);
|
||||
UNUSED(fg);
|
||||
}
|
||||
|
||||
|
||||
void printErr(const char *iname, const Throwable *e)
|
||||
{
|
||||
char buf[1024];
|
||||
size_t l;
|
||||
|
||||
upx_snprintf(buf, sizeof(buf), "%s", prettyName(typeid(*e)));
|
||||
if (e->getMsg())
|
||||
upx_snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),": %s", e->getMsg());
|
||||
if (e->getErrno())
|
||||
upx_snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),": %s", strerror(e->getErrno()));
|
||||
upx_snprintf(buf, sizeof(buf), "%s", prettyName(typeid(*e).name()));
|
||||
l = strlen(buf);
|
||||
if (l < sizeof(buf) && e->getMsg())
|
||||
upx_snprintf(buf+l, sizeof(buf)-l, ": %s", e->getMsg());
|
||||
l = strlen(buf);
|
||||
if (l < sizeof(buf) && e->getErrno()) {
|
||||
upx_snprintf(buf+l, sizeof(buf)-l, ": %s", strerror(e->getErrno()));
|
||||
#if 1
|
||||
// some compilers (e.g. Borland C++) put a trailing '\n'
|
||||
// into strerror() result
|
||||
l = strlen(buf);
|
||||
while (l-- > 0 && (buf[l] == '\n' || buf[l] == ' '))
|
||||
buf[l] = 0;
|
||||
#endif
|
||||
}
|
||||
pr_error(iname,buf,e->isWarning());
|
||||
}
|
||||
|
||||
|
||||
void printErr(const char *iname, const char *format, ...)
|
||||
void __acc_cdecl_va printErr(const char *iname, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[1024];
|
||||
@@ -132,7 +144,7 @@ void printErr(const char *iname, const char *format, ...)
|
||||
}
|
||||
|
||||
|
||||
void printWarn(const char *iname, const char *format, ...)
|
||||
void __acc_cdecl_va printWarn(const char *iname, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[1024];
|
||||
@@ -189,7 +201,7 @@ void infoHeader()
|
||||
info_header = 0;
|
||||
}
|
||||
|
||||
void infoHeader(const char *format, ...)
|
||||
void __acc_cdecl_va infoHeader(const char *format, ...)
|
||||
{
|
||||
if (opt->info_mode <= 0)
|
||||
return;
|
||||
@@ -203,7 +215,7 @@ void infoHeader(const char *format, ...)
|
||||
}
|
||||
|
||||
|
||||
void info(const char *format, ...)
|
||||
void __acc_cdecl_va info(const char *format, ...)
|
||||
{
|
||||
if (opt->info_mode <= 0)
|
||||
return;
|
||||
@@ -218,7 +230,7 @@ void info(const char *format, ...)
|
||||
}
|
||||
|
||||
|
||||
void infoWarning(const char *format, ...)
|
||||
void __acc_cdecl_va infoWarning(const char *format, ...)
|
||||
{
|
||||
if (opt->info_mode <= 0)
|
||||
{
|
||||
|
||||
+40
-30
@@ -21,11 +21,22 @@
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#include "tailor.h"
|
||||
|
||||
#undef PROGNAME
|
||||
#if 0
|
||||
#ifndef EOF
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
#define PROGNAME(x) (x)
|
||||
#else
|
||||
#include "conf.h"
|
||||
static const char *my_progname(const char *argv0)
|
||||
{
|
||||
return progname ? progname : argv0;
|
||||
}
|
||||
#define PROGNAME(x) my_progname(x)
|
||||
#endif
|
||||
|
||||
|
||||
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
|
||||
@@ -54,8 +65,6 @@
|
||||
#define optind mfx_optind
|
||||
#define opterr mfx_opterr
|
||||
#define optopt mfx_optopt
|
||||
#define my_index strchr
|
||||
#define my_strlen strlen
|
||||
#undef BAD_OPTION
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
@@ -167,7 +176,7 @@ static int last_nonopt;
|
||||
|
||||
static void exchange (char **argv)
|
||||
{
|
||||
char *temp, **first, **last;
|
||||
char *temp; char **first, **last;
|
||||
|
||||
/* Reverse all the elements [first_nonopt, optind) */
|
||||
first = &argv[first_nonopt];
|
||||
@@ -382,15 +391,10 @@ static int _getopt_internal (int argc, char **argv, const char *optstring,
|
||||
int indfound = 0;
|
||||
int needexact = 0;
|
||||
|
||||
#if defined(DOSISH)
|
||||
/* allow `--option#value' because you cannout assign a '='
|
||||
to an environment variable under DOS command.com */
|
||||
while (*s && *s != '=' && * s != '#')
|
||||
s++;
|
||||
#else
|
||||
while (*s && *s != '=')
|
||||
s++;
|
||||
#endif
|
||||
|
||||
/* Test all options for either exact match or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name;
|
||||
@@ -399,7 +403,7 @@ static int _getopt_internal (int argc, char **argv, const char *optstring,
|
||||
{
|
||||
if (p->has_arg & 0x10)
|
||||
needexact = 1;
|
||||
if ((unsigned) (s - nextchar) == my_strlen (p->name))
|
||||
if ((unsigned) (s - nextchar) == strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
@@ -423,8 +427,8 @@ static int _getopt_internal (int argc, char **argv, const char *optstring,
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: unrecognized option `%s'\n",
|
||||
argv[0], argv[optind]);
|
||||
nextchar += my_strlen (nextchar);
|
||||
PROGNAME(argv[0]), argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
return BAD_OPTION;
|
||||
}
|
||||
@@ -432,8 +436,8 @@ static int _getopt_internal (int argc, char **argv, const char *optstring,
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
||||
argv[0], argv[optind]);
|
||||
nextchar += my_strlen (nextchar);
|
||||
PROGNAME(argv[0]), argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
return BAD_OPTION;
|
||||
}
|
||||
@@ -459,14 +463,14 @@ static int _getopt_internal (int argc, char **argv, const char *optstring,
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
"%s: option `--%s' doesn't allow an argument\n",
|
||||
argv[0], pfound->name);
|
||||
PROGNAME(argv[0]), pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
"%s: option `%c%s' doesn't allow an argument\n",
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
PROGNAME(argv[0]), argv[optind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += my_strlen (nextchar);
|
||||
nextchar += strlen (nextchar);
|
||||
return BAD_OPTION;
|
||||
}
|
||||
}
|
||||
@@ -482,13 +486,13 @@ static int _getopt_internal (int argc, char **argv, const char *optstring,
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `--%s%s' requires an argument\n",
|
||||
argv[0], pfound->name,
|
||||
PROGNAME(argv[0]), pfound->name,
|
||||
(pfound->has_arg & 0x20) ? "=" : "");
|
||||
nextchar += my_strlen (nextchar);
|
||||
nextchar += strlen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : BAD_OPTION;
|
||||
}
|
||||
}
|
||||
nextchar += my_strlen (nextchar);
|
||||
nextchar += strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
@@ -506,31 +510,31 @@ static int _getopt_internal (int argc, char **argv, const char *optstring,
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
|| strchr (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr, "%s: unrecognized option `--%s'\n",
|
||||
argv[0], nextchar);
|
||||
PROGNAME(argv[0]), nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
||||
argv[0], argv[optind][0], nextchar);
|
||||
PROGNAME(argv[0]), argv[optind][0], nextchar);
|
||||
}
|
||||
nextchar = empty_string;
|
||||
optind++;
|
||||
return BAD_OPTION;
|
||||
}
|
||||
ambig = ambig;
|
||||
(void) &ambig; /* UNUSED */
|
||||
}
|
||||
|
||||
/* Look at and handle the next option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
const char *temp = my_index (optstring, c);
|
||||
const char *temp = strchr (optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
@@ -543,12 +547,12 @@ static int _getopt_internal (int argc, char **argv, const char *optstring,
|
||||
#if 0
|
||||
if (c < 040 || c >= 0177)
|
||||
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
||||
argv[0], c);
|
||||
PROGNAME(argv[0]), c);
|
||||
else
|
||||
fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
|
||||
fprintf (stderr, "%s: unrecognized option `-%c'\n", PROGNAME(argv[0]), c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
|
||||
fprintf (stderr, "%s: illegal option -- %c\n", PROGNAME(argv[0]), c);
|
||||
#endif
|
||||
}
|
||||
optopt = c;
|
||||
@@ -584,11 +588,11 @@ static int _getopt_internal (int argc, char **argv, const char *optstring,
|
||||
{
|
||||
#if 0
|
||||
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
||||
argv[0], c);
|
||||
PROGNAME(argv[0]), c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: option requires an argument -- %c\n",
|
||||
argv[0], c);
|
||||
PROGNAME(argv[0]), c);
|
||||
#endif
|
||||
}
|
||||
optopt = c;
|
||||
@@ -694,3 +698,9 @@ main (argc, argv)
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
|
||||
+3
-3
@@ -19,7 +19,7 @@
|
||||
#define __MFX_GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
//extern "C" {
|
||||
/* extern "C" { */
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
@@ -96,7 +96,7 @@ int mfx_getopt_long(int argc, char **argv, const char *shortopts,
|
||||
const struct mfx_option *longopts, int *longind);
|
||||
|
||||
#ifdef __cplusplus
|
||||
//}
|
||||
/* } */
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_H */
|
||||
#endif /* __MFX_GETOPT_H */
|
||||
|
||||
+56
-30
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -47,25 +47,44 @@ struct options_t {
|
||||
|
||||
// compression options
|
||||
int method;
|
||||
int level; // compression level 1..10
|
||||
int filter; // preferred filter from Packer::getFilters()
|
||||
bool all_methods; // try all available compression methods ?
|
||||
bool all_filters; // try all available filters ?
|
||||
bool method_lzma_seen;
|
||||
bool method_nrv2b_seen;
|
||||
bool method_nrv2d_seen;
|
||||
bool method_nrv2e_seen;
|
||||
int level; // compression level 1..10
|
||||
int filter; // preferred filter from Packer::getFilters()
|
||||
bool ultra_brute;
|
||||
bool all_methods; // try all available compression methods ?
|
||||
bool all_methods_use_lzma;
|
||||
bool all_filters; // try all available filters ?
|
||||
bool no_filter; // force no filter
|
||||
bool exact; // user requires byte-identical decompression
|
||||
|
||||
// other options
|
||||
int backup;
|
||||
int console;
|
||||
int debug;
|
||||
int force;
|
||||
int info_mode;
|
||||
bool ignorewarn;
|
||||
bool no_env;
|
||||
bool no_progress;
|
||||
const char *output_name;
|
||||
bool preserve_mode;
|
||||
bool preserve_ownership;
|
||||
bool preserve_timestamp;
|
||||
int small;
|
||||
int verbose;
|
||||
bool to_stdout;
|
||||
|
||||
// debug options
|
||||
struct {
|
||||
int debug_level;
|
||||
bool disable_random_id; // for Packer::getRandomId()
|
||||
const char *dump_stub_loader;
|
||||
char fake_stub_version[4+1]; // for internal debugging
|
||||
char fake_stub_year[4+1]; // for internal debugging
|
||||
} debug;
|
||||
|
||||
// overlay handling
|
||||
enum {
|
||||
SKIP_OVERLAY = 0,
|
||||
@@ -74,16 +93,14 @@ struct options_t {
|
||||
};
|
||||
int overlay;
|
||||
|
||||
// compression runtime parameters - see struct ucl_compress_config_t
|
||||
struct {
|
||||
upx_uint max_offset;
|
||||
upx_uint max_match;
|
||||
int s_level;
|
||||
int h_level;
|
||||
int p_level;
|
||||
int c_flags;
|
||||
upx_uint m_size;
|
||||
} crp;
|
||||
// compression runtime parameters - see struct XXX_compress_config_t
|
||||
struct crp_t {
|
||||
lzma_compress_config_t crp_lzma;
|
||||
ucl_compress_config_t crp_ucl;
|
||||
zlib_compress_config_t crp_zlib;
|
||||
void reset() { crp_lzma.reset(); crp_ucl.reset(); crp_zlib.reset(); }
|
||||
};
|
||||
crp_t crp;
|
||||
|
||||
// CPU
|
||||
enum {
|
||||
@@ -99,38 +116,47 @@ struct options_t {
|
||||
|
||||
// options for various executable formats
|
||||
struct {
|
||||
bool force_stub;
|
||||
bool no_reloc;
|
||||
} dos;
|
||||
bool split_segments;
|
||||
} atari_tos;
|
||||
struct {
|
||||
bool coff;
|
||||
} djgpp2;
|
||||
} djgpp2_coff;
|
||||
struct {
|
||||
bool force_stub;
|
||||
bool no_reloc;
|
||||
} dos_exe;
|
||||
struct {
|
||||
bool boot_only;
|
||||
bool no_align;
|
||||
} ps1;
|
||||
struct {
|
||||
bool split_segments;
|
||||
} tos;
|
||||
bool do_8bit;
|
||||
bool do_8mb;
|
||||
} ps1_exe;
|
||||
struct {
|
||||
unsigned blocksize;
|
||||
bool force_execve; // force the linux/386 execve format
|
||||
bool 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 make_ptinterp; // make PT_INTERP [ignore current file!]
|
||||
unsigned char osabi0; // replacement if 0==.e_ident[EI_OSABI]
|
||||
enum { SCRIPT_MAX = 32 };
|
||||
const char *script_name;
|
||||
} unix;
|
||||
} o_unix;
|
||||
struct {
|
||||
bool le;
|
||||
} wcle;
|
||||
} watcom_le;
|
||||
struct {
|
||||
int compress_exports;
|
||||
int compress_icons;
|
||||
int compress_resources;
|
||||
signed char compress_rt[25]; // 25 == RT_LAST
|
||||
int strip_relocs;
|
||||
} w32pe;
|
||||
const char *keep_resource;
|
||||
} win32_pe;
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
extern struct options_t * volatile opt;
|
||||
extern struct options_t *opt;
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
+1149
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
/* p_armpe.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 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
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_ARMPE_H
|
||||
#define __UPX_P_ARMPE_H
|
||||
|
||||
/*************************************************************************
|
||||
// arm/pe
|
||||
**************************************************************************/
|
||||
|
||||
class PackArmPe : public PeFile
|
||||
{
|
||||
typedef PeFile super;
|
||||
|
||||
public:
|
||||
PackArmPe(InputFile *f);
|
||||
virtual ~PackArmPe();
|
||||
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
|
||||
virtual const char *getName() const { return "arm/pe"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "arm-wince.pe"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
virtual void pack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
virtual int canUnpack();
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
virtual unsigned processImports();
|
||||
virtual void processImports(unsigned, unsigned);
|
||||
virtual void rebuildImports(upx_byte *&);
|
||||
|
||||
virtual void processTls(Interval *);
|
||||
|
||||
bool use_thumb_stub;
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
+35
-38
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -31,9 +31,10 @@
|
||||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_com.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
#include "stub/l_com.h"
|
||||
#include "stub/i086-dos16.com.h"
|
||||
|
||||
//#define TESTING
|
||||
|
||||
@@ -44,16 +45,11 @@ static const
|
||||
|
||||
const int *PackCom::getCompressionMethods(int method, int level) const
|
||||
{
|
||||
static const int m_nrv2b[] = { M_NRV2B_LE16, -1 };
|
||||
if (M_IS_NRV2B(method))
|
||||
return m_nrv2b;
|
||||
static const int m_nrv2b[] = { M_NRV2B_LE16, M_END };
|
||||
#if 0
|
||||
// NOT IMPLEMENTED
|
||||
static const int m_nrv2d[] = { M_NRV2D_LE16, -1 };
|
||||
if (M_IS_NRV2D(method))
|
||||
return m_nrv2d;
|
||||
static const int m_nrv2d[] = { M_NRV2D_LE16, M_END };
|
||||
#endif
|
||||
UNUSED(level);
|
||||
UNUSED(method); UNUSED(level);
|
||||
return m_nrv2b;
|
||||
}
|
||||
|
||||
@@ -62,7 +58,7 @@ const int *PackCom::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0x06, 0x03, 0x04, 0x01, 0x05, 0x02,
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
@@ -98,10 +94,9 @@ void PackCom::patchLoader(OutputFile *fo,
|
||||
upx_byte *loader, int lsize,
|
||||
unsigned calls)
|
||||
{
|
||||
const int filter_id = ph.filter;
|
||||
const int e_len = getLoaderSectionStart("COMCUTPO");
|
||||
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);
|
||||
|
||||
const unsigned upper_end = ph.u_len + ph.overlap_overhead + d_len + 0x100;
|
||||
@@ -111,22 +106,19 @@ void PackCom::patchLoader(OutputFile *fo,
|
||||
if (upper_end + stacksize > 0xfffe)
|
||||
throwCantPack("file is too big for dos/com");
|
||||
|
||||
if (filter_id)
|
||||
{
|
||||
assert(calls > 0);
|
||||
patch_le16(loader,lsize,"CT",calls);
|
||||
}
|
||||
linker->defineSymbol("calltrick_calls", calls);
|
||||
linker->defineSymbol("sp_limit", upper_end + stacksize);
|
||||
linker->defineSymbol("bytes_to_copy", ph.c_len + lsize);
|
||||
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);
|
||||
|
||||
// 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
|
||||
fo->write(loader,e_len); // entry
|
||||
fo->write(obuf,ph.c_len);
|
||||
@@ -139,18 +131,18 @@ void PackCom::patchLoader(OutputFile *fo,
|
||||
}
|
||||
|
||||
|
||||
int PackCom::buildLoader(const Filter *ft)
|
||||
void PackCom::buildLoader(const Filter *ft)
|
||||
{
|
||||
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
||||
addLoader("COMMAIN1""COMSUBSI",
|
||||
initLoader(stub_i086_dos16_com, sizeof(stub_i086_dos16_com));
|
||||
addLoader("COMMAIN1",
|
||||
ph.first_offset_found == 1 ? "COMSBBBP" : "",
|
||||
"COMPSHDI",
|
||||
ft->id ? "COMCALLT" : "",
|
||||
"COMMAIN2""UPX1HEAD""COMCUTPO""NRV2B160",
|
||||
"COMMAIN2,UPX1HEAD,COMCUTPO,NRV2B160",
|
||||
ft->id ? "NRVDDONE" : "NRVDRETU",
|
||||
"NRVDECO1",
|
||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
||||
"NRVDECO2""NRV2B169",
|
||||
"NRVDECO2",
|
||||
NULL
|
||||
);
|
||||
if (ft->id)
|
||||
@@ -158,7 +150,6 @@ int PackCom::buildLoader(const Filter *ft)
|
||||
assert(ft->calls > 0);
|
||||
addFilter16(ft->id);
|
||||
}
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +161,7 @@ void PackCom::addFilter16(int filter_id)
|
||||
if (filter_id % 3 == 0)
|
||||
addLoader("CALLTR16",
|
||||
filter_id < 4 ? "CT16SUB0" : "",
|
||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I086" : "CT16I286""CT16SUB0"),
|
||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I086" : "CT16I286,CT16SUB0"),
|
||||
"CALLTRI2",
|
||||
getFormat() == UPX_F_DOS_COM ? "CORETURN" : "",
|
||||
NULL
|
||||
@@ -180,7 +171,7 @@ void PackCom::addFilter16(int filter_id)
|
||||
"CALLTRI5",
|
||||
getFormat() == UPX_F_DOS_COM ? "CT16JEND" : "CT16JUL2",
|
||||
filter_id < 4 ? "CT16SUB1" : "",
|
||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I087" : "CT16I287""CT16SUB1"),
|
||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I087" : "CT16I287,CT16SUB1"),
|
||||
"CALLTRI6",
|
||||
NULL
|
||||
);
|
||||
@@ -206,7 +197,7 @@ void PackCom::pack(OutputFile *fo)
|
||||
ft.addvalue = getCallTrickOffset();
|
||||
// compress
|
||||
const unsigned overlap_range = ph.u_len < 0xFE00 - ft.addvalue ? 32 : 0;
|
||||
compressWithFilters(&ft, overlap_range);
|
||||
compressWithFilters(&ft, overlap_range, NULL_cconf);
|
||||
|
||||
const int lsize = getLoaderSize();
|
||||
MemBuffer loader(lsize);
|
||||
@@ -270,6 +261,12 @@ void PackCom::unpack(OutputFile *fo)
|
||||
}
|
||||
|
||||
|
||||
Linker* PackCom::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
+9
-6
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -38,10 +38,12 @@ class PackCom : public Packer
|
||||
{
|
||||
typedef Packer super;
|
||||
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 getFormat() const { return UPX_F_DOS_COM; }
|
||||
virtual const char *getName() const { return "dos/com"; }
|
||||
//virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_8086 ? "i086-dos16.com" : "i286-dos16.com"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i086-dos16.com"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -52,10 +54,11 @@ public:
|
||||
virtual int canUnpack();
|
||||
|
||||
protected:
|
||||
virtual const unsigned getCallTrickOffset() const { return 0x100; }
|
||||
virtual unsigned getCallTrickOffset() const { return 0x100; }
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
|
||||
virtual void addFilter16(int filter_id);
|
||||
};
|
||||
|
||||
+145
-92
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_djgpp2.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
#include "stub/stubify.h"
|
||||
|
||||
#include "stub/i386-dos32.djgpp2.h"
|
||||
static const
|
||||
#include "stub/l_djgpp2.h"
|
||||
#include "stub/i386-dos32.djgpp2-stubify.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -46,13 +46,16 @@ static const
|
||||
PackDjgpp2::PackDjgpp2(InputFile *f) :
|
||||
super(f), coff_offset(0)
|
||||
{
|
||||
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40);
|
||||
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8);
|
||||
COMPILE_TIME_ASSERT(sizeof(stubify_stub) == 2048);
|
||||
#if defined(STUBIFY_STUB_ADLER32)
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40)
|
||||
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(external_scnhdr_t)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(coff_header_t)
|
||||
COMPILE_TIME_ASSERT(sizeof(stub_i386_dos32_djgpp2_stubify) == 2048)
|
||||
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)));
|
||||
assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
||||
#endif
|
||||
//assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,41 +68,50 @@ const int *PackDjgpp2::getCompressionMethods(int method, int level) const
|
||||
const int *PackDjgpp2::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
||||
-1 };
|
||||
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
|
||||
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
||||
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned range,
|
||||
unsigned upper_limit) const
|
||||
{
|
||||
unsigned o = super::findOverlapOverhead(buf, range, upper_limit);
|
||||
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
|
||||
o = (o + 0x3ff) &~ 0x1ff;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
int PackDjgpp2::buildLoader(const Filter *ft)
|
||||
Linker* PackDjgpp2::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
|
||||
void PackDjgpp2::buildLoader(const Filter *ft)
|
||||
{
|
||||
// prepare loader
|
||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
||||
addLoader("IDENTSTR""DJ2MAIN1",
|
||||
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
|
||||
addLoader("IDENTSTR,DJ2MAIN1",
|
||||
ft->id ? "DJCALLT1" : "",
|
||||
"DJ2MAIN2",
|
||||
getDecompressor(),
|
||||
ph.first_offset_found == 1 ? "DJ2MAIN2" : "",
|
||||
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "",
|
||||
getDecompressorSections(),
|
||||
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "",
|
||||
"DJ2BSS00",
|
||||
NULL
|
||||
);
|
||||
if (ft->id)
|
||||
{
|
||||
assert(ft->calls > 0);
|
||||
addLoader("DJCALLT2",NULL);
|
||||
addLoader("DJCALLT2", NULL);
|
||||
addFilter32(ft->id);
|
||||
}
|
||||
addLoader("DJRETURN+40DXXXXUPX1HEAD",NULL);
|
||||
return getLoaderSize();
|
||||
addLoader("DJRETURN,+40C,UPX1HEAD", NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,18 +121,18 @@ int PackDjgpp2::buildLoader(const Filter *ft)
|
||||
|
||||
void PackDjgpp2::handleStub(OutputFile *fo)
|
||||
{
|
||||
if (fo && !opt->djgpp2.coff)
|
||||
if (fo && !opt->djgpp2_coff.coff)
|
||||
{
|
||||
if (coff_offset > 0)
|
||||
{
|
||||
// copy stub from exe
|
||||
Packer::handleStub(fi,fo,coff_offset);
|
||||
Packer::handleStub(fi, fo, coff_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
// "stubify" stub
|
||||
info("Adding stub: %ld bytes", (long)sizeof(stubify_stub));
|
||||
fo->write(stubify_stub,sizeof(stubify_stub));
|
||||
info("Adding stub: %ld bytes", (long)sizeof(stub_i386_dos32_djgpp2_stubify));
|
||||
fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,14 +144,14 @@ static bool is_dlm(InputFile *fi, long coff_offset)
|
||||
long off;
|
||||
|
||||
try {
|
||||
fi->seek(coff_offset,SEEK_SET);
|
||||
fi->readx(buf,4);
|
||||
fi->seek(coff_offset, SEEK_SET);
|
||||
fi->readx(buf, 4);
|
||||
off = get_le32(buf);
|
||||
if (off < 0 || off > coff_offset + 4)
|
||||
return false;
|
||||
fi->seek(off,SEEK_SET);
|
||||
fi->readx(buf,4);
|
||||
if (memcmp(buf,"DLMF",4) == 0)
|
||||
fi->seek(off, SEEK_SET);
|
||||
fi->readx(buf, 4);
|
||||
if (memcmp(buf, "DLMF", 4) == 0)
|
||||
return true;
|
||||
} catch (const IOException&) {
|
||||
}
|
||||
@@ -158,7 +170,7 @@ static void handle_allegropak(InputFile *fi, OutputFile *fo)
|
||||
if (memcmp(buf, "slh+", 4) != 0)
|
||||
return;
|
||||
pfsize = get_be32_signed(buf+4);
|
||||
if (pfsize <= 8 || pfsize >= fi->st.st_size)
|
||||
if (pfsize <= 8 || (off_t) pfsize >= (off_t) fi->st.st_size)
|
||||
return;
|
||||
fi->seek(-pfsize, SEEK_END);
|
||||
} catch (const IOException&) {
|
||||
@@ -179,25 +191,25 @@ int PackDjgpp2::readFileHeader()
|
||||
unsigned char hdr[0x1c];
|
||||
unsigned char magic[8];
|
||||
|
||||
fi->seek(0,SEEK_SET);
|
||||
fi->readx(hdr,sizeof(hdr));
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(hdr, sizeof(hdr));
|
||||
if (get_le16(hdr) == 0x5a4d) // MZ exe signature, stubbed?
|
||||
{
|
||||
coff_offset = 512 * get_le16(hdr+4);
|
||||
if (get_le16(hdr+2) != 0)
|
||||
coff_offset += get_le16(hdr+2) - 512;
|
||||
fi->seek(512,SEEK_SET);
|
||||
fi->readx(magic,8);
|
||||
if (memcmp("go32stub",magic,8) != 0)
|
||||
fi->seek(512, SEEK_SET);
|
||||
fi->readx(magic, 8);
|
||||
if (memcmp("go32stub", magic, 8) != 0)
|
||||
return 0; // not V2 image
|
||||
fi->seek(coff_offset,SEEK_SET);
|
||||
if (fi->read(&coff_hdr,sizeof(coff_hdr)) != sizeof(coff_hdr))
|
||||
fi->seek(coff_offset, SEEK_SET);
|
||||
if (fi->read(&coff_hdr, sizeof(coff_hdr)) != sizeof(coff_hdr))
|
||||
throwCantPack("skipping djgpp symlink");
|
||||
}
|
||||
else
|
||||
{
|
||||
fi->seek(coff_offset,SEEK_SET);
|
||||
fi->readx(&coff_hdr,0xa8);
|
||||
fi->seek(coff_offset, SEEK_SET);
|
||||
fi->readx(&coff_hdr, 0xa8);
|
||||
}
|
||||
if (coff_hdr.f_magic != 0x014c) // I386MAGIC
|
||||
return 0;
|
||||
@@ -220,7 +232,7 @@ void PackDjgpp2::stripDebug()
|
||||
coff_hdr.f_symptr = 0;
|
||||
coff_hdr.f_nsyms = 0;
|
||||
coff_hdr.f_flags = 0x10f; // 0x100: "32 bit machine: LSB first"
|
||||
memset(text->misc,0,12);
|
||||
memset(text->misc, 0, 12);
|
||||
}
|
||||
|
||||
|
||||
@@ -232,7 +244,7 @@ bool PackDjgpp2::canPack()
|
||||
{
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
if (is_dlm(fi,coff_offset))
|
||||
if (is_dlm(fi, coff_offset))
|
||||
throwCantPack("can't handle DLM");
|
||||
|
||||
if (opt->force == 0)
|
||||
@@ -269,56 +281,60 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
// read file
|
||||
const unsigned size = text->size + data->size;
|
||||
const unsigned tpos = text->scnptr;
|
||||
const unsigned usize = size + (tpos & 0x1ff);
|
||||
const unsigned hdrsize = 20 + 28 + (40 * coff_hdr.f_nscns);
|
||||
const unsigned hdrsize = 20 + 28 + sizeof(external_scnhdr_t) * coff_hdr.f_nscns;
|
||||
const unsigned usize = size + hdrsize;
|
||||
if (hdrsize < sizeof(coff_hdr) || hdrsize > tpos)
|
||||
throwCantPack("coff header error");
|
||||
if (hdrsize > (tpos & 0x1ff))
|
||||
throwCantPack("unsupported coff header");
|
||||
|
||||
ibuf.alloc(usize);
|
||||
obuf.allocForCompression(usize);
|
||||
|
||||
fi->seek(coff_offset,SEEK_SET);
|
||||
fi->readx(ibuf,hdrsize); // orig. coff header
|
||||
memset(ibuf + hdrsize, 0, tpos - hdrsize);
|
||||
fi->seek(coff_offset+tpos,SEEK_SET);
|
||||
fi->readx(ibuf + (tpos & 0x1ff),size);
|
||||
fi->seek(coff_offset, SEEK_SET);
|
||||
fi->readx(ibuf, hdrsize); // orig. coff header
|
||||
fi->seek(coff_offset + tpos, SEEK_SET);
|
||||
fi->readx(ibuf + hdrsize, size);
|
||||
|
||||
// prepare packheader
|
||||
ph.u_len = usize;
|
||||
// prepare filter
|
||||
Filter ft(ph.level);
|
||||
ft.buf_len = usize - data->size;
|
||||
ft.addvalue = text->vaddr & ~0x1ff;
|
||||
ft.addvalue = text->vaddr - hdrsize;
|
||||
// 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, &cconf);
|
||||
|
||||
// patch coff header #2
|
||||
const unsigned lsize = getLoaderSize();
|
||||
assert(lsize % 4 == 0);
|
||||
text->size = lsize; // new size of .text
|
||||
data->size = ph.c_len; // new size of .data
|
||||
|
||||
if (bss->size < ph.overlap_overhead) // give it a .bss
|
||||
bss->size = ph.overlap_overhead;
|
||||
unsigned stack = 1024 + ph.overlap_overhead + getDecompressorWrkmemSize();
|
||||
stack = ALIGN_UP(stack, 16u);
|
||||
if (bss->size < stack) // give it a .bss
|
||||
bss->size = stack;
|
||||
|
||||
text->scnptr = sizeof(coff_hdr);
|
||||
data->scnptr = text->scnptr + text->size;
|
||||
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + ph.overlap_overhead - 0x200;
|
||||
coff_hdr.f_nscns = 3;
|
||||
|
||||
// prepare loader
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader,getLoader(),lsize);
|
||||
|
||||
// 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);
|
||||
linker->defineSymbol("original_entry", coff_hdr.a_entry);
|
||||
linker->defineSymbol("length_of_bss", ph.overlap_overhead / 4);
|
||||
defineDecompressorSymbols();
|
||||
assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
|
||||
patch_le32(loader,lsize,"OUTP",text->vaddr &~ 0x1ff);
|
||||
patch_le32(loader,lsize,"INPP",data->vaddr);
|
||||
linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size);
|
||||
linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize);
|
||||
linker->defineSymbol("start_of_compressed", data->vaddr);
|
||||
defineFilterSymbols(&ft);
|
||||
|
||||
// we should not overwrite our decompressor during unpacking
|
||||
// the original coff header (which is put just before the
|
||||
// beginning of the original .text section)
|
||||
assert(text->vaddr > hdrsize + lsize + sizeof(coff_hdr));
|
||||
|
||||
// patch coff header #3
|
||||
text->vaddr = sizeof(coff_hdr);
|
||||
@@ -327,13 +343,23 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
bss->size -= ph.overlap_overhead;
|
||||
|
||||
// because of a feature (bug?) in stub.asm we need some padding
|
||||
memcpy(obuf+data->size,"UPX",3);
|
||||
data->size = ALIGN_UP(data->size,4);
|
||||
memcpy(obuf+data->size, "UPX", 3);
|
||||
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
|
||||
fo->write(&coff_hdr,sizeof(coff_hdr));
|
||||
fo->write(loader,lsize);
|
||||
fo->write(obuf,data->size);
|
||||
fo->write(&coff_hdr, sizeof(coff_hdr));
|
||||
fo->write(loader, lsize);
|
||||
if (opt->debug.dump_stub_loader)
|
||||
OutputFile::dump(opt->debug.dump_stub_loader, loader, lsize);
|
||||
fo->write(obuf, data->size);
|
||||
#if 0
|
||||
printf("%-13s: coff hdr : %8ld bytes\n", getName(), (long) sizeof(coff_hdr));
|
||||
printf("%-13s: loader : %8ld bytes\n", getName(), (long) lsize);
|
||||
@@ -345,7 +371,7 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
|
||||
// handle overlay
|
||||
// FIXME: only Allegro pakfiles are supported
|
||||
handle_allegropak(fi,fo);
|
||||
handle_allegropak(fi, fo);
|
||||
|
||||
// finally check the compression ratio
|
||||
if (!checkFinalCompressionRatio(fo))
|
||||
@@ -361,10 +387,10 @@ int PackDjgpp2::canUnpack()
|
||||
{
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
if (is_dlm(fi,coff_offset))
|
||||
if (is_dlm(fi, coff_offset))
|
||||
throwCantUnpack("can't handle DLM");
|
||||
fi->seek(coff_offset, SEEK_SET);
|
||||
return readPackHeader(1024) ? 1 : -1;
|
||||
return readPackHeader(4096) ? 1 : -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -379,19 +405,30 @@ void PackDjgpp2::unpack(OutputFile *fo)
|
||||
ibuf.alloc(ph.c_len);
|
||||
obuf.allocForUncompression(ph.u_len);
|
||||
|
||||
fi->seek(coff_offset + ph.buf_offset + ph.getPackHeaderSize(),SEEK_SET);
|
||||
fi->readx(ibuf,ph.c_len);
|
||||
fi->seek(coff_offset + ph.buf_offset + ph.getPackHeaderSize(), SEEK_SET);
|
||||
fi->readx(ibuf, ph.c_len);
|
||||
|
||||
// decompress
|
||||
decompress(ibuf,obuf);
|
||||
decompress(ibuf, obuf);
|
||||
|
||||
coff_header_t *chdr = (coff_header_t*) obuf.getVoidPtr();
|
||||
text = chdr->sh;
|
||||
data = text + 1;
|
||||
|
||||
const unsigned hdrsize = 20 + 28
|
||||
+ sizeof(external_scnhdr_t) * chdr->f_nscns;
|
||||
|
||||
unsigned addvalue;
|
||||
if (ph.version >= 14)
|
||||
addvalue = text->vaddr - hdrsize;
|
||||
else
|
||||
addvalue = text->vaddr &~ 0x1ff; // for old versions
|
||||
|
||||
// unfilter
|
||||
if (ph.filter)
|
||||
{
|
||||
memcpy(&coff_hdr,obuf,sizeof(coff_hdr));
|
||||
|
||||
Filter ft(ph.level);
|
||||
ft.init(ph.filter, text->vaddr &~ 0x1ff);
|
||||
ft.init(ph.filter, addvalue);
|
||||
ft.cto = (unsigned char) ph.filter_cto;
|
||||
if (ph.version < 11)
|
||||
{
|
||||
@@ -402,18 +439,34 @@ void PackDjgpp2::unpack(OutputFile *fo)
|
||||
ft.unfilter(obuf, ph.u_len - data->size);
|
||||
}
|
||||
|
||||
// fixup for the aligning bug in strip 2.8+
|
||||
text = ((coff_header_t*) (unsigned char *) obuf)->sh;
|
||||
data = text + 1;
|
||||
text->scnptr &= 0x1ff;
|
||||
data->scnptr = text->scnptr + text->size;
|
||||
|
||||
// write decompressed file
|
||||
if (fo)
|
||||
if (ph.version < 14)
|
||||
{
|
||||
fo->write(obuf,ph.u_len);
|
||||
handle_allegropak(fi,fo);
|
||||
// fixup for the aligning bug in strip 2.8+
|
||||
text->scnptr &= 0x1ff;
|
||||
data->scnptr = text->scnptr + text->size;
|
||||
// write decompressed file
|
||||
if (fo)
|
||||
fo->write(obuf, ph.u_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// write the header
|
||||
// some padding might be required between the end
|
||||
// of the header and the start of the .text section
|
||||
|
||||
const unsigned padding = text->scnptr - hdrsize;
|
||||
ibuf.clear(0, padding);
|
||||
|
||||
if (fo)
|
||||
{
|
||||
fo->write(obuf, hdrsize);
|
||||
fo->write(ibuf, padding);
|
||||
fo->write(obuf + hdrsize, ph.u_len - hdrsize);
|
||||
}
|
||||
}
|
||||
|
||||
if (fo)
|
||||
handle_allegropak(fi, fo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+8
-5
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -40,9 +40,10 @@ class PackDjgpp2 : public Packer
|
||||
|
||||
public:
|
||||
PackDjgpp2(InputFile *f);
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getVersion() const { return 14; }
|
||||
virtual int getFormat() const { return UPX_F_DJGPP2_COFF; }
|
||||
virtual const char *getName() const { return "djgpp2/coff"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-dos32.djgpp2.coff"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -57,9 +58,11 @@ protected:
|
||||
virtual int readFileHeader();
|
||||
|
||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned range = 0,
|
||||
unsigned upper_limit = ~0u) const;
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
long coff_offset;
|
||||
|
||||
|
||||
+358
-47
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -31,71 +31,382 @@
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// Some ELF type definitinons
|
||||
// N_Elf
|
||||
**************************************************************************/
|
||||
|
||||
namespace N_Elf {
|
||||
|
||||
// integral types
|
||||
template <class THalf, class TWord, class TXword, class TAddr, class TOff>
|
||||
struct ElfITypes
|
||||
{
|
||||
typedef THalf Half;
|
||||
typedef TWord Word;
|
||||
typedef TXword Xword;
|
||||
typedef TAddr Addr;
|
||||
typedef TOff Off;
|
||||
typedef THalf Section;
|
||||
typedef THalf Versym;
|
||||
};
|
||||
|
||||
|
||||
// The ELF file header. This appears at the start of every ELF file.
|
||||
struct Elf_LE32_Ehdr
|
||||
template <class TElfITypes>
|
||||
struct Ehdr
|
||||
{
|
||||
typedef typename TElfITypes::Half Half;
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Off Off;
|
||||
|
||||
unsigned char e_ident[16]; /* Magic number and other info */
|
||||
LE16 e_type; /* Object file type */
|
||||
LE16 e_machine; /* Architecture */
|
||||
LE32 e_version; /* Object file version */
|
||||
LE32 e_entry; /* Entry point virtual address */
|
||||
LE32 e_phoff; /* Program header table file offset */
|
||||
LE32 e_shoff; /* Section header table file offset */
|
||||
LE32 e_flags; /* Processor-specific flags */
|
||||
LE16 e_ehsize; /* ELF header size in bytes */
|
||||
LE16 e_phentsize; /* Program header table entry size */
|
||||
LE16 e_phnum; /* Program header table entry count */
|
||||
LE16 e_shentsize; /* Section header table entry size */
|
||||
LE16 e_shnum; /* Section header table entry count */
|
||||
LE16 e_shstrndx; /* Section header string table index */
|
||||
Half e_type; /* Object file type */
|
||||
Half e_machine; /* Architecture */
|
||||
Word e_version; /* Object file version */
|
||||
Addr e_entry; /* Entry point virtual address */
|
||||
Off e_phoff; /* Program header table file offset */
|
||||
Off e_shoff; /* Section header table file offset */
|
||||
Word e_flags; /* Processor-specific flags */
|
||||
Half e_ehsize; /* ELF header size in bytes */
|
||||
Half e_phentsize; /* Program header table entry size */
|
||||
Half e_phnum; /* Program header table entry count */
|
||||
Half e_shentsize; /* Section header table entry size */
|
||||
Half e_shnum; /* Section header table entry count */
|
||||
Half e_shstrndx; /* Section header string table index */
|
||||
|
||||
# define WANT_EHDR_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
// Program segment header.
|
||||
struct Elf_LE32_Phdr
|
||||
template <class TElfITypes>
|
||||
struct Dyn
|
||||
{
|
||||
LE32 p_type; /* Segment type */
|
||||
LE32 p_offset; /* Segment file offset */
|
||||
LE32 p_vaddr; /* Segment virtual address */
|
||||
LE32 p_paddr; /* Segment physical address */
|
||||
LE32 p_filesz; /* Segment size in file */
|
||||
LE32 p_memsz; /* Segment size in memory */
|
||||
LE32 p_flags; /* Segment flags */
|
||||
LE32 p_align; /* Segment alignment */
|
||||
typedef typename TElfITypes::Xword Xword;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
|
||||
// Values for p_type
|
||||
enum {
|
||||
PT_LOAD = 1, /* Loadable program segment */
|
||||
PT_DYNAMIC = 2, /* Dynamic linking information */
|
||||
PT_PHDR = 6 /* Entry for header table itself */
|
||||
};
|
||||
Xword d_tag;
|
||||
Addr d_val;
|
||||
|
||||
// Values for p_flags
|
||||
enum { PF_X = (1 << 0) }; /* Segment is executable */
|
||||
enum { PF_W = (1 << 1) }; /* Segment is writable */
|
||||
enum { PF_R = (1 << 2) }; /* Segment is readable */
|
||||
# define WANT_DYN_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
struct Elf_LE32_Dyn
|
||||
template <class TElfITypes>
|
||||
struct External_Note
|
||||
{
|
||||
LE32 d_tag;
|
||||
LE32 d_val;
|
||||
typedef typename TElfITypes::Word Word;
|
||||
|
||||
enum { // tags
|
||||
DT_NULL = 0, /* End flag */
|
||||
DT_NEEDED = 1, /* Name of needed library */
|
||||
DT_STRTAB = 5, /* String table */
|
||||
DT_STRSZ = 10 /* Sizeof string table */
|
||||
};
|
||||
Word xn_namesz; // includes terminating '\0'
|
||||
Word xn_datasz;
|
||||
Word xn_type;
|
||||
//char xn_name[N]; // terminate with '\0'
|
||||
//char xn_data[M]; // aligned to 0 mod 4
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
} // namespace N_Elf
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// N_Elf32
|
||||
**************************************************************************/
|
||||
|
||||
namespace N_Elf32 {
|
||||
|
||||
template <class TElfITypes>
|
||||
struct Phdr
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Off Off;
|
||||
|
||||
Word p_type; /* Segment type */
|
||||
Off p_offset; /* Segment file offset */
|
||||
Addr p_vaddr; /* Segment virtual address */
|
||||
Addr p_paddr; /* Segment physical address */
|
||||
Word p_filesz; /* Segment size in file */
|
||||
Word p_memsz; /* Segment size in memory */
|
||||
Word p_flags; /* Segment flags */
|
||||
Word p_align; /* Segment alignment */
|
||||
|
||||
# define WANT_PHDR_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
template <class TElfITypes>
|
||||
struct Shdr
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Off Off;
|
||||
|
||||
Word sh_name; /* Section name (string tbl index) */
|
||||
Word sh_type; /* Section type */
|
||||
Word sh_flags; /* Section flags */
|
||||
Addr sh_addr; /* Section virtual addr at execution */
|
||||
Off sh_offset; /* Section file offset */
|
||||
Word sh_size; /* Section size in bytes */
|
||||
Word sh_link; /* Link to another section */
|
||||
Word sh_info; /* Additional section information */
|
||||
Word sh_addralign; /* Section alignment */
|
||||
Word sh_entsize; /* Entry size if section holds table */
|
||||
|
||||
# define WANT_SHDR_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
template <class TElfITypes>
|
||||
struct Sym
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Section Section;
|
||||
|
||||
Word st_name; /* symbol name (index into string table) */
|
||||
Addr st_value; /* symbol value */
|
||||
Word st_size; /* symbol size */
|
||||
unsigned char st_info; /* symbol type and binding */
|
||||
unsigned char st_other; /* symbol visibility */
|
||||
Section st_shndx; /* section index */
|
||||
|
||||
# define WANT_SYM_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
|
||||
static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
|
||||
static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
|
||||
static unsigned char make_st_info(unsigned bind, unsigned type) { return (bind<<4) + (0xf & type); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
} // namespace N_Elf32
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// N_Elf64
|
||||
**************************************************************************/
|
||||
|
||||
namespace N_Elf64 {
|
||||
|
||||
template <class TElfITypes>
|
||||
struct Phdr
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Xword Xword;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Off Off;
|
||||
|
||||
Word p_type; /* Segment type */
|
||||
Word p_flags; /* Segment flags */
|
||||
Off p_offset; /* Segment file offset */
|
||||
Addr p_vaddr; /* Segment virtual address */
|
||||
Addr p_paddr; /* Segment physical address */
|
||||
Xword p_filesz; /* Segment size in file */
|
||||
Xword p_memsz; /* Segment size in memory */
|
||||
Xword p_align; /* Segment alignment */
|
||||
|
||||
# define WANT_PHDR_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
template <class TElfITypes>
|
||||
struct Shdr
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Xword Xword;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Off Off;
|
||||
|
||||
Word sh_name; /* Section name (string tbl index) */
|
||||
Word sh_type; /* Section type */
|
||||
Xword sh_flags; /* Section flags */
|
||||
Addr sh_addr; /* Section virtual addr at execution */
|
||||
Off sh_offset; /* Section file offset */
|
||||
Xword sh_size; /* Section size in bytes */
|
||||
Word sh_link; /* Link to another section */
|
||||
Word sh_info; /* Additional section information */
|
||||
Xword sh_addralign; /* Section alignment */
|
||||
Xword sh_entsize; /* Entry size if section holds table */
|
||||
|
||||
# define WANT_SHDR_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
template <class TElfITypes>
|
||||
struct Sym
|
||||
{
|
||||
typedef typename TElfITypes::Word Word;
|
||||
typedef typename TElfITypes::Xword Xword;
|
||||
typedef typename TElfITypes::Addr Addr;
|
||||
typedef typename TElfITypes::Section Section;
|
||||
|
||||
Word st_name; /* symbol name (index into string table) */
|
||||
unsigned char st_info; /* symbol type and binding */
|
||||
unsigned char st_other; /* symbol visibility */
|
||||
Section st_shndx; /* section index */
|
||||
Addr st_value; /* symbol value */
|
||||
Xword st_size; /* symbol size */
|
||||
|
||||
# define WANT_SYM_ENUM 1
|
||||
# include "p_elf_enum.h"
|
||||
|
||||
static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
|
||||
static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
|
||||
static unsigned char make_st_info(unsigned bind, unsigned type) { return (bind<<4) + (0xf & type); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
} // namespace N_Elf64
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// aggregate types into an ElfClass
|
||||
**************************************************************************/
|
||||
|
||||
namespace N_Elf {
|
||||
|
||||
template <class TP>
|
||||
struct ElfClass_32
|
||||
{
|
||||
typedef TP BeLePolicy;
|
||||
|
||||
// integral types
|
||||
typedef typename TP::U16 U16;
|
||||
typedef typename TP::U32 U32;
|
||||
typedef typename TP::U64 U64;
|
||||
typedef N_Elf::ElfITypes<U16, U32, U32, U32, U32> ElfITypes;
|
||||
|
||||
// ELF types
|
||||
typedef N_Elf ::Ehdr<ElfITypes> Ehdr;
|
||||
typedef N_Elf32::Phdr<ElfITypes> Phdr;
|
||||
typedef N_Elf32::Shdr<ElfITypes> Shdr;
|
||||
typedef N_Elf ::Dyn <ElfITypes> Dyn;
|
||||
typedef N_Elf32::Sym <ElfITypes> Sym;
|
||||
typedef N_Elf ::External_Note<ElfITypes> External_Note;
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
BeLePolicy::compileTimeAssertions();
|
||||
COMPILE_TIME_ASSERT(sizeof(Ehdr) == 52)
|
||||
COMPILE_TIME_ASSERT(sizeof(Phdr) == 32)
|
||||
COMPILE_TIME_ASSERT(sizeof(Shdr) == 40)
|
||||
COMPILE_TIME_ASSERT(sizeof(Dyn) == 8)
|
||||
COMPILE_TIME_ASSERT(sizeof(Sym) == 16)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Ehdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Phdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Shdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Dyn)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Sym)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class TP>
|
||||
struct ElfClass_64
|
||||
{
|
||||
typedef TP BeLePolicy;
|
||||
|
||||
// integral types
|
||||
typedef typename TP::U16 U16;
|
||||
typedef typename TP::U32 U32;
|
||||
typedef typename TP::U64 U64;
|
||||
typedef N_Elf::ElfITypes<U16, U32, U64, U64, U64> ElfITypes;
|
||||
|
||||
// ELF types
|
||||
typedef N_Elf ::Ehdr<ElfITypes> Ehdr;
|
||||
typedef N_Elf64::Phdr<ElfITypes> Phdr;
|
||||
typedef N_Elf64::Shdr<ElfITypes> Shdr;
|
||||
typedef N_Elf ::Dyn <ElfITypes> Dyn;
|
||||
typedef N_Elf64::Sym <ElfITypes> Sym;
|
||||
typedef N_Elf ::External_Note<ElfITypes> External_Note;
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
BeLePolicy::compileTimeAssertions();
|
||||
COMPILE_TIME_ASSERT(sizeof(Ehdr) == 64)
|
||||
COMPILE_TIME_ASSERT(sizeof(Phdr) == 56)
|
||||
COMPILE_TIME_ASSERT(sizeof(Shdr) == 64)
|
||||
COMPILE_TIME_ASSERT(sizeof(Dyn) == 16)
|
||||
COMPILE_TIME_ASSERT(sizeof(Sym) == 24)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Ehdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Phdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Shdr)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Dyn)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(Sym)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace N_Elf
|
||||
|
||||
|
||||
typedef N_Elf::ElfClass_32<N_BELE_CTP::HostPolicy> ElfClass_Host32;
|
||||
typedef N_Elf::ElfClass_64<N_BELE_CTP::HostPolicy> ElfClass_Host64;
|
||||
typedef N_Elf::ElfClass_32<N_BELE_CTP::BEPolicy> ElfClass_BE32;
|
||||
typedef N_Elf::ElfClass_64<N_BELE_CTP::BEPolicy> ElfClass_BE64;
|
||||
typedef N_Elf::ElfClass_32<N_BELE_CTP::LEPolicy> ElfClass_LE32;
|
||||
typedef N_Elf::ElfClass_64<N_BELE_CTP::LEPolicy> ElfClass_LE64;
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// shortcuts
|
||||
**************************************************************************/
|
||||
|
||||
typedef ElfClass_Host32::Ehdr Elf32_Ehdr;
|
||||
typedef ElfClass_Host32::Phdr Elf32_Phdr;
|
||||
typedef ElfClass_Host32::Shdr Elf32_Shdr;
|
||||
typedef ElfClass_Host32::Dyn Elf32_Dyn;
|
||||
typedef ElfClass_Host32::Sym Elf32_Sym;
|
||||
typedef ElfClass_Host32::External_Note Elf32_External_Note;
|
||||
|
||||
typedef ElfClass_Host64::Ehdr Elf64_Ehdr;
|
||||
typedef ElfClass_Host64::Phdr Elf64_Phdr;
|
||||
typedef ElfClass_Host64::Shdr Elf64_Shdr;
|
||||
typedef ElfClass_Host64::Dyn Elf64_Dyn;
|
||||
typedef ElfClass_Host64::Sym Elf64_Sym;
|
||||
typedef ElfClass_Host64::External_Note Elf64_External_Note;
|
||||
|
||||
typedef ElfClass_BE32::Ehdr Elf_BE32_Ehdr;
|
||||
typedef ElfClass_BE32::Phdr Elf_BE32_Phdr;
|
||||
typedef ElfClass_BE32::Shdr Elf_BE32_Shdr;
|
||||
typedef ElfClass_BE32::Dyn Elf_BE32_Dyn;
|
||||
typedef ElfClass_BE32::Sym Elf_BE32_Sym;
|
||||
typedef ElfClass_BE32::External_Note Elf_BE32_External_Note;
|
||||
|
||||
typedef ElfClass_BE64::Ehdr Elf_BE64_Ehdr;
|
||||
typedef ElfClass_BE64::Phdr Elf_BE64_Phdr;
|
||||
typedef ElfClass_BE64::Shdr Elf_BE64_Shdr;
|
||||
typedef ElfClass_BE64::Dyn Elf_BE64_Dyn;
|
||||
typedef ElfClass_BE64::Sym Elf_BE64_Sym;
|
||||
typedef ElfClass_BE64::External_Note Elf_BE64_External_Note;
|
||||
|
||||
typedef ElfClass_LE32::Ehdr Elf_LE32_Ehdr;
|
||||
typedef ElfClass_LE32::Phdr Elf_LE32_Phdr;
|
||||
typedef ElfClass_LE32::Shdr Elf_LE32_Shdr;
|
||||
typedef ElfClass_LE32::Dyn Elf_LE32_Dyn;
|
||||
typedef ElfClass_LE32::Sym Elf_LE32_Sym;
|
||||
typedef ElfClass_LE32::External_Note Elf_LE32_External_Note;
|
||||
|
||||
typedef ElfClass_LE64::Ehdr Elf_LE64_Ehdr;
|
||||
typedef ElfClass_LE64::Phdr Elf_LE64_Phdr;
|
||||
typedef ElfClass_LE64::Shdr Elf_LE64_Shdr;
|
||||
typedef ElfClass_LE64::Dyn Elf_LE64_Dyn;
|
||||
typedef ElfClass_LE64::Sym Elf_LE64_Sym;
|
||||
typedef ElfClass_LE64::External_Note Elf_LE64_External_Note;
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/* p_elf_enum.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 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
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// Use the preprocessor to work around
|
||||
// - that the types embedding these enums have to be PODs, and
|
||||
// deriving from an empty base class (which is the usual C++ way
|
||||
// of "importing" enums) does not yield a POD any more
|
||||
// - that older compilers do not correctly perform EBCO
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef WANT_EHDR_ENUM
|
||||
#undef WANT_EHDR_ENUM
|
||||
enum { // e_ident[]
|
||||
EI_CLASS = 4,
|
||||
EI_DATA = 5, /* Data encoding */
|
||||
EI_VERSION = 6,
|
||||
EI_OSABI = 7,
|
||||
EI_ABIVERSION = 8
|
||||
};
|
||||
enum { // e_ident[EI_CLASS]
|
||||
ELFCLASS32 = 1, /* 32-bit objects */
|
||||
ELFCLASS64 = 2 /* 64-bit objects */
|
||||
};
|
||||
enum { // e_ident[EI_DATA]
|
||||
ELFDATA2LSB = 1, /* 2's complement, little endian */
|
||||
ELFDATA2MSB = 2 /* 2's complement, big endian */
|
||||
};
|
||||
enum { // e_ident[EI_OSABI]
|
||||
ELFOSABI_NONE = 0, // == ELFOSABI_SYSV
|
||||
ELFOSABI_NETBSD = 2,
|
||||
ELFOSABI_LINUX = 3,
|
||||
ELFOSABI_FREEBSD = 9,
|
||||
ELFOSABI_OPENBSD = 12,
|
||||
ELFOSABI_ARM = 97
|
||||
};
|
||||
enum { // e_type
|
||||
ET_NONE = 0, /* No file type */
|
||||
ET_REL = 1, /* Relocatable file */
|
||||
ET_EXEC = 2, /* Executable file */
|
||||
ET_DYN = 3, /* Shared object file */
|
||||
ET_CORE = 4 /* Core file */
|
||||
};
|
||||
enum { // e_machine
|
||||
EM_386 = 3,
|
||||
EM_MIPS = 8,
|
||||
EM_MIPS_RS3_LE = 10, /* MIPS R3000 little-endian */
|
||||
EM_PPC = 20,
|
||||
EM_PPC64 = 21,
|
||||
EM_ARM = 40,
|
||||
EM_X86_64 = 62
|
||||
|
||||
};
|
||||
enum { // e_version
|
||||
EV_CURRENT = 1
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WANT_PHDR_ENUM
|
||||
#undef WANT_PHDR_ENUM
|
||||
enum { // p_type
|
||||
PT_LOAD = 1, /* Loadable program segment */
|
||||
PT_DYNAMIC = 2, /* Dynamic linking information */
|
||||
PT_INTERP = 3, /* Name of program interpreter */
|
||||
PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */
|
||||
PT_PHDR = 6 /* Entry for header table itself */
|
||||
};
|
||||
|
||||
enum { // p_flags
|
||||
PF_X = 1, /* Segment is executable */
|
||||
PF_W = 2, /* Segment is writable */
|
||||
PF_R = 4 /* Segment is readable */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WANT_SHDR_ENUM
|
||||
#undef WANT_SHDR_ENUM
|
||||
enum { // sh_type
|
||||
SHT_NULL = 0, /* Section header table entry unused */
|
||||
SHT_PROGBITS = 1, /* Program data */
|
||||
SHT_SYMTAB = 2, /* Symbol table */
|
||||
SHT_STRTAB = 3, /* String table */
|
||||
SHT_RELA = 4, /* Relocation entries with addends */
|
||||
SHT_HASH = 5, /* Symbol hash table */
|
||||
SHT_DYNAMIC = 6, /* Dynamic linking information */
|
||||
SHT_NOTE = 7, /* Notes */
|
||||
SHT_NOBITS = 8, /* Program space with no data (bss) */
|
||||
SHT_REL = 9, /* Relocation entries, no addends */
|
||||
SHT_SHLIB = 10, /* Reserved */
|
||||
SHT_DYNSYM = 11, /* Dynamic linker symbol table */
|
||||
/* 12, 13 hole */
|
||||
SHT_INIT_ARRAY = 14, /* Array of constructors */
|
||||
SHT_FINI_ARRAY = 15, /* Array of destructors */
|
||||
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
|
||||
SHT_GROUP = 17, /* Section group */
|
||||
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
|
||||
SHT_GNU_LIBLIST = 0x6ffffff7 /* Prelink library list */
|
||||
};
|
||||
|
||||
enum { // sh_flags
|
||||
SHF_WRITE = (1 << 0), /* Writable */
|
||||
SHF_ALLOC = (1 << 1), /* Occupies memory during execution */
|
||||
SHF_EXECINSTR = (1 << 2), /* Executable */
|
||||
SHF_MERGE = (1 << 4), /* Might be merged */
|
||||
SHF_STRINGS = (1 << 5), /* Contains nul-terminated strings */
|
||||
SHF_INFO_LINK = (1 << 6), /* 'sh_info' contains SHT index */
|
||||
SHF_LINK_ORDER = (1 << 7) /* Preserve order after combining */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WANT_DYN_ENUM
|
||||
#undef WANT_DYN_ENUM
|
||||
enum { // d_tag
|
||||
DT_NULL = 0, /* End flag */
|
||||
DT_NEEDED = 1, /* Name of needed library */
|
||||
DT_PLTRELSZ = 2, /* Size in bytes of PLT relocs */
|
||||
DT_HASH = 4, /* Hash table of symbol names */
|
||||
DT_STRTAB = 5, /* String table */
|
||||
DT_SYMTAB = 6, /* Symbol table */
|
||||
DT_STRSZ = 10, /* Sizeof string table */
|
||||
DT_PLTREL = 20, /* Type of reloc in PLT */
|
||||
DT_JMPREL = 23, /* Address of PLT relocs */
|
||||
DT_GNU_HASH = 0x6ffffef5 /* GNU-style hash table */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WANT_SYM_ENUM
|
||||
#undef WANT_SYM_ENUM
|
||||
enum { // st_bind (high 4 bits of st_info)
|
||||
STB_LOCAL = 0, /* Local symbol */
|
||||
STB_GLOBAL = 1, /* Global symbol */
|
||||
STB_WEAK = 2 /* Weak symbol */
|
||||
};
|
||||
|
||||
enum { // st_type (low 4 bits of st_info)
|
||||
STT_NOTYPE = 0, /* Symbol type is unspecified */
|
||||
STT_OBJECT = 1, /* Symbol is a data object */
|
||||
STT_FUNC = 2, /* Symbol is a code object */
|
||||
STT_SECTION = 3, /* Symbol associated with a section */
|
||||
STT_FILE = 4, /* Symbol's name is file name */
|
||||
STT_COMMON = 5, /* Symbol is a common data object */
|
||||
STT_TLS = 6 /* Symbol is thread-local data object*/
|
||||
};
|
||||
|
||||
enum { // st_other (visibility)
|
||||
STV_DEFAULT = 0, /* Default symbol visibility rules */
|
||||
STV_INTERNAL = 1, /* Processor specific hidden class */
|
||||
STV_HIDDEN = 2, /* Sym unavailable in other modules */
|
||||
STV_PROTECTED= 3 /* Not preemptible, not exported */
|
||||
};
|
||||
|
||||
enum { // st_shndx
|
||||
SHN_UNDEF = 0, /* Undefined section */
|
||||
SHN_ABS = 0xfff1, /* Associated symbol is absolute */
|
||||
SHN_COMMON = 0xfff2 /* Associated symbol is common */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
+10
-10
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||
// FIXME
|
||||
UNUSED(ft);
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +112,7 @@ void PackElks8086::pack(OutputFile *fo)
|
||||
ft.buf_len = ph.u_len;
|
||||
ft.addvalue = kernel_entry;
|
||||
// compress
|
||||
compressWithFilters(&ft, overlap_range);
|
||||
compressWithFilters(&ft, overlap_range, NULL_cconf);
|
||||
|
||||
const unsigned lsize = getLoaderSize();
|
||||
MemBuffer loader(lsize);
|
||||
@@ -122,10 +121,11 @@ void PackElks8086::pack(OutputFile *fo)
|
||||
patchPackHeader(loader, lsize);
|
||||
#if 0
|
||||
// FIXME
|
||||
patchFilter32(loader, lsize, &ft);
|
||||
patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
||||
patch_le32(loader, lsize, "KEIP", kernel_entry);
|
||||
patch_le32(loader, lsize, "STAK", stack_during_uncompression);
|
||||
defineFilterSymbols(&ft);
|
||||
defineDecompressorSymbols();
|
||||
//patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
||||
//patch_le32(loader, lsize, "KEIP", kernel_entry);
|
||||
//patch_le32(loader, lsize, "STAK", stack_during_uncompression);
|
||||
#endif
|
||||
|
||||
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
||||
|
||||
+286
-112
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -31,9 +31,10 @@
|
||||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_exe.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
#include "stub/l_exe.h"
|
||||
#include "stub/i086-dos16.exe.h"
|
||||
|
||||
#define RSFCRI 4096 // Reserved Space For Compressed Relocation Info
|
||||
#define MAXMATCH 0x2000
|
||||
@@ -49,8 +50,15 @@ static const
|
||||
PackExe::PackExe(InputFile *f) :
|
||||
super(f)
|
||||
{
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32);
|
||||
ih_exesize = ih_imagesize = ih_overlay = 0;
|
||||
stack_for_lzma = 0;
|
||||
use_clear_dirty_stack = false;
|
||||
|
||||
// disable lzma for "--brute" unless explicitly given "--lzma"
|
||||
if (opt->all_methods_use_lzma && !opt->method_lzma_seen)
|
||||
opt->all_methods_use_lzma = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +80,7 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||
#define oh (*eh)
|
||||
// fill new exe header
|
||||
int flag = 0;
|
||||
if (!opt->dos.no_reloc)
|
||||
if (!opt->dos_exe.no_reloc && !M_IS_LZMA(ph.method))
|
||||
flag |= USEJUMP;
|
||||
if (ih.relocs == 0)
|
||||
flag |= NORELOC;
|
||||
@@ -80,9 +88,17 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||
memset(&oh,0,sizeof(oh));
|
||||
oh.ident = 'M' + 'Z' * 256;
|
||||
oh.headsize16 = 2;
|
||||
oh.ip = 0;
|
||||
|
||||
oh.sp = ih.sp > 0x200 ? ih.sp : 0x200;
|
||||
unsigned minsp = 0x200;
|
||||
if (M_IS_LZMA(ph.method))
|
||||
minsp = stack_for_lzma;
|
||||
minsp = ALIGN_UP(minsp, 16u);
|
||||
assert(minsp < 0xff00);
|
||||
if (oh.sp > minsp)
|
||||
minsp = oh.sp;
|
||||
if (minsp < 0xff00 - 2)
|
||||
minsp = ALIGN_UP(minsp, 2u);
|
||||
oh.sp = minsp;
|
||||
|
||||
unsigned destpara = (ph.u_len + ph.overlap_overhead - ph.c_len + 31) / 16;
|
||||
oh.ss = ph.c_len/16 + destpara;
|
||||
@@ -94,63 +110,14 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||
|
||||
if (oh.ss != ih.ss)
|
||||
flag |= SS;
|
||||
if (oh.sp != ih.sp)
|
||||
if (oh.sp != ih.sp || M_IS_LZMA(ph.method))
|
||||
flag |= SP;
|
||||
return flag;
|
||||
#undef oh
|
||||
}
|
||||
|
||||
|
||||
int PackExe::buildLoader(const Filter *)
|
||||
void PackExe::addLoaderEpilogue(int flag)
|
||||
{
|
||||
struct exe_header_t tmp_oh;
|
||||
int flag = fillExeHeader(&tmp_oh);
|
||||
|
||||
// prepare loader
|
||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
||||
addLoader("EXEENTRY",
|
||||
relocsize ? "EXERELPU" : "",
|
||||
"EXEMAIN4""+G5DXXXX""UPX1HEAD""EXECUTPO",
|
||||
NULL
|
||||
);
|
||||
if (ph.method == M_NRV2B_8)
|
||||
addLoader("NRV2B16S", // decompressor
|
||||
ph.u_len > DI_LIMIT ? "N2B64K01" : "",
|
||||
"NRV2BEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601",
|
||||
"NRV2BEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
|
||||
"NRV2BEX3",
|
||||
ph.c_len > 0xffff ? "N2B64K02" : "",
|
||||
"NRV2BEX9""NRV2B16E",
|
||||
NULL
|
||||
);
|
||||
else if (ph.method == M_NRV2D_8)
|
||||
addLoader("NRV2D16S",
|
||||
ph.u_len > DI_LIMIT ? "N2D64K01" : "",
|
||||
"NRV2DEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601",
|
||||
"NRV2DEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
|
||||
"NRV2DEX3",
|
||||
ph.c_len > 0xffff ? "N2D64K02" : "",
|
||||
"NRV2DEX9""NRV2D16E",
|
||||
NULL
|
||||
);
|
||||
else if (ph.method == M_NRV2E_8)
|
||||
addLoader("NRV2E16S",
|
||||
ph.u_len > DI_LIMIT ? "N2E64K01" : "",
|
||||
"NRV2EEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2EX8601" : "N2E28601",
|
||||
"NRV2EEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602",
|
||||
"NRV2EEX3",
|
||||
ph.c_len > 0xffff ? "N2E64K02" : "",
|
||||
"NRV2EEX9""NRV2E16E",
|
||||
NULL
|
||||
);
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
addLoader("EXEMAIN5", NULL);
|
||||
if (relocsize)
|
||||
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
|
||||
@@ -162,6 +129,7 @@ int PackExe::buildLoader(const Filter *)
|
||||
NULL
|
||||
);
|
||||
addLoader("EXEMAIN8",
|
||||
device_driver ? "DEVICEEND" : "",
|
||||
(flag & SS) ? "EXESTACK" : "",
|
||||
(flag & SP) ? "EXESTASP" : "",
|
||||
(flag & USEJUMP) ? "EXEJUMPF" : "",
|
||||
@@ -172,7 +140,132 @@ int PackExe::buildLoader(const Filter *)
|
||||
"EXERETIP",
|
||||
NULL
|
||||
);
|
||||
return getLoaderSize();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void PackExe::buildLoader(const Filter *)
|
||||
{
|
||||
// get flag
|
||||
exe_header_t dummy_oh;
|
||||
int flag = fillExeHeader(&dummy_oh);
|
||||
|
||||
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
|
||||
|
||||
if (M_IS_LZMA(ph.method))
|
||||
{
|
||||
addLoader("LZMA_DEC00",
|
||||
opt->small ? "LZMA_DEC10" : "LZMA_DEC20",
|
||||
"LZMA_DEC30",
|
||||
use_clear_dirty_stack ? "LZMA_DEC31" : "",
|
||||
"LZMA_DEC32",
|
||||
ph.u_len > 0xffff ? "LZMA_DEC33" : "",
|
||||
NULL
|
||||
);
|
||||
|
||||
addLoaderEpilogue(flag);
|
||||
defineDecompressorSymbols();
|
||||
const unsigned lsize0 = getLoaderSize();
|
||||
|
||||
// Lzma decompression code starts at ss:0x10, and its size is
|
||||
// lsize bytes. It also needs getDecompressorWrkmemSize() bytes
|
||||
// during uncompression. It also uses some stack, so 0x100
|
||||
// more bytes are allocated
|
||||
stack_for_lzma = 0x10 + lsize0 + getDecompressorWrkmemSize() + 0x100;
|
||||
stack_for_lzma = ALIGN_UP(stack_for_lzma, 16u);
|
||||
|
||||
unsigned clear_dirty_stack_low = 0x10 + lsize0;
|
||||
clear_dirty_stack_low = ALIGN_UP(clear_dirty_stack_low, 2u);
|
||||
if (use_clear_dirty_stack)
|
||||
linker->defineSymbol("clear_dirty_stack_low", clear_dirty_stack_low);
|
||||
|
||||
relocateLoader();
|
||||
const unsigned lsize = getLoaderSize();
|
||||
assert(lsize0 == lsize);
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
|
||||
MemBuffer compressed_lzma;
|
||||
compressed_lzma.allocForCompression(lsize);
|
||||
unsigned c_len_lzma = MemBuffer::getSizeForCompression(lsize);
|
||||
int r = upx_compress(loader, lsize, compressed_lzma, &c_len_lzma,
|
||||
NULL, M_NRV2B_LE16, 9, NULL, NULL);
|
||||
assert(r == UPX_E_OK); assert(c_len_lzma < lsize);
|
||||
|
||||
info("lzma+relocator code compressed: %u -> %u", lsize, c_len_lzma);
|
||||
// reinit the loader
|
||||
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
|
||||
// prepare loader
|
||||
if (device_driver)
|
||||
addLoader("DEVICEENTRY,LZMADEVICE,DEVICEENTRY2", NULL);
|
||||
|
||||
linker->addSection("COMPRESSED_LZMA", compressed_lzma, c_len_lzma, 0);
|
||||
addLoader("LZMAENTRY,NRV2B160,NRVDDONE,NRVDECO1,NRVGTD00,NRVDECO2",
|
||||
NULL);
|
||||
|
||||
}
|
||||
else if (device_driver)
|
||||
addLoader("DEVICEENTRY,DEVICEENTRY2", NULL);
|
||||
|
||||
addLoader("EXEENTRY",
|
||||
M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB",
|
||||
"JNCDOCOPY",
|
||||
relocsize ? "EXERELPU" : "",
|
||||
"EXEMAIN4",
|
||||
M_IS_LZMA(ph.method) ? "" : "EXEMAIN4B",
|
||||
"EXEMAIN4C",
|
||||
M_IS_LZMA(ph.method) ? "COMPRESSED_LZMA_START,COMPRESSED_LZMA" : "",
|
||||
"+G5DXXXX,UPX1HEAD,EXECUTPO",
|
||||
NULL
|
||||
);
|
||||
if (ph.method == M_NRV2B_8)
|
||||
addLoader("NRV2B16S", // decompressor
|
||||
ph.u_len > DI_LIMIT ? "N2B64K01" : "",
|
||||
"NRV2BEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601",
|
||||
"NRV2BEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
|
||||
"NRV2BEX3",
|
||||
ph.c_len > 0xffff ? "N2B64K02" : "",
|
||||
"NRV2BEX9",
|
||||
NULL
|
||||
);
|
||||
else if (ph.method == M_NRV2D_8)
|
||||
addLoader("NRV2D16S",
|
||||
ph.u_len > DI_LIMIT ? "N2D64K01" : "",
|
||||
"NRV2DEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601",
|
||||
"NRV2DEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
|
||||
"NRV2DEX3",
|
||||
ph.c_len > 0xffff ? "N2D64K02" : "",
|
||||
"NRV2DEX9",
|
||||
NULL
|
||||
);
|
||||
else if (ph.method == M_NRV2E_8)
|
||||
addLoader("NRV2E16S",
|
||||
ph.u_len > DI_LIMIT ? "N2E64K01" : "",
|
||||
"NRV2EEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2EX8601" : "N2E28601",
|
||||
"NRV2EEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602",
|
||||
"NRV2EEX3",
|
||||
ph.c_len > 0xffff ? "N2E64K02" : "",
|
||||
"NRV2EEX9",
|
||||
NULL
|
||||
);
|
||||
else if M_IS_LZMA(ph.method)
|
||||
return;
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
|
||||
addLoaderEpilogue(flag);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +306,7 @@ bool PackExe::canPack()
|
||||
fi->readx(&offs,sizeof (offs));
|
||||
if (ih.relocoffs >= 0x40 && offs)
|
||||
{
|
||||
if (opt->dos.force_stub)
|
||||
if (opt->dos_exe.force_stub)
|
||||
opt->overlay = opt->COPY_OVERLAY;
|
||||
else
|
||||
throwCantPack("can't pack new-exe");
|
||||
@@ -231,6 +324,9 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
const upx_byte *relocs, const unsigned nrelocs,
|
||||
upx_byte *crel, bool *has_9a)
|
||||
{
|
||||
if (opt->exact)
|
||||
throwCantPackExact();
|
||||
|
||||
upx_byte * const crel_save = crel;
|
||||
unsigned i;
|
||||
unsigned seg_high = 0;
|
||||
@@ -293,7 +389,9 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
{
|
||||
addr = get_le32(relocs+4*i);
|
||||
//printf ("%x\n",es*16+di);
|
||||
if (addr - es*16 > 0xfffe)
|
||||
if ((addr - es*16 > 0xfffe)
|
||||
|| (i == nrelocs - 1 && addr - es * 16 > 0xff00)
|
||||
)
|
||||
{
|
||||
// segment change
|
||||
t = 1+(0xffff-di)/254;
|
||||
@@ -303,7 +401,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
break;
|
||||
}
|
||||
unsigned offs = addr - es*16;
|
||||
if (offs >= 3 && b[es*16 + offs-3] == 0x9a)
|
||||
if (offs >= 3 && b[es*16 + offs-3] == 0x9a && offs > di + 3)
|
||||
{
|
||||
for (t = di; t < offs-3; t++)
|
||||
if (b[es*16+t] == 0x9a && get_le16(b+es*16+t+3) <= seg_high)
|
||||
@@ -338,7 +436,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
set_le16 (crel_save+2,seg_high);
|
||||
|
||||
//OutputFile::dump("x.rel", crel_save, crel - crel_save);
|
||||
return crel - crel_save;
|
||||
return (unsigned) (crel - crel_save);
|
||||
}
|
||||
|
||||
|
||||
@@ -365,6 +463,8 @@ void PackExe::pack(OutputFile *fo)
|
||||
|
||||
checkAlreadyPacked(ibuf, UPX_MIN(ih_imagesize, 127u));
|
||||
|
||||
device_driver = get_le32(ibuf) == 0xffffffffu;
|
||||
|
||||
// relocations
|
||||
has_9a = false;
|
||||
upx_byte *w = ibuf + ih_imagesize;
|
||||
@@ -378,7 +478,7 @@ void PackExe::pack(OutputFile *fo)
|
||||
for (ic = 0; ic < ih.relocs; ic++)
|
||||
{
|
||||
unsigned jc = get_le32(wr+4*ic);
|
||||
set_le32(wr+4*ic, (jc>>16)*16+(jc&0xffff));
|
||||
set_le32(wr+4*ic, ((jc>>16)*16+(jc&0xffff)) & 0xfffff);
|
||||
}
|
||||
qsort(wr,ih.relocs,4,le32_compare);
|
||||
relocsize = optimize_relocs(ibuf, ih_imagesize, wr, ih.relocs, w, &has_9a);
|
||||
@@ -403,13 +503,18 @@ void PackExe::pack(OutputFile *fo)
|
||||
ph.u_len = ih_imagesize + relocsize;
|
||||
// prepare filter
|
||||
Filter ft(ph.level);
|
||||
// compress
|
||||
compressWithFilters(&ft, 32, 0, NULL, 0, MAXMATCH);
|
||||
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
||||
// compress (max_match = 8192)
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
cconf.conf_ucl.max_match = MAXMATCH;
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, 32, &cconf);
|
||||
|
||||
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
|
||||
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
||||
|
||||
#ifdef TESTING
|
||||
if (opt->debug)
|
||||
if (opt->debug.debug_level)
|
||||
{
|
||||
printf("image+relocs %d -> %d\n",ih_imagesize+relocsize,ph.c_len);
|
||||
printf("offsets: %d - %d\nmatches: %d - %d\nruns: %d - %d\n",
|
||||
@@ -437,8 +542,8 @@ void PackExe::pack(OutputFile *fo)
|
||||
|
||||
// set oh.min & oh.max
|
||||
ic = ih.min*16 + ih_imagesize;
|
||||
if (ic < oh.ss*16 + oh.sp)
|
||||
ic = oh.ss*16 + oh.sp;
|
||||
if (ic < oh.ss*16u + oh.sp)
|
||||
ic = oh.ss*16u + oh.sp;
|
||||
oh.min = (ic - (packedsize + lsize)) / 16;
|
||||
ic = oh.min + (ih.max - ih.min);
|
||||
oh.max = ic < 0xffff && ih.max != 0xffff ? ic : 0xffff;
|
||||
@@ -472,60 +577,61 @@ void PackExe::pack(OutputFile *fo)
|
||||
}
|
||||
extra_info[eisize++] = (unsigned char) flag;
|
||||
|
||||
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
|
||||
linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((packedsize & 15) + 1));
|
||||
|
||||
unsigned decompressor_entry = 1 + (packedsize & 15);
|
||||
if (M_IS_LZMA(ph.method))
|
||||
decompressor_entry = 0x10;
|
||||
linker->defineSymbol("decompressor_entry", decompressor_entry);
|
||||
|
||||
// patch loader
|
||||
if (flag & USEJUMP)
|
||||
{
|
||||
// I use a relocation entry to set the original cs
|
||||
unsigned n = find_le32(loader,lsize,get_le32("IPCS"));
|
||||
patch_le32(loader,lsize,get_le32("IPCS"), ih.cs*0x10000 + ih.ip);
|
||||
unsigned n = getLoaderSectionStart("EXEJUMPF") + 1;
|
||||
n += packedsize + 2;
|
||||
oh.relocs = 1;
|
||||
oh.firstreloc = (n&0xf) + ((n>>4)<<16);
|
||||
oh.firstreloc = (n & 0xf) + ((n >> 4) << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
patch_le16(loader,lsize,"IP",ih.ip);
|
||||
if (ih.cs)
|
||||
patch_le16(loader,lsize,"CS",ih.cs);
|
||||
oh.relocs = 0;
|
||||
oh.firstreloc = ih.cs*0x10000 + ih.ip;
|
||||
oh.firstreloc = ih.cs * 0x10000 + ih.ip;
|
||||
}
|
||||
|
||||
// g++ 3.1 does not like the following line...
|
||||
// oh.relocoffs = offsetof(exe_header_t, firstreloc);
|
||||
oh.relocoffs = ptr_diff(&oh.firstreloc, &oh);
|
||||
|
||||
if (flag & SP)
|
||||
patch_le16(loader,lsize,"SP",ih.sp);
|
||||
if (flag & SS)
|
||||
patch_le16(loader,lsize,"SS",ih.ss);
|
||||
if (relocsize)
|
||||
patch_le16(loader,lsize,"RS",(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? 0 : MAXRELOCS) - relocsize);
|
||||
linker->defineSymbol("destination_segment", oh.ss - ph.c_len / 16 - e_len / 16);
|
||||
linker->defineSymbol("source_segment", e_len / 16 + (copysize - firstcopy) / 16);
|
||||
linker->defineSymbol("copy_offset", firstcopy - 2);
|
||||
linker->defineSymbol("words_to_copy",firstcopy / 2);
|
||||
|
||||
patchPackHeader(loader,e_len);
|
||||
|
||||
patch_le16(loader,e_len,"BX",0x800F + 0x10*((packedsize&15)+1) - 0x10);
|
||||
patch_le16(loader,e_len,"BP",(packedsize&15)+1);
|
||||
|
||||
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");
|
||||
linker->defineSymbol("exe_stack_sp", oh.sp);
|
||||
linker->defineSymbol("exe_stack_ss", oh.ss);
|
||||
linker->defineSymbol("interrupt", get_le16(ibuf + 8));
|
||||
linker->defineSymbol("attribute", get_le16(ibuf + 4));
|
||||
linker->defineSymbol("orig_strategy", get_le16(ibuf + 6));
|
||||
|
||||
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
||||
oh.m512 = outputlen & 511;
|
||||
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);
|
||||
const char *exeentry = M_IS_LZMA(ph.method) ? "LZMAENTRY" : "EXEENTRY";
|
||||
oh.ip = device_driver ? getLoaderSection(exeentry) - 2 : 0;
|
||||
|
||||
defineDecompressorSymbols();
|
||||
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
|
||||
#ifdef TESTING
|
||||
if (opt->debug)
|
||||
if (opt->debug.debug_level)
|
||||
printf("\n%d %d %d %d\n",(int)sizeof(oh),e_len,packedsize,d_len);
|
||||
#endif
|
||||
fo->write(&oh,sizeof(oh));
|
||||
@@ -565,7 +671,7 @@ int PackExe::canUnpack()
|
||||
return false;
|
||||
const off_t off = ih.headsize16 * 16;
|
||||
fi->seek(off, SEEK_SET);
|
||||
bool b = readPackHeader(128);
|
||||
bool b = readPackHeader(4096);
|
||||
return b && (off + (off_t) ph.c_len <= file_size);
|
||||
}
|
||||
|
||||
@@ -605,12 +711,11 @@ void PackExe::unpack(OutputFile *fo)
|
||||
{
|
||||
relocs -= get_le16(obuf+ph.u_len-2);
|
||||
ph.u_len -= 2;
|
||||
upx_byte *p;
|
||||
|
||||
wrkmem.alloc(4*MAXRELOCS);
|
||||
unsigned es = 0,ones = get_le16(relocs);
|
||||
unsigned seghi = get_le16(relocs+2);
|
||||
p = relocs + 4;
|
||||
unsigned es = 0, ones = get_le16(relocs);
|
||||
const unsigned seghi = get_le16(relocs+2);
|
||||
const upx_byte *p = relocs + 4;
|
||||
|
||||
while (ones)
|
||||
{
|
||||
@@ -628,10 +733,10 @@ void PackExe::unpack(OutputFile *fo)
|
||||
dorel = true;
|
||||
if (*p == 0)
|
||||
{
|
||||
upx_byte *q;
|
||||
const upx_byte *q;
|
||||
for (q = obuf+es*16+di; !(*q == 0x9a && get_le16(q+3) <= seghi); q++)
|
||||
;
|
||||
di = q - (obuf+es*16) + 3;
|
||||
di = ptr_diff(q, obuf+es*16) + 3;
|
||||
}
|
||||
else if (*p == 1)
|
||||
{
|
||||
@@ -668,15 +773,15 @@ void PackExe::unpack(OutputFile *fo)
|
||||
oh.ss = ih.ss;
|
||||
|
||||
if (flag & MAXMEM)
|
||||
imagesize -= 2, oh.max = get_le16(ibuf+imagesize);
|
||||
{ imagesize -= 2; oh.max = get_le16(ibuf+imagesize); }
|
||||
if (flag & MINMEM)
|
||||
imagesize -= 2, oh.min = get_le16(ibuf+imagesize);
|
||||
{ imagesize -= 2; oh.min = get_le16(ibuf+imagesize); }
|
||||
if (flag & SP)
|
||||
imagesize -= 2, oh.sp = get_le16(ibuf+imagesize);
|
||||
{ imagesize -= 2; oh.sp = get_le16(ibuf+imagesize); }
|
||||
if (flag & SS)
|
||||
imagesize -= 2, oh.ss = get_le16(ibuf+imagesize);
|
||||
{ imagesize -= 2; oh.ss = get_le16(ibuf+imagesize); }
|
||||
|
||||
unsigned ip = (flag & USEJUMP) ? get_le32(ibuf+imagesize-4) : ih.firstreloc;
|
||||
unsigned ip = (flag & USEJUMP) ? get_le32(ibuf+imagesize-4) : (unsigned) ih.firstreloc;
|
||||
oh.ip = ip & 0xffff;
|
||||
oh.cs = ip >> 16;
|
||||
|
||||
@@ -696,6 +801,75 @@ void PackExe::unpack(OutputFile *fo)
|
||||
}
|
||||
|
||||
|
||||
Linker* PackExe::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
memory layout at decompression time
|
||||
===================================
|
||||
|
||||
normal exe
|
||||
----------
|
||||
|
||||
a, at load time
|
||||
|
||||
(e - copying code, C - compressed data, d - decompressor+relocator,
|
||||
x - not specified, U - uncompressed code+data, R uncompressed relocation)
|
||||
|
||||
eeCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCdddd
|
||||
^ CS:0 ^ SS:0
|
||||
|
||||
b, after copying
|
||||
|
||||
xxxxxxxxxxxxxxxCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCdddd
|
||||
^ES:DI=0 ^ DS:SI=0 ^ CS=SS, IP in range 0..0xf
|
||||
|
||||
c, after uncompression
|
||||
|
||||
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUURRdddd
|
||||
^ ES:DI
|
||||
|
||||
device driver
|
||||
-------------
|
||||
|
||||
the file has 2 entry points, CS:0 in device driver mode, and
|
||||
CS:exe_as_device_entry in normal mode. the code in section DEVICEENTRY
|
||||
sets up the same environment for section EXEENTRY, as it would see in normal
|
||||
execution mode.
|
||||
|
||||
lzma uncompression for normal exes
|
||||
----------------------------------
|
||||
|
||||
(n - nrv2b uncompressor, l - nrv2b compressed lzma + relocator code)
|
||||
|
||||
a, at load time
|
||||
|
||||
nneelllCCCCCCCCCCCCCCCCCCCCCCCCC
|
||||
|
||||
^ CS:0 ^ SS:0
|
||||
|
||||
b, after nrv2b
|
||||
|
||||
nneelllCCCCCCCCCCCCCCCCCCCCCCCCC dddd
|
||||
^ CS:0 ^ SS:0x10
|
||||
|
||||
after this, normal ee code runs
|
||||
|
||||
lzma + device driver
|
||||
--------------------
|
||||
|
||||
(D - device driver adapter)
|
||||
|
||||
a, at load time
|
||||
|
||||
DDnneelllCCCCCCCCCCCCCCCCCCCCCCCCC
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
+12
-4
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@ public:
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_DOS_EXE; }
|
||||
virtual const char *getName() const { return "dos/exe"; }
|
||||
//virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_8086 ? "i086-dos16.exe" : "i286-dos16.exe"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i086-dos16.exe"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
@@ -68,7 +70,9 @@ protected:
|
||||
virtual int readFileHeader(void);
|
||||
|
||||
virtual int fillExeHeader(struct exe_header_t *) const;
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
void addLoaderEpilogue(int flag);
|
||||
|
||||
struct exe_header_t
|
||||
{
|
||||
@@ -98,6 +102,7 @@ protected:
|
||||
unsigned relocsize;
|
||||
|
||||
bool has_9a;
|
||||
bool device_driver;
|
||||
|
||||
enum {
|
||||
NORELOC = 1,
|
||||
@@ -107,6 +112,9 @@ protected:
|
||||
MINMEM = 16,
|
||||
MAXMEM = 32
|
||||
};
|
||||
|
||||
unsigned stack_for_lzma; // stack size required for lzma
|
||||
bool use_clear_dirty_stack;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+2182
-267
File diff suppressed because it is too large
Load Diff
+457
-32
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 2000-2002 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
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.,
|
||||
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
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
@@ -31,52 +34,474 @@
|
||||
#define __UPX_P_LX_ELF_H
|
||||
|
||||
|
||||
class PackLinuxElf : public PackUnix
|
||||
{
|
||||
typedef PackUnix super;
|
||||
public:
|
||||
PackLinuxElf(InputFile *f);
|
||||
virtual ~PackLinuxElf();
|
||||
/*virtual void buildLoader(const Filter *);*/
|
||||
virtual bool canUnpackVersion(int version) const { return (version >= 11); }
|
||||
|
||||
protected:
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
|
||||
// All other virtual functions in this class must be pure virtual
|
||||
// because they depend on Elf32 or Elf64 data structures, which differ.
|
||||
|
||||
virtual void pack1(OutputFile *, Filter &) = 0; // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &) = 0; // append compressed data
|
||||
virtual void pack3(OutputFile *, Filter &) = 0; // append loader
|
||||
//virtual void pack4(OutputFile *, Filter &) = 0; // append pack header
|
||||
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
void const *proto,
|
||||
unsigned const brka
|
||||
) = 0;
|
||||
virtual void defineSymbols(Filter const *);
|
||||
virtual void addStubEntrySections(Filter const *);
|
||||
virtual void unpack(OutputFile *fo) = 0;
|
||||
|
||||
protected:
|
||||
char *file_image; // if ET_DYN investigation
|
||||
char const *dynstr; // from DT_STRTAB
|
||||
|
||||
unsigned sz_phdrs; // sizeof Phdr[]
|
||||
unsigned sz_elf_hdrs; // all Elf headers
|
||||
unsigned sz_pack2; // after pack2(), before loader
|
||||
unsigned lg2_page; // log2(PAGE_SIZE)
|
||||
unsigned page_size; // 1u<<lg2_page
|
||||
|
||||
unsigned short e_machine;
|
||||
unsigned char ei_class;
|
||||
unsigned char ei_data;
|
||||
unsigned char ei_osabi;
|
||||
char const *osabi_note;
|
||||
};
|
||||
|
||||
class PackLinuxElf32 : public PackLinuxElf
|
||||
{
|
||||
typedef PackLinuxElf super;
|
||||
public:
|
||||
PackLinuxElf32(InputFile *f);
|
||||
virtual ~PackLinuxElf32();
|
||||
protected:
|
||||
virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
|
||||
virtual bool canPack();
|
||||
|
||||
// These ARM routines are essentially common to big/little endian,
|
||||
// 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 pack2(OutputFile *, Filter &); // append compressed data
|
||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
void const *proto,
|
||||
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 void patchLoader();
|
||||
virtual void updateLoader(OutputFile *fo);
|
||||
virtual unsigned find_LOAD_gap(Elf32_Phdr const *const phdri, unsigned const k,
|
||||
unsigned const e_phnum);
|
||||
virtual off_t getbase(const Elf32_Phdr *phdr, int e_phnum) const;
|
||||
|
||||
static unsigned elf_hash(char const *) /*const*/;
|
||||
static unsigned gnu_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;
|
||||
Elf32_Shdr const *elf_find_section_name(char const *) const;
|
||||
Elf32_Shdr const *elf_find_section_type(unsigned) const;
|
||||
|
||||
protected:
|
||||
Elf32_Ehdr ehdri; // from input file
|
||||
Elf32_Phdr *phdri; // for input file
|
||||
Elf32_Shdr const *shdri; // from input file
|
||||
unsigned page_mask; // AND clears the offset-within-page
|
||||
|
||||
Elf32_Dyn const *dynseg; // from PT_DYNAMIC
|
||||
unsigned int const *hashtab; // from DT_HASH
|
||||
unsigned int const *gashtab; // from DT_GNU_HASH
|
||||
Elf32_Sym const *dynsym; // from DT_SYMTAB
|
||||
char const *shstrtab; // via Elf32_Shdr
|
||||
int n_elf_shnum; // via e_shnum
|
||||
|
||||
Elf32_Shdr const *sec_strndx;
|
||||
Elf32_Shdr const *sec_dynsym;
|
||||
Elf32_Shdr const *sec_dynstr;
|
||||
|
||||
struct cprElfHdr1 {
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Phdr phdr[1];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr2 {
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Phdr phdr[2];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr3 {
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Phdr phdr[3];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
cprElfHdr3 elfout;
|
||||
|
||||
struct Elf32_Note {
|
||||
unsigned namesz; // 8
|
||||
unsigned descsz; // 4
|
||||
unsigned type; // 1
|
||||
char text[0x18 - 4*4]; // "OpenBSD"
|
||||
unsigned end; // 0
|
||||
} elfnote;
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 52 + 1*32 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 52 + 2*32 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 52 + 3*32 + 12)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class PackLinuxElf64 : public PackLinuxElf
|
||||
{
|
||||
typedef PackLinuxElf super;
|
||||
public:
|
||||
PackLinuxElf64(InputFile *f);
|
||||
virtual ~PackLinuxElf64();
|
||||
/*virtual void buildLoader(const Filter *);*/
|
||||
|
||||
protected:
|
||||
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
|
||||
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
void const *proto,
|
||||
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 void patchLoader();
|
||||
virtual void updateLoader(OutputFile *fo);
|
||||
virtual unsigned find_LOAD_gap(Elf64_Phdr const *const phdri, unsigned const k,
|
||||
unsigned const e_phnum);
|
||||
|
||||
protected:
|
||||
Elf64_Ehdr ehdri; // from input file
|
||||
Elf64_Phdr *phdri; // for input file
|
||||
acc_uint64l_t page_mask; // AND clears the offset-within-page
|
||||
|
||||
struct cprElfHdr1 {
|
||||
Elf64_Ehdr ehdr;
|
||||
Elf64_Phdr phdr[1];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr2 {
|
||||
Elf64_Ehdr ehdr;
|
||||
Elf64_Phdr phdr[2];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr3 {
|
||||
Elf64_Ehdr ehdr;
|
||||
Elf64_Phdr phdr[3];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
cprElfHdr3 elfout;
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 64 + 1*56 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 64 + 2*56 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 64 + 3*56 + 12)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
|
||||
}
|
||||
};
|
||||
|
||||
class PackLinuxElf32Be : public PackLinuxElf32
|
||||
{
|
||||
typedef PackLinuxElf32 super;
|
||||
protected:
|
||||
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 unsigned get_native32(const void *b) const { return get_be32(b); }
|
||||
virtual unsigned get_native16(const void *b) const { return get_be16(b); }
|
||||
virtual void set_native64(void *b, acc_uint64l_t v) const { set_be64(b, v); }
|
||||
virtual void set_native32(void *b, unsigned v) const { set_be32(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
|
||||
{
|
||||
typedef PackLinuxElf64 super;
|
||||
protected:
|
||||
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 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); }
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
// linux/elf64amd
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxElf64amd : public PackLinuxElf64Le
|
||||
{
|
||||
typedef PackLinuxElf64Le super;
|
||||
public:
|
||||
PackLinuxElf64amd(InputFile *f);
|
||||
virtual ~PackLinuxElf64amd();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF64_AMD; }
|
||||
virtual const char *getName() const { return "linux/ElfAMD"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "amd64-linux.elf"; }
|
||||
virtual const int *getFilters() const;
|
||||
virtual bool canPack();
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
//virtual void pack3(OutputFile *, Filter &); // append loader
|
||||
virtual void buildLoader(const Filter *);
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void defineSymbols(Filter const *);
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
// linux/elf32ppc
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxElf32ppc : public PackLinuxElf32Be
|
||||
{
|
||||
typedef PackLinuxElf32Be super;
|
||||
public:
|
||||
PackLinuxElf32ppc(InputFile *f);
|
||||
virtual ~PackLinuxElf32ppc();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
|
||||
virtual const char *getName() const { return "linux/ElfPPC"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "powerpc-linux.elf"; }
|
||||
virtual const int *getFilters() const;
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual void buildLoader(const Filter *);
|
||||
virtual Linker* newLinker() const;
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
// linux/elf386
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxI386elf : public PackLinuxI386
|
||||
class PackLinuxElf32x86 : public PackLinuxElf32Le
|
||||
{
|
||||
typedef PackLinuxI386 super;
|
||||
typedef PackLinuxElf32Le super;
|
||||
public:
|
||||
PackLinuxI386elf(InputFile *f);
|
||||
virtual ~PackLinuxI386elf();
|
||||
virtual int getVersion() const { return 13; }
|
||||
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 char *getFullName(const options_t *) const { return "i386-linux.elf"; }
|
||||
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:
|
||||
struct Extent {
|
||||
off_t offset;
|
||||
off_t size;
|
||||
};
|
||||
virtual void packExtent(Extent const &x,
|
||||
unsigned &total_in, unsigned &total_out, Filter *, OutputFile *);
|
||||
virtual void unpackExtent(unsigned wanted, OutputFile *fo,
|
||||
unsigned &total_in, unsigned &total_out,
|
||||
unsigned &c_adler, unsigned &u_adler,
|
||||
bool first_PF_X, unsigned szb_info );
|
||||
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 pack2(OutputFile *, Filter &); // append compressed data
|
||||
|
||||
virtual void patchLoader();
|
||||
|
||||
Elf_LE32_Ehdr ehdri; // from input file
|
||||
Elf_LE32_Phdr *phdri; // for input file
|
||||
unsigned sz_phdrs; // sizeof Phdr[]
|
||||
|
||||
virtual void buildLoader(const Filter *);
|
||||
};
|
||||
|
||||
class PackFreeBSDElf32x86 : public PackBSDElf32x86
|
||||
{
|
||||
typedef PackBSDElf32x86 super;
|
||||
public:
|
||||
PackFreeBSDElf32x86(InputFile *f);
|
||||
virtual ~PackFreeBSDElf32x86();
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-freebsd.elf"; }
|
||||
};
|
||||
|
||||
class PackNetBSDElf32x86 : public PackBSDElf32x86
|
||||
{
|
||||
typedef PackBSDElf32x86 super;
|
||||
public:
|
||||
PackNetBSDElf32x86(InputFile *f);
|
||||
virtual ~PackNetBSDElf32x86();
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-netbsd.elf"; }
|
||||
};
|
||||
|
||||
class PackOpenBSDElf32x86 : public PackBSDElf32x86
|
||||
{
|
||||
typedef PackBSDElf32x86 super;
|
||||
public:
|
||||
PackOpenBSDElf32x86(InputFile *f);
|
||||
virtual ~PackOpenBSDElf32x86();
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-openbsd.elf"; }
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
void const *proto,
|
||||
unsigned const brka
|
||||
);
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
// linux/elfarm
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxElf32armLe : public PackLinuxElf32Le
|
||||
{
|
||||
typedef PackLinuxElf32Le super;
|
||||
public:
|
||||
PackLinuxElf32armLe(InputFile *f);
|
||||
virtual ~PackLinuxElf32armLe();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMEL; }
|
||||
virtual const char *getName() const { return "linux/armel"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "arm-linux.elf"; }
|
||||
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 *);
|
||||
};
|
||||
|
||||
class PackLinuxElf32armBe : public PackLinuxElf32Be
|
||||
{
|
||||
typedef PackLinuxElf32Be super;
|
||||
public:
|
||||
PackLinuxElf32armBe(InputFile *f);
|
||||
virtual ~PackLinuxElf32armBe();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMEB; }
|
||||
virtual const char *getName() const { return "linux/armeb"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "armeb-linux.elf"; }
|
||||
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 *);
|
||||
};
|
||||
|
||||
class PackLinuxElf32mipseb : public PackLinuxElf32Be
|
||||
{
|
||||
typedef PackLinuxElf32Be super;
|
||||
public:
|
||||
PackLinuxElf32mipseb(InputFile *f);
|
||||
virtual ~PackLinuxElf32mipseb();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF32_MIPSEB; }
|
||||
virtual const char *getName() const { return "linux/mipseb"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "mips-linux.elf"; }
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
protected:
|
||||
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 *);
|
||||
};
|
||||
|
||||
class PackLinuxElf32mipsel : public PackLinuxElf32Le
|
||||
{
|
||||
typedef PackLinuxElf32Le super;
|
||||
public:
|
||||
PackLinuxElf32mipsel(InputFile *f);
|
||||
virtual ~PackLinuxElf32mipsel();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF32_MIPSEL; }
|
||||
virtual const char *getName() const { return "linux/mipsel"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "mipsel-linux.elf"; }
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
protected:
|
||||
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 */
|
||||
|
||||
|
||||
+336
-188
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 2001-2002 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2001-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
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.,
|
||||
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
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
@@ -37,22 +40,49 @@
|
||||
#include "p_unix.h"
|
||||
#include "p_lx_exc.h"
|
||||
|
||||
#define PT_LOAD Elf_LE32_Phdr::PT_LOAD
|
||||
#define PT_DYNAMIC Elf_LE32_Phdr::PT_DYNAMIC
|
||||
#define DT_NULL Elf_LE32_Dyn::DT_NULL
|
||||
#define DT_NEEDED Elf_LE32_Dyn::DT_NEEDED
|
||||
#define DT_STRTAB Elf_LE32_Dyn::DT_STRTAB
|
||||
#define DT_STRSZ Elf_LE32_Dyn::DT_STRSZ
|
||||
#define PT_LOAD Elf32_Phdr::PT_LOAD
|
||||
#define PT_DYNAMIC Elf32_Phdr::PT_DYNAMIC
|
||||
#if 0 // UNUSED
|
||||
#define DT_NULL Elf32_Dyn::DT_NULL
|
||||
#define DT_NEEDED Elf32_Dyn::DT_NEEDED
|
||||
#define DT_STRTAB Elf32_Dyn::DT_STRTAB
|
||||
#define DT_STRSZ Elf32_Dyn::DT_STRSZ
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// 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
|
||||
#include "stub/l_lx_exec86.h"
|
||||
#include "stub/i386-linux.elf.execve-entry.h"
|
||||
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
|
||||
@@ -63,32 +93,53 @@ const int *PackLinuxI386::getCompressionMethods(int method, int level) const
|
||||
const int *PackLinuxI386::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
#if 1
|
||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
||||
#else
|
||||
0x49, 0x46,
|
||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
||||
#if 0
|
||||
// 0x80..0x87 are regarded as "untested".
|
||||
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
|
||||
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
||||
#endif
|
||||
-1 };
|
||||
FT_END };
|
||||
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
|
||||
PackLinuxI386::generateElfHdr(
|
||||
OutputFile *const fo,
|
||||
void const *const proto,
|
||||
OutputFile *fo,
|
||||
void const *proto,
|
||||
unsigned const brka
|
||||
)
|
||||
{
|
||||
cprElfHdr1 *const h1 = (cprElfHdr1 *)&elfout;
|
||||
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout;
|
||||
memcpy(h2, proto, sizeof(*h2));
|
||||
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;
|
||||
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
|
||||
|
||||
assert(h2->ehdr.e_phoff == sizeof(Elf_LE32_Ehdr));
|
||||
assert(h2->ehdr.e_phoff == sizeof(Elf32_Ehdr));
|
||||
assert(h2->ehdr.e_shoff == 0);
|
||||
assert(h2->ehdr.e_ehsize == sizeof(Elf_LE32_Ehdr));
|
||||
assert(h2->ehdr.e_phentsize == sizeof(Elf_LE32_Phdr));
|
||||
assert(h2->ehdr.e_ehsize == sizeof(Elf32_Ehdr));
|
||||
assert(h2->ehdr.e_phentsize == sizeof(Elf32_Phdr));
|
||||
assert(h2->ehdr.e_shnum == 0);
|
||||
|
||||
#if 0 //{
|
||||
@@ -100,29 +151,26 @@ PackLinuxI386::generateElfHdr(
|
||||
|
||||
// Info for OS kernel to set the brk()
|
||||
if (brka) {
|
||||
h2->phdr[1].p_type = PT_LOAD; // be sure
|
||||
h2->phdr[1].p_offset = 0xfff&brka;
|
||||
h2->phdr[1].p_vaddr = brka;
|
||||
h2->phdr[1].p_paddr = brka;
|
||||
h2->phdr[1].p_filesz = 0;
|
||||
h2->phdr[1].p_memsz = 0;
|
||||
set_stub_brk(&h2->phdr[1], brka);
|
||||
}
|
||||
|
||||
if (ph.format==UPX_F_LINUX_i386 ) {
|
||||
assert(h1->ehdr.e_phnum==1);
|
||||
memset(&h1->linfo, 0, sizeof(h1->linfo));
|
||||
fo->write(h1, sizeof(*h1));
|
||||
}
|
||||
else if (ph.format==UPX_F_LINUX_ELF_i386) {
|
||||
if (ph.format==UPX_F_LINUX_i386
|
||||
|| ph.format==UPX_F_LINUX_SH_i386
|
||||
|| ph.format==UPX_F_BSD_i386
|
||||
) {
|
||||
// SELinux, PAx, grSecurity demand no PF_W if PF_X.
|
||||
// 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);
|
||||
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
||||
fo->write(h2, sizeof(*h2));
|
||||
}
|
||||
else if (ph.format==UPX_F_LINUX_SH_i386) {
|
||||
assert(h2->ehdr.e_phnum==1);
|
||||
h2->ehdr.e_phnum = 2;
|
||||
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
||||
fo->write(h2, sizeof(*h2));
|
||||
else if (ph.format==UPX_F_LINUX_ELFI_i386) {
|
||||
assert(h3->ehdr.e_phnum==3);
|
||||
memset(&h3->linfo, 0, sizeof(h3->linfo));
|
||||
fo->write(h3, sizeof(*h3));
|
||||
}
|
||||
else {
|
||||
assert(false); // unknown ph.format, PackUnix::generateElfHdr
|
||||
@@ -135,7 +183,16 @@ PackLinuxI386::pack1(OutputFile *fo, Filter &)
|
||||
// create a pseudo-unique program id for our paranoid stub
|
||||
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
|
||||
@@ -144,21 +201,82 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
||||
overlay_offset = sizeof(elfout.ehdr) +
|
||||
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||
sizeof(l_info) +
|
||||
((elfout.ehdr.e_phnum==3) ? elfout.phdr[2].p_memsz : 0) ;
|
||||
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
|
||||
unsigned nw = fo->getBytesWritten();
|
||||
elfout.phdr[0].p_filesz = nw;
|
||||
nw = 0u-((0u-elfout.phdr[0].p_align) & (0u-nw)); // ALIGN_UP
|
||||
super::pack4(fo, ft); // write PackHeader and overlay_offset
|
||||
set_stub_brk(&elfout.phdr[1], nw + elfout.phdr[0].p_vaddr);
|
||||
|
||||
elfout.phdr[0].p_filesz = fo->getBytesWritten();
|
||||
#if 0 // {
|
||||
// /usr/bin/strip from RedHat 8.0 (binutils-2.13.90.0.2-2)
|
||||
// generates a 92-byte [only] output, because the "linking view"
|
||||
// is empty. This code supplies a "linking view".
|
||||
// However, 'strip' then generates _plausible_ junk that gets
|
||||
// "Illegal instruction" because 'strip' changes p_hdr[1].p_align,
|
||||
// .p_offset, and .p_vaddr incorrectly. So the "cure" is worse than
|
||||
// the disease. It is obvious that a 92-byte file is bad,
|
||||
// but it is not obvious that the changed .p_align is bad.
|
||||
// Also, having a totally empty "linking view" is easier for 'strip'
|
||||
// to fix: just detect that, and do nothing.
|
||||
// So, we don't use this code for now [2003-01-11].
|
||||
|
||||
#define PAGE_MASK (~0<<12)
|
||||
// Supply a "linking view" that covers everything,
|
||||
// so that 'strip' does not omit everything.
|
||||
Elf_LE32_Shdr shdr;
|
||||
// The section header string table.
|
||||
char const shstrtab[] = "\0.\0.shstrtab";
|
||||
|
||||
unsigned eod = elfout.phdr[0].p_filesz;
|
||||
elfout.ehdr.e_shoff = eod;
|
||||
elfout.ehdr.e_shentsize = sizeof(shdr);
|
||||
elfout.ehdr.e_shnum = 3;
|
||||
elfout.ehdr.e_shstrndx = 2;
|
||||
|
||||
// An empty Elf32_Shdr for space as a null index.
|
||||
memset(&shdr, 0, sizeof(shdr));
|
||||
shdr.sh_type = Elf32_Shdr::SHT_NULL;
|
||||
fo->write(&shdr, sizeof(shdr));
|
||||
|
||||
// Cover all the bits we need at runtime.
|
||||
memset(&shdr, 0, sizeof(shdr));
|
||||
shdr.sh_name = 1;
|
||||
shdr.sh_type = Elf32_Shdr::SHT_PROGBITS;
|
||||
shdr.sh_flags = Elf32_Shdr::SHF_ALLOC;
|
||||
shdr.sh_addr = elfout.phdr[0].p_vaddr;
|
||||
shdr.sh_offset = overlay_offset;
|
||||
shdr.sh_size = eod - overlay_offset;
|
||||
shdr.sh_addralign = 4096;
|
||||
fo->write(&shdr, sizeof(shdr));
|
||||
|
||||
// A section header for the section header string table.
|
||||
memset(&shdr, 0, sizeof(shdr));
|
||||
shdr.sh_name = 3;
|
||||
shdr.sh_type = Elf32_Shdr::SHT_STRTAB;
|
||||
shdr.sh_offset = 3*sizeof(shdr) + eod;
|
||||
shdr.sh_size = sizeof(shstrtab);
|
||||
fo->write(&shdr, sizeof(shdr));
|
||||
|
||||
fo->write(shstrtab, sizeof(shstrtab));
|
||||
#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
|
||||
#define PAGE_MASK (~0u<<12)
|
||||
// pre-calculate for benefit of runtime disappearing act via munmap()
|
||||
elfout.phdr[0].p_memsz = PAGE_MASK & (~PAGE_MASK + elfout.phdr[0].p_filesz);
|
||||
#undef PAGE_MASK
|
||||
#else /*}{*/
|
||||
elfout.phdr[0].p_memsz = elfout.phdr[0].p_filesz;
|
||||
#endif /*}*/
|
||||
|
||||
// rewrite Elf header
|
||||
fo->seek(0, SEEK_SET);
|
||||
fo->rewrite(&elfout, sizeof(elfout.ehdr) +
|
||||
elfout.ehdr.e_phnum * sizeof(elfout.phdr[0]) +
|
||||
sizeof(l_info) );
|
||||
fo->rewrite(&elfout, overlay_offset);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
@@ -170,7 +288,12 @@ umax(unsigned a, unsigned b)
|
||||
return a;
|
||||
}
|
||||
|
||||
int
|
||||
Linker *PackLinuxI386::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
void
|
||||
PackLinuxI386::buildLinuxLoader(
|
||||
upx_byte const *const proto,
|
||||
unsigned const szproto,
|
||||
@@ -181,128 +304,106 @@ PackLinuxI386::buildLinuxLoader(
|
||||
{
|
||||
initLoader(proto, szproto);
|
||||
|
||||
unsigned fold_hdrlen = 0;
|
||||
if (0 < szfold) {
|
||||
cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
|
||||
unsigned const fold_hdrlen = umax(0x80, sizeof(hf->ehdr) +
|
||||
hf->ehdr.e_phentsize * hf->ehdr.e_phnum + sizeof(l_info) );
|
||||
struct b_info h; memset(&h, 0, sizeof(h));
|
||||
h.sz_unc = 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];
|
||||
int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &h.sz_cpr,
|
||||
NULL, ph.method, 10, NULL, NULL );
|
||||
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
|
||||
throwInternalError("loader compression failed");
|
||||
memcpy(cprLoader, &h, sizeof(h));
|
||||
|
||||
fold_hdrlen = sizeof(hf->ehdr) + hf->ehdr.e_phentsize * hf->ehdr.e_phnum +
|
||||
sizeof(l_info);
|
||||
if (0 == get_le32(fold_hdrlen + fold)) {
|
||||
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
||||
fold_hdrlen = umax(0x80, fold_hdrlen);
|
||||
}
|
||||
}
|
||||
// This adds the definition to the "library", to be used later.
|
||||
linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + h.sz_cpr);
|
||||
delete cprLoader;
|
||||
// NOTE: the stub is NOT compressed! The savings is not worth it.
|
||||
linker->addSection("FOLDEXEC", fold + fold_hdrlen, szfold - fold_hdrlen, 0);
|
||||
|
||||
n_mru = ft->n_mru;
|
||||
|
||||
// Here is a quick summary of the format of the output file:
|
||||
linker->setLoaderAlignOffset(
|
||||
// Elf32_Edhr
|
||||
sizeof(elfout.ehdr) +
|
||||
// Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
|
||||
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||
// checksum UPX! lsize version format
|
||||
sizeof(l_info) +
|
||||
// PT_DYNAMIC with DT_NEEDED "forwarded" from original file
|
||||
((elfout.ehdr.e_phnum==3) ? elfout.phdr[2].p_memsz : 0) +
|
||||
// p_progid, p_filesize, p_blocksize
|
||||
sizeof(p_info) +
|
||||
// compressed data
|
||||
b_len + ph.c_len );
|
||||
// entry to stub
|
||||
addLoader("LEXEC000", 0);
|
||||
// Rely on "+80CXXXX" [etc] in getDecompressorSections() packer_c.cpp */
|
||||
// // Here is a quick summary of the format of the output file:
|
||||
// linker->setLoaderAlignOffset(
|
||||
// // Elf32_Edhr
|
||||
// sizeof(elfout.ehdr) +
|
||||
// // Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
|
||||
// (elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||
// // checksum UPX! lsize version format
|
||||
// sizeof(l_info) +
|
||||
// // PT_DYNAMIC with DT_NEEDED "forwarded" from original file
|
||||
// ((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) +
|
||||
// // p_progid, p_filesize, p_blocksize
|
||||
// sizeof(p_info) +
|
||||
// // compressed data
|
||||
// b_len + ph.c_len );
|
||||
// // entry to stub
|
||||
addLoader("LEXEC000", NULL);
|
||||
|
||||
if (ft->id) {
|
||||
if (ph.format==UPX_F_LINUX_ELF_i386) { // decompr, unfilter are separate
|
||||
addLoader("LXUNF000", 0);
|
||||
addLoader("LXUNF002", 0);
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
if (256==n_mru) {
|
||||
addLoader("MRUBYTE0", 0);
|
||||
}
|
||||
else if (n_mru) {
|
||||
addLoader("LXMRU005", 0);
|
||||
}
|
||||
if (n_mru) {
|
||||
addLoader("LXMRU006", 0);
|
||||
}
|
||||
else {
|
||||
addLoader("LXMRU007", 0);
|
||||
}
|
||||
}
|
||||
else if (0x40==(ft->id & 0xF0)) {
|
||||
addLoader("LXUNF008", 0);
|
||||
}
|
||||
addLoader("LXUNF010", 0);
|
||||
}
|
||||
if (n_mru) {
|
||||
addLoader("LEXEC009", 0);
|
||||
addLoader("LEXEC009", NULL);
|
||||
}
|
||||
}
|
||||
addLoader("LEXEC010", 0);
|
||||
addLoader(getDecompressor(), 0);
|
||||
addLoader("LEXEC015", 0);
|
||||
addLoader("LEXEC010", 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);
|
||||
if (ft->id) {
|
||||
if (ph.format==UPX_F_LINUX_ELF_i386) { // decompr, unfilter are separate
|
||||
if (0x80!=(ft->id & 0xF0)) {
|
||||
addLoader("LXUNF042", 0);
|
||||
}
|
||||
}
|
||||
else { // decompr, unfilter not separate
|
||||
{ // decompr, unfilter not separate
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
addLoader("LEXEC110", 0);
|
||||
addLoader("LEXEC110", NULL);
|
||||
if (n_mru) {
|
||||
addLoader("LEXEC100", 0);
|
||||
addLoader("LEXEC100", NULL);
|
||||
}
|
||||
// bug in APP: jmp and label must be in same .asx/.asy
|
||||
addLoader("LEXEC016", 0);
|
||||
addLoader("LEXEC016", NULL);
|
||||
}
|
||||
}
|
||||
addFilter32(ft->id);
|
||||
if (ph.format==UPX_F_LINUX_ELF_i386) { // decompr, unfilter are separate
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
if (0==n_mru) {
|
||||
addLoader("LXMRU058", 0);
|
||||
}
|
||||
}
|
||||
addLoader("LXUNF035", 0);
|
||||
}
|
||||
else { // decompr always unfilters
|
||||
addLoader("LEXEC017", 0);
|
||||
{ // decompr always unfilters
|
||||
addLoader("LEXEC017", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
addLoader("IDENTSTR", 0);
|
||||
addLoader("LEXEC020", 0);
|
||||
addLoader("FOLDEXEC", 0);
|
||||
|
||||
char *ptr_cto = (char *)const_cast<unsigned char *>(getLoader());
|
||||
int sz_cto = getLoaderSize();
|
||||
if (0x20==(ft->id & 0xF0) || 0x30==(ft->id & 0xF0)) { // push byte '?' ; cto8
|
||||
patch_le16(ptr_cto, sz_cto, "\x6a?", 0x6a + (ft->cto << 8));
|
||||
checkPatch(NULL, 0, 0, 0); // reset
|
||||
else {
|
||||
addLoader("LEXEC017", NULL);
|
||||
}
|
||||
// PackHeader and overlay_offset at the end of the output file,
|
||||
// after the compressed data.
|
||||
|
||||
return getLoaderSize();
|
||||
addLoader("IDENTSTR", NULL);
|
||||
addLoader("LEXEC020", NULL);
|
||||
addLoader("FOLDEXEC", NULL);
|
||||
if (M_IS_LZMA(ph.method)) {
|
||||
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
|
||||
acc_uint32e_t properties = // lc, lp, pb, dummy
|
||||
(res->lit_context_bits << 0) |
|
||||
(res->lit_pos_bits << 8) |
|
||||
(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);
|
||||
}
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
int const mru = ft->n_mru ? 1+ ft->n_mru : 0;
|
||||
if (mru && mru!=256) {
|
||||
unsigned const is_pwr2 = (0==((mru -1) & mru));
|
||||
linker->defineSymbol("NMRU", mru - is_pwr2);
|
||||
}
|
||||
}
|
||||
relocateLoader();
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
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);
|
||||
memcpy(buf, linux_i386exec_fold, sz_fold);
|
||||
memcpy(buf, stub_i386_linux_elf_execve_fold, sz_fold);
|
||||
|
||||
// patch loader
|
||||
// note: we only can use /proc/<pid>/fd when exetype > 0.
|
||||
@@ -312,22 +413,32 @@ PackLinuxI386::buildLoader(Filter const *ft)
|
||||
patch_le32(buf,sz_fold,"UPX3",progid);
|
||||
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
|
||||
|
||||
// get fresh filter
|
||||
Filter fold_ft = *ft;
|
||||
fold_ft.init(ft->id, ft->addvalue);
|
||||
int preferred_ctos[2] = {ft->cto, -1};
|
||||
fold_ft.preferred_ctos = preferred_ctos;
|
||||
|
||||
// filter
|
||||
optimizeFilter(&fold_ft, buf, sz_fold);
|
||||
bool success = fold_ft.filter(buf + sizeof(cprElfHdr2), sz_fold - sizeof(cprElfHdr2));
|
||||
(void)success;
|
||||
|
||||
return buildLinuxLoader(
|
||||
linux_i386exec_loader, sizeof(linux_i386exec_loader),
|
||||
buildLinuxLoader(
|
||||
stub_i386_linux_elf_execve_entry, sizeof(stub_i386_linux_elf_execve_entry),
|
||||
buf, sz_fold, ft );
|
||||
}
|
||||
|
||||
void
|
||||
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 );
|
||||
}
|
||||
|
||||
// FIXME: getLoaderPrefixSize is unused?
|
||||
int PackLinuxI386::getLoaderPrefixSize() const
|
||||
{
|
||||
return 116;
|
||||
@@ -347,17 +458,18 @@ int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
|
||||
return -1;
|
||||
|
||||
// now check the ELF header
|
||||
if (!memcmp(buf+8, "FreeBSD", 7)) // branded
|
||||
if (!memcmp(buf+8, "FreeBSD", 7)) // branded
|
||||
return 1;
|
||||
if (ehdr->e_type != 2) // executable
|
||||
if (ehdr->e_type != Elf32_Ehdr::ET_EXEC
|
||||
&& ehdr->e_type != Elf32_Ehdr::ET_DYN ) // executable
|
||||
return 2;
|
||||
if (ehdr->e_machine != 3) // Intel 80386
|
||||
if (ehdr->e_machine != Elf32_Ehdr::EM_386) // Intel 80386
|
||||
return 3;
|
||||
if (ehdr->e_version != 1) // version
|
||||
if (ehdr->e_version != Elf32_Ehdr::EV_CURRENT) // version
|
||||
return 4;
|
||||
if (ehdr->e_phnum < 1)
|
||||
return 5;
|
||||
if (ehdr->e_phentsize != sizeof(Elf_LE32_Phdr))
|
||||
if (ehdr->e_phentsize != sizeof(Elf32_Phdr))
|
||||
return 6;
|
||||
|
||||
// check for Linux kernels
|
||||
@@ -378,19 +490,6 @@ int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
|
||||
}
|
||||
|
||||
|
||||
off_t PackLinuxI386::getbrk(const Elf_LE32_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;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
@@ -404,6 +503,7 @@ bool PackLinuxI386::canPack()
|
||||
Elf_LE32_Ehdr ehdr;
|
||||
unsigned char *buf = ehdr.e_ident;
|
||||
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&ehdr, sizeof(ehdr));
|
||||
fi->seek(0, SEEK_SET);
|
||||
|
||||
@@ -411,12 +511,58 @@ bool PackLinuxI386::canPack()
|
||||
const unsigned l = get_le32(buf);
|
||||
|
||||
int elf = checkEhdr(&ehdr);
|
||||
if (elf >= 0)
|
||||
{
|
||||
if (elf >= 0) {
|
||||
// NOTE: ELF executables are now handled by p_lx_elf.cpp,
|
||||
// so we only handle them here if force_execve
|
||||
if (elf == 0 && opt->unix.force_execve)
|
||||
if (elf == 0 && opt->o_unix.force_execve) {
|
||||
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)
|
||||
{
|
||||
@@ -425,15 +571,17 @@ bool PackLinuxI386::canPack()
|
||||
// FIXME: N_TRSIZE, N_DRSIZE
|
||||
// FIXME: check for aout shared libraries
|
||||
}
|
||||
#if defined(__linux__)
|
||||
// only compress scripts when running under Linux
|
||||
else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
||||
exetype = -2;
|
||||
#endif
|
||||
else { // shell scripts and other interpreters
|
||||
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
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
||||
exetype = -2;
|
||||
}
|
||||
|
||||
return super::canPack();
|
||||
}
|
||||
@@ -444,7 +592,7 @@ void PackLinuxI386::patchLoader() { }
|
||||
|
||||
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) +
|
||||
(elfout.ehdr.e_phnum * elfout.ehdr.e_phentsize) + (char *)&elfout );
|
||||
// checksum for loader + p_info
|
||||
|
||||
+55
-18
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -21,8 +21,11 @@
|
||||
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
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
@@ -38,17 +41,18 @@ class PackLinuxI386 : public PackUnixLe32
|
||||
{
|
||||
typedef PackUnixLe32 super;
|
||||
public:
|
||||
PackLinuxI386(InputFile *f) : super(f) { }
|
||||
PackLinuxI386(InputFile *f);
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
void const *proto,
|
||||
unsigned brka
|
||||
unsigned const brka
|
||||
);
|
||||
virtual int getFormat() const { return UPX_F_LINUX_i386; }
|
||||
virtual const char *getName() const { return "linux/386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf.execve"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void buildLoader(const Filter *);
|
||||
|
||||
virtual bool canPack();
|
||||
|
||||
@@ -59,8 +63,9 @@ protected:
|
||||
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||
|
||||
// loader util
|
||||
virtual Linker* newLinker() const;
|
||||
virtual int getLoaderPrefixSize() const;
|
||||
virtual int buildLinuxLoader(
|
||||
virtual void buildLinuxLoader(
|
||||
upx_byte const *const proto, // assembly-only sections
|
||||
unsigned const szproto,
|
||||
upx_byte const *const fold, // linked assembly + C section
|
||||
@@ -75,7 +80,6 @@ protected:
|
||||
|
||||
// ELF util
|
||||
virtual int checkEhdr(const Elf_LE32_Ehdr *ehdr) const;
|
||||
virtual off_t getbrk(const Elf_LE32_Phdr *phdr, int e_phnum) const;
|
||||
|
||||
enum {
|
||||
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
|
||||
@@ -84,31 +88,64 @@ protected:
|
||||
unsigned n_mru;
|
||||
|
||||
struct cprElfHdr1 {
|
||||
struct Elf_LE32_Ehdr ehdr;
|
||||
struct Elf_LE32_Phdr phdr[1];
|
||||
struct PackUnix::l_info linfo;
|
||||
Elf_LE32_Ehdr ehdr;
|
||||
Elf_LE32_Phdr phdr[1];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr2 {
|
||||
struct Elf_LE32_Ehdr ehdr;
|
||||
struct Elf_LE32_Phdr phdr[2];
|
||||
struct PackUnix::l_info linfo;
|
||||
Elf_LE32_Ehdr ehdr;
|
||||
Elf_LE32_Phdr phdr[2];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr3 {
|
||||
struct Elf_LE32_Ehdr ehdr;
|
||||
struct Elf_LE32_Phdr phdr[3];
|
||||
struct PackUnix::l_info linfo;
|
||||
Elf_LE32_Ehdr ehdr;
|
||||
Elf_LE32_Phdr phdr[3];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
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;
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 52 + 1*32 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 52 + 2*32 + 12)
|
||||
COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 52 + 3*32 + 12)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-bsd.elf.execve"; }
|
||||
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
|
||||
virtual void buildLoader(const Filter *);
|
||||
};
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
/* p_lx_interp.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 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
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#include "file.h"
|
||||
#include "filter.h"
|
||||
#include "linker.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_interp.h"
|
||||
|
||||
#define PT_LOAD Elf32_Phdr::PT_LOAD
|
||||
#define PT_INTERP Elf32_Phdr::PT_INTERP
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static const
|
||||
#include "stub/i386-linux.elf.interp-entry.h"
|
||||
static const
|
||||
#include "stub/i386-linux.elf.interp-fold.h"
|
||||
|
||||
PackLinuxElf32x86interp::PackLinuxElf32x86interp(InputFile *f) :
|
||||
super(f)
|
||||
{
|
||||
}
|
||||
|
||||
PackLinuxElf32x86interp::~PackLinuxElf32x86interp()
|
||||
{
|
||||
}
|
||||
|
||||
bool PackLinuxElf32x86interp::canPack()
|
||||
{
|
||||
if (opt->o_unix.make_ptinterp) {
|
||||
return true;
|
||||
}
|
||||
if (!opt->o_unix.use_ptinterp) {
|
||||
return false;
|
||||
}
|
||||
return super::canPack();
|
||||
}
|
||||
|
||||
void PackLinuxElf32x86interp::pack1(OutputFile *fo, Filter &)
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&ehdri, sizeof(ehdri));
|
||||
assert(ehdri.e_phoff == sizeof(Elf32_Ehdr)); // checked by canPack()
|
||||
sz_phdrs = ehdri.e_phnum * ehdri.e_phentsize;
|
||||
|
||||
phdri = new Elf32_Phdr[(unsigned)ehdri.e_phnum];
|
||||
fi->seek(ehdri.e_phoff, SEEK_SET);
|
||||
fi->readx(phdri, sz_phdrs);
|
||||
|
||||
#define E Elf32_Ehdr
|
||||
cprElfHdr3 h3;
|
||||
memset(&h3, 0, sizeof(h3));
|
||||
memcpy(h3.ehdr.e_ident, "\177ELF", 4);
|
||||
h3.ehdr.e_ident[E::EI_CLASS] = E::ELFCLASS32;
|
||||
h3.ehdr.e_ident[E::EI_DATA] = E::ELFDATA2LSB;
|
||||
h3.ehdr.e_ident[E::EI_VERSION] = E::EV_CURRENT;
|
||||
h3.ehdr.e_ident[E::EI_OSABI] = E::ELFOSABI_LINUX;
|
||||
h3.ehdr.e_ident[E::EI_ABIVERSION] = E::EV_CURRENT;
|
||||
h3.ehdr.e_type = E::ET_EXEC;
|
||||
h3.ehdr.e_machine = E::EM_386;
|
||||
h3.ehdr.e_version = 1;
|
||||
h3.ehdr.e_phoff = sizeof(Elf32_Ehdr);
|
||||
h3.ehdr.e_ehsize = sizeof(Elf32_Ehdr);
|
||||
h3.ehdr.e_phentsize = sizeof(Elf32_Phdr);
|
||||
h3.ehdr.e_phnum = 3;
|
||||
h3.phdr[0].p_type = PT_LOAD;
|
||||
h3.phdr[0].p_flags = Elf32_Phdr::PF_X | Elf32_Phdr::PF_R;
|
||||
h3.phdr[0].p_align = 0x1000;
|
||||
h3.phdr[1].p_type = PT_LOAD;
|
||||
h3.phdr[1].p_flags = Elf32_Phdr::PF_W | Elf32_Phdr::PF_R;
|
||||
h3.phdr[1].p_align = 1;
|
||||
h3.phdr[2].p_type = PT_INTERP;
|
||||
h3.phdr[2].p_offset = (char *)&h3.phdr[2].p_vaddr - (char *)&h3;
|
||||
memcpy(&h3.phdr[2].p_vaddr, "/upxrun", h3.phdr[2].p_filesz = 8);
|
||||
h3.phdr[2].p_align = 1;
|
||||
|
||||
if (opt->o_unix.make_ptinterp) { // unusual "once per release"
|
||||
elfout = h3;
|
||||
elfout.ehdr.e_phnum = 1;
|
||||
fo->write(&elfout, elfout.ehdr.e_ehsize + elfout.ehdr.e_phentsize);
|
||||
}
|
||||
else { // usual case
|
||||
generateElfHdr(fo, &h3, getbrk(phdri, ehdri.e_phnum));
|
||||
}
|
||||
#undef E
|
||||
}
|
||||
|
||||
void PackLinuxElf32x86interp::pack2(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
if (opt->o_unix.make_ptinterp) {
|
||||
return; // ignore current input file!
|
||||
}
|
||||
super::pack2(fo, ft);
|
||||
}
|
||||
|
||||
#undef PAGE_MASK
|
||||
#define PAGE_MASK (~0u<<12)
|
||||
|
||||
void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
||||
{
|
||||
unsigned base = getbase(phdri, ehdri.e_phnum);
|
||||
unsigned sz = PAGE_MASK & (~PAGE_MASK + elfout.phdr[0].p_filesz);
|
||||
if (base < (0x11000 + sz)) {
|
||||
base = 0x11000 + sz;
|
||||
}
|
||||
if (opt->o_unix.make_ptinterp) {
|
||||
base = 0x10000;
|
||||
}
|
||||
elfout.phdr[0].p_paddr = elfout.phdr[0].p_vaddr = base - sz;
|
||||
if (opt->o_unix.make_ptinterp) {
|
||||
initLoader(stub_i386_linux_elf_interp_entry, sizeof(stub_i386_linux_elf_interp_entry));
|
||||
linker->addSection("FOLDEXEC", stub_i386_linux_elf_interp_fold, sizeof(stub_i386_linux_elf_interp_fold), 0);
|
||||
|
||||
addLoader("LXPTI000", NULL);
|
||||
|
||||
addLoader("LXPTI040", NULL);
|
||||
ph.method = M_NRV2B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||
addLoader("LXPTI090", NULL);
|
||||
|
||||
addLoader("LXPTI041", NULL);
|
||||
ph.method = M_NRV2D_LE32; addLoader(getDecompressorSections(), NULL);
|
||||
addLoader("LXPTI090", NULL);
|
||||
|
||||
addLoader("LXPTI042", NULL);
|
||||
ph.method = M_NRV2E_LE32; addLoader(getDecompressorSections(), NULL);
|
||||
addLoader("LXPTI090", NULL);
|
||||
|
||||
//addLoader("LXPTI043", NULL);
|
||||
//ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||
//addLoader("LXPTI090", NULL);
|
||||
|
||||
addLoader("LXPTI091", NULL);
|
||||
|
||||
addLoader("LXPTI140", NULL);
|
||||
|
||||
addLoader("LXUNF002,LXUNF008,LXUNF010", NULL);
|
||||
addFilter32(0x46);
|
||||
addLoader("LXUNF042,LXUNF035", NULL);
|
||||
|
||||
addLoader("LXUNF002,LXUNF008,LXUNF010", NULL);
|
||||
addFilter32(0x49);
|
||||
addLoader("LXUNF042,LXUNF035", NULL);
|
||||
|
||||
addLoader("LXPTI200", NULL);
|
||||
addLoader("FOLDEXEC", NULL);
|
||||
upx_byte const *p = getLoader();
|
||||
lsize = getLoaderSize();
|
||||
updateLoader(fo);
|
||||
fo->write(p, lsize);
|
||||
elfout.phdr[0].p_filesz = fo->getBytesWritten();
|
||||
}
|
||||
else {
|
||||
updateLoader(fo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PackLinuxElf32x86interp::unpack(OutputFile *fo)
|
||||
{
|
||||
#define MAX_INTERP_HDR 512
|
||||
char bufehdr[MAX_INTERP_HDR];
|
||||
Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)bufehdr;
|
||||
Elf32_Phdr const *phdr = (Elf32_Phdr *)(1+ehdr);
|
||||
|
||||
unsigned szb_info = sizeof(b_info);
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(bufehdr, MAX_INTERP_HDR);
|
||||
unsigned const e_entry = get_native32(&ehdr->e_entry);
|
||||
if (e_entry < 0x401180) { /* old style, 8-byte b_info */
|
||||
szb_info = 2*sizeof(unsigned);
|
||||
}
|
||||
}
|
||||
|
||||
fi->seek(overlay_offset, SEEK_SET);
|
||||
p_info hbuf;
|
||||
fi->readx(&hbuf, sizeof(hbuf));
|
||||
unsigned orig_file_size = get_native32(&hbuf.p_filesize);
|
||||
blocksize = get_native32(&hbuf.p_blocksize);
|
||||
if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)
|
||||
throwCantUnpack("file header corrupted");
|
||||
|
||||
ibuf.alloc(blocksize + OVERHEAD);
|
||||
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
|
||||
fi->readx(&bhdr, szb_info);
|
||||
ph.u_len = get_native32(&bhdr.sz_unc);
|
||||
ph.c_len = get_native32(&bhdr.sz_cpr);
|
||||
ph.filter_cto = bhdr.b_cto8;
|
||||
|
||||
// Uncompress Ehdr and Phdrs.
|
||||
fi->readx(ibuf, ph.c_len);
|
||||
decompress(ibuf, (upx_byte *)ehdr, false);
|
||||
|
||||
unsigned total_in = 0;
|
||||
unsigned total_out = 0;
|
||||
unsigned c_adler = upx_adler32(NULL, 0);
|
||||
unsigned u_adler = upx_adler32(NULL, 0);
|
||||
off_t ptload0hi=0, ptload1lo=0, ptload1sz=0;
|
||||
|
||||
// decompress PT_LOAD
|
||||
bool first_PF_X = true;
|
||||
fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR);
|
||||
for (unsigned j=0; j < ehdr->e_phnum; ++phdr, ++j) {
|
||||
if (PT_LOAD==phdr->p_type) {
|
||||
if (0==ptload0hi) {
|
||||
ptload0hi = phdr->p_filesz + phdr->p_offset;
|
||||
}
|
||||
else if (0==ptload1lo) {
|
||||
ptload1lo = phdr->p_offset;
|
||||
ptload1sz = phdr->p_filesz;
|
||||
}
|
||||
if (fo)
|
||||
fo->seek(phdr->p_offset, SEEK_SET);
|
||||
if (Elf32_Phdr::PF_X & phdr->p_flags) {
|
||||
unpackExtent(phdr->p_filesz, fo, total_in, total_out,
|
||||
c_adler, u_adler, first_PF_X, szb_info);
|
||||
first_PF_X = false;
|
||||
}
|
||||
else {
|
||||
unpackExtent(phdr->p_filesz, fo, total_in, total_out,
|
||||
c_adler, u_adler, false, szb_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0!=ptload1sz && ptload0hi < ptload1lo) { // alignment hole?
|
||||
if (fo)
|
||||
fo->seek(ptload0hi, SEEK_SET);
|
||||
unpackExtent(ptload1lo - ptload0hi, fo, total_in, total_out,
|
||||
c_adler, u_adler, false, szb_info);
|
||||
}
|
||||
if (total_out != orig_file_size) { // non-PT_LOAD stuff
|
||||
if (fo)
|
||||
fo->seek(0, SEEK_END);
|
||||
unpackExtent(orig_file_size - total_out, fo, total_in, total_out,
|
||||
c_adler, u_adler, false, szb_info);
|
||||
}
|
||||
|
||||
// check for end-of-file
|
||||
fi->readx(&bhdr, szb_info);
|
||||
unsigned const sz_unc = ph.u_len = get_native32(&bhdr.sz_unc);
|
||||
|
||||
if (sz_unc == 0) { // uncompressed size 0 -> EOF
|
||||
// note: magic is always stored le32
|
||||
unsigned const sz_cpr = get_le32(&bhdr.sz_cpr);
|
||||
if (sz_cpr != UPX_MAGIC_LE32) // sz_cpr must be h->magic
|
||||
throwCompressedDataViolation();
|
||||
}
|
||||
else { // extra bytes after end?
|
||||
throwCompressedDataViolation();
|
||||
}
|
||||
|
||||
// update header with totals
|
||||
ph.c_len = total_in;
|
||||
ph.u_len = total_out;
|
||||
|
||||
// all bytes must be written
|
||||
if (total_out != orig_file_size)
|
||||
throwEOFException();
|
||||
|
||||
// finally test the checksums
|
||||
if (ph.c_adler != c_adler || ph.u_adler != u_adler)
|
||||
throwChecksumError();
|
||||
#undef MAX_INTERP_HDR
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/* p_lx_interp.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 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
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_LX_INTERP_H //{
|
||||
#define __UPX_P_LX_INTERP_H
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// linux/interp386
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxElf32x86interp : public PackLinuxElf32x86
|
||||
{
|
||||
typedef PackLinuxElf32x86 super;
|
||||
public:
|
||||
PackLinuxElf32x86interp(InputFile *f);
|
||||
virtual ~PackLinuxElf32x86interp();
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELFI_i386; }
|
||||
virtual const char *getName() const { return "linux/elfi386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf.interp"; }
|
||||
|
||||
virtual bool canPack();
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||
virtual void pack3(OutputFile *, Filter &); // build loader
|
||||
};
|
||||
|
||||
|
||||
#endif /*} already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/* p_lx_sep.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 2000-2002 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->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->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->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-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 2000-2002 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
|
||||
*/
|
||||
|
||||
+47
-18
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 2000-2002 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
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.,
|
||||
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
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
@@ -45,9 +48,9 @@
|
||||
**************************************************************************/
|
||||
|
||||
static const
|
||||
#include "stub/l_lx_sh86.h"
|
||||
#include "stub/i386-linux.elf.shell-entry.h"
|
||||
static const
|
||||
#include "stub/fold_sh86.h"
|
||||
#include "stub/i386-linux.elf.shell-fold.h"
|
||||
|
||||
|
||||
PackLinuxI386sh::PackLinuxI386sh(InputFile *f) :
|
||||
@@ -59,12 +62,21 @@ PackLinuxI386sh::~PackLinuxI386sh()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
static unsigned
|
||||
umax(unsigned a, unsigned b)
|
||||
{
|
||||
if (a <= b) {
|
||||
return b;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
void
|
||||
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);
|
||||
memcpy(buf, linux_i386sh_fold, sz_fold);
|
||||
memcpy(buf, stub_i386_linux_elf_shell_fold, sz_fold);
|
||||
|
||||
checkPatch(NULL, 0, 0, 0); // reset
|
||||
patch_le32(buf,sz_fold,"UPX3",l_shname);
|
||||
@@ -73,16 +85,22 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
|
||||
// get fresh filter
|
||||
Filter fold_ft = *ft;
|
||||
fold_ft.init(ft->id, ft->addvalue);
|
||||
int preferred_ctos[2] = {ft->cto, -1};
|
||||
int preferred_ctos[2] = { ft->cto, -1 };
|
||||
fold_ft.preferred_ctos = preferred_ctos;
|
||||
|
||||
// filter
|
||||
optimizeFilter(&fold_ft, buf, sz_fold);
|
||||
bool success = fold_ft.filter(buf + sizeof(cprElfHdr2), sz_fold - sizeof(cprElfHdr2));
|
||||
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);
|
||||
UNUSED(success);
|
||||
|
||||
return buildLinuxLoader(
|
||||
linux_i386sh_loader, sizeof(linux_i386sh_loader),
|
||||
buildLinuxLoader(
|
||||
stub_i386_linux_elf_shell_entry, sizeof(stub_i386_linux_elf_shell_entry),
|
||||
buf, sz_fold, ft );
|
||||
}
|
||||
|
||||
@@ -92,11 +110,11 @@ void PackLinuxI386sh::patchLoader() { }
|
||||
bool PackLinuxI386sh::getShellName(char *buf)
|
||||
{
|
||||
exetype = -1;
|
||||
l_shname = strcspn(buf, " \t\n\v\f\r");
|
||||
l_shname = (int) strcspn(buf, " \t\n\v\f\r");
|
||||
buf[l_shname] = 0;
|
||||
static char const *const shname[] = { // known shells that accept "-c" arg
|
||||
"ash", "bash", "bsh", "csh", "ksh", "pdksh", "sh", "tcsh", "zsh",
|
||||
//"python", // FIXME: does python work ???
|
||||
"python",
|
||||
NULL
|
||||
};
|
||||
const char *bname = strrchr(buf, '/');
|
||||
@@ -104,7 +122,11 @@ bool PackLinuxI386sh::getShellName(char *buf)
|
||||
return false;
|
||||
for (int j = 0; NULL != shname[j]; ++j) {
|
||||
if (0 == strcmp(shname[j], bname + 1)) {
|
||||
return super::canPack();
|
||||
bool const s = super::canPack();
|
||||
if (s) {
|
||||
opt->o_unix.blocksize = blocksize = file_size;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -136,7 +158,14 @@ bool PackLinuxI386sh::canPack()
|
||||
void
|
||||
PackLinuxI386sh::pack1(OutputFile *fo, Filter &)
|
||||
{
|
||||
generateElfHdr(fo, linux_i386sh_fold, 0x08048000);
|
||||
generateElfHdr(fo, stub_i386_linux_elf_shell_fold, 0x08048000);
|
||||
}
|
||||
|
||||
void
|
||||
PackLinuxI386sh::pack3(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
super::pack3(fo,ft);
|
||||
elfout.phdr[0].p_filesz = fo->getBytesWritten();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+11
-6
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2002 Laszlo Molnar
|
||||
Copyright (C) 2000-2002 John F. Reiser
|
||||
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2007 Laszlo Molnar
|
||||
Copyright (C) 2000-2007 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
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.,
|
||||
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
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
@@ -44,10 +47,12 @@ public:
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_LINUX_SH_i386; }
|
||||
virtual const char *getName() const { return "linux/sh386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf.shell"; }
|
||||
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 pack3(OutputFile *fo, Filter &ft);
|
||||
|
||||
virtual bool canPack();
|
||||
// virtual void unpack(OutputFile *fo) { super::unpack(fo); }
|
||||
|
||||
+832
@@ -0,0 +1,832 @@
|
||||
/* p_mach.cpp -- pack Mach Object executable
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 2004-2007 John 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.
|
||||
|
||||
John Reiser
|
||||
jreiser@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#include "file.h"
|
||||
#include "filter.h"
|
||||
#include "linker.h"
|
||||
#include "packer.h"
|
||||
#include "p_mach.h"
|
||||
#include "ui.h"
|
||||
|
||||
static const
|
||||
#include "stub/powerpc-darwin.macho-entry.h"
|
||||
static const
|
||||
#include "stub/powerpc-darwin.macho-fold.h"
|
||||
|
||||
static const
|
||||
#include "stub/i386-darwin.macho-entry.h"
|
||||
static const
|
||||
#include "stub/i386-darwin.macho-fold.h"
|
||||
|
||||
template <class T>
|
||||
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned flavor,
|
||||
unsigned count, unsigned size) :
|
||||
super(f), my_cputype(cputype), my_thread_flavor(flavor),
|
||||
my_thread_state_word_count(count), my_thread_command_size(size),
|
||||
n_segment(0), rawmseg(NULL), msegcmd(NULL)
|
||||
{
|
||||
MachClass::compileTimeAssertions();
|
||||
bele = N_BELE_CTP::getRTP<BeLePolicy>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PackMachBase<T>::~PackMachBase()
|
||||
{
|
||||
delete [] rawmseg;
|
||||
delete [] msegcmd;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const int *PackMachBase<T>::getCompressionMethods(int method, int level) const
|
||||
{
|
||||
// There really is no LE bias.
|
||||
return Packer::getDefaultCompressionMethods_le32(method, level);
|
||||
}
|
||||
|
||||
|
||||
const int *PackMachPPC32::getFilters() const
|
||||
{
|
||||
static const int filters[] = { 0xd0, FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
int const *PackMachI386::getFilters() const
|
||||
{
|
||||
static const int filters[] = { 0x49, FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
Linker *PackMachPPC32::newLinker() const
|
||||
{
|
||||
return new ElfLinkerPpc32;
|
||||
}
|
||||
|
||||
Linker *PackMachI386::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void
|
||||
PackMachBase<T>::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 PackMachI386::addStubEntrySections(Filter const *ft)
|
||||
{
|
||||
int const n_mru = ft->n_mru; // FIXME: belongs to filter? packerf?
|
||||
|
||||
// entry to stub
|
||||
addLoader("LEXEC000", NULL);
|
||||
|
||||
if (ft->id) {
|
||||
{ // 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) {
|
||||
addLoader("LEXEC009", NULL);
|
||||
}
|
||||
}
|
||||
addLoader("LEXEC010", NULL);
|
||||
addLoader(getDecompressorSections(), NULL);
|
||||
addLoader("LEXEC015", NULL);
|
||||
if (ft->id) {
|
||||
{ // decompr, unfilter are separate
|
||||
if (0x80!=(ft->id & 0xF0)) {
|
||||
addLoader("LXUNF042", NULL);
|
||||
}
|
||||
}
|
||||
addFilter32(ft->id);
|
||||
{ // decompr, unfilter are separate
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
if (0==n_mru) {
|
||||
addLoader("LXMRU058", NULL);
|
||||
}
|
||||
}
|
||||
addLoader("LXUNF035", NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
addLoader("LEXEC017", NULL);
|
||||
}
|
||||
|
||||
addLoader("IDENTSTR", NULL);
|
||||
addLoader("LEXEC020", NULL);
|
||||
addLoader("FOLDEXEC", NULL);
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::defineSymbols(Filter const *)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void
|
||||
PackMachBase<T>::buildMachLoader(
|
||||
upx_byte const *const proto,
|
||||
unsigned const szproto,
|
||||
upx_byte const *const fold,
|
||||
unsigned const szfold,
|
||||
Filter const *ft
|
||||
)
|
||||
{
|
||||
initLoader(proto, szproto);
|
||||
|
||||
struct b_info h; memset(&h, 0, sizeof(h));
|
||||
unsigned fold_hdrlen = 0;
|
||||
if (0 < szfold) {
|
||||
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 = 0;
|
||||
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.
|
||||
linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + h.sz_cpr, 0);
|
||||
delete [] cprLoader;
|
||||
|
||||
int const GAP = 128; // must match stub/l_mac_ppc.S
|
||||
segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + 64;
|
||||
|
||||
addStubEntrySections(ft);
|
||||
|
||||
defineSymbols(ft);
|
||||
relocateLoader();
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::buildLoader(const Filter *ft)
|
||||
{
|
||||
buildMachLoader(
|
||||
stub_powerpc_darwin_macho_entry, sizeof(stub_powerpc_darwin_macho_entry),
|
||||
stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft );
|
||||
}
|
||||
|
||||
void
|
||||
PackMachI386::buildLoader(const Filter *ft)
|
||||
{
|
||||
buildMachLoader(
|
||||
stub_i386_darwin_macho_entry, sizeof(stub_i386_darwin_macho_entry),
|
||||
stub_i386_darwin_macho_fold, sizeof(stub_i386_darwin_macho_fold), ft );
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::patchLoader() { }
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::updateLoader(OutputFile *) {}
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::patchLoaderChecksum()
|
||||
{
|
||||
unsigned char *const ptr = getLoader();
|
||||
l_info *const lp = &linfo;
|
||||
// checksum for loader; also some PackHeader info
|
||||
lp->l_checksum = 0;
|
||||
lp->l_magic = UPX_MAGIC_LE32; // LE32 always
|
||||
lp->l_lsize = (unsigned short) lsize;
|
||||
lp->l_version = (unsigned char) ph.version;
|
||||
lp->l_format = (unsigned char) ph.format;
|
||||
// INFO: lp->l_checksum is currently unused
|
||||
lp->l_checksum = upx_adler32(ptr, lsize);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int __acc_cdecl_qsort
|
||||
PackMachBase<T>::compare_segment_command(void const *const aa, void const *const bb)
|
||||
{
|
||||
Mach_segment_command const *const a = (Mach_segment_command const *)aa;
|
||||
Mach_segment_command const *const b = (Mach_segment_command const *)bb;
|
||||
unsigned const xa = a->cmd - Mach_segment_command::LC_SEGMENT;
|
||||
unsigned const xb = b->cmd - Mach_segment_command::LC_SEGMENT;
|
||||
if (xa < xb) return -1; // LC_SEGMENT first
|
||||
if (xa > xb) return 1;
|
||||
if (a->vmaddr < b->vmaddr) return -1; // ascending by .vmaddr
|
||||
if (a->vmaddr > b->vmaddr) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
|
||||
super::pack4(fo, ft);
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
segcmdo.vmsize += segcmdo.filesize;
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||
fo->rewrite(&threado, sizeof(threado));
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
|
||||
super::pack4(fo, ft);
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
segcmdo.vmsize += segcmdo.filesize;
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||
fo->rewrite(&threado, sizeof(threado));
|
||||
fo->rewrite(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
{
|
||||
BE32 disp;
|
||||
unsigned const zero = 0;
|
||||
unsigned len = fo->getBytesWritten();
|
||||
fo->write(&zero, 3& (0u-len));
|
||||
len += (3& (0u-len)) + sizeof(disp);
|
||||
disp = 4+ len - sz_mach_headers; // 4: sizeof(instruction)
|
||||
fo->write(&disp, sizeof(disp));
|
||||
|
||||
threado.state.srr0 = len + segcmdo.vmaddr; /* entry address */
|
||||
super::pack3(fo, ft);
|
||||
}
|
||||
|
||||
void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
{
|
||||
LE32 disp;
|
||||
unsigned const zero = 0;
|
||||
unsigned len = fo->getBytesWritten();
|
||||
fo->write(&zero, 3& (0u-len));
|
||||
len += (3& (0u-len));
|
||||
disp = len - sz_mach_headers;
|
||||
fo->write(&disp, sizeof(disp));
|
||||
|
||||
threado.state.eip = len + sizeof(disp) + segcmdo.vmaddr; /* entry address */
|
||||
super::pack3(fo, ft);
|
||||
}
|
||||
|
||||
// Determine length of gap between PT_LOAD phdri[k] and closest PT_LOAD
|
||||
// which follows in the file (or end-of-file). Optimize for common case
|
||||
// where the PT_LOAD are adjacent ascending by .p_offset. Assume no overlap.
|
||||
|
||||
template <class T>
|
||||
unsigned PackMachBase<T>::find_SEGMENT_gap(
|
||||
unsigned const k
|
||||
)
|
||||
{
|
||||
if (Mach_segment_command::LC_SEGMENT!=msegcmd[k].cmd
|
||||
|| 0==msegcmd[k].filesize ) {
|
||||
return 0;
|
||||
}
|
||||
unsigned const hi = msegcmd[k].fileoff + msegcmd[k].filesize;
|
||||
unsigned lo = ph.u_file_size;
|
||||
unsigned j = k;
|
||||
for (;;) { // circular search, optimize for adjacent ascending
|
||||
++j;
|
||||
if (n_segment==j) {
|
||||
j = 0;
|
||||
}
|
||||
if (k==j) {
|
||||
break;
|
||||
}
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd
|
||||
&& 0!=msegcmd[j].filesize ) {
|
||||
unsigned const t = msegcmd[j].fileoff;
|
||||
if ((t - hi) < (lo - hi)) {
|
||||
lo = t;
|
||||
if (hi==lo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return lo - hi;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
PackUnix::pack4(fo, ft); // FIXME super() does not work?
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::pack3(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
PackUnix::pack3(fo, ft); // FIXME super() does not work?
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
||||
{
|
||||
Extent x;
|
||||
unsigned k;
|
||||
|
||||
// count passes, set ptload vars
|
||||
uip->ui_total_passes = 0;
|
||||
for (k = 0; k < n_segment; ++k) {
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
||||
&& 0!=msegcmd[k].filesize ) {
|
||||
uip->ui_total_passes++;
|
||||
if (find_SEGMENT_gap(k)) {
|
||||
uip->ui_total_passes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compress extents
|
||||
unsigned total_in = 0;
|
||||
unsigned total_out = 0;
|
||||
|
||||
unsigned hdr_u_len = mhdri.sizeofcmds;
|
||||
|
||||
uip->ui_pass = 0;
|
||||
ft.addvalue = 0;
|
||||
|
||||
// Packer::compressWithFilters chooses a filter for us, and the stubs
|
||||
// can handle only one filter, and most filters are for executable
|
||||
// instructions. So filter only the largest executable segment.
|
||||
unsigned exe_filesize_max = 0;
|
||||
for (k = 0; k < n_segment; ++k)
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
||||
&& 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
||||
&& exe_filesize_max < msegcmd[k].filesize) {
|
||||
exe_filesize_max = msegcmd[k].filesize;
|
||||
}
|
||||
|
||||
int nx = 0;
|
||||
for (k = 0; k < n_segment; ++k)
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
||||
&& 0!=msegcmd[k].filesize ) {
|
||||
x.offset = msegcmd[k].fileoff;
|
||||
x.size = msegcmd[k].filesize;
|
||||
if (0 == nx) { // 1st LC_SEGMENT must cover Mach_header at 0==fileoffset
|
||||
unsigned const delta = mhdri.sizeofcmds;
|
||||
x.offset += delta;
|
||||
x.size -= delta;
|
||||
}
|
||||
bool const do_filter = (msegcmd[k].filesize==exe_filesize_max)
|
||||
&& 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot);
|
||||
packExtent(x, total_in, total_out,
|
||||
(do_filter ? &ft : 0 ), fo, hdr_u_len );
|
||||
if (do_filter) {
|
||||
exe_filesize_max = 0;
|
||||
}
|
||||
hdr_u_len = 0;
|
||||
++nx;
|
||||
}
|
||||
for (k = 0; k < n_segment; ++k) {
|
||||
x.size = find_SEGMENT_gap(k);
|
||||
if (x.size) {
|
||||
x.offset = msegcmd[k].fileoff +msegcmd[k].filesize;
|
||||
packExtent(x, total_in, total_out, 0, fo);
|
||||
}
|
||||
}
|
||||
|
||||
if ((off_t)total_in != file_size)
|
||||
throwEOFException();
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
}
|
||||
|
||||
#undef PAGE_MASK
|
||||
#undef PAGE_SIZE
|
||||
#define PAGE_MASK (~0u<<12)
|
||||
#define PAGE_SIZE -PAGE_MASK
|
||||
|
||||
void PackMachPPC32::pack1_setup_threado(OutputFile *const fo)
|
||||
{
|
||||
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
||||
threado.cmdsize = sizeof(threado);
|
||||
threado.flavor = my_thread_flavor;
|
||||
threado.count = my_thread_state_word_count;
|
||||
memset(&threado.state, 0, sizeof(threado.state));
|
||||
fo->write(&threado, sizeof(threado));
|
||||
}
|
||||
|
||||
void PackMachI386::pack1_setup_threado(OutputFile *const fo)
|
||||
{
|
||||
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
||||
threado.cmdsize = sizeof(threado);
|
||||
threado.flavor = my_thread_flavor;
|
||||
threado.count = my_thread_state_word_count;
|
||||
memset(&threado.state, 0, sizeof(threado.state));
|
||||
fo->write(&threado, sizeof(threado));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header
|
||||
{
|
||||
mhdro = mhdri;
|
||||
mhdro.ncmds = 2;
|
||||
mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size;
|
||||
mhdro.flags = Mach_header::MH_NOUNDEFS;
|
||||
fo->write(&mhdro, sizeof(mhdro));
|
||||
|
||||
segcmdo.cmd = Mach_segment_command::LC_SEGMENT;
|
||||
segcmdo.cmdsize = sizeof(segcmdo);
|
||||
strncpy((char *)&segcmdo.segname, "__TEXT", sizeof(segcmdo.segname));
|
||||
segcmdo.vmaddr = PAGE_MASK & (~PAGE_MASK +
|
||||
msegcmd[n_segment -1].vmsize + msegcmd[n_segment -1].vmaddr );
|
||||
segcmdo.vmsize = 0; // adjust later
|
||||
segcmdo.fileoff = 0;
|
||||
segcmdo.filesize = 0; // adjust later
|
||||
segcmdo.initprot = segcmdo.maxprot =
|
||||
Mach_segment_command::VM_PROT_READ |
|
||||
Mach_segment_command::VM_PROT_WRITE |
|
||||
Mach_segment_command::VM_PROT_EXECUTE;
|
||||
segcmdo.nsects = 0;
|
||||
segcmdo.flags = 0;
|
||||
fo->write(&segcmdo, sizeof(segcmdo));
|
||||
|
||||
pack1_setup_threado(fo);
|
||||
sz_mach_headers = fo->getBytesWritten();
|
||||
|
||||
memset((char *)&linfo, 0, sizeof(linfo));
|
||||
fo->write(&linfo, sizeof(linfo));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::unpack(OutputFile *fo)
|
||||
{
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) +
|
||||
my_thread_command_size + sizeof(linfo);
|
||||
fi->seek(overlay_offset, SEEK_SET);
|
||||
p_info hbuf;
|
||||
fi->readx(&hbuf, sizeof(hbuf));
|
||||
unsigned orig_file_size = get_native32(&hbuf.p_filesize);
|
||||
blocksize = get_native32(&hbuf.p_blocksize);
|
||||
if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)
|
||||
throwCantUnpack("file header corrupted");
|
||||
|
||||
ibuf.alloc(blocksize + OVERHEAD);
|
||||
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
|
||||
fi->readx(&bhdr, sizeof(bhdr));
|
||||
ph.u_len = get_native32(&bhdr.sz_unc);
|
||||
ph.c_len = get_native32(&bhdr.sz_cpr);
|
||||
ph.method = bhdr.b_method;
|
||||
ph.filter = bhdr.b_ftid;
|
||||
ph.filter_cto = bhdr.b_cto8;
|
||||
|
||||
// Uncompress Macho headers
|
||||
fi->readx(ibuf, ph.c_len);
|
||||
Mach_header *const mhdr = (Mach_header *)new upx_byte[ph.u_len];
|
||||
decompress(ibuf, (upx_byte *)mhdr, false);
|
||||
unsigned const ncmds = mhdr->ncmds;
|
||||
|
||||
msegcmd = new Mach_segment_command[ncmds];
|
||||
unsigned char *ptr = (unsigned char *)(1+mhdr);
|
||||
for (unsigned j= 0; j < ncmds; ++j) {
|
||||
msegcmd[j] = *(Mach_segment_command *)ptr;
|
||||
ptr += (unsigned) ((Mach_segment_command *)ptr)->cmdsize;
|
||||
}
|
||||
|
||||
// Put LC_SEGMENT together at the beginning, ascending by .vmaddr.
|
||||
qsort(msegcmd, ncmds, sizeof(*msegcmd), compare_segment_command);
|
||||
n_segment = 0;
|
||||
for (unsigned j= 0; j < ncmds; ++j) {
|
||||
n_segment += (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd);
|
||||
}
|
||||
|
||||
unsigned total_in = 0;
|
||||
unsigned total_out = 0;
|
||||
unsigned c_adler = upx_adler32(NULL, 0);
|
||||
unsigned u_adler = upx_adler32(NULL, 0);
|
||||
Mach_segment_command const *sc = (Mach_segment_command const *)(1+ mhdr);
|
||||
unsigned k;
|
||||
|
||||
fi->seek(- (off_t)(sizeof(bhdr) + ph.c_len), SEEK_CUR);
|
||||
for (
|
||||
k = 0;
|
||||
k < ncmds;
|
||||
(++k), (sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc))
|
||||
) {
|
||||
if (Mach_segment_command::LC_SEGMENT==sc->cmd
|
||||
&& 0!=sc->filesize ) {
|
||||
unsigned filesize = sc->filesize;
|
||||
unpackExtent(filesize, fo, total_in, total_out, c_adler, u_adler, false, sizeof(bhdr));
|
||||
}
|
||||
}
|
||||
for (unsigned j = 0; j < ncmds; ++j) {
|
||||
unsigned const size = find_SEGMENT_gap(j);
|
||||
if (size) {
|
||||
unsigned const where = msegcmd[k].fileoff +msegcmd[k].filesize;
|
||||
if (fo)
|
||||
fo->seek(where, SEEK_SET);
|
||||
unpackExtent(size, fo, total_in, total_out,
|
||||
c_adler, u_adler, false, sizeof(bhdr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
bool PackMachBase<T>::canPack()
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&mhdri, sizeof(mhdri));
|
||||
|
||||
if (Mach_header::MH_MAGIC !=mhdri.magic
|
||||
|| my_cputype !=mhdri.cputype
|
||||
|| Mach_header::MH_EXECUTE !=mhdri.filetype
|
||||
)
|
||||
return false;
|
||||
|
||||
rawmseg = (Mach_segment_command *)new char[mhdri.sizeofcmds];
|
||||
fi->readx(rawmseg, mhdri.sizeofcmds);
|
||||
|
||||
msegcmd = new Mach_segment_command[mhdri.ncmds];
|
||||
unsigned char *ptr = (unsigned char *)rawmseg;
|
||||
for (unsigned j= 0; j < mhdri.ncmds; ++j) {
|
||||
msegcmd[j] = *(Mach_segment_command *)ptr;
|
||||
ptr += (unsigned) ((Mach_segment_command *)ptr)->cmdsize;
|
||||
}
|
||||
|
||||
|
||||
// Put LC_SEGMENT together at the beginning, ascending by .vmaddr.
|
||||
qsort(msegcmd, mhdri.ncmds, sizeof(*msegcmd), compare_segment_command);
|
||||
|
||||
// Check that LC_SEGMENTs form one contiguous chunk of the file.
|
||||
for (unsigned j= 0; j < mhdri.ncmds; ++j) {
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd) {
|
||||
if (0xfff & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) {
|
||||
return false;
|
||||
}
|
||||
if (0 < j) {
|
||||
unsigned const sz = ~0xfff
|
||||
& (0xfff + msegcmd[j-1].filesize);
|
||||
if ((sz + msegcmd[j-1].fileoff)!=msegcmd[j].fileoff) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++n_segment;
|
||||
sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff;
|
||||
}
|
||||
}
|
||||
|
||||
// info: currently the header is 36 (32+4) bytes before EOF
|
||||
unsigned char buf[256];
|
||||
fi->seek(-(off_t)sizeof(buf), SEEK_END);
|
||||
fi->readx(buf, sizeof(buf));
|
||||
checkAlreadyPacked(buf, sizeof(buf));
|
||||
|
||||
// set options
|
||||
opt->o_unix.blocksize = file_size;
|
||||
return 0 < n_segment;
|
||||
}
|
||||
|
||||
template class PackMachBase<MachClass_BE32>;
|
||||
template class PackMachBase<MachClass_LE32>;
|
||||
|
||||
|
||||
PackMachFat::PackMachFat(InputFile *f) : super(f)
|
||||
{
|
||||
bele = &N_BELE_RTP::le_policy; // sham
|
||||
}
|
||||
|
||||
PackMachFat::~PackMachFat()
|
||||
{
|
||||
}
|
||||
|
||||
const int *PackMachFat::getCompressionMethods(int /*method*/, int /*level*/) const
|
||||
{
|
||||
static const int m_nrv2e[] = { M_NRV2E_LE32, M_END };
|
||||
return m_nrv2e; // sham
|
||||
}
|
||||
|
||||
const int *PackMachFat::getFilters() const
|
||||
{
|
||||
static const int filters[] = { 0x49, FT_END };
|
||||
return filters; // sham
|
||||
}
|
||||
|
||||
void PackMachFat::pack(OutputFile *fo)
|
||||
{
|
||||
unsigned const in_size = this->file_size;
|
||||
fo->write(&fat_head, sizeof(fat_head.fat) +
|
||||
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
|
||||
unsigned length = 0;
|
||||
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
|
||||
unsigned base = fo->unset_extent(); // actual length
|
||||
base += ~(~0u<<fat_head.arch[j].align) & (0-base); // align up
|
||||
fo->seek(base, SEEK_SET);
|
||||
fo->set_extent(base, ~0u);
|
||||
|
||||
ph.u_file_size = fat_head.arch[j].size;
|
||||
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
||||
switch (fat_head.arch[j].cputype) {
|
||||
case PackMachFat::CPU_TYPE_I386: {
|
||||
PackMachI386 packer(fi);
|
||||
packer.initPackHeader();
|
||||
packer.canPack();
|
||||
packer.updatePackHeader();
|
||||
packer.pack(fo);
|
||||
} break;
|
||||
case PackMachFat::CPU_TYPE_POWERPC: {
|
||||
PackMachPPC32 packer(fi);
|
||||
packer.initPackHeader();
|
||||
packer.canPack();
|
||||
packer.updatePackHeader();
|
||||
packer.pack(fo);
|
||||
} break;
|
||||
} // switch cputype
|
||||
fat_head.arch[j].offset = base;
|
||||
length = fo->unset_extent();
|
||||
fat_head.arch[j].size = length - base;
|
||||
}
|
||||
ph.u_file_size = in_size;
|
||||
fi->set_extent(0, in_size);
|
||||
|
||||
fo->seek(0, SEEK_SET);
|
||||
fo->rewrite(&fat_head, sizeof(fat_head.fat) +
|
||||
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
|
||||
fo->set_extent(0, length);
|
||||
}
|
||||
|
||||
void PackMachFat::unpack(OutputFile *fo)
|
||||
{
|
||||
fo->seek(0, SEEK_SET);
|
||||
fo->write(&fat_head, sizeof(fat_head.fat) +
|
||||
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
|
||||
unsigned length;
|
||||
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
|
||||
unsigned base = fo->unset_extent(); // actual length
|
||||
base += ~(~0u<<fat_head.arch[j].align) & (0-base); // align up
|
||||
fo->seek(base, SEEK_SET);
|
||||
fo->set_extent(base, ~0u);
|
||||
|
||||
ph.u_file_size = fat_head.arch[j].size;
|
||||
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
||||
switch (fat_head.arch[j].cputype) {
|
||||
case PackMachFat::CPU_TYPE_I386: {
|
||||
PackMachI386 packer(fi);
|
||||
packer.initPackHeader();
|
||||
packer.canUnpack();
|
||||
packer.unpack(fo);
|
||||
} break;
|
||||
case PackMachFat::CPU_TYPE_POWERPC: {
|
||||
PackMachPPC32 packer(fi);
|
||||
packer.initPackHeader();
|
||||
packer.canUnpack();
|
||||
packer.unpack(fo);
|
||||
} break;
|
||||
} // switch cputype
|
||||
fat_head.arch[j].offset = base;
|
||||
length = fo->unset_extent();
|
||||
fat_head.arch[j].size = length - base;
|
||||
}
|
||||
fo->unset_extent();
|
||||
fo->seek(0, SEEK_SET);
|
||||
fo->rewrite(&fat_head, sizeof(fat_head.fat) +
|
||||
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
|
||||
}
|
||||
|
||||
bool PackMachFat::canPack()
|
||||
{
|
||||
struct Mach_fat_arch *arch = &fat_head.arch[0];
|
||||
|
||||
fi->readx(&fat_head, sizeof(fat_head));
|
||||
if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic
|
||||
|| N_FAT_ARCH < fat_head.fat.nfat_arch) {
|
||||
return false;
|
||||
}
|
||||
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
|
||||
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
||||
switch (arch[j].cputype) {
|
||||
default: return false;
|
||||
case PackMachFat::CPU_TYPE_I386: {
|
||||
PackMachI386 packer(fi);
|
||||
if (!packer.canPack())
|
||||
return false;
|
||||
} break;
|
||||
case PackMachFat::CPU_TYPE_POWERPC: {
|
||||
PackMachPPC32 packer(fi);
|
||||
if (!packer.canPack())
|
||||
return false;
|
||||
} break;
|
||||
} // switch cputype
|
||||
}
|
||||
|
||||
// info: currently the header is 36 (32+4) bytes before EOF
|
||||
unsigned char buf[256];
|
||||
fi->seek(-(off_t)sizeof(buf), SEEK_END);
|
||||
fi->readx(buf, sizeof(buf));
|
||||
checkAlreadyPacked(buf, sizeof(buf));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int PackMachFat::canUnpack()
|
||||
{
|
||||
struct Mach_fat_arch *arch = &fat_head.arch[0];
|
||||
|
||||
fi->readx(&fat_head, sizeof(fat_head));
|
||||
if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic
|
||||
|| N_FAT_ARCH < fat_head.fat.nfat_arch) {
|
||||
return false;
|
||||
}
|
||||
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
|
||||
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
||||
switch (arch[j].cputype) {
|
||||
default: return false;
|
||||
case PackMachFat::CPU_TYPE_I386: {
|
||||
PackMachI386 packer(fi);
|
||||
if (!packer.canUnpack())
|
||||
return 0;
|
||||
ph.format = packer.getFormat(); // FIXME: copy entire PackHeader
|
||||
} break;
|
||||
case PackMachFat::CPU_TYPE_POWERPC: {
|
||||
PackMachPPC32 packer(fi);
|
||||
if (!packer.canUnpack())
|
||||
return 0;
|
||||
ph.format = packer.getFormat(); // FIXME: copy entire PackHeader
|
||||
} break;
|
||||
} // switch cputype
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void PackMachFat::buildLoader(const Filter */*ft*/)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
Linker* PackMachFat::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86; // sham
|
||||
}
|
||||
|
||||
void PackMachFat::list()
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user