Compare commits
1143 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 955c31b165 | |||
| e307cd48ad | |||
| 25f8b9e451 | |||
| e8ba14a2c1 | |||
| 9670d3341c | |||
| cec9778fd5 | |||
| 7451db4a68 | |||
| e31777ec53 | |||
| 7aa0b3dc7a | |||
| e7b2d5dc01 | |||
| 47d728667d | |||
| e1f8989d54 | |||
| 1d8cb47830 | |||
| faaa7c37a9 | |||
| 0aff9d8df4 | |||
| 30c3f8c1ac | |||
| bcd2469e01 | |||
| 983c6ae73d | |||
| 6d8e1fe776 | |||
| 99b4921309 | |||
| 3c231c3c9e | |||
| 175c0a6236 | |||
| 0031ceb06c | |||
| e3cc5a63df | |||
| 3cb61402c2 | |||
| 5336c51199 | |||
| 52aa658aaa | |||
| d08a51d7e4 | |||
| d97a557ac3 | |||
| 8a68d9cded | |||
| b031f7e902 | |||
| 963ffecb96 | |||
| 8f8aaca818 | |||
| 801f92b7e7 | |||
| 44db45700e | |||
| 25902005f6 | |||
| ffec71e0d8 | |||
| 99a208110b | |||
| e56799c993 | |||
| 957eb300f8 | |||
| 626025d539 | |||
| 9e8a0a020f | |||
| 40f592eade | |||
| 5e899f0be4 | |||
| f2748284b1 | |||
| a15ce00934 | |||
| 9e3e80261b | |||
| c72c685434 | |||
| 0177a8d277 | |||
| b6a9b0a4c9 | |||
| f4f8bd8d42 | |||
| 6e4aeffc0c | |||
| dba256d384 | |||
| 910008e9e7 | |||
| 8cb9545c41 | |||
| 59c16da6fb | |||
| 630df5bbd2 | |||
| f550111400 | |||
| 77377195aa | |||
| 7e2e72bd40 | |||
| aa7a13bd02 | |||
| 5895058a17 | |||
| ffb60d5149 | |||
| 1e2cb279b0 | |||
| e7f766f5ba | |||
| 8de5aa9409 | |||
| bf28a4df49 | |||
| fe1a0ab371 | |||
| 01daccfaf7 | |||
| 94e861e298 | |||
| d36af2ed5c | |||
| 7104b33214 | |||
| 32998e5377 | |||
| af0c9ef092 | |||
| 3bc3b3d10e | |||
| f03f42ca4d | |||
| 79783abeb1 | |||
| 895b0bd602 | |||
| 2ee5ee92f8 | |||
| 3e619423b1 | |||
| b524e18bdf | |||
| 6aa4579db8 | |||
| 17fb86c0f1 | |||
| 62ecfe4873 | |||
| 04e55e6b9a | |||
| f432aa1090 | |||
| 7add104313 | |||
| 36de249066 | |||
| b7a54dcffd | |||
| 6bb28deab2 | |||
| 7f88d15c86 | |||
| 94c5014e23 | |||
| c5a8256500 | |||
| 5f39884bf7 | |||
| d96825a242 | |||
| 443a938091 | |||
| 6bc3197721 | |||
| 269cc91fd5 | |||
| c1ddea479d | |||
| 5f3a95962c | |||
| ee1a8e6a32 | |||
| eeae73296e | |||
| 4ca8357af4 | |||
| 8a5b8c87fb | |||
| 6ab04d7bbc | |||
| a5a1380636 | |||
| eeab1aef64 | |||
| 4e1c342e55 | |||
| d8ed259bce | |||
| 9f6cb5de4c | |||
| ba634118d7 | |||
| 63da091d36 | |||
| ad0dc88a33 | |||
| 147acf4b57 | |||
| 5085f3a15e | |||
| 22a95ad8ea | |||
| df4bd6a60c | |||
| 813e7b05e4 | |||
| ab8b486b4a | |||
| 590f666ec9 | |||
| 9adaee915b | |||
| bce0f06fe9 | |||
| 856ecb84a0 | |||
| 90ddc06c98 | |||
| 405abc4e95 | |||
| 549c59ecf5 | |||
| 0a485eafcb | |||
| e0c11956a6 | |||
| da6a9bf3eb | |||
| dacd11e1cc | |||
| fc854b4c77 | |||
| 4dcc1f0374 | |||
| fc57390242 | |||
| bd15ef0a0c | |||
| 967ecafc33 | |||
| 29576da985 | |||
| 200a2556ef | |||
| ae0ab5025e | |||
| aa74276b25 | |||
| b03112a5dd | |||
| a3f49df62d | |||
| aa2af3f6dd | |||
| 20dcbc593c | |||
| 472ba8c1fd | |||
| d8345a44a4 | |||
| a187cb6c9c | |||
| b89c0b35d1 | |||
| 7ffcc0a5e7 | |||
| bde43fbdfb | |||
| 3728b2208f | |||
| dc52a756ee | |||
| 98dc886841 | |||
| d0cf104e43 | |||
| d7ed2412f6 | |||
| 7d38f0e234 | |||
| 3e8d072d24 | |||
| 84ac771893 | |||
| 3a9e0b5be6 | |||
| 9694ff433f | |||
| 2e82e78b98 | |||
| aaef4bee27 | |||
| 4ca8569488 | |||
| 8377ada3e0 | |||
| 8a034d59ed | |||
| 8e492d8798 | |||
| 7974ef80d7 | |||
| 3664d86430 | |||
| 9adef80d6b | |||
| be57adaee7 | |||
| d117e442a4 | |||
| 8820bc0796 | |||
| 57a64de023 | |||
| 5ed689ceb0 | |||
| 25f1765f36 | |||
| 063bd58802 | |||
| 901c6b34fa | |||
| 5b2d6488a2 | |||
| f6f35415d1 | |||
| 6c6069e963 | |||
| 6219d82560 | |||
| 1dcd7a16ab | |||
| b60caeb9dd | |||
| 4c4768aaf3 | |||
| 2f4ac0a663 | |||
| 23a446f852 | |||
| ec48334a1a | |||
| f4c061d412 | |||
| 31a076d7b3 | |||
| 6bd43d986c | |||
| dd32a2f15a | |||
| c88c20820f | |||
| 86de510731 | |||
| 0b31fbf827 | |||
| 34ad1450eb | |||
| e6ba71390d | |||
| f0c8dbe0ec | |||
| bf046a8ccb | |||
| b05ba7683e | |||
| aedf8dad15 | |||
| 74ebb7c722 | |||
| 1307f66494 | |||
| 448a24cb36 | |||
| 7266f23450 | |||
| c0ad31acfc | |||
| 25d3a0de27 | |||
| 1e38bbfbc1 | |||
| 1c62e95812 | |||
| d453cc27a3 | |||
| 2c3e841d8a | |||
| 50668c462f | |||
| 8d1192e832 | |||
| 4a8e2e9ed4 | |||
| 12fc45220a | |||
| 6bce68fbe7 | |||
| d54f947c98 | |||
| 6c8bb3a22e | |||
| ed29ce5183 | |||
| a51d269b7c | |||
| 8283e4e6d6 | |||
| 23ce91eb55 | |||
| 545ac7fcfa | |||
| 3926ccccad | |||
| f431307ef2 | |||
| ca368e0f9b | |||
| 8afeb56c11 | |||
| 2a6f90c5f3 | |||
| 271031128e | |||
| b991f954d0 | |||
| f12bb3f80d | |||
| 6dc978e8d8 | |||
| 9f05a873bc | |||
| 703d498772 | |||
| ed3b9543bb | |||
| fc7efba7d8 | |||
| b3178fe8f4 | |||
| e36798a993 | |||
| a143605465 | |||
| d3ad35b21e | |||
| 68134941bf | |||
| 54d0fef559 | |||
| 7f9c47176a | |||
| 9060ac7897 | |||
| d9073e4a17 | |||
| de1c1d7cc2 | |||
| 6ff1bd5917 | |||
| a6b04f426e | |||
| fa49dbe2cb | |||
| 682eb04a52 | |||
| 77064fb09e | |||
| be8d93563a | |||
| d4a6a5216d | |||
| 1cb1427050 | |||
| e4f4eace1c | |||
| 30a98b7e8c | |||
| d36c8d95ad | |||
| 506bd0abcf | |||
| 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 | |||
| 1f18050930 | |||
| 537b78d564 | |||
| 717fd57ce1 | |||
| 3fb7786868 | |||
| 17ecfc9765 | |||
| 5326260a76 |
@@ -1,43 +1,52 @@
|
|||||||
syntax: regexp
|
syntax: regexp
|
||||||
|
|
||||||
|
^\.bzr
|
||||||
^ChangeLog
|
^ChangeLog
|
||||||
|
^Makevars.global
|
||||||
^build
|
^build
|
||||||
^maint
|
^maint
|
||||||
|
|
||||||
syntax: glob
|
syntax: glob
|
||||||
|
|
||||||
|
.depend
|
||||||
|
Makevars.local
|
||||||
|
|
||||||
*.a
|
*.a
|
||||||
*.d
|
|
||||||
*.dll
|
*.dll
|
||||||
*.exe
|
|
||||||
*.lib
|
*.lib
|
||||||
*.map
|
|
||||||
*.o
|
|
||||||
*.out
|
|
||||||
*.py[cdo]
|
*.py[cdo]
|
||||||
*.so
|
*.so
|
||||||
*.res
|
*.swp
|
||||||
*.ttp
|
|
||||||
|
|
||||||
doc/*.1
|
doc/*.1
|
||||||
doc/*.doc
|
doc/*.doc
|
||||||
doc/*.html
|
doc/*.html
|
||||||
|
doc/*.man
|
||||||
|
doc/*.ps
|
||||||
|
doc/*.tex
|
||||||
|
|
||||||
|
src/GNUmakefile
|
||||||
src/MMakefile
|
src/MMakefile
|
||||||
src/compress_nrv*
|
src/compress_nrv*
|
||||||
|
src/*.mft
|
||||||
src/*.rc
|
src/*.rc
|
||||||
|
|
||||||
stub/MMakefile
|
src/*.d
|
||||||
stub/l_t_*.i
|
src/*.exe
|
||||||
stub/stamp-h
|
src/*.map
|
||||||
stub/*.ash
|
src/*.o
|
||||||
stub/*.asx
|
src/*.obj
|
||||||
stub/*.asy
|
src/*.out
|
||||||
stub/*.bin
|
src/*.res
|
||||||
stub/*.lst
|
src/*.ttp
|
||||||
|
|
||||||
stub/util/armpe/armpe_tester
|
stub/**MMakefile
|
||||||
|
stub/**.*-stamp
|
||||||
|
stub/tmp*/*
|
||||||
|
stub/**/tmp*/*
|
||||||
|
|
||||||
stub/util/sstrip/amd64-linux-sstrip
|
stub/tools/armpe/armpe_tester{,.exe,.out}
|
||||||
stub/util/sstrip/i386-linux-sstrip
|
|
||||||
stub/util/sstrip/sstrip
|
stub/tools/sstrip/amd64-linux-sstrip
|
||||||
|
stub/tools/sstrip/i386-linux-sstrip
|
||||||
|
stub/tools/sstrip/sstrip
|
||||||
|
|||||||
@@ -1,10 +1,22 @@
|
|||||||
140415ffbcef86a42b4d672249927364430d3d38 RELEASE_111
|
140415ffbcef86a42b4d672249927364430d3d38 RELEASE_111
|
||||||
|
155618b5b7930f97bd84b82befa7a4fd6672efb3 RELEASE_304
|
||||||
|
1931f4f28074970ec53b4cd21c7fc181b4da8e5e RELEASE_301
|
||||||
223ac5b23f9731ceac9ff8d65167df4900776e36 RELEASE_190
|
223ac5b23f9731ceac9ff8d65167df4900776e36 RELEASE_190
|
||||||
2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194
|
2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194
|
||||||
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
|
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
|
||||||
|
396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291
|
||||||
|
46f3a6cca02603000fadc16637b02e30caddd909 RELEASE_302
|
||||||
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
|
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
|
||||||
|
95c558f81a0b8d5bb2bede4c8208bb84ae7d1e58 RELEASE_303
|
||||||
|
a1c61174f54aac714f59ac20fcba839d71e64c5c RELEASE_292
|
||||||
|
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
|
||||||
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
|
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
|
||||||
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
|
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
|
||||||
|
b82ef51896199484afe5b0553af7d1e59b7ce428 BRANCHPOINT_FOR_upx2.hg
|
||||||
c2e0cd4d621b047f254f2def42132a03683ff52c RELEASE_192
|
c2e0cd4d621b047f254f2def42132a03683ff52c RELEASE_192
|
||||||
|
c9a983b7da9d4a2311f74366478348412cac2986 RELEASE_305
|
||||||
|
d276aa09033c24d0981bc3f4fee5628aecc988ad RELEASE_290
|
||||||
eb1ce56dce7dd1835964362470610925963b9043 RELEASE_110
|
eb1ce56dce7dd1835964362470610925963b9043 RELEASE_110
|
||||||
ed96891ef795bceec6b7ff3ca1ca7764431bfb39 RELEASE_191
|
ed96891ef795bceec6b7ff3ca1ca7764431bfb39 RELEASE_191
|
||||||
|
ef9c7f2c9658d73a9b5ab2ed291483d2bbcd8bc7 RELEASE_300
|
||||||
|
efa52753e366300c0e0ebe20631adcb24ed3c15b RELEASE_293
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2010 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
http://upx.sourceforge.net
|
http://upx.sourceforge.net
|
||||||
|
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ dos/exe
|
|||||||
watcom/le
|
watcom/le
|
||||||
---------
|
---------
|
||||||
* 16-bit selector alias fixups
|
* 16-bit selector alias fixups
|
||||||
* 16-bit offset relocation for objects larger than 4 kB
|
* 16-bit offset relocation for objects larger than 4 KiB
|
||||||
* 16:16 fixups
|
* 16:16 fixups
|
||||||
|
|
||||||
If you need any of the above (they're very rare), send us an URL of a
|
If you need any of the above (they're very rare), send us an URL of a
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
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
|
General Public License applies to most of the Free Software
|
||||||
Foundation's software and to any other program whose authors commit to
|
Foundation's software and to any other program whose authors commit to
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
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.
|
your programs, too.
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
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
|
The precise terms and conditions for copying, distribution and
|
||||||
modification follow.
|
modification follow.
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
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
|
License. (Exception: if the Program itself is interactive but
|
||||||
does not normally print such an announcement, your work based on
|
does not normally print such an announcement, your work based on
|
||||||
the Program is not required to print an announcement.)
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
These requirements apply to the modified work as a whole. If
|
||||||
identifiable sections of that work are not derived from the Program,
|
identifiable sections of that work are not derived from the Program,
|
||||||
and can be reasonably considered independent and separate works in
|
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
|
access to copy the source code from the same place counts as
|
||||||
distribution of the source code, even though third parties are not
|
distribution of the source code, even though third parties are not
|
||||||
compelled to copy the source along with the object code.
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
except as expressly provided under this License. Any attempt
|
except as expressly provided under this License. Any attempt
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
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
|
This section is intended to make thoroughly clear what is believed to
|
||||||
be a consequence of the rest of this License.
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
original copyright holder who places the Program under this License
|
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.
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
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.
|
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.>
|
<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
|
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
|
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
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License along
|
||||||
along with this program; if not, write to the Free Software
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
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
|
If the program is interactive, make it output a short notice like this
|
||||||
when it starts in an interactive mode:
|
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'.
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it
|
This is free software, and you are welcome to redistribute it
|
||||||
under certain conditions; type `show c' for details.
|
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
|
This General Public License does not permit incorporating your program into
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
consider it more useful to permit linking proprietary applications with the
|
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.
|
Public License instead of this License.
|
||||||
|
|||||||
@@ -1,33 +1,42 @@
|
|||||||
# Toplevel Makefile for UPX
|
#
|
||||||
|
# UPX toplevel Makefile - needs GNU make 3.81 or better
|
||||||
|
#
|
||||||
|
# Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
export SHELL = /bin/sh
|
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 = .
|
srcdir = .
|
||||||
top_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:
|
default:
|
||||||
@echo "UPX info: please choose a target for 'make'"
|
@echo "UPX info: please choose a target for 'make'"
|
||||||
|
|
||||||
all mostlyclean clean distclean maintainer-clean:
|
all mostlyclean clean distclean maintainer-clean:
|
||||||
ifneq ($(wildcard $(HOME)/local/bin/bin-upx),)
|
ifeq ($(BUILD_STUB),1)
|
||||||
# these need special build tools
|
|
||||||
$(MAKE) -C src/stub/util/sstrip $@
|
|
||||||
$(MAKE) -C src/stub $@
|
$(MAKE) -C src/stub $@
|
||||||
endif
|
endif
|
||||||
$(MAKE) -C src $@
|
$(MAKE) -C src $@
|
||||||
$(MAKE) -C doc $@
|
$(MAKE) -C doc $@
|
||||||
|
|
||||||
dist: distclean
|
|
||||||
false
|
|
||||||
|
|
||||||
# automatically generate ChangeLog from hg
|
|
||||||
ChangeLog:
|
|
||||||
hg log --style=changelog > $@
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
||||||
.PHONY: dist ChangeLog
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,95 @@
|
|||||||
User visible changes for UPX
|
User visible changes for UPX
|
||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
|
Changes in 3.06 (04 Sep 2010):
|
||||||
|
* win32/pe: TLS callback support contributed by Stefan Widmann. Thanks!
|
||||||
|
* bug fixes
|
||||||
|
|
||||||
|
Changes in 3.05 (27 Apr 2010):
|
||||||
|
* i386-linux and amd64-linux support shared libraries (DT_INIT must
|
||||||
|
exist, all info needed by runtime loader must be first in .text, etc.)
|
||||||
|
* Linux /proc/self/exe now is preserved by default, by leaving behind
|
||||||
|
one page. New compress-time option --unmap-all-pages is available.
|
||||||
|
* Withdraw support for shared libraries on Darwin (Apple Mac OS X)
|
||||||
|
because upx does not understand enough about .dylib.
|
||||||
|
* bug fixes
|
||||||
|
|
||||||
|
Changes in 3.04 (27 Sep 2009):
|
||||||
|
* new format Mach/AMD64 supports 64-bit programs on Apple Macintosh.
|
||||||
|
* new formats Dylib/i386 and Dylib/ppc32 support shared libraries
|
||||||
|
[such as browser plugins] on Darwin (Apple Macintosh). An existing
|
||||||
|
-init function (LC_ROUTINES command) is required.
|
||||||
|
* new format vmlinuz/armel for Debian NSLU2 (etc.) linux kernel
|
||||||
|
* bvmlinuz boot protocol 2.08 for 386 Linux kernel
|
||||||
|
* Extended ABI version 4 for armel-eabi ARM Linux ELF
|
||||||
|
* bug fixes
|
||||||
|
|
||||||
|
Changes in 3.03 (27 Apr 2008):
|
||||||
|
* implement cache flushing for PowerPC (esp. model 440)
|
||||||
|
* fix cache flushing on MIPS (>3 MiB compressed, or with holes)
|
||||||
|
* fix MIPS big-endian
|
||||||
|
* bug fixes
|
||||||
|
|
||||||
|
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):
|
Changes in 2.01 (06 Jun 2006):
|
||||||
* arm/pe: better DLL support
|
* arm/pe: better DLL support
|
||||||
* dos/exe: device driver support added
|
* dos/exe: device driver support added
|
||||||
@@ -269,8 +358,8 @@ Changes in 0.80 (03 Aug 1999)
|
|||||||
* win32/pe: even better TLS support
|
* win32/pe: even better TLS support
|
||||||
* win32/pe: versioninfo works on NT
|
* win32/pe: versioninfo works on NT
|
||||||
* win32/pe: import by ordinal from kernel32.dll works
|
* win32/pe: import by ordinal from kernel32.dll works
|
||||||
* win32/pe: other import improvements: importing a nonexistant DLL
|
* win32/pe: other import improvements: importing a nonexistent DLL
|
||||||
results in a usual Windows message, importing a nonexistant function
|
results in a usual Windows message, importing a nonexistent function
|
||||||
results in program exit (instead of crash ;-)
|
results in program exit (instead of crash ;-)
|
||||||
* win32/pe: new option: '--compress-resources=0'
|
* win32/pe: new option: '--compress-resources=0'
|
||||||
* win32/pe: reduced memory requirement during uncompression, some
|
* win32/pe: reduced memory requirement during uncompression, some
|
||||||
@@ -322,7 +411,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 file corruption when the size of the export data is invalid
|
||||||
* win32/pe: fixed a problem with empty resource data
|
* win32/pe: fixed a problem with empty resource data
|
||||||
* win32/pe: compressed file alignment set to minimum value
|
* 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 some other win32/pe bugs
|
||||||
* fixed an address optimization problem for some not Watcom LE files
|
* fixed an address optimization problem for some not Watcom LE files
|
||||||
* fixed a bug which could make UPX hang when an exe header contained
|
* fixed a bug which could make UPX hang when an exe header contained
|
||||||
@@ -363,3 +452,5 @@ Changes in 0.20 (05 Jul 1998)
|
|||||||
Changes in 0.05 (26 May 1998)
|
Changes in 0.05 (26 May 1998)
|
||||||
* first public beta release
|
* first public beta release
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set syntax=off tw=0 ts=4 sw=4 et: -*- coding: utf-8 -*-
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2010 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
http://upx.sourceforge.net
|
http://upx.sourceforge.net
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2010 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
http://upx.sourceforge.net
|
http://upx.sourceforge.net
|
||||||
|
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ THE FUTURE
|
|||||||
- We will *NOT* add any sort of protection and/or encryption.
|
- We will *NOT* add any sort of protection and/or encryption.
|
||||||
This only gives people a false feeling of security because
|
This only gives people a false feeling of security because
|
||||||
by definition all protectors/compressors can be broken.
|
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"...
|
compressors about this topic - just do a websearch on "unpackers"...
|
||||||
|
|
||||||
- Fix all remaining bugs - keep your reports coming ;-)
|
- Fix all remaining bugs - keep your reports coming ;-)
|
||||||
@@ -108,9 +108,9 @@ THE FUTURE
|
|||||||
COPYRIGHT
|
COPYRIGHT
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2006 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2000-2006 John F. Reiser
|
Copyright (C) 2000-2010 John F. Reiser
|
||||||
|
|
||||||
This program may be used freely, and you are welcome to
|
This program may be used freely, and you are welcome to
|
||||||
redistribute it under certain conditions.
|
redistribute it under certain conditions.
|
||||||
@@ -128,8 +128,8 @@ Share and enjoy,
|
|||||||
Markus & Laszlo
|
Markus & Laszlo
|
||||||
|
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+5
-15
@@ -8,26 +8,16 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2010 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
http://upx.sourceforge.net
|
http://upx.sourceforge.net
|
||||||
|
|
||||||
|
|
||||||
|
MAJOR NEWS IN UPX 3
|
||||||
MAJOR NEWS IN UPX 2
|
|
||||||
===================
|
===================
|
||||||
|
|
||||||
The main news since 1.25 are:
|
The main news since UPX 2 are:
|
||||||
|
|
||||||
* new format: added support for arm/pe (ARM executables running on WinCE)
|
* new format: added support for linux elf/arm
|
||||||
* 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)
|
|
||||||
* new format: added support for bootable Linux kernels ("vmlinuz/386")
|
|
||||||
* new format: added support for Playstation exes ("ps1/exe")
|
|
||||||
|
|
||||||
* slightly better compression using the new NRV2E algorithm
|
* better compression using the LZMA algorithm (option '--lzma')
|
||||||
* new options for compression tuning (e.g. '--brute')
|
|
||||||
* improved win32/pe compatibility
|
|
||||||
* direct ELF-to-memory decompression
|
|
||||||
* various bug fixes
|
|
||||||
|
|
||||||
|
|||||||
+17
-34
@@ -69,53 +69,36 @@ Tools needed to build/modify the UPX sources
|
|||||||
- A C++ compiler supporting inner classes, templates, exceptions
|
- A C++ compiler supporting inner classes, templates, exceptions
|
||||||
and RTTI.
|
and RTTI.
|
||||||
|
|
||||||
- GNU make 3.80 or better
|
- GNU make 3.81 or better
|
||||||
|
|
||||||
|
|
||||||
To compile the packer sources
|
To compile the packer sources
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
set the environment variable UCLDIR to point to your UCL installation, e.g.
|
Set the environment variable UPX_UCLDIR to point to your
|
||||||
|
UCL build directory, e.g.
|
||||||
|
|
||||||
set UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
|
set UPX_UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
|
||||||
export UCLDIR=$HOME/local/src/ucl-1.03 (Unix)
|
export UPX_UCLDIR=$HOME/local/src/ucl-1.03 (Unix)
|
||||||
|
|
||||||
then type
|
Set the environment variable UPX_LZMADIR to point to your
|
||||||
|
to your unpacked lzma443.tar.bz2 source directory, e.g.
|
||||||
|
|
||||||
make target=linux # linux
|
export UPX_LZMADIR=$HOME/local/src/lzma-4.43 (Unix)
|
||||||
make target=djgpp2 # dos32 - djgpp2
|
|
||||||
make target=cygwin # win32 - cygwin 1.3.x
|
Finally type
|
||||||
make target=mingw32 # win32 - mingw32
|
|
||||||
make target=no-cygwin # win32 - mingw32 as included in cygwin
|
make
|
||||||
|
|
||||||
|
|
||||||
If you want to modify the stub sources you'll also need
|
If you want to modify the stub sources you'll also need
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
- A68K - a 68000 macro assembler
|
|
||||||
http://upx.sourceforge.net/download/tools/
|
|
||||||
|
|
||||||
- ASM5900 - a MIPS R3000 assembler
|
|
||||||
http://upx.sourceforge.net/download/tools/
|
|
||||||
|
|
||||||
- djasm - an assembler for the djgpp stub
|
|
||||||
http://upx.sourceforge.net/download/tools/
|
|
||||||
|
|
||||||
- nasm 0.98.39 - the Netwide Assembler
|
|
||||||
http://upx.sourceforge.net/download/tools/
|
|
||||||
http://sourceforge.net/projects/nasm/
|
|
||||||
|
|
||||||
- Perl & Python
|
- Perl & Python
|
||||||
|
|
||||||
- Certain versions of some i386-linux tools:
|
- A number of cross-assemblers and cross-compilers - precompiled
|
||||||
- gcc-2.95.3
|
binaries for i386-linux hosts are available from
|
||||||
- gcc-3.4.6
|
http://sourceforge.net/projects/upx/files/upx-tools/20060823/
|
||||||
- binutils-2.16.1
|
|
||||||
|
|
||||||
- Other cross compilers targeted at the following architectures:
|
|
||||||
- arm-9tdmi-linux-gnu
|
|
||||||
- powerpc-750-linux-gnu
|
|
||||||
- x86_64-unknown-linux-gnu
|
|
||||||
|
|
||||||
|
|
||||||
Misc. notes
|
Misc. notes
|
||||||
@@ -130,8 +113,6 @@ Misc. notes
|
|||||||
stream.
|
stream.
|
||||||
- Use gcc extensions and other compiler specific stuff only through
|
- Use gcc extensions and other compiler specific stuff only through
|
||||||
macros.
|
macros.
|
||||||
- Keep in mind that it should be possible to build UPX on braindead
|
|
||||||
case insensitive file systems (FAT).
|
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
@@ -156,3 +137,5 @@ Patches/Contributions
|
|||||||
|
|
||||||
diff -uNr olddirectory newdirectory
|
diff -uNr olddirectory newdirectory
|
||||||
|
|
||||||
|
|
||||||
|
# vi:ts=4:et
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2010 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
http://upx.sourceforge.net
|
http://upx.sourceforge.net
|
||||||
|
|
||||||
|
|
||||||
@@ -53,6 +53,8 @@ Ralph Roth <RalphRoth@gmx.net>
|
|||||||
for reporting several bugs
|
for reporting several bugs
|
||||||
Salvador Eduardo Tropea
|
Salvador Eduardo Tropea
|
||||||
for beta testing
|
for beta testing
|
||||||
|
Stefan Widmann
|
||||||
|
for the win32/pe TLS callback support
|
||||||
The WINE project (http://www.winehq.com/)
|
The WINE project (http://www.winehq.com/)
|
||||||
for lots of useful information found in their PE loader sources
|
for lots of useful information found in their PE loader sources
|
||||||
Natascha
|
Natascha
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
UPX TODO list. Last updated 2006-03-11.
|
UPX TODO list. Last updated 2006-12-08.
|
||||||
|
|
||||||
|
|
||||||
IMPORTANT PROBLEMS THAT SHOULD BE FIXED SOON:
|
IMPORTANT PROBLEMS THAT SHOULD BE FIXED SOON:
|
||||||
@@ -41,8 +41,6 @@ ALL FORMATS
|
|||||||
- implement `--cpu=486' option to use bswap on the 32-bit formats
|
- implement `--cpu=486' option to use bswap on the 32-bit formats
|
||||||
(if cpu >= 486)
|
(if cpu >= 486)
|
||||||
|
|
||||||
- consider removing "or ebp,-1" when not needed
|
|
||||||
|
|
||||||
|
|
||||||
FORMAT DJGPP2/COFF
|
FORMAT DJGPP2/COFF
|
||||||
==================
|
==================
|
||||||
@@ -86,10 +84,6 @@ FORMAT WATCOM/LE
|
|||||||
|
|
||||||
- handle holes in the file
|
- handle holes in the file
|
||||||
|
|
||||||
- implement compressWithFilters()
|
|
||||||
|
|
||||||
- add a call to verifyOverlappingDecompression()
|
|
||||||
|
|
||||||
|
|
||||||
FORMAT WIN16/NE
|
FORMAT WIN16/NE
|
||||||
===============
|
===============
|
||||||
|
|||||||
+47
-30
@@ -1,36 +1,51 @@
|
|||||||
|
#
|
||||||
|
# UPX doc Makefile - needs GNU make 3.80 or better
|
||||||
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
top_srcdir = ..
|
# internal make variables
|
||||||
|
comma := ,
|
||||||
|
empty :=
|
||||||
|
space := $(empty) $(empty)
|
||||||
|
tab := $(empty) $(empty)
|
||||||
|
|
||||||
|
# update $PATH for our special stub build tools
|
||||||
|
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
||||||
|
export PATH := $(HOME)/local/bin/bin-upx:$(PATH)
|
||||||
|
endif
|
||||||
|
ifneq ($(wildcard $(HOME)/bin/bin-upx/.),)
|
||||||
|
export PATH := $(HOME)/bin/bin-upx:$(PATH)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# //
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
top_srcdir ?= ..
|
||||||
|
|
||||||
PACKAGE = upx
|
PACKAGE = upx
|
||||||
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||||
VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||||
|
|
||||||
TRIMSPACE = cat
|
RTRIM := sed -e 's/[ $(tab)]*$$//'
|
||||||
TRIMSPACE = sed -e 's/ *$$//'
|
DETAB2 := sed -e 's/$(tab)/ /g'
|
||||||
|
|
||||||
BUILT_SOURCES = upx.1 upx.doc upx.html upx.man upx.ps upx.tex
|
BUILT_SOURCES = upx.1 upx.doc upx.html upx.man upx.ps upx.tex
|
||||||
BUILT_SOURCES = upx.1 upx.doc upx.html
|
BUILT_SOURCES = upx.1 upx.doc upx.html
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
###
|
### targets
|
||||||
###
|
###
|
||||||
|
|
||||||
all: $(BUILT_SOURCES)
|
all: $(BUILT_SOURCES)
|
||||||
|
|
||||||
mostlyclean:
|
mostlyclean clean distclean maintainer-clean:
|
||||||
-rm -f $(BUILT_SOURCES) pod2htm*
|
rm -f $(BUILT_SOURCES) pod2htm*
|
||||||
|
|
||||||
clean: mostlyclean
|
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
|
|
||||||
maintainer-clean: distclean
|
|
||||||
|
|
||||||
.SUFFIXES: .1 .doc .html .man .pod .ps .tex .texi
|
|
||||||
|
|
||||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||||
|
|
||||||
@@ -39,30 +54,32 @@ maintainer-clean: distclean
|
|||||||
### rules
|
### rules
|
||||||
###
|
###
|
||||||
|
|
||||||
.pod.1:
|
.SUFFIXES: .1 .doc .html .man .pod .ps .tex
|
||||||
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
.pod.html:
|
%.1 : %.pod
|
||||||
### pod2html $< | $(TRIMSPACE) > $@
|
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(RTRIM) > $@
|
||||||
pod2html --noindex $< | $(TRIMSPACE) > $@
|
|
||||||
@-rm -f pod2htm*
|
|
||||||
|
|
||||||
.pod.tex:
|
%.doc : %.pod
|
||||||
|
pod2text < $< | $(RTRIM) > $@
|
||||||
|
|
||||||
|
%.html : %.pod
|
||||||
|
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
|
||||||
|
@rm -f pod2htm*
|
||||||
|
|
||||||
|
%.man : %.1
|
||||||
|
nroff -man $< | $(RTRIM) > $@
|
||||||
|
|
||||||
|
%.ps : %.1
|
||||||
|
groff -man $< | $(RTRIM) > $@
|
||||||
|
|
||||||
|
%.tex : %.pod
|
||||||
pod2latex $<
|
pod2latex $<
|
||||||
|
|
||||||
.pod.doc:
|
|
||||||
pod2text < $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
.1.man:
|
|
||||||
nroff -man $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
.1.ps:
|
|
||||||
groff -man $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
### dependencies
|
### dependencies
|
||||||
###
|
###
|
||||||
|
|
||||||
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
||||||
|
.DELETE_ON_ERROR: $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
|||||||
+32
-5
@@ -1,5 +1,5 @@
|
|||||||
Decompressing ELF Directly to Memory on Linux/x86
|
Decompressing ELF Directly to Memory on Linux/x86
|
||||||
Copyright 2000 John F. Reiser jreiser@BitWagon.com
|
Copyright (C) 2000-2010 John F. Reiser jreiser@BitWagon.com
|
||||||
|
|
||||||
References:
|
References:
|
||||||
<elf.h> definitions for the ELF file format
|
<elf.h> definitions for the ELF file format
|
||||||
@@ -17,7 +17,7 @@ program itself. So, the decompressor program (which contains the
|
|||||||
compressed version of the original executable) must have the same
|
compressed version of the original executable) must have the same
|
||||||
brk() as the original executable. So, the second PT_LOAD
|
brk() as the original executable. So, the second PT_LOAD
|
||||||
ELF "segment" of the compressed program is used only to set the brk(0).
|
ELF "segment" of the compressed program is used only to set the brk(0).
|
||||||
See src/p_lx_elf.cpp, function PackLinuxI386elf::patchLoader().
|
See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr.
|
||||||
All of the decompressor's code, and all of the compressed image
|
All of the decompressor's code, and all of the compressed image
|
||||||
of the original executable, reside in the first PT_LOAD of the
|
of the original executable, reside in the first PT_LOAD of the
|
||||||
decompressor program.
|
decompressor program.
|
||||||
@@ -46,8 +46,8 @@ may not be used to take the address of a function.
|
|||||||
|
|
||||||
The address 0x00400000 was chosen to be out of the way of the usual
|
The address 0x00400000 was chosen to be out of the way of the usual
|
||||||
load address 0x08048000, and to minimize fragmentation in kernel
|
load address 0x08048000, and to minimize fragmentation in kernel
|
||||||
page tables; one page of page tables covers 4MB. The address
|
page tables; one page of page tables covers 4 MiB. The address
|
||||||
0x00401000 was chosen as 1 page up from a 64KB boundary, to
|
0x00401000 was chosen as 1 page up from a 64 KiB boundary, to
|
||||||
make the startup code and its constants smaller.
|
make the startup code and its constants smaller.
|
||||||
|
|
||||||
Decompression of the executable begins by decompressing the Elf32_Ehdr
|
Decompression of the executable begins by decompressing the Elf32_Ehdr
|
||||||
@@ -57,9 +57,36 @@ Subroutine do_xmap() of src/stub/l_lx_elf.c performs the
|
|||||||
"virtual execve()" using the compressed data as source, and stores
|
"virtual execve()" using the compressed data as source, and stores
|
||||||
the decompressed bytes directly into the appropriate virtual addresses.
|
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,
|
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
|
clear the free portion of the stack (to compensate for ld-linux.so.2
|
||||||
assuming that its automatic stack variables are initialized to zero),
|
assuming that its automatic stack variables are initialized to zero),
|
||||||
and remove (all but 4 bytes of) the decompression program (and
|
and remove (all but 4 bytes of) the decompression program (and
|
||||||
compressed executable) from the address space.
|
compressed executable) from the address space.
|
||||||
|
|
||||||
|
As of upx-3.05, by default on Linux, upon decompression then one page
|
||||||
|
of the compressed executable remains mapped into the address space
|
||||||
|
of the process. If all of the pages of the compressed executable are
|
||||||
|
unmapped, then the Linux kernel erases the symlink /proc/self/exe,
|
||||||
|
and this can cause trouble for the runtime shared library loader
|
||||||
|
expanding $ORIGIN in -rpath, or for application code that relies on
|
||||||
|
/proc/self/exe. Use the compress-time command-line option
|
||||||
|
--unmap-all-pages to achieve that effect at run time. Upx-3.04
|
||||||
|
and previous versions did this by default with no option. However,
|
||||||
|
too much other software erroneously assumes that /proc/self/exe
|
||||||
|
always exists.
|
||||||
|
|
||||||
|
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. Linux kernel 2.6.29 and later
|
||||||
|
records a pointer to that character string in Elf32_auxv[AT_EXECFN].
|
||||||
|
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.
|
||||||
|
|||||||
+2
-2
@@ -108,14 +108,14 @@ then skip another one - the unfiltering process needs some information
|
|||||||
to be able to reverse the filtering.
|
to be able to reverse the filtering.
|
||||||
|
|
||||||
UPX uses the following idea, which works nicely. First we assume that
|
UPX uses the following idea, which works nicely. First we assume that
|
||||||
the size of the area that should be filtered is less than 16MB. Then
|
the size of the area that should be filtered is less than 16 MiB. Then
|
||||||
UPX scans over this area and keeps a record of the bytes that are
|
UPX scans over this area and keeps a record of the bytes that are
|
||||||
following the 0xE8 bytes. If we are lucky, there will be bytes that
|
following the 0xE8 bytes. If we are lucky, there will be bytes that
|
||||||
were not found following 0xE8. These bytes are our candidates to be
|
were not found following 0xE8. These bytes are our candidates to be
|
||||||
used as markers.
|
used as markers.
|
||||||
|
|
||||||
Do you still remember that we assumed that the size of scanned area is
|
Do you still remember that we assumed that the size of scanned area is
|
||||||
less than 16MB? Well, this means that when we process a real call, the
|
less than 16 MiB? Well, this means that when we process a real call, the
|
||||||
resulting offset will be less than 0x00FFFFFF too. So the MSB is always
|
resulting offset will be less than 0x00FFFFFF too. So the MSB is always
|
||||||
0x00. Which is a nice place to store our marker. Of course we should
|
0x00. Which is a nice place to store our marker. Of course we should
|
||||||
reverse the byte order in the resulting offset - so this marker will
|
reverse the byte order in the resulting offset - so this marker will
|
||||||
|
|||||||
+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
|
understand and/or modify the UPX assembly stubs - the small snippets
|
||||||
that do the runtime decompression when a compressed program is started.
|
that do the runtime decompression when a compressed program is started.
|
||||||
|
|
||||||
So, how the runtime stub/loader generation works?
|
If you look at the C++ source files, you can find code fragments like
|
||||||
|
this:
|
||||||
You might have already noticed that for some file formats the loaders
|
|
||||||
are quite simple (linux/i386 & tos) while in the other cases the
|
|
||||||
loaders look very suspicious: they're full of `%ifdef's and contain
|
|
||||||
loads of cryptic comments like `__PERELOC2__'.
|
|
||||||
|
|
||||||
If you look at the C++ source files, however you can notice that these
|
|
||||||
comment strings (without the leading and trailing underscores) are used
|
|
||||||
in the following way:
|
|
||||||
|
|
||||||
addLoader("PEMAIN20",
|
addLoader("PEMAIN20",
|
||||||
ih.entry ? "PEDOJUMP" : "PERETURN",
|
ih.entry ? "PEDOJUMP" : "PERETURN",
|
||||||
@@ -19,71 +11,40 @@ in the following way:
|
|||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
Basically that's all you have to know: when you want to add a section
|
linker->defineSymbol("original_entry", ih.entry);
|
||||||
of assembly code to the runtime loader, you just write
|
|
||||||
|
|
||||||
l_foo.asm
|
and in the assembly files fragments like this:
|
||||||
---------
|
|
||||||
;__FOOBAR00__
|
|
||||||
|
|
||||||
xor eax, eax
|
section PEISDLL1
|
||||||
label1:
|
cmpb [esp + 8], 1
|
||||||
jmps label1
|
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);
|
Everything works as you would expect. If you want to add the code
|
||||||
|
fragment which is in `section PERETURN' to the runtime stub, then
|
||||||
This will add the assembly section starting from __FOOBAR00__ and ending
|
simply use `addLoader("PERETURN")' in the C++ source.
|
||||||
before __FOOBARZZ__ to the loader. You can add an %ifdef - %endif pair
|
|
||||||
before these comments if you wish - but these conditionals will NOT be
|
|
||||||
seen by the assembler, they are just syntactic sugar to make the code a
|
|
||||||
little bit more readable and understandable. (Note however, that only
|
|
||||||
%ifdefs which are started on the 1st column are removed by the upx
|
|
||||||
assembly preprocessor program, so you can still use preprocessor
|
|
||||||
conditionals if you wish - just write them starting from the 2nd
|
|
||||||
column.)
|
|
||||||
|
|
||||||
That's nice, you could say, but how cross section jumps and calls are
|
That's nice, you could say, but how cross section jumps and calls are
|
||||||
handled? Well, that is the nicest part of this stuff - they are handled
|
handled? Well, that is the nicest part of this stuff - they are handled
|
||||||
automatically. All you have to do is to add the required sections to the
|
automatically. All you have to do is to add the required sections to the
|
||||||
loader using `addLoader()' and the rest is done by upx. It will resolve
|
loader using `addLoader()' and the rest is done by upx. It will resolve
|
||||||
every conditional or unconditional jumps or subrutine calls for you.
|
every conditional or unconditional jumps or subroutine calls for you.
|
||||||
|
|
||||||
This functionality (we could say it's a simple linker) is achived by the
|
You can also use (undefined) symbols in the assembly for values that
|
||||||
assembly preprocessor (src/stub/scripts/app.pl) and a little C++ module
|
can only be computed during compression time (like `original_entry').
|
||||||
(src/linker.cpp). And of course NASM - the Netwide Assembler. You can
|
These symbols can be defined later in C++ using
|
||||||
see what's going on behind the scenes - just do:
|
|
||||||
|
|
||||||
cd src/stubs
|
linker->defineSymbol("xx", yy)
|
||||||
make maintainer-clean
|
|
||||||
make all
|
|
||||||
|
|
||||||
This will rebuild all the loaders - and keep the temporary files (*.as[xy])
|
This functionality (we could say it's a simple linker) is achieved by
|
||||||
which are seen by the assembler.
|
compiling the assembly into an ELF object file which a little C++
|
||||||
|
module (src/linker.cpp) can interpret and work with.
|
||||||
Currently this loader/stub building method only works with ix86
|
|
||||||
assembly - both app.pl and linker.cpp heavily rely on this when dealing
|
|
||||||
with cross section references.
|
|
||||||
|
|
||||||
And finally some important features/requirements you should be aware of:
|
|
||||||
|
|
||||||
- as previously stated - preprocessor conditionals starting on the 1st
|
|
||||||
column are removed by app.pl
|
|
||||||
- sections are separated by comments in the form `;__X1234567__'
|
|
||||||
- jumps are recognized by searching for a word which starts with `j'
|
|
||||||
and followed by a label - this also means that `jmp short label1'
|
|
||||||
will NOT be recognized (but you can use a macro called `jmps' for it
|
|
||||||
by adding `%define jmps jmp short' to the beginning of the file)
|
|
||||||
- at the end of the file you need something like this
|
|
||||||
|
|
||||||
eof:
|
|
||||||
; __XTHEENDX__
|
|
||||||
section .data
|
|
||||||
dd -1
|
|
||||||
dw eof
|
|
||||||
|
|
||||||
That's all for now.
|
|
||||||
|
|||||||
+58
-67
@@ -13,7 +13,7 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
|
|||||||
=head1 ABSTRACT
|
=head1 ABSTRACT
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2010 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
http://upx.sourceforge.net
|
http://upx.sourceforge.net
|
||||||
|
|
||||||
|
|
||||||
@@ -51,8 +51,8 @@ B<UPX> is a versatile executable packer with the following features:
|
|||||||
- excellent compression ratio: compresses better than zip/gzip,
|
- excellent compression ratio: compresses better than zip/gzip,
|
||||||
use UPX to decrease the size of your distribution !
|
use UPX to decrease the size of your distribution !
|
||||||
|
|
||||||
- very fast decompression: about 10 MB/sec on an ancient Pentium 133,
|
- very fast decompression: about 10 MiB/sec on an ancient Pentium 133,
|
||||||
about 200 MB/sec on an Athlon XP 2000+.
|
about 200 MiB/sec on an Athlon XP 2000+.
|
||||||
|
|
||||||
- no memory overhead for your compressed executables for most of the
|
- no memory overhead for your compressed executables for most of the
|
||||||
supported formats
|
supported formats
|
||||||
@@ -138,6 +138,13 @@ B<--help>: prints the help
|
|||||||
|
|
||||||
B<--version>: print the version of B<UPX>
|
B<--version>: print the version of B<UPX>
|
||||||
|
|
||||||
|
B<--exact>: when compressing, require to be able to get a byte-identical file
|
||||||
|
after decompression with option B<-d>. [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 ]
|
[ ...to be written... - type `B<upx --help>' for now ]
|
||||||
|
|
||||||
|
|
||||||
@@ -146,7 +153,7 @@ B<--version>: print the version of B<UPX>
|
|||||||
|
|
||||||
B<UPX> offers ten different compression levels from B<-1> to B<-9>,
|
B<UPX> offers ten different compression levels from B<-1> to B<-9>,
|
||||||
and B<--best>. The default compression level is B<-8> for files
|
and B<--best>. The default compression level is B<-8> for files
|
||||||
smaller than 512 kB, and B<-7> otherwise.
|
smaller than 512 KiB, and B<-7> otherwise.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|
||||||
@@ -172,38 +179,13 @@ Note that compression level B<--best> can be somewhat slow for large
|
|||||||
files, but you definitely should use it when releasing a final version
|
files, but you definitely should use it when releasing a final version
|
||||||
of your program.
|
of your program.
|
||||||
|
|
||||||
Quick start for achieving the best compression ratio:
|
Quick info for achieving the best compression ratio:
|
||||||
|
|
||||||
=over 4
|
|
||||||
|
|
||||||
Try B<upx --brute myfile.exe>.
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
Details for achieving the best compression ratio:
|
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|
||||||
=item *
|
=item *
|
||||||
|
|
||||||
Use the compression level B<--best>.
|
Try B<upx --brute myfile.exe> or even B<upx --ultra-brute myfile.exe>.
|
||||||
|
|
||||||
=item *
|
|
||||||
|
|
||||||
Try one or both of the options B<--all-methods> and B<--all-filters>.
|
|
||||||
|
|
||||||
=item *
|
|
||||||
|
|
||||||
Try the option B<--crp-ms=NUMBER>. This uses more memory during compression
|
|
||||||
to achieve a (slightly) better compression ratio.
|
|
||||||
|
|
||||||
NUMBER must be a decimal value from 10000 to 999999, inclusive.
|
|
||||||
The default value is 10000 (ten thousand).
|
|
||||||
|
|
||||||
=item *
|
|
||||||
|
|
||||||
Info: the option B<--brute> is an abbrevation for the options
|
|
||||||
B<S<--best> S<--all-methods> S<--all-filters> S<--crp-ms=999999>>.
|
|
||||||
|
|
||||||
=item *
|
=item *
|
||||||
|
|
||||||
@@ -219,7 +201,7 @@ For win32/pe programs there's B<--strip-relocs=0>. See notes below.
|
|||||||
|
|
||||||
=head1 OVERLAY HANDLING OPTIONS
|
=head1 OVERLAY HANDLING OPTIONS
|
||||||
|
|
||||||
Info: An "overlay" means auxillary data atached after the logical end of
|
Info: An "overlay" means auxiliary data attached after the logical end of
|
||||||
an executable, and it often contains application specific data
|
an executable, and it often contains application specific data
|
||||||
(this is a common practice to avoid an extra data file, though
|
(this is a common practice to avoid an extra data file, though
|
||||||
it would be better to use resource sections).
|
it would be better to use resource sections).
|
||||||
@@ -367,7 +349,7 @@ Extra options available for this executable format:
|
|||||||
First of all, it is recommended to use B<UPX> *instead* of B<strip>. strip has
|
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.
|
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
|
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 KiB alignment of the stub.
|
||||||
|
|
||||||
B<UPX> includes the full functionality of stubify. This means it will
|
B<UPX> includes the full functionality of stubify. This means it will
|
||||||
automatically stubify your COFF files. Use the option B<--coff> to
|
automatically stubify your COFF files. Use the option B<--coff> to
|
||||||
@@ -402,7 +384,7 @@ Extra options available for this executable format:
|
|||||||
Introduction
|
Introduction
|
||||||
|
|
||||||
Linux/386 support in UPX consists of 3 different executable formats,
|
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
|
for shell scripts ("linux/sh386"), and one generic format
|
||||||
("linux/386").
|
("linux/386").
|
||||||
|
|
||||||
@@ -430,14 +412,14 @@ General user's overview
|
|||||||
or network I/O.
|
or network I/O.
|
||||||
|
|
||||||
Depending on the statistics of usage and access, and the relative
|
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
|
invoking and running a compressed executable can be faster than
|
||||||
directly running the corresponding uncompressed program.
|
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
|
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
|
``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
|
Small programs tend not to benefit as much because the absolute
|
||||||
savings is less. Big programs tend not to benefit proportionally
|
savings is less. Big programs tend not to benefit proportionally
|
||||||
because each invocation may use only a small fraction of the program,
|
because each invocation may use only a small fraction of the program,
|
||||||
@@ -446,7 +428,7 @@ General user's overview
|
|||||||
then compression may win anyway.
|
then compression may win anyway.
|
||||||
|
|
||||||
Currently, executables compressed by UPX do not share RAM at runtime
|
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
|
result, if the same program is run simultaneously by more than one
|
||||||
process, then using the compressed version will require more RAM and/or
|
process, then using the compressed version will require more RAM and/or
|
||||||
swap space. So, shell programs (bash, csh, etc.) and ``make''
|
swap space. So, shell programs (bash, csh, etc.) and ``make''
|
||||||
@@ -535,7 +517,7 @@ The linux/elf386 format decompresses directly into RAM,
|
|||||||
uses only one exec, does not use space in /tmp,
|
uses only one exec, does not use space in /tmp,
|
||||||
and does not use /proc.
|
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.
|
Packed programs will be byte-identical to the original after uncompression.
|
||||||
|
|
||||||
@@ -624,7 +606,7 @@ Extra options available for this executable format:
|
|||||||
Please read the general Linux description first.
|
Please read the general Linux description first.
|
||||||
|
|
||||||
The generic linux/386 format decompresses to /tmp and needs
|
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.
|
via the execve() syscall.
|
||||||
|
|
||||||
Linux/386 is only selected if the specialized linux/elf386
|
Linux/386 is only selected if the specialized linux/elf386
|
||||||
@@ -636,11 +618,11 @@ How it works:
|
|||||||
|
|
||||||
For files which are not ELF and not a script for a known "-c" shell,
|
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
|
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
|
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
|
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
|
A compressed executable consists of the UPX stub and an overlay
|
||||||
which contains the original program in a compressed form.
|
which contains the original program in a compressed form.
|
||||||
@@ -666,7 +648,7 @@ Specific drawbacks:
|
|||||||
decompression, but you still need it for the full execution time
|
decompression, but you still need it for the full execution time
|
||||||
of the program.
|
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
|
/proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you
|
||||||
cannot compress programs that are used during the boot sequence
|
cannot compress programs that are used during the boot sequence
|
||||||
before /proc is mounted.
|
before /proc is mounted.
|
||||||
@@ -678,8 +660,8 @@ Specific drawbacks:
|
|||||||
|
|
||||||
- Because of temporary decompression to disk the decompression speed
|
- Because of temporary decompression to disk the decompression speed
|
||||||
is not as fast as with the other executable formats. Still, I can see
|
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 MiB emacs (which
|
||||||
is less than 1 MB when compressed :-).
|
is less than 1 MiB when compressed :-).
|
||||||
|
|
||||||
Extra options available for this executable format:
|
Extra options available for this executable format:
|
||||||
|
|
||||||
@@ -699,19 +681,23 @@ nostalgic feelings of one of the authors.
|
|||||||
Packed programs will be byte-identical to the original after uncompression,
|
Packed programs will be byte-identical to the original after uncompression,
|
||||||
until further notice.
|
until further notice.
|
||||||
|
|
||||||
Maximum uncompressed size: ~1998848 bytes.
|
Maximum uncompressed size: ~1.89 / ~7.60 MiB.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
- UPX creates as default a 'CD-Rom only' PS1/PS2 compatible executable.
|
- UPX creates as default a suitable executable for CD-Mastering
|
||||||
For transfer between client/target use options below.
|
and console transfer. For a CD-Master main executable you could also try
|
||||||
|
the special option "--boot-only" as 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
|
- Normally the packed files use the same memory areas like the uncompressed
|
||||||
versions, so they will not override other memory areas while unpacking.
|
versions, so they will not override other memory areas while unpacking.
|
||||||
If this isn't possible UPX will abort showing a 'packed data overlap'
|
If this isn't possible UPX will abort showing a 'packed data overlap'
|
||||||
error. With the "--force" option UPX will set a few 'bytes higher' loading
|
error. With the "--force" option UPX will relocate the loading address
|
||||||
offset for the packed file, but this isn't a real problem if it is a
|
for the packed file, but this isn't a real problem if it is a single or
|
||||||
single or boot-only executable.
|
the main executable.
|
||||||
|
|
||||||
Extra options available for this executable format:
|
Extra options available for this executable format:
|
||||||
|
|
||||||
@@ -720,15 +706,19 @@ Extra options available for this executable format:
|
|||||||
the compression ratio in some cases, but usually
|
the compression ratio in some cases, but usually
|
||||||
the default method gives the best results anyway.
|
the default method gives the best results anyway.
|
||||||
|
|
||||||
--boot-only The format will only run from a CD and may slightly
|
--8-bit Uses 8 bit size compression [default: 32 bit]
|
||||||
improves the compression ratio. The decompression
|
|
||||||
routines are faster than default ones.
|
--8mib-ram PSone has 8 MiB ram available [default: 2 MiB]
|
||||||
But it cannot be used for host/client transfer !
|
|
||||||
|
--boot-only This format is for main exes and CD-Mastering only !
|
||||||
|
It may slightly improve the compression ratio,
|
||||||
|
decompression routines are faster than default ones.
|
||||||
|
But it cannot be used for console transfer !
|
||||||
|
|
||||||
--no-align This option disables CD mode 2 data sector format
|
--no-align This option disables CD mode 2 data sector format
|
||||||
alignment. May slightly improves the compression ratio,
|
alignment. May slightly improves the compression ratio,
|
||||||
but the compressed executable will not boot from a CD.
|
but the compressed executable will not boot from a CD.
|
||||||
Use it for client/target transfer only !
|
Use it for console transfer only !
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -776,7 +766,7 @@ Benefits:
|
|||||||
- Better compression (but note that the kernel was already compressed,
|
- Better compression (but note that the kernel was already compressed,
|
||||||
so the improvement is not as large as with other formats).
|
so the improvement is not as large as with other formats).
|
||||||
Still, the bytes saved may be essential for special needs like
|
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:
|
For example, this is what I get for my 2.2.16 kernel:
|
||||||
1589708 vmlinux
|
1589708 vmlinux
|
||||||
@@ -823,13 +813,13 @@ Extra options available for this executable format:
|
|||||||
=head2 NOTES FOR WIN32/PE
|
=head2 NOTES FOR WIN32/PE
|
||||||
|
|
||||||
The PE support in B<UPX> is quite stable now, but probably there are
|
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
|
Because of the way B<UPX> (and other packers for this format) works, you
|
||||||
can see increased memory usage of your compressed files because the whole
|
can see increased memory usage of your compressed files because the whole
|
||||||
program is loaded into memory at startup.
|
program is loaded into memory at startup.
|
||||||
If you start several instances of huge compressed programs you're
|
If you start several instances of huge compressed programs you're
|
||||||
wasting memory because the common segements of the program won't
|
wasting memory because the common segments of the program won't
|
||||||
get shared across the instances.
|
get shared across the instances.
|
||||||
On the other hand if you're compressing only smaller programs, or
|
On the other hand if you're compressing only smaller programs, or
|
||||||
running only one instance of larger programs, then this penalty is
|
running only one instance of larger programs, then this penalty is
|
||||||
@@ -847,8 +837,8 @@ Screensavers are supported, with the restriction that the filename
|
|||||||
must end with ".scr" (as screensavers are handled slightly different
|
must end with ".scr" (as screensavers are handled slightly different
|
||||||
than normal exe files).
|
than normal exe files).
|
||||||
|
|
||||||
UPX compressed PE files has some minor memory overhead (usually in the
|
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
|
10 - 30 KiB range) which can be seen by specifying the "-i" command
|
||||||
line switch during compression.
|
line switch during compression.
|
||||||
|
|
||||||
Extra options available for this executable format:
|
Extra options available for this executable format:
|
||||||
@@ -867,6 +857,7 @@ Extra options available for this executable format:
|
|||||||
--compress-icons=1 Compress all but the first icon.
|
--compress-icons=1 Compress all but the first icon.
|
||||||
--compress-icons=2 Compress all icons which are not in the
|
--compress-icons=2 Compress all icons which are not in the
|
||||||
first icon directory. [DEFAULT]
|
first icon directory. [DEFAULT]
|
||||||
|
--compress-icons=3 Compress all icons.
|
||||||
|
|
||||||
--compress-resources=0 Don't compress any resources at all.
|
--compress-resources=0 Don't compress any resources at all.
|
||||||
|
|
||||||
@@ -942,13 +933,13 @@ Please report all bugs immediately to the authors.
|
|||||||
|
|
||||||
=head1 COPYRIGHT
|
=head1 COPYRIGHT
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
|
|
||||||
Copyright (C) 2000-2006 John F. Reiser
|
Copyright (C) 2000-2010 John F. Reiser
|
||||||
|
|
||||||
Copyright (C) 2002-2006 Jens Medoch
|
Copyright (C) 2002-2010 Jens Medoch
|
||||||
|
|
||||||
This program may be used freely, and you are welcome to
|
This program may be used freely, and you are welcome to
|
||||||
redistribute it under certain conditions.
|
redistribute it under certain conditions.
|
||||||
|
|||||||
+77
-18
@@ -1,5 +1,7 @@
|
|||||||
#
|
#
|
||||||
# UPX Makefile - needs GNU make 3.80 or better
|
# UPX Makefile - needs GNU make 3.81 or better
|
||||||
|
#
|
||||||
|
# Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
#
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
@@ -7,9 +9,19 @@ MAKEFLAGS += -rR
|
|||||||
export SHELL = /bin/sh
|
export SHELL = /bin/sh
|
||||||
override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1)
|
override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1)
|
||||||
|
|
||||||
srcdir ?= $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
|
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.77 3.78 3.78.1 3.79 3.79.1 3.80),)
|
||||||
ifneq ($(srcdir),./)
|
$(error GNU make 3.81 or better is required)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef srcdir
|
||||||
|
srcdir := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
|
||||||
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,')
|
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))
|
##$(info Info: using VPATH . $(srcdir))
|
||||||
VPATH := . $(srcdir)
|
VPATH := . $(srcdir)
|
||||||
endif
|
endif
|
||||||
@@ -17,9 +29,18 @@ endif
|
|||||||
ifeq ($(CXX),)
|
ifeq ($(CXX),)
|
||||||
CXX = g++
|
CXX = g++
|
||||||
endif
|
endif
|
||||||
ifeq ($(CXX),g++)
|
ifneq ($(findstring $(firstword $(CXX)),g++),)
|
||||||
CXXFLAGS += -O2 -MMD
|
USE_GNUC ?= 1
|
||||||
CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wwrite-strings -Werror
|
endif
|
||||||
|
ifeq ($(USE_GNUC),1)
|
||||||
|
ifeq ($(DEBUG),1)
|
||||||
|
CXXFLAGS += -O0 -g
|
||||||
|
else
|
||||||
|
CXXFLAGS += -O2
|
||||||
|
endif
|
||||||
|
CXXFLAGS_WERROR = -Werror
|
||||||
|
CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wshadow -Wwrite-strings
|
||||||
|
CXXFLAGS += $(CXXFLAGS_WERROR)
|
||||||
endif
|
endif
|
||||||
CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
|
CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
|
||||||
CXXLD ?= $(CXX)
|
CXXLD ?= $(CXX)
|
||||||
@@ -28,28 +49,66 @@ exeext ?= .out
|
|||||||
libext ?= .a
|
libext ?= .a
|
||||||
objext ?= .o
|
objext ?= .o
|
||||||
|
|
||||||
# we need UCL and zlib - you can set envvar UCLDIR
|
upx_SOURCES := $(sort $(wildcard $(srcdir)/*.cpp))
|
||||||
ifneq ($(wildcard $(UCLDIR)/include/ucl/ucl.h),)
|
|
||||||
INCLUDES += -I$(UCLDIR)/include
|
|
||||||
LIBS += $(addprefix -L,$(dir $(wildcard $(UCLDIR)/libucl$(libext) $(UCLDIR)/src/.libs/libucl$(libext))))
|
|
||||||
endif
|
|
||||||
LIBS += -lucl -lz
|
|
||||||
|
|
||||||
upx_SOURCES := $(wildcard $(srcdir)/*.cpp)
|
|
||||||
upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
|
upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
|
||||||
|
|
||||||
all: upx$(exeext)
|
# 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
|
||||||
|
|
||||||
|
|
||||||
|
all: upx$(exeext) | .depend
|
||||||
|
.DELETE_ON_ERROR: upx$(exeext) $(upx_OBJECTS) .depend
|
||||||
|
|
||||||
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
||||||
$($(notdir $@).PRE_LINK_STEP)
|
$($(notdir $@).PRE_LINK_STEP)
|
||||||
$(strip $(CXXLD) $(call e,CPPFLAGS) $(call e,CXXFLAGS) $(call e,LDFLAGS) -o $@ $(upx_OBJECTS) $(call e,LDADD) $(call e,LIBS))
|
$(strip $(CXXLD) $(call e,CPPFLAGS) $(call e,CXXFLAGS) $(call e,LDFLAGS) -o $@ $(upx_OBJECTS) $(call e,LDADD) $(call e,LIBS))
|
||||||
$($(notdir $@).POST_LINK_STEP)
|
$($(notdir $@).POST_LINK_STEP)
|
||||||
|
|
||||||
%.o : %.cpp
|
%.o : %.cpp | .depend
|
||||||
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
||||||
|
|
||||||
|
.depend: $(sort $(wildcard $(srcdir)/*.cpp $(srcdir)/*.h)) $(MAKEFILE_LIST)
|
||||||
|
@rm -f $@
|
||||||
|
ifeq ($(USE_GNUC),1)
|
||||||
|
@echo "Updating $@"
|
||||||
|
@$(strip $(CXX) $(call e,CPPFLAGS) -MM) $(filter %.cpp,$^) > $@
|
||||||
|
else
|
||||||
|
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:
|
mostlyclean clean distclean maintainer-clean:
|
||||||
rm -f *.d *.map *.o *.obj *.res upx.exe upx.out upx.ttp upx$(exeext)
|
rm -f *.d *.map *.o *.obj *.res .depend upx.exe upx.out upx.ttp upx$(exeext)
|
||||||
|
|
||||||
-include *.d
|
|
||||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||||
|
|
||||||
|
ifeq ($(MAKECMDGOALS),mostlyclean)
|
||||||
|
else ifeq ($(MAKECMDGOALS),clean)
|
||||||
|
else ifeq ($(MAKECMDGOALS),distclean)
|
||||||
|
else ifeq ($(MAKECMDGOALS),maintainer-clean)
|
||||||
|
else
|
||||||
|
-include .depend
|
||||||
|
endif
|
||||||
|
|||||||
+186
-44
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2005 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_BELE_H
|
#ifndef __UPX_BELE_H
|
||||||
#define __UPX_BELE_H
|
#define __UPX_BELE_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -183,81 +183,142 @@ inline void set_le64(void *p, acc_uint64l_t v)
|
|||||||
// get signed values, i.e. sign-extend
|
// get signed values, i.e. sign-extend
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
inline int sign_extend(int v, int bits)
|
inline int sign_extend(unsigned v, unsigned bits)
|
||||||
{
|
{
|
||||||
const unsigned sign_bit = 1u << (bits - 1);
|
const unsigned sign_bit = 1u << (bits - 1);
|
||||||
v |= 0u - (v & sign_bit);
|
v &= sign_bit | (sign_bit - 1);
|
||||||
return v;
|
//v = (v ^ sign_bit) - sign_bit;
|
||||||
|
v |= 0 - (v & sign_bit);
|
||||||
|
return (int) v;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline acc_int64l_t sign_extend(acc_int64l_t v, int bits)
|
inline acc_int64l_t sign_extend(acc_uint64l_t v, unsigned bits)
|
||||||
{
|
{
|
||||||
const acc_uint64l_t sign_bit = ACC_UINT64_C(1) << (bits - 1);
|
const acc_uint64l_t sign_bit = ACC_UINT64_C(1) << (bits - 1);
|
||||||
v |= ACC_UINT64_C(0) - (v & sign_bit);
|
v &= sign_bit | (sign_bit - 1);
|
||||||
return v;
|
//v = (v ^ sign_bit) - sign_bit;
|
||||||
|
v |= 0 - (v & sign_bit);
|
||||||
|
return (acc_int64l_t) v;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_be16_signed(const void *p)
|
inline int get_be16_signed(const void *p)
|
||||||
{
|
{
|
||||||
int v = get_be16(p);
|
unsigned v = get_be16(p);
|
||||||
return sign_extend(v, 16);
|
return sign_extend(v, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_be24_signed(const void *p)
|
inline int get_be24_signed(const void *p)
|
||||||
{
|
{
|
||||||
int v = get_be24(p);
|
unsigned v = get_be24(p);
|
||||||
return sign_extend(v, 24);
|
return sign_extend(v, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_be32_signed(const void *p)
|
inline int get_be32_signed(const void *p)
|
||||||
{
|
{
|
||||||
int v = get_be32(p);
|
unsigned v = get_be32(p);
|
||||||
return sign_extend(v, 32);
|
return sign_extend(v, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline acc_int64l_t get_be64_signed(const void *p)
|
inline acc_int64l_t get_be64_signed(const void *p)
|
||||||
{
|
{
|
||||||
acc_int64l_t v = get_be64(p);
|
acc_uint64l_t v = get_be64(p);
|
||||||
return sign_extend(v, 64);
|
return sign_extend(v, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_le16_signed(const void *p)
|
inline int get_le16_signed(const void *p)
|
||||||
{
|
{
|
||||||
int v = get_le16(p);
|
unsigned v = get_le16(p);
|
||||||
return sign_extend(v, 16);
|
return sign_extend(v, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_le24_signed(const void *p)
|
inline int get_le24_signed(const void *p)
|
||||||
{
|
{
|
||||||
int v = get_le24(p);
|
unsigned v = get_le24(p);
|
||||||
return sign_extend(v, 24);
|
return sign_extend(v, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_le32_signed(const void *p)
|
inline int get_le32_signed(const void *p)
|
||||||
{
|
{
|
||||||
int v = get_le32(p);
|
unsigned v = get_le32(p);
|
||||||
return sign_extend(v, 32);
|
return sign_extend(v, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_le64_signed(const void *p)
|
inline acc_int64l_t get_le64_signed(const void *p)
|
||||||
{
|
{
|
||||||
acc_int64l_t v = get_le64(p);
|
acc_uint64l_t v = get_le64(p);
|
||||||
return sign_extend(v, 64);
|
return sign_extend(v, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// swab (bswap)
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
inline unsigned acc_swab16(unsigned v)
|
||||||
|
{
|
||||||
|
return ((v & 0x00ff) << 8) |
|
||||||
|
((v & 0xff00) >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned acc_swab32(unsigned v)
|
||||||
|
{
|
||||||
|
return ((v & 0x000000ff) << 24) |
|
||||||
|
((v & 0x0000ff00) << 8) |
|
||||||
|
((v & 0x00ff0000) >> 8) |
|
||||||
|
((v & 0xff000000) >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline unsigned acc_swab16p(const acc_uint16e_t *p)
|
||||||
|
{
|
||||||
|
return acc_swab16(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned acc_swap32p(const acc_uint32e_t *p)
|
||||||
|
{
|
||||||
|
return acc_swab32(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void acc_swab16s(acc_uint16e_t *p)
|
||||||
|
{
|
||||||
|
*p = (acc_uint16e_t) acc_swab16(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void acc_swab32s(acc_uint32e_t *p)
|
||||||
|
{
|
||||||
|
*p = (acc_uint32e_t) acc_swab32(*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void acc_ua_swab16s(void *p)
|
||||||
|
{
|
||||||
|
set_be16(p, get_le16(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void acc_ua_swab32s(void *p)
|
||||||
|
{
|
||||||
|
set_be32(p, get_le32(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// classes for portable unaligned access
|
// classes for portable unaligned access
|
||||||
//
|
//
|
||||||
// Important: these classes must be PODs (Plain Old Data), i.e. no
|
// Important: these classes must be PODs (Plain Old Data), i.e. no
|
||||||
// constructor, no destructor, no virtual functions and no default
|
// constructor, no destructor, no virtual functions and no default
|
||||||
// assignment operator, and all fields must be public(!).
|
// 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 ]
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
struct BE16
|
__packed_struct(BE16)
|
||||||
{
|
|
||||||
unsigned char d[2];
|
unsigned char d[2];
|
||||||
|
|
||||||
|
//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, 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; }
|
||||||
@@ -270,14 +331,15 @@ struct BE16
|
|||||||
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 unsigned () const { return get_be16(d); }
|
operator unsigned () const { return get_be16(d); }
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
|
|
||||||
struct BE32
|
__packed_struct(BE32)
|
||||||
{
|
|
||||||
unsigned char d[4];
|
unsigned char d[4];
|
||||||
|
|
||||||
|
//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, 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; }
|
||||||
@@ -290,14 +352,15 @@ struct BE32
|
|||||||
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 unsigned () const { return get_be32(d); }
|
operator unsigned () const { return get_be32(d); }
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
|
|
||||||
struct BE64
|
__packed_struct(BE64)
|
||||||
{
|
|
||||||
unsigned char d[8];
|
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, 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; }
|
||||||
@@ -310,14 +373,15 @@ struct BE64
|
|||||||
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); }
|
operator acc_uint64l_t () const { return get_be64(d); }
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
|
|
||||||
struct LE16
|
__packed_struct(LE16)
|
||||||
{
|
|
||||||
unsigned char d[2];
|
unsigned char d[2];
|
||||||
|
|
||||||
|
//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, 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; }
|
||||||
@@ -330,14 +394,15 @@ struct LE16
|
|||||||
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 unsigned () const { return get_le16(d); }
|
operator unsigned () const { return get_le16(d); }
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
|
|
||||||
struct LE32
|
__packed_struct(LE32)
|
||||||
{
|
|
||||||
unsigned char d[4];
|
unsigned char d[4];
|
||||||
|
|
||||||
|
//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, 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; }
|
||||||
@@ -350,14 +415,15 @@ struct LE32
|
|||||||
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 unsigned () const { return get_le32(d); }
|
operator unsigned () const { return get_le32(d); }
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
|
|
||||||
struct LE64
|
__packed_struct(LE64)
|
||||||
{
|
|
||||||
unsigned char d[8];
|
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, 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; }
|
||||||
@@ -370,8 +436,7 @@ struct LE64
|
|||||||
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); }
|
operator acc_uint64l_t () const { return get_le64(d); }
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -417,11 +482,47 @@ template <class T> T* operator + (const LE64& v, T* ptr);
|
|||||||
template <class T> T* operator - (T* ptr, const LE64& v);
|
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
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// misc
|
// misc
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
// for use with qsort()
|
// for use with qsort()
|
||||||
|
extern "C" {
|
||||||
int __acc_cdecl_qsort be16_compare(const void *, const void *);
|
int __acc_cdecl_qsort be16_compare(const void *, const void *);
|
||||||
int __acc_cdecl_qsort be24_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 be32_compare(const void *, const void *);
|
||||||
@@ -438,10 +539,11 @@ 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 le24_compare_signed(const void *, const void *);
|
||||||
int __acc_cdecl_qsort le32_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 *);
|
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
|
||||||
// just for testing...
|
// just for testing...
|
||||||
#if !defined(ACC_CFG_NO_UNALIGNED)
|
#if !(ACC_CFG_NO_UNALIGNED)
|
||||||
#if 0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386) && (ACC_CC_GNUC >= 0x030200)
|
#if 0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386) && (ACC_CC_GNUC >= 0x030200)
|
||||||
typedef acc_uint16e_t LE16_unaligned __attribute__((__aligned__(1)));
|
typedef acc_uint16e_t LE16_unaligned __attribute__((__aligned__(1)));
|
||||||
typedef acc_uint32e_t LE32_unaligned __attribute__((__aligned__(1)));
|
typedef acc_uint32e_t LE32_unaligned __attribute__((__aligned__(1)));
|
||||||
@@ -476,6 +578,46 @@ int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// Provide namespaces and classes to abstract endianness policies.
|
||||||
|
//
|
||||||
|
// CTP - Compile-Time Polymorphism (templates)
|
||||||
|
// RTP - Run-Time Polymorphism (virtual functions)
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
namespace N_BELE_CTP {
|
||||||
|
struct BEPolicy; struct LEPolicy;
|
||||||
|
extern const BEPolicy be_policy;
|
||||||
|
extern const LEPolicy le_policy;
|
||||||
|
}
|
||||||
|
namespace N_BELE_RTP {
|
||||||
|
struct AbstractPolicy;
|
||||||
|
struct BEPolicy; struct 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 {
|
||||||
|
inline const N_BELE_RTP::AbstractPolicy* getRTP(const BEPolicy*)
|
||||||
|
{ return &N_BELE_RTP::be_policy; }
|
||||||
|
inline const N_BELE_RTP::AbstractPolicy* getRTP(const LEPolicy*)
|
||||||
|
{ return &N_BELE_RTP::le_policy; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#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-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2010 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_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 /*empty*/
|
||||||
|
#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
|
||||||
|
*/
|
||||||
|
|
||||||
+4
-4
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_BPTR_H
|
#ifndef __UPX_BPTR_H
|
||||||
#define __UPX_BPTR_H
|
#define __UPX_BPTR_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
|||||||
+5
-5
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,13 +22,13 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
|
||||||
#if defined(USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -72,7 +72,7 @@ static void print0(FILE *f, const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+8
-8
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
FILE *con_term = NULL;
|
FILE *con_term = NULL;
|
||||||
|
|
||||||
#if defined(USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -84,14 +84,14 @@ static int do_init(FILE *f)
|
|||||||
if (!acc_isatty(STDIN_FILENO) || !acc_isatty(STDOUT_FILENO) || !acc_isatty(STDERR_FILENO))
|
if (!acc_isatty(STDIN_FILENO) || !acc_isatty(STDOUT_FILENO) || !acc_isatty(STDERR_FILENO))
|
||||||
return con_mode;
|
return con_mode;
|
||||||
|
|
||||||
#if defined(USE_ANSI)
|
#if (USE_ANSI)
|
||||||
try_init(&console_ansi_mono,f);
|
try_init(&console_ansi_mono,f);
|
||||||
try_init(&console_ansi_color,f);
|
try_init(&console_ansi_color,f);
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
try_init(&console_screen,f);
|
try_init(&console_screen,f);
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_AALIB)
|
#if (USE_AALIB)
|
||||||
try_init(&console_aalib,f);
|
try_init(&console_aalib,f);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ static int set_fg(FILE *f, int fg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
if (con == me)
|
if (con == me)
|
||||||
init(f,-1,-1);
|
init(f,-1,-1);
|
||||||
|
|||||||
+5
-5
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,13 +22,13 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
|
||||||
#if defined(USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -58,7 +58,7 @@ static void print0(FILE *f, const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+9
-9
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,13 +22,13 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
|
||||||
#if defined(USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
|
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
@@ -130,15 +130,15 @@ static int init(FILE *f, int o, int now)
|
|||||||
if (!screen)
|
if (!screen)
|
||||||
screen = do_construct(screen_djgpp2_construct(),fd);
|
screen = do_construct(screen_djgpp2_construct(),fd);
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_SCREEN_WIN32)
|
#if (USE_SCREEN_WIN32)
|
||||||
if (!screen)
|
if (!screen)
|
||||||
screen = do_construct(screen_win32_construct(),fd);
|
screen = do_construct(screen_win32_construct(),fd);
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_SCREEN_VCSA)
|
#if (USE_SCREEN_VCSA)
|
||||||
if (!screen)
|
if (!screen)
|
||||||
screen = do_construct(screen_vcsa_construct(),fd);
|
screen = do_construct(screen_vcsa_construct(),fd);
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_SCREEN_CURSES)
|
#if (USE_SCREEN_CURSES)
|
||||||
if (!screen && o == CON_SCREEN)
|
if (!screen && o == CON_SCREEN)
|
||||||
screen = do_construct(screen_curses_construct(),fd);
|
screen = do_construct(screen_curses_construct(),fd);
|
||||||
#endif
|
#endif
|
||||||
@@ -295,10 +295,10 @@ static void print0(FILE *f, const char *ss)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
#if defined(USE_FRAMES)
|
#if (USE_FRAMES)
|
||||||
if (screen->intro)
|
if (screen->intro)
|
||||||
return screen->intro(screen,screen_show_frames);
|
return screen->intro(screen,screen_show_frames);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+190
-13
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,26 +22,203 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
|
||||||
#if defined(WITH_NRV)
|
/*************************************************************************
|
||||||
# include "compress_nrv.ch"
|
//
|
||||||
#elif defined(WITH_UCL)
|
**************************************************************************/
|
||||||
# define ALG_NRV2E
|
|
||||||
# define upx_adler32 upx_adler32
|
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
||||||
//# define upx_crc32 upx_crc32
|
{
|
||||||
# define upx_compress upx_compress
|
if (len == 0)
|
||||||
# define upx_decompress upx_decompress
|
return adler;
|
||||||
# define upx_test_overlap upx_test_overlap
|
assert(buf != NULL);
|
||||||
# include "compress.ch"
|
#if 0
|
||||||
|
return adler32(adler, (const Bytef *) buf, len); // zlib
|
||||||
|
#elif (WITH_UCL)
|
||||||
|
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
||||||
#else
|
#else
|
||||||
# error
|
# error
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 /* UNUSED */
|
||||||
|
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||||
|
{
|
||||||
|
if (len == 0)
|
||||||
|
return crc;
|
||||||
|
assert(buf != NULL);
|
||||||
|
#if 0
|
||||||
|
return crc32(crc, (const Bytef *) buf, len); // zlib
|
||||||
|
#elif (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 (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 (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 (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 (WITH_LZMA)
|
||||||
|
else if (M_IS_LZMA(method))
|
||||||
|
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if (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 (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 (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 (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 (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 (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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+127
@@ -0,0 +1,127 @@
|
|||||||
|
/* compress.h --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2010 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_COMPRESS_H
|
||||||
|
#define __UPX_COMPRESS_H 1
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if (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 (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 (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 (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,799 @@
|
|||||||
|
/* compress_lzma.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2010 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>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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 !(WITH_LZMA)
|
||||||
|
extern int compress_lzma_dummy;
|
||||||
|
int compress_lzma_dummy = 0;
|
||||||
|
#else
|
||||||
|
#define opt compress_lzma_opt
|
||||||
|
|
||||||
|
#undef USE_LZMA_PROPERTIES
|
||||||
|
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
|
||||||
|
#if (WITH_LZMA >= 0x461)
|
||||||
|
#include "C/7zVersion.h"
|
||||||
|
#if (WITH_LZMA != (0x100 * MY_VER_MAJOR) + (0x10 * (MY_VER_MINOR / 10)) + (MY_VER_MINOR % 10))
|
||||||
|
# error "WITH_LZMA version mismatch"
|
||||||
|
#endif
|
||||||
|
#include "C/Types.h"
|
||||||
|
static void *cb_alloc(void *, size_t size) {
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
static void cb_free(void *, void *ptr) {
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compress defaults
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
static int prepare(lzma_compress_result_t *res,
|
||||||
|
unsigned src_len, int method, int level,
|
||||||
|
const lzma_compress_config_t *lcconf)
|
||||||
|
{
|
||||||
|
// setup defaults
|
||||||
|
res->pos_bits = 2; // 0 .. 4
|
||||||
|
res->lit_pos_bits = 0; // 0 .. 4
|
||||||
|
res->lit_context_bits = 3; // 0 .. 8
|
||||||
|
res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30
|
||||||
|
res->fast_mode = 2;
|
||||||
|
res->num_fast_bytes = 64; // 5 .. 273
|
||||||
|
res->match_finder_cycles = 0;
|
||||||
|
#if 1
|
||||||
|
res->pos_bits = lzma_compress_config_t::pos_bits_t::default_value_c;
|
||||||
|
res->lit_pos_bits = lzma_compress_config_t::lit_pos_bits_t::default_value_c;
|
||||||
|
res->lit_context_bits = lzma_compress_config_t::lit_context_bits_t::default_value_c;
|
||||||
|
res->dict_size = lzma_compress_config_t::dict_size_t::default_value_c;
|
||||||
|
res->num_fast_bytes = lzma_compress_config_t::num_fast_bytes_t::default_value_c;
|
||||||
|
#endif
|
||||||
|
// method overrides
|
||||||
|
if (method >= 0x100) {
|
||||||
|
res->pos_bits = (method >> 16) & 15;
|
||||||
|
res->lit_pos_bits = (method >> 12) & 15;
|
||||||
|
res->lit_context_bits = (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 MiB of stack during runtime decompression.
|
||||||
|
res->lit_pos_bits = 4;
|
||||||
|
res->lit_context_bits = 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// FIXME: tune these settings according to level
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
res->dict_size = 256 * 1024;
|
||||||
|
res->fast_mode = 0;
|
||||||
|
res->num_fast_bytes = 8;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
res->dict_size = 256 * 1024;
|
||||||
|
res->fast_mode = 0;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
res->dict_size = 8 * 1024 * 1024;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
res->dict_size = src_len;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cconf overrides
|
||||||
|
if (lcconf)
|
||||||
|
{
|
||||||
|
oassign(res->pos_bits, lcconf->pos_bits);
|
||||||
|
oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
|
||||||
|
oassign(res->lit_context_bits, lcconf->lit_context_bits);
|
||||||
|
oassign(res->dict_size, lcconf->dict_size);
|
||||||
|
oassign(res->num_fast_bytes, lcconf->num_fast_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit dictionary size
|
||||||
|
if (res->dict_size > src_len)
|
||||||
|
res->dict_size = src_len;
|
||||||
|
|
||||||
|
// limit num_probs
|
||||||
|
if (lcconf && lcconf->max_num_probs)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
unsigned n = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
|
||||||
|
if (n <= lcconf->max_num_probs)
|
||||||
|
break;
|
||||||
|
if (res->lit_pos_bits > res->lit_context_bits)
|
||||||
|
{
|
||||||
|
if (res->lit_pos_bits == 0)
|
||||||
|
goto error;
|
||||||
|
res->lit_pos_bits -= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (res->lit_context_bits == 0)
|
||||||
|
goto error;
|
||||||
|
res->lit_context_bits -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compress
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if (WITH_LZMA >= 0x461)
|
||||||
|
#define kLiteralNextStates kLiteralNextStates_enc
|
||||||
|
#include "C/LzmaEnc.h"
|
||||||
|
#include "C/LzmaEnc.c"
|
||||||
|
#include "C/LzFind.c"
|
||||||
|
#undef kLiteralNextStates
|
||||||
|
#undef kNumFullDistances
|
||||||
|
|
||||||
|
|
||||||
|
struct upx_ICompressProgress {
|
||||||
|
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||||
|
upx_callback_p cb;
|
||||||
|
};
|
||||||
|
|
||||||
|
static SRes cb_progress(void *p, UInt64 inSize, UInt64 outSize) {
|
||||||
|
upx_callback_p cb = ((upx_ICompressProgress *) p)->cb;
|
||||||
|
if (cb && cb->nprogress)
|
||||||
|
cb->nprogress(cb, (unsigned) inSize, (unsigned) outSize);
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
COMPILE_TIME_ASSERT(LZMA_PROPS_SIZE == 5)
|
||||||
|
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
int rh;
|
||||||
|
|
||||||
|
unsigned dst_avail = *dst_len;
|
||||||
|
*dst_len = 0;
|
||||||
|
|
||||||
|
ISzAlloc cba; cba.Alloc = cb_alloc; cba.Free = cb_free;
|
||||||
|
upx_ICompressProgress progress;
|
||||||
|
progress.Progress = cb_progress; progress.cb = cb;
|
||||||
|
|
||||||
|
const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : NULL;
|
||||||
|
lzma_compress_result_t *res = &cresult->result_lzma;
|
||||||
|
if (prepare(res, src_len, method, level, lcconf) != 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
CLzmaEncProps props; memset(&props, 0, sizeof(props));
|
||||||
|
props.level = level;
|
||||||
|
LzmaEncProps_Init(&props);
|
||||||
|
props.pb = res->pos_bits;
|
||||||
|
props.lp = res->lit_pos_bits;
|
||||||
|
props.lc = res->lit_context_bits;
|
||||||
|
props.dictSize = res->dict_size;
|
||||||
|
props.algo = res->fast_mode ? 1 : 0;
|
||||||
|
props.fb = res->num_fast_bytes;
|
||||||
|
props.mc = res->match_finder_cycles;
|
||||||
|
|
||||||
|
unsigned char props_buf[LZMA_PROPS_SIZE];
|
||||||
|
SizeT props_buf_size; props_buf_size = LZMA_PROPS_SIZE;
|
||||||
|
|
||||||
|
#if (USE_LZMA_PROPERTIES)
|
||||||
|
if (dst_avail < 1)
|
||||||
|
goto error;
|
||||||
|
dst[0] = 0; // filled below
|
||||||
|
dst += 1; *dst_len += 1; dst_avail -= 1;
|
||||||
|
#else
|
||||||
|
if (dst_avail < 2)
|
||||||
|
goto error;
|
||||||
|
// extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||||
|
unsigned tt; tt = res->lit_context_bits + res->lit_pos_bits;
|
||||||
|
dst[0] = ((tt << 3) | res->pos_bits);
|
||||||
|
dst[1] = ((res->lit_pos_bits << 4) | (res->lit_context_bits));
|
||||||
|
dst += 2; *dst_len += 2; dst_avail -= 2;
|
||||||
|
#endif
|
||||||
|
SizeT x_len; x_len = dst_avail;
|
||||||
|
rh = LzmaEncode(dst, &x_len, src, src_len,
|
||||||
|
&props, props_buf, &props_buf_size, 0,
|
||||||
|
(ICompressProgress *) (void *) &progress, &cba, &cba);
|
||||||
|
assert(x_len <= dst_avail);
|
||||||
|
*dst_len += x_len;
|
||||||
|
if (rh == SZ_OK) {
|
||||||
|
#if (USE_LZMA_PROPERTIES)
|
||||||
|
dst[-1] = props_buf[0];
|
||||||
|
#endif
|
||||||
|
r = UPX_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
//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);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (WITH_LZMA >= 0x461) */
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compress - cruft because of pseudo-COM layer
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if (WITH_LZMA < 0x461)
|
||||||
|
|
||||||
|
#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];
|
||||||
|
#ifdef COMPRESS_MF_BT4
|
||||||
|
const unsigned nprops = 8;
|
||||||
|
static wchar_t matchfinder[] = L"BT4";
|
||||||
|
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
|
||||||
|
pr[7].vt = VT_BSTR; pr[7].bstrVal = matchfinder;
|
||||||
|
#else
|
||||||
|
const unsigned nprops = 7;
|
||||||
|
#endif
|
||||||
|
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;
|
||||||
|
if (prepare(res, src_len, method, level, lcconf) != 0)
|
||||||
|
goto error;
|
||||||
|
pr[0].uintVal = res->pos_bits;
|
||||||
|
pr[1].uintVal = res->lit_pos_bits;
|
||||||
|
pr[2].uintVal = res->lit_context_bits;
|
||||||
|
pr[3].uintVal = res->dict_size;
|
||||||
|
pr[4].uintVal = res->fast_mode;
|
||||||
|
pr[5].uintVal = res->num_fast_bytes;
|
||||||
|
pr[6].uintVal = res->match_finder_cycles;
|
||||||
|
|
||||||
|
#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 (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 = (unsigned) 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (WITH_LZMA < 0x461) */
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// decompress
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if (WITH_LZMA >= 0x461)
|
||||||
|
|
||||||
|
#undef _LZMA_PROB32
|
||||||
|
#include "C/LzmaDec.h"
|
||||||
|
#include "C/LzmaDec.c"
|
||||||
|
|
||||||
|
|
||||||
|
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
#define Properties prop
|
||||||
|
assert(M_IS_LZMA(method));
|
||||||
|
// see res->num_probs above
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(CLzmaProb) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(LZMA_PROPS_SIZE == 5)
|
||||||
|
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
||||||
|
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
||||||
|
|
||||||
|
ISzAlloc cba; cba.Alloc = cb_alloc; cba.Free = cb_free;
|
||||||
|
CLzmaDec s; memset(&s, 0, sizeof(s));
|
||||||
|
SizeT srcLen = 0;
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
SRes rh;
|
||||||
|
ELzmaStatus status;
|
||||||
|
|
||||||
|
#if (USE_LZMA_PROPERTIES)
|
||||||
|
rh = LzmaProps_Decode(&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) != (int)(s.Properties.lc + s.Properties.lp)) goto error;
|
||||||
|
src += 2; src_len -= 2;
|
||||||
|
#endif
|
||||||
|
s.Properties.dicSize = 0;
|
||||||
|
|
||||||
|
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) LzmaProps_GetNumProbs(&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);
|
||||||
|
}
|
||||||
|
|
||||||
|
rh = LzmaDec_AllocateProbs2(&s, &s.Properties, &cba);
|
||||||
|
if (rh != SZ_OK)
|
||||||
|
{
|
||||||
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
s.dic = dst; s.dicPos = 0; s.dicBufSize = *dst_len;
|
||||||
|
LzmaDec_Init(&s);
|
||||||
|
srcLen = src_len;
|
||||||
|
rh = LzmaDec_DecodeToDic(&s, *dst_len, src, &srcLen, LZMA_FINISH_ANY, &status);
|
||||||
|
assert(srcLen <= src_len);
|
||||||
|
assert(s.dicPos <= *dst_len);
|
||||||
|
if (rh == SZ_OK && status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||||
|
rh = SZ_ERROR_INPUT_EOF;
|
||||||
|
if (rh == SZ_OK && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
||||||
|
{
|
||||||
|
r = UPX_E_OK;
|
||||||
|
if (srcLen != src_len)
|
||||||
|
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||||
|
}
|
||||||
|
error:
|
||||||
|
*dst_len = s.dicPos;
|
||||||
|
LzmaDec_FreeProbs(&s, &cba);
|
||||||
|
return r;
|
||||||
|
#undef Properties
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* (WITH_LZMA >= 0x461) */
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// decompress
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if (WITH_LZMA < 0x461)
|
||||||
|
|
||||||
|
#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 (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);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (WITH_LZMA < 0x461) */
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// 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 >= 0x461)
|
||||||
|
return MY_VERSION;
|
||||||
|
#elif (WITH_LZMA + 0 == 0x457)
|
||||||
|
return "4.57";
|
||||||
|
#elif (WITH_LZMA + 0 == 0x449)
|
||||||
|
return "4.49";
|
||||||
|
#elif (WITH_LZMA + 0 == 0x443)
|
||||||
|
return "4.43";
|
||||||
|
#else
|
||||||
|
# error "unknown WITH_LZMA version"
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WITH_LZMA */
|
||||||
|
/*
|
||||||
|
vi:ts=4:et:nowrap
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
/* compress.ch --
|
/* compress_ucl.cpp --
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,11 +22,29 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if 1 && defined(UCL_USE_ASM)
|
#include "conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
#if !(WITH_UCL)
|
||||||
|
extern int compress_ucl_dummy;
|
||||||
|
int compress_ucl_dummy = 0;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if 1 && !(UCL_USE_ASM) && (ACC_ARCH_I386)
|
||||||
|
# if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_MSC || ACC_CC_WATCOMC)
|
||||||
|
# define UCL_USE_ASM 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if (UCL_NO_ASM)
|
||||||
|
# undef UCL_USE_ASM
|
||||||
|
#endif
|
||||||
|
#if (ACC_CFG_NO_UNALIGNED)
|
||||||
|
# undef UCL_USE_ASM
|
||||||
|
#endif
|
||||||
|
#if 1 && (UCL_USE_ASM)
|
||||||
# include <ucl/ucl_asm.h>
|
# include <ucl/ucl_asm.h>
|
||||||
# define ucl_nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8
|
# define ucl_nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8
|
||||||
# define ucl_nrv2b_decompress_safe_le16 ucl_nrv2b_decompress_asm_safe_le16
|
# define ucl_nrv2b_decompress_safe_le16 ucl_nrv2b_decompress_asm_safe_le16
|
||||||
@@ -44,115 +62,128 @@
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_adler32)
|
static int convert_errno_from_ucl(int r)
|
||||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
|
||||||
{
|
{
|
||||||
if (len == 0)
|
switch (r)
|
||||||
return adler;
|
{
|
||||||
assert(buf != NULL);
|
case UCL_E_OK: return UPX_E_OK;
|
||||||
return ucl_adler32(adler, (const ucl_bytep)buf, len);
|
case UCL_E_ERROR: return UPX_E_ERROR;
|
||||||
|
case UCL_E_OUT_OF_MEMORY: return UPX_E_OUT_OF_MEMORY;
|
||||||
|
case UCL_E_NOT_COMPRESSIBLE: return UPX_E_NOT_COMPRESSIBLE;
|
||||||
|
case UCL_E_INPUT_OVERRUN: return UPX_E_INPUT_OVERRUN;
|
||||||
|
case UCL_E_OUTPUT_OVERRUN: return UPX_E_OUTPUT_OVERRUN;
|
||||||
|
case UCL_E_LOOKBEHIND_OVERRUN: return UPX_E_LOOKBEHIND_OVERRUN;
|
||||||
|
case UCL_E_EOF_NOT_FOUND: return UPX_E_EOF_NOT_FOUND;
|
||||||
|
case UCL_E_INPUT_NOT_CONSUMED: return UPX_E_INPUT_NOT_CONSUMED;
|
||||||
|
// case UCL_E_NOT_YET_IMPLEMENTED: return UPX_E_NOT_YET_IMPLEMENTED;
|
||||||
|
case UCL_E_INVALID_ARGUMENT: return UPX_E_INVALID_ARGUMENT;
|
||||||
|
// UCL extra:
|
||||||
|
case UCL_E_OVERLAP_OVERRUN: return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(upx_crc32)
|
extern "C" {
|
||||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (state != -1 && state != 3) return;
|
||||||
return crc;
|
upx_callback_p cb = (upx_callback_p) user;
|
||||||
assert(buf != NULL);
|
if (cb && cb->nprogress)
|
||||||
return ucl_crc32(crc, (const ucl_bytep)buf, len);
|
cb->nprogress(cb, a, b);
|
||||||
}
|
}}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_compress)
|
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int upx_compress ( const upx_bytep src, upx_uint src_len,
|
upx_callback_p cb_parm,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
|
||||||
upx_progress_callback_t *cb,
|
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const struct upx_compress_config_t *conf_parm,
|
const upx_compress_config_t *cconf_parm,
|
||||||
upx_uintp result )
|
upx_compress_result_t *cresult )
|
||||||
{
|
{
|
||||||
struct upx_compress_config_t conf;
|
int r;
|
||||||
upx_uint result_buffer[16];
|
assert(level > 0); assert(cresult != NULL);
|
||||||
int r = UPX_E_ERROR;
|
|
||||||
|
|
||||||
assert(level > 0);
|
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
|
||||||
memset(&conf, 0xff, sizeof(conf));
|
|
||||||
if (conf_parm)
|
|
||||||
conf = *conf_parm; // struct copy
|
|
||||||
if (!result)
|
|
||||||
result = result_buffer;
|
|
||||||
|
|
||||||
|
ucl_progress_callback_t cb;
|
||||||
|
cb.callback = 0;
|
||||||
|
cb.user = NULL;
|
||||||
|
if (cb_parm && cb_parm->nprogress) {
|
||||||
|
cb.callback = wrap_nprogress_ucl;
|
||||||
|
cb.user = cb_parm;
|
||||||
|
}
|
||||||
|
|
||||||
|
ucl_compress_config_t cconf; cconf.reset();
|
||||||
|
if (cconf_parm)
|
||||||
|
memcpy(&cconf, &cconf_parm->conf_ucl, sizeof(cconf)); // cconf = cconf_parm->conf_ucl; // struct copy
|
||||||
|
|
||||||
|
ucl_uint *res = cresult->result_ucl.result;
|
||||||
// assume no info available - fill in worst case results
|
// assume no info available - fill in worst case results
|
||||||
//result[0] = 1; // min_offset_found - NOT USED
|
//res[0] = 1; // min_offset_found - NOT USED
|
||||||
result[1] = src_len - 1; // max_offset_found
|
res[1] = src_len - 1; // max_offset_found
|
||||||
//result[2] = 2; // min_match_found - NOT USED
|
//res[2] = 2; // min_match_found - NOT USED
|
||||||
result[3] = src_len - 1; // max_match_found
|
res[3] = src_len - 1; // max_match_found
|
||||||
//result[4] = 1; // min_run_found - NOT USED
|
//res[4] = 1; // min_run_found - NOT USED
|
||||||
result[5] = src_len; // max_run_found
|
res[5] = src_len; // max_run_found
|
||||||
result[6] = 1; // first_offset_found
|
res[6] = 1; // first_offset_found
|
||||||
//result[7] = 999999; // same_match_offsets_found - NOT USED
|
//res[7] = 999999; // same_match_offsets_found - NOT USED
|
||||||
|
|
||||||
// prepare bit-buffer settings
|
// prepare bit-buffer settings
|
||||||
conf.bb_endian = 0;
|
cconf.bb_endian = 0;
|
||||||
conf.bb_size = 0;
|
cconf.bb_size = 0;
|
||||||
if (method >= M_NRV2B_LE32 && method <= M_CL1B_LE16)
|
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
|
||||||
{
|
{
|
||||||
static const unsigned char sizes[3]={32,8,16};
|
static const unsigned char sizes[3] = {32, 8, 16};
|
||||||
conf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// optimize compression parms
|
// optimize compression parms
|
||||||
if (level <= 3 && conf.max_offset == UPX_UINT_MAX)
|
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
conf.max_offset = 8*1024-1;
|
cconf.max_offset = 8*1024-1;
|
||||||
else if (level == 4 && conf.max_offset == UPX_UINT_MAX)
|
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
conf.max_offset = 32*1024-1;
|
cconf.max_offset = 32*1024-1;
|
||||||
|
|
||||||
if M_IS_NRV2B(method)
|
if M_IS_NRV2B(method)
|
||||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
||||||
cb, level, &conf, result);
|
&cb, level, &cconf, res);
|
||||||
else if M_IS_NRV2D(method)
|
else if M_IS_NRV2D(method)
|
||||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
||||||
cb, level, &conf, result);
|
&cb, level, &cconf, res);
|
||||||
#if defined(ALG_NRV2E)
|
|
||||||
else if M_IS_NRV2E(method)
|
else if M_IS_NRV2E(method)
|
||||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
||||||
cb, level, &conf, result);
|
&cb, level, &cconf, res);
|
||||||
#endif
|
else {
|
||||||
#if 0 /*{*/
|
|
||||||
else if M_IS_CL1B(method)
|
|
||||||
r = cl1b_compress(src, src_len, dst, dst_len,
|
|
||||||
cb, level, &conf, result);
|
|
||||||
#endif /*}*/
|
|
||||||
else
|
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
// make sure first_offset_found is set
|
||||||
|
if (res[6] == 0)
|
||||||
|
res[6] = 1;
|
||||||
|
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* upx_compress */
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_decompress)
|
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
int method,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
const upx_compress_result_t *cresult )
|
||||||
int method )
|
|
||||||
{
|
{
|
||||||
int r = UPX_E_ERROR;
|
int r;
|
||||||
|
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
@@ -174,7 +205,6 @@ int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
|||||||
case M_NRV2D_LE32:
|
case M_NRV2D_LE32:
|
||||||
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#if defined(ALG_NRV2E)
|
|
||||||
case M_NRV2E_8:
|
case M_NRV2E_8:
|
||||||
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
@@ -184,40 +214,29 @@ int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
|||||||
case M_NRV2E_LE32:
|
case M_NRV2E_LE32:
|
||||||
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#if 0 /*{*/
|
|
||||||
case M_CL1B_8:
|
|
||||||
r = cl1b_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE16:
|
|
||||||
r = cl1b_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE32:
|
|
||||||
r = cl1b_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
#endif /*}*/
|
|
||||||
default:
|
default:
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown decompression method");
|
||||||
break;
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
UNUSED(cresult);
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* upx_decompress */
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_test_overlap)
|
int upx_ucl_test_overlap ( const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
unsigned src_off, unsigned src_len,
|
||||||
upx_uint src_len, upx_uintp dst_len,
|
unsigned* dst_len,
|
||||||
int method )
|
int method,
|
||||||
|
const upx_compress_result_t *cresult )
|
||||||
{
|
{
|
||||||
int r = UPX_E_ERROR;
|
int r;
|
||||||
|
UNUSED(tbuf); // not needed for UCL
|
||||||
|
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
@@ -239,7 +258,6 @@ int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
|||||||
case M_NRV2D_LE32:
|
case M_NRV2D_LE32:
|
||||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#if defined(ALG_NRV2E)
|
|
||||||
case M_NRV2E_8:
|
case M_NRV2E_8:
|
||||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
@@ -249,29 +267,27 @@ int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
|||||||
case M_NRV2E_LE32:
|
case M_NRV2E_LE32:
|
||||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#if 0 /*{*/
|
|
||||||
case M_CL1B_8:
|
|
||||||
r = cl1b_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE16:
|
|
||||||
r = cl1b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE32:
|
|
||||||
r = cl1b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
#endif /*}*/
|
|
||||||
default:
|
default:
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown decompression method");
|
||||||
break;
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
UNUSED(cresult);
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* upx_test_overlap */
|
|
||||||
|
/*************************************************************************
|
||||||
|
// misc
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
const char *upx_ucl_version_string(void)
|
||||||
|
{
|
||||||
|
return ucl_version_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WITH_UCL */
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et:nowrap
|
vi:ts=4:et:nowrap
|
||||||
*/
|
*/
|
||||||
@@ -0,0 +1,235 @@
|
|||||||
|
/* compress_zlib.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2010 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>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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 !(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
|
||||||
|
*/
|
||||||
|
|
||||||
+404
-140
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_CONF_H
|
#ifndef __UPX_CONF_H
|
||||||
#define __UPX_CONF_H
|
#define __UPX_CONF_H 1
|
||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
@@ -36,12 +36,35 @@
|
|||||||
// ACC
|
// ACC
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if (defined(_WIN32) || defined(_WIN64)) && defined(_MSC_VER)
|
||||||
|
#ifndef _CRT_NONSTDC_NO_DEPRECATE
|
||||||
|
#define _CRT_NONSTDC_NO_DEPRECATE 1
|
||||||
|
#endif
|
||||||
|
#ifndef _CRT_NONSTDC_NO_WARNINGS
|
||||||
|
#define _CRT_NONSTDC_NO_WARNINGS 1
|
||||||
|
#endif
|
||||||
|
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||||
|
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||||
|
#endif
|
||||||
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "miniacc.h"
|
#include "miniacc.h"
|
||||||
#if ((ACC_OS_WIN32 || ACC_OS_WIN64) && ACC_CC_MWERKS) && defined(__MSL__)
|
#if ((ACC_OS_WIN32 || ACC_OS_WIN64) && ACC_CC_MWERKS) && defined(__MSL__)
|
||||||
# undef HAVE_UTIME_H /* this pulls in <windows.h> */
|
# undef HAVE_UTIME_H /* this pulls in <windows.h> */
|
||||||
#endif
|
#endif
|
||||||
|
// FIXME - quick hack for arm-wince-gcc-3.4 (Debian pocketpc-*.deb packages)
|
||||||
|
#if 1 && (ACC_ARCH_ARM) && defined(__pe__) && !defined(_WIN32)
|
||||||
|
# undef HAVE_CHMOD
|
||||||
|
# undef HAVE_CHOWN
|
||||||
|
# undef HAVE_LSTAT
|
||||||
|
# undef HAVE_UTIME
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// pragmas
|
||||||
#if (ACC_CC_BORLANDC)
|
#if (ACC_CC_BORLANDC)
|
||||||
# if (__BORLANDC__ < 0x0500)
|
# if (__BORLANDC__ < 0x0500)
|
||||||
# error "need Borland C++ 5.0 or newer"
|
# error "need Borland C++ 5.0 or newer"
|
||||||
@@ -70,10 +93,13 @@
|
|||||||
# if (ACC_OS_WIN32 || ACC_OS_WIN64)
|
# if (ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||||
# elif defined(__linux__)
|
# elif defined(__linux__)
|
||||||
# pragma warning(error: 424) // #424: extra ";" ignored
|
# pragma warning(error: 424) // #424: extra ";" ignored
|
||||||
|
//# pragma warning(disable: 128) // #128: loop is not reachable from preceding code
|
||||||
|
//# pragma warning(disable: 181) // #181: argument is incompatible with corresponding format string conversion
|
||||||
# pragma warning(disable: 193) // #193: zero used for undefined preprocessing identifier
|
# pragma warning(disable: 193) // #193: zero used for undefined preprocessing identifier
|
||||||
# pragma warning(disable: 810) // #810: conversion from "A" to "B" may lose significant bits
|
# pragma warning(disable: 810) // #810: conversion from "A" to "B" may lose significant bits
|
||||||
# pragma warning(disable: 981) // #981: operands are evaluated in unspecified order
|
# pragma warning(disable: 981) // #981: operands are evaluated in unspecified order
|
||||||
# pragma warning(disable: 1418) // #1418: external definition with no prior declaration
|
# pragma warning(disable: 1418) // #1418: external function definition with no prior declaration
|
||||||
|
//# pragma warning(disable: 1419) // #1419: external declaration in primary source file
|
||||||
# else
|
# else
|
||||||
# error "untested platform"
|
# error "untested platform"
|
||||||
# endif
|
# endif
|
||||||
@@ -82,6 +108,7 @@
|
|||||||
# error "need Visual C++ 5.0 or newer"
|
# error "need Visual C++ 5.0 or newer"
|
||||||
# endif
|
# endif
|
||||||
# pragma warning(error: 4096) // W2: '__cdecl' must be used with '...'
|
# pragma warning(error: 4096) // W2: '__cdecl' must be used with '...'
|
||||||
|
# pragma warning(error: 4138) // Wx: '*/' found outside of comment
|
||||||
# pragma warning(disable: 4097) // W3: typedef-name 'A' used as synonym for class-name 'B'
|
# pragma warning(disable: 4097) // W3: typedef-name 'A' used as synonym for class-name 'B'
|
||||||
# pragma warning(disable: 4511) // W3: 'class': copy constructor could not be generated
|
# pragma warning(disable: 4511) // W3: 'class': copy constructor could not be generated
|
||||||
# pragma warning(disable: 4512) // W4: 'class': assignment operator could not be generated
|
# pragma warning(disable: 4512) // W4: 'class': assignment operator could not be generated
|
||||||
@@ -96,11 +123,16 @@
|
|||||||
# if (_MSC_VER >= 1400)
|
# if (_MSC_VER >= 1400)
|
||||||
# pragma warning(disable: 4996) // W1: 'function': was declared deprecated
|
# pragma warning(disable: 4996) // W1: 'function': was declared deprecated
|
||||||
# endif
|
# endif
|
||||||
|
#elif (ACC_CC_SUNPROC)
|
||||||
|
//# pragma error_messages(off,"badargtype2w") // FIXME
|
||||||
#elif (ACC_CC_WATCOMC)
|
#elif (ACC_CC_WATCOMC)
|
||||||
# if (__WATCOMC__ < 1100)
|
# if (__WATCOMC__ < 1280)
|
||||||
# error "need Watcom C++ 11.0c or newer"
|
# error "need Open Watcom C++ 1.8 or newer" // because earlier versions do not support nested classes
|
||||||
# endif
|
# endif
|
||||||
# if defined(__cplusplus)
|
# if defined(__cplusplus)
|
||||||
|
# pragma warning 367 9 // w3: conditional expression in if statement is always true
|
||||||
|
# pragma warning 368 9 // w3: conditional expression in if statement is always false
|
||||||
|
# pragma warning 389 9 // w3: integral value may be truncated
|
||||||
# pragma warning 656 9 // w5: define this function inside its class definition (may improve code quality)
|
# pragma warning 656 9 // w5: define this function inside its class definition (may improve code quality)
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
@@ -127,15 +159,18 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// just in case
|
// just in case
|
||||||
|
#undef _
|
||||||
|
#undef __
|
||||||
|
#undef ___
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
#undef dos
|
#undef dos
|
||||||
#undef linux
|
#undef linux
|
||||||
#undef small
|
#undef small
|
||||||
#undef tos
|
#undef tos
|
||||||
#if defined(ACC_CC_DMC)
|
#if (ACC_CC_DMC)
|
||||||
# undef tell
|
# undef tell
|
||||||
#endif
|
#endif
|
||||||
#if !defined(ACC_CC_PGI)
|
#if !(ACC_CC_PGI)
|
||||||
# undef unix
|
# undef unix
|
||||||
#endif
|
#endif
|
||||||
#if defined(__DJGPP__)
|
#if defined(__DJGPP__)
|
||||||
@@ -144,64 +179,48 @@
|
|||||||
# undef __unix
|
# undef __unix
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(WITH_UCL)
|
#if !defined(WITH_UCL)
|
||||||
# define WITH_UCL 1
|
# define WITH_UCL 1
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_UCL)
|
#if 0 && !defined(WITH_LZMA)
|
||||||
# include <ucl/uclconf.h>
|
# define WITH_LZMA 1
|
||||||
# include <ucl/ucl.h>
|
#endif
|
||||||
# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010200L)
|
#if 1 && (ACC_CC_WATCOMC)
|
||||||
# error "please upgrade your UCL installation"
|
# undef WITH_LZMA
|
||||||
# endif
|
#endif
|
||||||
# if !defined(UPX_UINT_MAX)
|
#if defined(UPX_OFFICIAL_BUILD)
|
||||||
# define UPX_UINT_MAX UCL_UINT_MAX
|
# if !(WITH_LZMA) || !(WITH_NRV) || !(WITH_UCL)
|
||||||
# define upx_uint ucl_uint
|
# error
|
||||||
# define upx_voidp ucl_voidp
|
|
||||||
# define upx_uintp ucl_uintp
|
|
||||||
# define upx_byte ucl_byte
|
|
||||||
# define upx_bytep ucl_bytep
|
|
||||||
# define upx_bool ucl_bool
|
|
||||||
# define upx_compress_config_t ucl_compress_config_t
|
|
||||||
# define upx_progress_callback_t ucl_progress_callback_t
|
|
||||||
# define UPX_E_OK UCL_E_OK
|
|
||||||
# define UPX_E_ERROR UCL_E_ERROR
|
|
||||||
# define UPX_E_OUT_OF_MEMORY UCL_E_OUT_OF_MEMORY
|
|
||||||
# define __UPX_CDECL __UCL_CDECL
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_NRV)
|
#if (WITH_NRV)
|
||||||
# include <nrv/nrvconf.h>
|
# include <nrv/nrvconf.h>
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__UPX_CHECKER)
|
#if (WITH_UCL)
|
||||||
# if defined(__UCL_CHECKER) || defined(__NRV_CHECKER)
|
# define ucl_compress_config_t REAL_ucl_compress_config_t
|
||||||
# define __UPX_CHECKER
|
# include <ucl/uclconf.h>
|
||||||
|
# include <ucl/ucl.h>
|
||||||
|
# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010300L)
|
||||||
|
# error "please upgrade your UCL installation"
|
||||||
# endif
|
# endif
|
||||||
|
# undef ucl_compress_config_t
|
||||||
|
# undef ucl_compress_config_p
|
||||||
#endif
|
#endif
|
||||||
#if !defined(UINT_MAX) || (UINT_MAX < 0xffffffffL)
|
#if !defined(UINT_MAX) || (UINT_MAX < 0xffffffffL)
|
||||||
# error "UINT_MAX"
|
# error "UINT_MAX"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define upx_byte unsigned char
|
||||||
|
#define upx_bytep upx_byte *
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// system includes
|
// system includes
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
// malloc debuggers
|
// malloc debuggers
|
||||||
#if defined(WITH_VALGRIND)
|
#if (WITH_VALGRIND)
|
||||||
# include <valgrind/memcheck.h>
|
# include <valgrind/memcheck.h>
|
||||||
#elif defined(WITH_DMALLOC)
|
|
||||||
# define DMALLOC_FUNC_CHECK
|
|
||||||
# include <dmalloc.h>
|
|
||||||
#elif defined(WITH_GC)
|
|
||||||
# define GC_DEBUG
|
|
||||||
# include <gc/gc.h>
|
|
||||||
# undef malloc
|
|
||||||
# undef realloc
|
|
||||||
# undef free
|
|
||||||
# define malloc GC_MALLOC
|
|
||||||
# define realloc GC_REALLOC
|
|
||||||
# define free GC_FREE
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(VALGRIND_MAKE_WRITABLE)
|
#if !defined(VALGRIND_MAKE_WRITABLE)
|
||||||
@@ -219,6 +238,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// unconditionally turn on assertions
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
@@ -238,11 +258,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(HAVE_STRCASECMP) && defined(HAVE_STRICMP)
|
#if !(HAVE_STRCASECMP) && (HAVE_STRICMP)
|
||||||
# define strcasecmp stricmp
|
# define strcasecmp stricmp
|
||||||
#endif
|
#endif
|
||||||
#if !defined(HAVE_STRNCASECMP) && defined(HAVE_STRNICMP)
|
#if !(HAVE_STRNCASECMP) && (HAVE_STRNICMP)
|
||||||
# define strncasecmp strnicmp
|
# define strncasecmp strnicmp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -295,18 +315,6 @@
|
|||||||
#undef PAGE_MASK
|
#undef PAGE_MASK
|
||||||
#undef PAGE_SIZE
|
#undef PAGE_SIZE
|
||||||
|
|
||||||
|
|
||||||
#undef __attribute_packed
|
|
||||||
#if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
|
|
||||||
# if (1 && (ACC_ARCH_I386))
|
|
||||||
# define __attribute_packed
|
|
||||||
# else
|
|
||||||
# define __attribute_packed __attribute__((__packed__,__aligned__(1)))
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define __attribute_packed
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(O_BINARY)
|
#if !defined(O_BINARY)
|
||||||
# define O_BINARY 0
|
# define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
@@ -316,6 +324,21 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (ACC_CC_INTELC && (__INTEL_COMPILER < 800))
|
||||||
|
#elif (0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386))
|
||||||
|
#elif (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
|
||||||
|
# define __packed_struct(s) struct s {
|
||||||
|
# define __packed_struct_end() } __attribute__((__packed__,__aligned__(1)));
|
||||||
|
#elif (ACC_CC_WATCOMC)
|
||||||
|
# define __packed_struct(s) _Packed struct s {
|
||||||
|
# define __packed_struct_end() };
|
||||||
|
#endif
|
||||||
|
#if !defined(__packed_struct)
|
||||||
|
# define __packed_struct(s) struct s {
|
||||||
|
# define __packed_struct_end() };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -323,68 +346,53 @@
|
|||||||
#define UNUSED(var) ACC_UNUSED(var)
|
#define UNUSED(var) ACC_UNUSED(var)
|
||||||
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
|
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
|
||||||
|
|
||||||
#if 1
|
#define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
|
||||||
# define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
|
|
||||||
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
|
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
|
||||||
struct acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z[7]; } __attribute_packed; \
|
__packed_struct(acc_tmp_t) acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; __packed_struct_end() \
|
||||||
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 8*sizeof(b)+sizeof(a)) \
|
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2*sizeof(b)+sizeof(a)) \
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(((acc_tmp_t*)0)->x)+sizeof(((acc_tmp_t*)0)->y)+sizeof(((acc_tmp_t*)0)->z) == 2*sizeof(b)+sizeof(a)) \
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
# define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
|
|
||||||
struct acc_tmp_t { b x; a y; b z[7]; } __attribute_packed; \
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 8*sizeof(b)+sizeof(a)) \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__acc_alignof)
|
#if defined(__acc_alignof)
|
||||||
# define COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
# define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
||||||
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) \
|
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) \
|
||||||
COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b))
|
COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b))
|
||||||
#else
|
#else
|
||||||
# define COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
# define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
||||||
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b)
|
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b)
|
||||||
#endif
|
#endif
|
||||||
|
#define COMPILE_TIME_ASSERT_ALIGNED1(a) __COMPILE_TIME_ASSERT_ALIGNOF(a,char)
|
||||||
|
|
||||||
#define TABLESIZE(table) ((sizeof(table)/sizeof((table)[0])))
|
#define TABLESIZE(table) ((sizeof(table)/sizeof((table)[0])))
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define ALIGN_DOWN(a,b) (((a) / (b)) * (b))
|
#define ALIGN_DOWN(a,b) (((a) / (b)) * (b))
|
||||||
#define ALIGN_UP(a,b) ALIGN_DOWN((a) + ((b) - 1), b)
|
#define ALIGN_UP(a,b) ALIGN_DOWN((a) + ((b) - 1), b)
|
||||||
#define ALIGN_GAP(a,b) (ALIGN_UP(a,b) - (a))
|
#define ALIGN_GAP(a,b) (ALIGN_UP(a,b) - (a))
|
||||||
|
#elif 1
|
||||||
|
template <class T>
|
||||||
|
inline T ALIGN_DOWN(const T& a, const T& b) { T r; r = (a / b) * b; return r; }
|
||||||
|
template <class T>
|
||||||
|
inline T ALIGN_UP (const T& a, const T& b) { T r; r = ((a + b - 1) / b) * b; return r; }
|
||||||
|
template <class T>
|
||||||
|
inline T ALIGN_GAP (const T& a, const T& b) { T r; r = ALIGN_UP(a, b) - a; return r; }
|
||||||
|
#else
|
||||||
|
inline unsigned ALIGN_DOWN(unsigned a, unsigned b) { return (a / b) * b; }
|
||||||
|
inline unsigned ALIGN_UP (unsigned a, unsigned b) { return ((a + b - 1) / b) * b; }
|
||||||
|
inline unsigned ALIGN_GAP (unsigned a, unsigned b) { return ALIGN_UP(a, b) - a; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define UPX_MAX(a,b) ((a) >= (b) ? (a) : (b))
|
#define UPX_MAX(a,b) ((a) >= (b) ? (a) : (b))
|
||||||
#define UPX_MIN(a,b) ((a) <= (b) ? (a) : (b))
|
#define UPX_MIN(a,b) ((a) <= (b) ? (a) : (b))
|
||||||
#define UPX_MAX3(a,b,c) ((a) >= (b) ? UPX_MAX(a,c) : UPX_MAX(b,c))
|
#elif 1
|
||||||
#define UPX_MIN3(a,b,c) ((a) <= (b) ? UPX_MIN(a,c) : UPX_MIN(b,c))
|
template <class T>
|
||||||
|
inline const T& UPX_MAX(const T& a, const T& b) { if (a < b) return b; return a; }
|
||||||
|
template <class T>
|
||||||
#if 0 && defined(__cplusplus) && !defined(new) && !defined(delete)
|
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
|
||||||
// global operators - debug
|
#else
|
||||||
inline void *operator new(size_t l)
|
inline unsigned UPX_MAX(unsigned a, unsigned b) { return a < b ? b : a; }
|
||||||
{
|
inline unsigned UPX_MIN(unsigned a, unsigned b) { return a < b ? a : b; }
|
||||||
void *p = malloc(l);
|
|
||||||
printf("new %6ld %p\n",(long)l,p);
|
|
||||||
fflush(stdout);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
inline void *operator new[](size_t l)
|
|
||||||
{
|
|
||||||
void *p = malloc(l);
|
|
||||||
printf("new[] %6ld %p\n",(long)l,p);
|
|
||||||
fflush(stdout);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
inline void operator delete(void *p)
|
|
||||||
{
|
|
||||||
printf("delete %p\n",p);
|
|
||||||
fflush(stdout);
|
|
||||||
if (p) free(p);
|
|
||||||
}
|
|
||||||
inline void operator delete[](void *p)
|
|
||||||
{
|
|
||||||
printf("delete[] %p\n",p);
|
|
||||||
fflush(stdout);
|
|
||||||
if (p) free(p);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -397,6 +405,16 @@ inline void operator delete[](void *p)
|
|||||||
|
|
||||||
#define ByteArray(var, size) Array(unsigned char, var, size)
|
#define ByteArray(var, size) Array(unsigned char, var, size)
|
||||||
|
|
||||||
|
struct noncopyable
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
inline noncopyable() {}
|
||||||
|
inline ~noncopyable() {}
|
||||||
|
private:
|
||||||
|
noncopyable(const noncopyable &); // undefined
|
||||||
|
const noncopyable& operator=(const noncopyable &); // undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// constants
|
// constants
|
||||||
@@ -416,24 +434,23 @@ inline void operator delete[](void *p)
|
|||||||
#define EXIT_INTERNAL 1
|
#define EXIT_INTERNAL 1
|
||||||
|
|
||||||
|
|
||||||
// compression methods - DO NOT CHANGE
|
// magic constants for patching
|
||||||
#define M_NRV2B_LE32 2
|
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
|
||||||
#define M_NRV2B_8 3
|
#define UPX_MAGIC2_LE32 0xD5D0D8A1
|
||||||
#define M_NRV2B_LE16 4
|
|
||||||
#define M_NRV2D_LE32 5
|
|
||||||
#define M_NRV2D_8 6
|
|
||||||
#define M_NRV2D_LE16 7
|
|
||||||
#define M_NRV2E_LE32 8
|
|
||||||
#define M_NRV2E_8 9
|
|
||||||
#define M_NRV2E_LE16 10
|
|
||||||
#define M_CL1B_LE32 11
|
|
||||||
#define M_CL1B_8 12
|
|
||||||
#define M_CL1B_LE16 13
|
|
||||||
|
|
||||||
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
|
|
||||||
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
|
// upx_compress() error codes
|
||||||
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
|
#define UPX_E_OK (0)
|
||||||
#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
#define UPX_E_ERROR (-1)
|
||||||
|
#define UPX_E_OUT_OF_MEMORY (-2)
|
||||||
|
#define UPX_E_NOT_COMPRESSIBLE (-3)
|
||||||
|
#define UPX_E_INPUT_OVERRUN (-4)
|
||||||
|
#define UPX_E_OUTPUT_OVERRUN (-5)
|
||||||
|
#define UPX_E_LOOKBEHIND_OVERRUN (-6)
|
||||||
|
#define UPX_E_EOF_NOT_FOUND (-7)
|
||||||
|
#define UPX_E_INPUT_NOT_CONSUMED (-8)
|
||||||
|
#define UPX_E_NOT_YET_IMPLEMENTED (-9)
|
||||||
|
#define UPX_E_INVALID_ARGUMENT (-10)
|
||||||
|
|
||||||
|
|
||||||
// Executable formats. Note: big endian types are >= 128.
|
// Executable formats. Note: big endian types are >= 128.
|
||||||
@@ -459,6 +476,21 @@ inline void operator delete[](void *p)
|
|||||||
#define UPX_F_LINUX_ELFI_i386 20
|
#define UPX_F_LINUX_ELFI_i386 20
|
||||||
#define UPX_F_WINCE_ARM_PE 21
|
#define UPX_F_WINCE_ARM_PE 21
|
||||||
#define UPX_F_LINUX_ELF64_AMD 22
|
#define UPX_F_LINUX_ELF64_AMD 22
|
||||||
|
#define UPX_F_LINUX_ELF32_ARMEL 23
|
||||||
|
#define UPX_F_BSD_i386 24
|
||||||
|
#define UPX_F_BSD_ELF_i386 25
|
||||||
|
#define UPX_F_BSD_SH_i386 26
|
||||||
|
|
||||||
|
#define UPX_F_VMLINUX_AMD64 27
|
||||||
|
#define UPX_F_VMLINUX_ARMEL 28
|
||||||
|
#define UPX_F_MACH_i386 29
|
||||||
|
#define UPX_F_LINUX_ELF32_MIPSEL 30
|
||||||
|
#define UPX_F_VMLINUZ_ARMEL 31
|
||||||
|
#define UPX_F_MACH_ARMEL 32
|
||||||
|
|
||||||
|
#define UPX_F_DYLIB_i386 33
|
||||||
|
#define UPX_F_MACH_AMD64 34
|
||||||
|
#define UPX_F_DYLIB_AMD64 35
|
||||||
|
|
||||||
#define UPX_F_PLAIN_TEXT 127
|
#define UPX_F_PLAIN_TEXT 127
|
||||||
|
|
||||||
@@ -466,10 +498,234 @@ inline void operator delete[](void *p)
|
|||||||
#define UPX_F_SOLARIS_SPARC 130
|
#define UPX_F_SOLARIS_SPARC 130
|
||||||
#define UPX_F_MACH_PPC32 131
|
#define UPX_F_MACH_PPC32 131
|
||||||
#define UPX_F_LINUX_ELFPPC32 132
|
#define UPX_F_LINUX_ELFPPC32 132
|
||||||
|
#define UPX_F_LINUX_ELF32_ARMEB 133
|
||||||
|
#define UPX_F_MACH_FAT 134
|
||||||
|
#define UPX_F_VMLINUX_ARMEB 135
|
||||||
|
#define UPX_F_VMLINUX_PPC32 136
|
||||||
|
#define UPX_F_LINUX_ELF32_MIPSEB 137
|
||||||
|
#define UPX_F_DYLIB_PPC32 138
|
||||||
|
|
||||||
|
|
||||||
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
|
// compression methods
|
||||||
#define UPX_MAGIC2_LE32 0xD5D0D8A1
|
#define M_ALL (-1)
|
||||||
|
#define M_END (-2)
|
||||||
|
#define M_NONE (-3)
|
||||||
|
#define M_SKIP (-4)
|
||||||
|
#define M_ULTRA_BRUTE (-5)
|
||||||
|
// compression methods - DO NOT CHANGE
|
||||||
|
#define M_NRV2B_LE32 2
|
||||||
|
#define M_NRV2B_8 3
|
||||||
|
#define M_NRV2B_LE16 4
|
||||||
|
#define M_NRV2D_LE32 5
|
||||||
|
#define M_NRV2D_8 6
|
||||||
|
#define M_NRV2D_LE16 7
|
||||||
|
#define M_NRV2E_LE32 8
|
||||||
|
#define M_NRV2E_8 9
|
||||||
|
#define M_NRV2E_LE16 10
|
||||||
|
//#define M_CL1B_LE32 11
|
||||||
|
//#define M_CL1B_8 12
|
||||||
|
//#define M_CL1B_LE16 13
|
||||||
|
#define M_LZMA 14
|
||||||
|
#define M_DEFLATE 15 /* zlib */
|
||||||
|
|
||||||
|
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
|
||||||
|
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
|
||||||
|
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
|
||||||
|
//#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
||||||
|
#define M_IS_LZMA(x) (((x) & 255) == M_LZMA)
|
||||||
|
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
|
||||||
|
|
||||||
|
|
||||||
|
// filters
|
||||||
|
#define FT_END (-1)
|
||||||
|
#define FT_NONE (-2)
|
||||||
|
#define FT_SKIP (-3)
|
||||||
|
#define FT_ULTRA_BRUTE (-4)
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compression - callback_t
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
struct upx_callback_t;
|
||||||
|
#define upx_callback_p upx_callback_t *
|
||||||
|
#if 0
|
||||||
|
typedef void* (__acc_cdecl *upx_alloc_func_t)
|
||||||
|
(upx_callback_p self, unsigned items, unsigned size);
|
||||||
|
typedef void (__acc_cdecl *upx_free_func_t)
|
||||||
|
(upx_callback_p self, void* ptr);
|
||||||
|
#endif
|
||||||
|
typedef void (__acc_cdecl *upx_progress_func_t)
|
||||||
|
(upx_callback_p, unsigned, unsigned);
|
||||||
|
|
||||||
|
struct upx_callback_t
|
||||||
|
{
|
||||||
|
upx_progress_func_t nprogress;
|
||||||
|
void *user;
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compression - config_t
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
template <class T, T default_value, T min_value, T max_value>
|
||||||
|
struct OptVar
|
||||||
|
{
|
||||||
|
typedef T Type;
|
||||||
|
static const T default_value_c = default_value;
|
||||||
|
static const T min_value_c = min_value;
|
||||||
|
static const T max_value_c = max_value;
|
||||||
|
|
||||||
|
void assertValue() {
|
||||||
|
// FIXME: this generates annoying warnings "unsigned >= 0 is always true"
|
||||||
|
//assert((v >= min_value) && (v <= max_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
OptVar() : v(default_value), is_set(0) { }
|
||||||
|
OptVar& operator= (const T other) {
|
||||||
|
v = other; is_set += 1;
|
||||||
|
assertValue();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
#error
|
||||||
|
// there is too much implicit magic in this copy operator;
|
||||||
|
// better introduce an explicit "oassign" function.
|
||||||
|
OptVar& operator= (const OptVar& other) {
|
||||||
|
if (other.is_set) { v = other.v; is_set += 1; }
|
||||||
|
assertValue(); return *this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void reset() { v = default_value; is_set = 0; }
|
||||||
|
operator T () const { return v; }
|
||||||
|
|
||||||
|
T v;
|
||||||
|
unsigned is_set;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// optional assignments
|
||||||
|
template <class T> inline void oassign(T& self, const T& other) {
|
||||||
|
if (other.is_set) { self.v = other.v; self.is_set += 1; }
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
template <class V, class T> inline void oassign(V& v, const T& other) {
|
||||||
|
if (other.is_set) { v = other.v; }
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <class T> inline void oassign(unsigned& v, const T& other) {
|
||||||
|
if (other.is_set) { v = other.v; }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct lzma_compress_config_t
|
||||||
|
{
|
||||||
|
typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb
|
||||||
|
typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lb
|
||||||
|
typedef OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc
|
||||||
|
typedef OptVar<unsigned, (1u<<22), 1u, (1u<<30) > dict_size_t;
|
||||||
|
typedef OptVar<unsigned, 64u, 5u, 273u> num_fast_bytes_t;
|
||||||
|
|
||||||
|
pos_bits_t pos_bits; // pb
|
||||||
|
lit_pos_bits_t lit_pos_bits; // lp
|
||||||
|
lit_context_bits_t lit_context_bits; // lc
|
||||||
|
dict_size_t dict_size;
|
||||||
|
unsigned fast_mode;
|
||||||
|
num_fast_bytes_t num_fast_bytes;
|
||||||
|
unsigned match_finder_cycles;
|
||||||
|
|
||||||
|
unsigned max_num_probs;
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ucl_compress_config_t : public REAL_ucl_compress_config_t
|
||||||
|
{
|
||||||
|
void reset() { memset(this, 0xff, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct zlib_compress_config_t
|
||||||
|
{
|
||||||
|
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
|
||||||
|
typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb
|
||||||
|
typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st
|
||||||
|
|
||||||
|
mem_level_t mem_level; // ml
|
||||||
|
window_bits_t window_bits; // wb
|
||||||
|
strategy_t strategy; // st
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct upx_compress_config_t
|
||||||
|
{
|
||||||
|
lzma_compress_config_t conf_lzma;
|
||||||
|
ucl_compress_config_t conf_ucl;
|
||||||
|
zlib_compress_config_t conf_zlib;
|
||||||
|
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NULL_cconf ((upx_compress_config_t *) NULL)
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// compression - result_t
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
struct lzma_compress_result_t
|
||||||
|
{
|
||||||
|
unsigned pos_bits; // pb
|
||||||
|
unsigned lit_pos_bits; // lp
|
||||||
|
unsigned lit_context_bits; // lc
|
||||||
|
unsigned dict_size;
|
||||||
|
unsigned fast_mode;
|
||||||
|
unsigned num_fast_bytes;
|
||||||
|
unsigned match_finder_cycles;
|
||||||
|
unsigned num_probs; // (computed result)
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ucl_compress_result_t
|
||||||
|
{
|
||||||
|
ucl_uint result[16];
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct zlib_compress_result_t
|
||||||
|
{
|
||||||
|
unsigned dummy;
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct upx_compress_result_t
|
||||||
|
{
|
||||||
|
// debug
|
||||||
|
int method, level;
|
||||||
|
unsigned u_len, c_len;
|
||||||
|
|
||||||
|
lzma_compress_result_t result_lzma;
|
||||||
|
ucl_compress_result_t result_ucl;
|
||||||
|
zlib_compress_result_t result_zlib;
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
memset(this, 0, sizeof(*this));
|
||||||
|
result_lzma.reset(); result_ucl.reset(); result_zlib.reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -488,9 +744,13 @@ inline void operator delete[](void *p)
|
|||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
|
||||||
|
|
||||||
|
// classes
|
||||||
|
class ElfLinker;
|
||||||
|
typedef ElfLinker Linker;
|
||||||
|
|
||||||
|
|
||||||
// main.cpp
|
// main.cpp
|
||||||
extern const char *progname;
|
extern const char *progname;
|
||||||
void init_options(struct options_t *o);
|
|
||||||
bool set_ec(int ec);
|
bool set_ec(int ec);
|
||||||
#if (ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
#if (ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
||||||
void e_exit(int ec) __attribute__((__noreturn__));
|
void e_exit(int ec) __attribute__((__noreturn__));
|
||||||
@@ -537,7 +797,7 @@ void do_files(int i, int argc, char *argv[]);
|
|||||||
|
|
||||||
// help.cpp
|
// help.cpp
|
||||||
void show_head(void);
|
void show_head(void);
|
||||||
void show_help(int x = 0);
|
void show_help(int verbose=0);
|
||||||
void show_license(void);
|
void show_license(void);
|
||||||
void show_usage(void);
|
void show_usage(void);
|
||||||
void show_version(int);
|
void show_version(int);
|
||||||
@@ -547,18 +807,22 @@ void show_version(int);
|
|||||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
||||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc=0);
|
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc=0);
|
||||||
|
|
||||||
int upx_compress ( const upx_bytep src, upx_uint src_len,
|
int upx_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
upx_progress_callback_t *cb,
|
upx_callback_p cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const struct upx_compress_config_t *conf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_uintp result );
|
upx_compress_result_t *cresult );
|
||||||
int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
int upx_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int method );
|
int method,
|
||||||
int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
const upx_compress_result_t *cresult );
|
||||||
upx_uint src_len, upx_uintp dst_len,
|
int upx_test_overlap ( const upx_bytep buf,
|
||||||
int method );
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|||||||
+23
-23
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -39,41 +39,41 @@
|
|||||||
#undef USE_SCREEN_WIN32
|
#undef USE_SCREEN_WIN32
|
||||||
#undef USE_FRAMES
|
#undef USE_FRAMES
|
||||||
|
|
||||||
#if defined(WITH_GUI) && !defined(NO_CONSOLE)
|
#if 1 && (WITH_GUI) && !defined(NO_CONSOLE)
|
||||||
# define NO_CONSOLE
|
# define NO_CONSOLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1 && defined(__linux__)
|
#if 1 && defined(__linux__)
|
||||||
# define USE_SCREEN
|
# define USE_SCREEN 1
|
||||||
# define USE_SCREEN_VCSA
|
# define USE_SCREEN_VCSA 1
|
||||||
# if !defined(HAVE_LINUX_KD_H)
|
# if !(HAVE_LINUX_KD_H)
|
||||||
# undef USE_SCREEN
|
# undef USE_SCREEN
|
||||||
# undef USE_SCREEN_VCSA
|
# undef USE_SCREEN_VCSA
|
||||||
# endif
|
# endif
|
||||||
# if !defined(HAVE_LINUX_KDEV_T_H) || !defined(HAVE_LINUX_MAJOR_H)
|
# if !(HAVE_LINUX_KDEV_T_H) || !(HAVE_LINUX_MAJOR_H)
|
||||||
# undef USE_SCREEN
|
# undef USE_SCREEN
|
||||||
# undef USE_SCREEN_VCSA
|
# undef USE_SCREEN_VCSA
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1 && defined(__DJGPP__)
|
#if 1 && defined(__DJGPP__)
|
||||||
# define USE_SCREEN
|
# define USE_SCREEN 1
|
||||||
#elif 1 && (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64)
|
#elif 1 && (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||||
# define USE_SCREEN
|
# define USE_SCREEN 1
|
||||||
# define USE_SCREEN_WIN32
|
# define USE_SCREEN_WIN32 1
|
||||||
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
|
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
|
||||||
# define USE_SCREEN
|
# define USE_SCREEN 1
|
||||||
# define USE_SCREEN_WIN32
|
# define USE_SCREEN_WIN32 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0 || defined(NO_ANSI)
|
#if 0 || (NO_ANSI)
|
||||||
# undef USE_ANSI
|
# undef USE_ANSI
|
||||||
#endif
|
#endif
|
||||||
#if 0 || defined(NO_SCREEN)
|
#if 0 || (NO_SCREEN)
|
||||||
# undef USE_SCREEN
|
# undef USE_SCREEN
|
||||||
#endif
|
#endif
|
||||||
#if 0 || defined(NO_FRAMES) || !defined(USE_SCREEN)
|
#if 0 || (NO_FRAMES) || !(USE_SCREEN)
|
||||||
# undef USE_FRAMES
|
# undef USE_FRAMES
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
@@ -81,11 +81,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0 || defined(USE_ANSI) || defined(USE_SCREEN)
|
#if 0 || (USE_ANSI) || (USE_SCREEN)
|
||||||
# define USE_CONSOLE
|
# define USE_CONSOLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0 || defined(NO_CONSOLE) || !defined(USE_CONSOLE)
|
#if 0 || (NO_CONSOLE) || !(USE_CONSOLE)
|
||||||
# undef USE_CONSOLE
|
# undef USE_CONSOLE
|
||||||
# undef USE_ANSI
|
# undef USE_ANSI
|
||||||
# undef USE_SCREEN
|
# undef USE_SCREEN
|
||||||
@@ -110,14 +110,14 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#if defined(USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int (*init)(FILE *f, int, int);
|
int (*init)(FILE *f, int, int);
|
||||||
int (*set_fg)(FILE *f, int fg);
|
int (*set_fg)(FILE *f, int fg);
|
||||||
void (*print0)(FILE *f, const char *s);
|
void (*print0)(FILE *f, const char *s);
|
||||||
upx_bool (*intro)(FILE *f);
|
bool (*intro)(FILE *f);
|
||||||
}
|
}
|
||||||
console_t;
|
console_t;
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...);
|
|||||||
|
|
||||||
extern FILE *con_term;
|
extern FILE *con_term;
|
||||||
|
|
||||||
#if defined(USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
extern int con_mode;
|
extern int con_mode;
|
||||||
extern console_t *con;
|
extern console_t *con;
|
||||||
|
|||||||
+16
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -85,6 +85,11 @@ void throwCantPack(const char *msg)
|
|||||||
throw CantUnpackException(msg);
|
throw CantUnpackException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void throwCantPackExact()
|
||||||
|
{
|
||||||
|
throwCantPack("option '--exact' does not work with this file");
|
||||||
|
}
|
||||||
|
|
||||||
void throwFilterException()
|
void throwFilterException()
|
||||||
{
|
{
|
||||||
throwCantPack("filter problem");
|
throwCantPack("filter problem");
|
||||||
@@ -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)
|
void throwIOException(const char *msg, int e)
|
||||||
{
|
{
|
||||||
throw IOException(msg, e);
|
throw IOException(msg, e);
|
||||||
|
|||||||
+7
-5
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_EXCEPT_H
|
#ifndef __UPX_EXCEPT_H
|
||||||
#define __UPX_EXCEPT_H
|
#define __UPX_EXCEPT_H 1
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
@@ -204,10 +204,11 @@ public:
|
|||||||
// (noreturn) is probably not the correct semantics for throwing exceptions
|
// (noreturn) is probably not the correct semantics for throwing exceptions
|
||||||
#define NORET __attribute__((__noreturn__))
|
#define NORET __attribute__((__noreturn__))
|
||||||
#else
|
#else
|
||||||
#define NORET
|
#define NORET /*empty*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void throwCantPack(const char *msg) NORET;
|
void throwCantPack(const char *msg) NORET;
|
||||||
|
void throwCantPackExact() NORET;
|
||||||
void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET;
|
void throwUnknownExecutableFormat(const char *msg = NULL, bool warn = false) NORET;
|
||||||
void throwNotCompressible(const char *msg = NULL) NORET;
|
void throwNotCompressible(const char *msg = NULL) NORET;
|
||||||
void throwAlreadyPacked(const char *msg = NULL) NORET;
|
void throwAlreadyPacked(const char *msg = NULL) NORET;
|
||||||
@@ -219,6 +220,7 @@ void throwBadLoader() NORET;
|
|||||||
void throwChecksumError() NORET;
|
void throwChecksumError() NORET;
|
||||||
void throwCompressedDataViolation() NORET;
|
void throwCompressedDataViolation() NORET;
|
||||||
void throwInternalError(const char *msg) 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 throwIOException(const char *msg = NULL, int e = 0) NORET;
|
||||||
void throwEOFException(const char *msg = NULL, int e = 0) NORET;
|
void throwEOFException(const char *msg = NULL, int e = 0) NORET;
|
||||||
|
|
||||||
|
|||||||
+104
-16
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
void File::chmod(const char *name, int mode)
|
void File::chmod(const char *name, int mode)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_CHMOD)
|
#if (HAVE_CHMOD)
|
||||||
if (::chmod(name,mode) != 0)
|
if (::chmod(name,mode) != 0)
|
||||||
throwIOException(name,errno);
|
throwIOException(name,errno);
|
||||||
#else
|
#else
|
||||||
@@ -69,7 +69,7 @@ void File::unlink(const char *name)
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
FileBase::FileBase() :
|
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));
|
memset(&st,0,sizeof(st));
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ FileBase::~FileBase()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileBase::sopen()
|
bool FileBase::do_sopen()
|
||||||
{
|
{
|
||||||
if (_shflags < 0)
|
if (_shflags < 0)
|
||||||
_fd = ::open(_name, _flags, _mode);
|
_fd = ::open(_name, _flags, _mode);
|
||||||
@@ -101,9 +101,15 @@ void FileBase::sopen()
|
|||||||
#elif defined(SH_DENYRW)
|
#elif defined(SH_DENYRW)
|
||||||
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
_fd = ::sopen(_name, _flags, _shflags, _mode);
|
||||||
#else
|
#else
|
||||||
assert(0);
|
throwInternalError("bad usage of do_sopen()");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
if (_fd < 0)
|
||||||
|
return false;
|
||||||
|
if (::fstat(_fd, &st) != 0)
|
||||||
|
throwIOException(_name, errno);
|
||||||
|
_length = st.st_size;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -117,6 +123,8 @@ bool FileBase::close()
|
|||||||
_flags = 0;
|
_flags = 0;
|
||||||
_mode = 0;
|
_mode = 0;
|
||||||
_name = NULL;
|
_name = NULL;
|
||||||
|
_offset = 0;
|
||||||
|
_length = 0;
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,10 +172,17 @@ void FileBase::seek(off_t off, int whence)
|
|||||||
{
|
{
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throwIOException("bad seek 1");
|
throwIOException("bad seek 1");
|
||||||
if (whence == SEEK_SET && off < 0)
|
if (whence == SEEK_SET) {
|
||||||
throwIOException("bad seek 2");
|
if (off < 0)
|
||||||
if (whence == SEEK_END && off > 0)
|
throwIOException("bad seek 2");
|
||||||
throwIOException("bad seek 3");
|
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)
|
if (::lseek(_fd,off,whence) < 0)
|
||||||
throwIOException("seek error",errno);
|
throwIOException("seek error",errno);
|
||||||
}
|
}
|
||||||
@@ -180,7 +195,19 @@ off_t FileBase::tell() const
|
|||||||
off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
throwIOException("tell error",errno);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -205,8 +232,9 @@ void InputFile::sopen(const char *name, int flags, int shflags)
|
|||||||
_flags = flags;
|
_flags = flags;
|
||||||
_shflags = shflags;
|
_shflags = shflags;
|
||||||
_mode = 0;
|
_mode = 0;
|
||||||
FileBase::sopen();
|
_offset = 0;
|
||||||
if (!isOpen())
|
_length = 0;
|
||||||
|
if (!FileBase::do_sopen())
|
||||||
{
|
{
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
throw FileNotFoundException(_name, errno);
|
throw FileNotFoundException(_name, errno);
|
||||||
@@ -289,8 +317,9 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
|||||||
_flags = flags;
|
_flags = flags;
|
||||||
_shflags = shflags;
|
_shflags = shflags;
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
FileBase::sopen();
|
_offset = 0;
|
||||||
if (!isOpen())
|
_length = 0;
|
||||||
|
if (!FileBase::do_sopen())
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
// don't throw FileNotFound here -- this is confusing
|
// don't throw FileNotFound here -- this is confusing
|
||||||
@@ -316,6 +345,8 @@ bool OutputFile::openStdout(int flags, bool force)
|
|||||||
_flags = flags;
|
_flags = flags;
|
||||||
_shflags = -1;
|
_shflags = -1;
|
||||||
_mode = 0;
|
_mode = 0;
|
||||||
|
_offset = 0;
|
||||||
|
_length = 0;
|
||||||
if (flags && acc_set_binmode(fd, 1) == -1)
|
if (flags && acc_set_binmode(fd, 1) == -1)
|
||||||
throwIOException(_name, errno);
|
throwIOException(_name, errno);
|
||||||
_fd = fd;
|
_fd = fd;
|
||||||
@@ -329,6 +360,18 @@ void OutputFile::write(const void *buf, int len)
|
|||||||
bytes_written += 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;
|
||||||
|
my_st.st_size = 0;
|
||||||
|
if (::fstat(_fd, &my_st) != 0)
|
||||||
|
throwIOException(_name, errno);
|
||||||
|
return my_st.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void OutputFile::write(const MemBuffer *buf, int len)
|
void OutputFile::write(const MemBuffer *buf, int len)
|
||||||
{
|
{
|
||||||
@@ -343,6 +386,51 @@ void OutputFile::write(const MemBuffer &buf, int len)
|
|||||||
write(&buf, 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);
|
||||||
|
switch (whence) {
|
||||||
|
case SEEK_SET: {
|
||||||
|
if (bytes_written < off) {
|
||||||
|
bytes_written = off;
|
||||||
|
}
|
||||||
|
_length = bytes_written; // cheap, lazy update; needed?
|
||||||
|
} break;
|
||||||
|
case SEEK_END: {
|
||||||
|
_length = bytes_written; // necessary
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
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)
|
void OutputFile::dump(const char *name, const void *buf, int len, int flags)
|
||||||
{
|
{
|
||||||
|
|||||||
+15
-17
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_FILE_H
|
#ifndef __UPX_FILE_H
|
||||||
#define __UPX_FILE_H
|
#define __UPX_FILE_H 1
|
||||||
|
|
||||||
class MemBuffer;
|
class MemBuffer;
|
||||||
|
|
||||||
@@ -59,9 +59,11 @@ public:
|
|||||||
virtual bool isOpen() const { return _fd >= 0; }
|
virtual bool isOpen() const { return _fd >= 0; }
|
||||||
int getFd() const { return _fd; }
|
int getFd() const { return _fd; }
|
||||||
const char *getName() const { return _name; }
|
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:
|
protected:
|
||||||
void sopen();
|
bool do_sopen();
|
||||||
virtual int read(void *buf, int len);
|
virtual int read(void *buf, int len);
|
||||||
virtual int readx(void *buf, int len);
|
virtual int readx(void *buf, int len);
|
||||||
virtual void write(const void *buf, int len);
|
virtual void write(const void *buf, int len);
|
||||||
@@ -73,6 +75,8 @@ protected:
|
|||||||
int _shflags;
|
int _shflags;
|
||||||
int _mode;
|
int _mode;
|
||||||
const char *_name;
|
const char *_name;
|
||||||
|
off_t _offset;
|
||||||
|
off_t _length;
|
||||||
public:
|
public:
|
||||||
struct stat st;
|
struct stat st;
|
||||||
};
|
};
|
||||||
@@ -128,21 +132,15 @@ public:
|
|||||||
virtual void write(const void *buf, int len);
|
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 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; }
|
off_t getBytesWritten() const { return bytes_written; }
|
||||||
|
virtual off_t st_size() const; // { return _length; }
|
||||||
|
|
||||||
// FIXME - these won't work when using the `--stdout' option
|
// FIXME - these won't work when using the '--stdout' option
|
||||||
virtual void seek(off_t off, int whence)
|
virtual void seek(off_t off, int whence);
|
||||||
{
|
virtual void rewrite(const void *buf, int len);
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// util
|
// util
|
||||||
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
||||||
|
|||||||
+21
-7
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -61,10 +61,10 @@ const FilterImp::FilterEntry *FilterImp::getFilter(int id)
|
|||||||
memset(filter_map, 0xff, sizeof(filter_map));
|
memset(filter_map, 0xff, sizeof(filter_map));
|
||||||
for (int i = 0; i < n_filters; i++)
|
for (int i = 0; i < n_filters; i++)
|
||||||
{
|
{
|
||||||
int fid = filters[i].id;
|
int filter_id = filters[i].id;
|
||||||
assert(fid >= 0 && fid <= 255);
|
assert(filter_id >= 0 && filter_id <= 255);
|
||||||
assert(filter_map[fid] == 0xff);
|
assert(filter_map[filter_id] == 0xff);
|
||||||
filter_map[fid] = (unsigned char) i;
|
filter_map[filter_id] = (unsigned char) i;
|
||||||
}
|
}
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
@@ -85,6 +85,20 @@ bool Filter::isValidFilter(int filter_id)
|
|||||||
return fe != NULL;
|
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
|
// high level API
|
||||||
|
|||||||
+6
-5
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,13 +21,13 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_FILTER_H
|
#ifndef __UPX_FILTER_H
|
||||||
#define __UPX_FILTER_H
|
#define __UPX_FILTER_H 1
|
||||||
|
|
||||||
class Filter;
|
class Filter;
|
||||||
class FilterImp;
|
class FilterImp;
|
||||||
@@ -62,6 +62,7 @@ public:
|
|||||||
bool scan(const upx_byte *buf, unsigned buf_len);
|
bool scan(const upx_byte *buf, unsigned buf_len);
|
||||||
|
|
||||||
static bool isValidFilter(int filter_id);
|
static bool isValidFilter(int filter_id);
|
||||||
|
static bool isValidFilter(int filter_id, const int *allowed_filters);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Will be set by each call to filter()/unfilter().
|
// Will be set by each call to filter()/unfilter().
|
||||||
|
|||||||
+44
-9
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@ static int s_ct32_e8e9_bswap_be(Filter *f)
|
|||||||
// 24-bit ARM calltrick ("naive")
|
// 24-bit ARM calltrick ("naive")
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define CT24ARM(f, cond, addvalue, get, set) \
|
#define CT24ARM_LE(f, cond, addvalue, get, set) \
|
||||||
upx_byte *b = f->buf; \
|
upx_byte *b = f->buf; \
|
||||||
upx_byte *b_end = b + f->buf_len - 4; \
|
upx_byte *b_end = b + f->buf_len - 4; \
|
||||||
do { \
|
do { \
|
||||||
@@ -404,24 +404,59 @@ static int s_ct32_e8e9_bswap_be(Filter *f)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
#define ARMCT_COND (((b[3] & 0x0f) == 0x0b))
|
#define ARMCT_COND_le (((b[3] & 0x0f) == 0x0b))
|
||||||
|
|
||||||
static int f_ct24arm_le(Filter *f)
|
static int f_ct24arm_le(Filter *f)
|
||||||
{
|
{
|
||||||
CT24ARM(f, ARMCT_COND, a / 4 + f->addvalue, get_le24, set_le24)
|
CT24ARM_LE(f, ARMCT_COND_le, a / 4 + f->addvalue, get_le24, set_le24)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct24arm_le(Filter *f)
|
static int u_ct24arm_le(Filter *f)
|
||||||
{
|
{
|
||||||
CT24ARM(f, ARMCT_COND, 0 - a / 4 - f->addvalue, get_le24, set_le24)
|
CT24ARM_LE(f, ARMCT_COND_le, 0 - a / 4 - f->addvalue, get_le24, set_le24)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct24arm_le(Filter *f)
|
static int s_ct24arm_le(Filter *f)
|
||||||
{
|
{
|
||||||
CT24ARM(f, ARMCT_COND, a + f->addvalue, get_le24, set_dummy)
|
CT24ARM_LE(f, ARMCT_COND_le, a + f->addvalue, get_le24, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CT24ARM
|
#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
|
#undef ARMCT_COND
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+16
-9
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ static int F(Filter *f)
|
|||||||
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
||||||
unsigned lastnoncall = size, lastcall = 0;
|
unsigned lastnoncall = size, lastcall = 0;
|
||||||
|
|
||||||
// find a 16MB large empty address space
|
// find a 16 MiB large empty address space
|
||||||
{
|
{
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
memset(buf,0,256);
|
memset(buf,0,256);
|
||||||
@@ -58,10 +58,18 @@ static int F(Filter *f)
|
|||||||
// must not conflict with the mark.
|
// must not conflict with the mark.
|
||||||
// Note that unsigned comparison checks both edges of buffer.
|
// Note that unsigned comparison checks both edges of buffer.
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
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)
|
if (getcto(f, buf) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -79,8 +87,7 @@ static int F(Filter *f)
|
|||||||
// try to detect 'real' calls only
|
// try to detect 'real' calls only
|
||||||
if (jc < size)
|
if (jc < size)
|
||||||
{
|
{
|
||||||
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8
|
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||||
return 1; // fail - buffer not restored
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
set_be32(b+ic+1,jc+addvalue+cto);
|
set_be32(b+ic+1,jc+addvalue+cto);
|
||||||
#endif
|
#endif
|
||||||
@@ -119,7 +126,7 @@ static int F(Filter *f)
|
|||||||
f->noncalls = noncalls;
|
f->noncalls = noncalls;
|
||||||
f->lastcall = lastcall;
|
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);
|
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+17
-10
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2010 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
John F. Reiser
|
John F. Reiser
|
||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
@@ -51,16 +51,24 @@ static int F(Filter *f)
|
|||||||
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
||||||
unsigned lastnoncall = size, lastcall = 0;
|
unsigned lastnoncall = size, lastcall = 0;
|
||||||
|
|
||||||
// find a 16MB large empty address space
|
// find a 16 MiB large empty address space
|
||||||
{
|
{
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
memset(buf,0,256);
|
memset(buf,0,256);
|
||||||
|
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
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)
|
if (getcto(f, buf) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -78,8 +86,7 @@ static int F(Filter *f)
|
|||||||
// try to detect 'real' calls only
|
// try to detect 'real' calls only
|
||||||
if (jc < size)
|
if (jc < size)
|
||||||
{
|
{
|
||||||
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8
|
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||||
return 1; // fail - buffer not restored
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
set_be32(b+ic+1,jc+addvalue+cto);
|
set_be32(b+ic+1,jc+addvalue+cto);
|
||||||
#endif
|
#endif
|
||||||
@@ -118,7 +125,7 @@ static int F(Filter *f)
|
|||||||
f->noncalls = noncalls;
|
f->noncalls = noncalls;
|
||||||
f->lastcall = lastcall;
|
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);
|
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+8
-8
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2010 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
John F. Reiser
|
John F. Reiser
|
||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
@@ -123,8 +123,8 @@ static int F(Filter *f)
|
|||||||
N_MRU : 0;
|
N_MRU : 0;
|
||||||
#endif //}
|
#endif //}
|
||||||
|
|
||||||
// FIXME: We must fit into 8MB because we steal one bit.
|
// FIXME: We must fit into 8 MiB because we steal one bit.
|
||||||
// find a 16MB large empty address space
|
// find a 16 MiB large empty address space
|
||||||
{
|
{
|
||||||
int which;
|
int which;
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
@@ -249,11 +249,11 @@ static int F(Filter *f)
|
|||||||
f->noncalls = noncalls;
|
f->noncalls = noncalls;
|
||||||
f->lastcall = lastcall;
|
f->lastcall = lastcall;
|
||||||
|
|
||||||
/*#ifdef TESTING*/
|
#if 0 || defined(TESTING)
|
||||||
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",
|
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",
|
||||||
calls,noncalls,noncalls2,size,cto8);
|
calls,noncalls,noncalls2,size,cto8);
|
||||||
printf("CALL/JMP/JCC %d %d %d\n",wtally[0],wtally[1],wtally[2]);
|
printf("CALL/JMP/JCC %d %d %d\n",wtally[0],wtally[1],wtally[2]);
|
||||||
/*#endif*/
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-10
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2010 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
John F. Reiser
|
John F. Reiser
|
||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
@@ -52,16 +52,24 @@ static int F(Filter *f)
|
|||||||
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
unsigned calls = 0, noncalls = 0, noncalls2 = 0;
|
||||||
unsigned lastnoncall = size, lastcall = 0;
|
unsigned lastnoncall = size, lastcall = 0;
|
||||||
|
|
||||||
// find a 16MB large empty address space
|
// find a 16 MiB large empty address space
|
||||||
{
|
{
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
memset(buf,0,256);
|
memset(buf,0,256);
|
||||||
|
|
||||||
for (ic = 0; ic < size - 5; ic++)
|
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)
|
if (getcto(f, buf) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -79,8 +87,7 @@ static int F(Filter *f)
|
|||||||
// try to detect 'real' calls only
|
// try to detect 'real' calls only
|
||||||
if (jc < size)
|
if (jc < size)
|
||||||
{
|
{
|
||||||
if ((1u<<24)<=(jc+addvalue)) // hi 8 bits won't be cto8
|
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
|
||||||
return 1; // fail - buffer not restored
|
|
||||||
#ifdef U
|
#ifdef U
|
||||||
set_be32(b+ic+1,jc+addvalue+cto);
|
set_be32(b+ic+1,jc+addvalue+cto);
|
||||||
#endif
|
#endif
|
||||||
@@ -119,7 +126,7 @@ static int F(Filter *f)
|
|||||||
f->noncalls = noncalls;
|
f->noncalls = noncalls;
|
||||||
f->lastcall = lastcall;
|
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);
|
printf("\ncalls=%d noncalls=%d noncalls2=%d text_size=%x calltrickoffset=%x\n",calls,noncalls,noncalls2,size,cto);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+16
-12
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2004-2005 John F. Reiser
|
Copyright (C) 2004-2010 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
John F. Reiser
|
John F. Reiser
|
||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
@@ -47,7 +47,7 @@ static int F(Filter *f)
|
|||||||
// scan
|
// scan
|
||||||
const upx_byte *b = f->buf;
|
const upx_byte *b = f->buf;
|
||||||
#endif
|
#endif
|
||||||
const unsigned size = umin(f->buf_len, -(~0u<<(32 - (6+ W_CTO))));
|
const unsigned size = umin(f->buf_len, 0u - (~0u<<(32 - (6+ W_CTO))));
|
||||||
const unsigned size4 = size -4;
|
const unsigned size4 = size -4;
|
||||||
|
|
||||||
unsigned ic;
|
unsigned ic;
|
||||||
@@ -58,7 +58,7 @@ static int F(Filter *f)
|
|||||||
{
|
{
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
unsigned short wbuf[256];
|
unsigned short wbuf[256];
|
||||||
const size_t WW = (size_t)0 - (~(size_t)0) << W_CTO; // ???
|
const size_t WW = (size_t)0 - ((~(size_t)0) << W_CTO); // ???
|
||||||
memset(wbuf, 0, sizeof(wbuf));
|
memset(wbuf, 0, sizeof(wbuf));
|
||||||
memset(buf , 0, WW);
|
memset(buf , 0, WW);
|
||||||
memset(buf + WW, 1, 256 - WW);
|
memset(buf + WW, 1, 256 - WW);
|
||||||
@@ -72,9 +72,11 @@ static int F(Filter *f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (getcto(f, buf) < 0) {
|
if (getcto(f, buf) < 0) {
|
||||||
if (0!=W_CTO) // FIXME: what is this ???
|
#if (W_CTO != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
#else
|
||||||
f->cto = 0;
|
f->cto = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const unsigned char cto8 = f->cto;
|
const unsigned char cto8 = f->cto;
|
||||||
@@ -95,8 +97,9 @@ static int F(Filter *f)
|
|||||||
lastcall = ic;
|
lastcall = ic;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(0==W_CTO // FIXME: what is this ???
|
#if (W_CTO != 0)
|
||||||
|| (~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) != cto8); // this should not happen
|
assert((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) != cto8); // this should not happen
|
||||||
|
#endif
|
||||||
lastnoncall = ic;
|
lastnoncall = ic;
|
||||||
noncalls++;
|
noncalls++;
|
||||||
}
|
}
|
||||||
@@ -105,8 +108,9 @@ static int F(Filter *f)
|
|||||||
f->calls = calls;
|
f->calls = calls;
|
||||||
f->noncalls = noncalls;
|
f->noncalls = noncalls;
|
||||||
f->lastcall = lastcall;
|
f->lastcall = lastcall;
|
||||||
|
ACC_UNUSED(lastnoncall);
|
||||||
|
|
||||||
#if 0
|
#if 0 || defined(TESTING)
|
||||||
printf("\ncalls=%d noncalls=%d text_size=%x calltrickoffset=%x\n",
|
printf("\ncalls=%d noncalls=%d text_size=%x calltrickoffset=%x\n",
|
||||||
calls,noncalls,size,cto8);
|
calls,noncalls,size,cto8);
|
||||||
#endif
|
#endif
|
||||||
@@ -122,7 +126,7 @@ static int F(Filter *f)
|
|||||||
static int U(Filter *f)
|
static int U(Filter *f)
|
||||||
{
|
{
|
||||||
upx_byte *b = f->buf;
|
upx_byte *b = f->buf;
|
||||||
const unsigned size4 = umin(f->buf_len - 4, -(~0u<<(32 - (6+ W_CTO))));
|
const unsigned size4 = umin(f->buf_len - 4, 0u - (~0u<<(32 - (6+ W_CTO))));
|
||||||
const unsigned addvalue = f->addvalue;
|
const unsigned addvalue = f->addvalue;
|
||||||
|
|
||||||
unsigned ic;
|
unsigned ic;
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ umin(unsigned const a, unsigned const b)
|
|||||||
|
|
||||||
#define COND1(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
|
#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 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 F f_ctok32_e8e9_bswap_le
|
||||||
#define U u_ctok32_e8e9_bswap_le
|
#define U u_ctok32_e8e9_bswap_le
|
||||||
#include "filter/ctok.h"
|
#include "filter/ctok.h"
|
||||||
@@ -226,6 +226,7 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
|||||||
|
|
||||||
// 24-bit calltrick for arm
|
// 24-bit calltrick for arm
|
||||||
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
|
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
|
||||||
|
{ 0x51, 8, 0x01ffffff, f_ct24arm_be, u_ct24arm_be, s_ct24arm_be },
|
||||||
|
|
||||||
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
|
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
|
||||||
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
||||||
|
|||||||
+151
-98
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2006 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,11 +22,14 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
#include "packmast.h"
|
||||||
|
#include "packer.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -48,8 +51,9 @@ void show_head(void)
|
|||||||
fg = con_fg(f,FG_GREEN);
|
fg = con_fg(f,FG_GREEN);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" Ultimate Packer for eXecutables\n"
|
" Ultimate Packer for eXecutables\n"
|
||||||
" Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006\n"
|
" Copyright (C) 1996 - %s\n"
|
||||||
"UPX %-10s Markus Oberhumer, Laszlo Molnar & John Reiser %14s\n\n",
|
"UPX %-10s Markus Oberhumer, Laszlo Molnar & John Reiser %14s\n\n",
|
||||||
|
UPX_VERSION_YEAR,
|
||||||
#if (ACC_OS_DOS16 || ACC_OS_DOS32)
|
#if (ACC_OS_DOS16 || ACC_OS_DOS32)
|
||||||
V("d"),
|
V("d"),
|
||||||
#elif (ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
|
#elif (ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||||
@@ -88,7 +92,79 @@ 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);
|
||||||
|
delete p; p = NULL;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
size_t fl = strlen(fn);
|
||||||
|
if (pos == 0) {
|
||||||
|
con_fprintf(f, " %s", fn);
|
||||||
|
pos = 2 + fl;
|
||||||
|
} else if (pos + 1 + fl > 80) {
|
||||||
|
con_fprintf(f, "\n %s", fn);
|
||||||
|
pos = 2 + fl;
|
||||||
|
} else {
|
||||||
|
con_fprintf(f, " %s", fn);
|
||||||
|
pos += 1 + fl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!verbose && pn.names_count)
|
||||||
|
con_fprintf(f, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
void show_help(int verbose)
|
||||||
{
|
{
|
||||||
FILE *f = con_term;
|
FILE *f = con_term;
|
||||||
int fg;
|
int fg;
|
||||||
@@ -105,8 +181,8 @@ void show_help(int x)
|
|||||||
" -d decompress -l list compressed file\n"
|
" -d decompress -l list compressed file\n"
|
||||||
" -t test compressed file -V display version number\n"
|
" -t test compressed file -V display version number\n"
|
||||||
" -h give %s help -L display software license\n%s",
|
" -h give %s help -L display software license\n%s",
|
||||||
x == 0 ? "" : " --best compress best (can be slow for big files)\n",
|
verbose == 0 ? "" : " --best compress best (can be slow for big files)\n",
|
||||||
x == 0 ? "more" : "this", x == 0 ? "" : "\n");
|
verbose == 0 ? "more" : "this", verbose == 0 ? "" : "\n");
|
||||||
|
|
||||||
fg = con_fg(f,FG_YELLOW);
|
fg = con_fg(f,FG_YELLOW);
|
||||||
con_fprintf(f,"Options:\n");
|
con_fprintf(f,"Options:\n");
|
||||||
@@ -114,22 +190,29 @@ void show_help(int x)
|
|||||||
|
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" -q be quiet -v be verbose\n"
|
" -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 overwrite of output files and compression of suspicious files\n"
|
||||||
" -f force compression of suspicious files\n"
|
" -f force compression of suspicious files\n"
|
||||||
"%s%s"
|
"%s%s"
|
||||||
, (x == 0) ? " -k keep backup files\n" : ""
|
, (verbose == 0) ? " -k keep backup files\n" : ""
|
||||||
#if 1
|
#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
|
#else
|
||||||
, ""
|
, ""
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
if (x > 0)
|
if (verbose > 0)
|
||||||
{
|
{
|
||||||
fg = con_fg(f,FG_YELLOW);
|
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);
|
fg = con_fg(f,fg);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" -k, --backup keep backup files\n"
|
" -k, --backup keep backup files\n"
|
||||||
@@ -144,26 +227,16 @@ void show_help(int x)
|
|||||||
" --overlay=skip don't compress a file with an overlay\n"
|
" --overlay=skip don't compress a file with an overlay\n"
|
||||||
"\n");
|
"\n");
|
||||||
fg = con_fg(f,FG_YELLOW);
|
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");
|
|
||||||
fg = con_fg(f,FG_YELLOW);
|
|
||||||
con_fprintf(f,"Options for djgpp2/coff:\n");
|
con_fprintf(f,"Options for djgpp2/coff:\n");
|
||||||
fg = con_fg(f,fg);
|
fg = con_fg(f,fg);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" --coff produce COFF output [default: EXE]\n"
|
" --coff produce COFF output [default: EXE]\n"
|
||||||
" --all-methods try all available compression methods\n"
|
|
||||||
" --all-filters try all available preprocessing filters\n"
|
|
||||||
"\n");
|
"\n");
|
||||||
fg = con_fg(f,FG_YELLOW);
|
fg = con_fg(f,FG_YELLOW);
|
||||||
con_fprintf(f,"Options for dos/com:\n");
|
con_fprintf(f,"Options for dos/com:\n");
|
||||||
fg = con_fg(f,fg);
|
fg = con_fg(f,fg);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" --8086 make compressed com work on any 8086\n"
|
" --8086 make compressed com work on any 8086\n"
|
||||||
" --all-methods try all available compression methods\n"
|
|
||||||
" --all-filters try all available preprocessing filters\n"
|
|
||||||
"\n");
|
"\n");
|
||||||
fg = con_fg(f,FG_YELLOW);
|
fg = con_fg(f,FG_YELLOW);
|
||||||
con_fprintf(f,"Options for dos/exe:\n");
|
con_fprintf(f,"Options for dos/exe:\n");
|
||||||
@@ -171,15 +244,12 @@ void show_help(int x)
|
|||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" --8086 make compressed exe work on any 8086\n"
|
" --8086 make compressed exe work on any 8086\n"
|
||||||
" --no-reloc put no relocations in to the exe header\n"
|
" --no-reloc put no relocations in to the exe header\n"
|
||||||
" --all-methods try all available compression methods\n"
|
|
||||||
"\n");
|
"\n");
|
||||||
fg = con_fg(f,FG_YELLOW);
|
fg = con_fg(f,FG_YELLOW);
|
||||||
con_fprintf(f,"Options for dos/sys:\n");
|
con_fprintf(f,"Options for dos/sys:\n");
|
||||||
fg = con_fg(f,fg);
|
fg = con_fg(f,fg);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" --8086 make compressed sys work on any 8086\n"
|
" --8086 make compressed sys work on any 8086\n"
|
||||||
" --all-methods try all available compression methods\n"
|
|
||||||
" --all-filters try all available preprocessing filters\n"
|
|
||||||
"\n");
|
"\n");
|
||||||
#if 0
|
#if 0
|
||||||
fg = con_fg(f,FG_YELLOW);
|
fg = con_fg(f,FG_YELLOW);
|
||||||
@@ -194,33 +264,19 @@ void show_help(int x)
|
|||||||
con_fprintf(f,"Options for ps1/exe:\n");
|
con_fprintf(f,"Options for ps1/exe:\n");
|
||||||
fg = con_fg(f,fg);
|
fg = con_fg(f,fg);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" --all-methods try all available compression methods\n"
|
|
||||||
" --8-bit uses 8 bit size compression [default: 32 bit]\n"
|
" --8-bit uses 8 bit size compression [default: 32 bit]\n"
|
||||||
" --console-run enables client/host transfer compatibility\n"
|
" --8mib-ram 8 megabyte memory limit [default: 2 MiB]\n"
|
||||||
|
" --boot-only disables client/host transfer compatibility\n"
|
||||||
" --no-align don't align to 2048 bytes [enables: --console-run]\n"
|
" --no-align don't align to 2048 bytes [enables: --console-run]\n"
|
||||||
"\n");
|
"\n");
|
||||||
fg = con_fg(f,FG_YELLOW);
|
fg = con_fg(f,FG_YELLOW);
|
||||||
con_fprintf(f,"Options for tmt/adam:\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");
|
|
||||||
fg = con_fg(f,FG_YELLOW);
|
|
||||||
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");
|
|
||||||
fg = con_fg(f,FG_YELLOW);
|
|
||||||
con_fprintf(f,"Options for watcom/le:\n");
|
con_fprintf(f,"Options for watcom/le:\n");
|
||||||
fg = con_fg(f,fg);
|
fg = con_fg(f,fg);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" --le produce LE output [default: EXE]\n"
|
" --le produce LE output [default: EXE]\n"
|
||||||
"\n");
|
"\n");
|
||||||
fg = con_fg(f,FG_YELLOW);
|
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);
|
fg = con_fg(f,fg);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" --compress-exports=0 do not compress the export section\n"
|
" --compress-exports=0 do not compress the export section\n"
|
||||||
@@ -228,60 +284,39 @@ void show_help(int x)
|
|||||||
" --compress-icons=0 do not compress any icons\n"
|
" --compress-icons=0 do not compress any icons\n"
|
||||||
" --compress-icons=1 compress all but the first icon\n"
|
" --compress-icons=1 compress all but the first icon\n"
|
||||||
" --compress-icons=2 compress all but the first icon directory [default]\n"
|
" --compress-icons=2 compress all but the first icon directory [default]\n"
|
||||||
|
" --compress-icons=3 compress all icons\n"
|
||||||
" --compress-resources=0 do not compress any resources at all\n"
|
" --compress-resources=0 do not compress any resources at all\n"
|
||||||
" --keep-resource=list do not compress resources specified by list\n"
|
" --keep-resource=list do not compress resources specified by list\n"
|
||||||
" --strip-relocs=0 do not strip relocations\n"
|
" --strip-relocs=0 do not strip relocations\n"
|
||||||
" --strip-relocs=1 strip relocations [default]\n"
|
" --strip-relocs=1 strip relocations [default]\n"
|
||||||
" --all-methods try all available compression methods\n"
|
|
||||||
" --all-filters try all available preprocessing filters\n"
|
|
||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
con_fprintf(f,
|
con_fprintf(f, "file.. executables to (de)compress\n");
|
||||||
"file.. executables to (de)compress\n"
|
|
||||||
"\n");
|
if (verbose > 0)
|
||||||
fg = con_fg(f,FG_YELLOW);
|
{
|
||||||
con_fprintf(f,"This version supports:\n");
|
fg = con_fg(f,FG_YELLOW);
|
||||||
fg = con_fg(f,fg);
|
con_fprintf(f,"\nThis version supports:\n");
|
||||||
con_fprintf(f," "
|
fg = con_fg(f,fg);
|
||||||
// TODO:
|
show_all_packers(f, verbose);
|
||||||
// support for mach/ppc32
|
}
|
||||||
// support for linux elf/ppc32
|
else
|
||||||
// support for linux elf/amd64
|
{
|
||||||
" arm/pe,"
|
con_fprintf(f,"\nType '%s --help' for more detailed help.\n", progname);
|
||||||
" atari/tos,"
|
}
|
||||||
" bvmlinuz/386,"
|
|
||||||
" djgpp2/coff,"
|
con_fprintf(f,"\nUPX comes with ABSOLUTELY NO WARRANTY; for details visit http://upx.sf.net\n"
|
||||||
" dos/com,"
|
// "\nUPX comes with ABSOLUTELY NO WARRANTY; for details type 'upx -L'.\n"
|
||||||
" dos/exe,"
|
|
||||||
" dos/sys,"
|
|
||||||
"\n "
|
|
||||||
//" elks/8086,"
|
|
||||||
" linux/amd64,"
|
|
||||||
" linux/i386,"
|
|
||||||
" linux/ppc32,"
|
|
||||||
" mach/ppc32,"
|
|
||||||
" ps1/exe,"
|
|
||||||
" rtm32/pe,"
|
|
||||||
"\n "
|
|
||||||
" tmt/adam,"
|
|
||||||
" vmlinux/386,"
|
|
||||||
" 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"
|
|
||||||
"");
|
"");
|
||||||
|
|
||||||
|
#if (DEBUG) || (TESTING)
|
||||||
#if defined(DEBUG) || defined(TESTING)
|
|
||||||
fg = con_fg(f,FG_RED);
|
fg = con_fg(f,FG_RED);
|
||||||
con_fprintf(f,"\nWARNING: this version is compiled with"
|
con_fprintf(f,"\nWARNING: this version is compiled with"
|
||||||
#if defined(DEBUG)
|
#if (DEBUG)
|
||||||
" -DDEBUG"
|
" -DDEBUG"
|
||||||
#endif
|
#endif
|
||||||
#if defined(TESTING)
|
#if (TESTING)
|
||||||
" -DTESTING"
|
" -DTESTING"
|
||||||
#endif
|
#endif
|
||||||
"\n");
|
"\n");
|
||||||
@@ -325,7 +360,7 @@ void show_license(void)
|
|||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
"\n"
|
"\n"
|
||||||
" Markus F.X.J. Oberhumer Laszlo Molnar\n"
|
" Markus F.X.J. Oberhumer Laszlo Molnar\n"
|
||||||
" <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>\n"
|
" <markus@oberhumer.com> <ml1050@users.sourceforge.net>\n"
|
||||||
);
|
);
|
||||||
fg = con_fg(f,fg);
|
fg = con_fg(f,fg);
|
||||||
|
|
||||||
@@ -339,25 +374,43 @@ void show_license(void)
|
|||||||
|
|
||||||
void show_version(int x)
|
void show_version(int x)
|
||||||
{
|
{
|
||||||
FILE *f = stdout;
|
FILE *fp = stdout;
|
||||||
|
const char *v;
|
||||||
UNUSED(x);
|
UNUSED(x);
|
||||||
|
UNUSED(v);
|
||||||
|
|
||||||
#if (0 && ACC_CC_GNUC)
|
fprintf(fp, "upx %s\n", UPX_VERSION_STRING);
|
||||||
fprintf(f,"upx %s (gcc 0x%06lx)\n", UPX_VERSION_STRING, ACC_CC_GNUC);
|
#if (WITH_NRV)
|
||||||
#else
|
v = upx_nrv_version_string();
|
||||||
fprintf(f,"upx %s\n", UPX_VERSION_STRING);
|
if (v != NULL && v[0])
|
||||||
|
fprintf(fp, "NRV data compression library %s\n", v);
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_NRV)
|
#if (WITH_UCL)
|
||||||
fprintf(f,"NRV data compression library %s\n", nrv_version_string());
|
v = upx_ucl_version_string();
|
||||||
|
if (v != NULL && v[0])
|
||||||
|
fprintf(fp, "UCL data compression library %s\n", v);
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_UCL)
|
#if (WITH_ZLIB)
|
||||||
fprintf(f,"UCL data compression library %s\n", ucl_version_string());
|
v = upx_zlib_version_string();
|
||||||
|
if (v != NULL && v[0])
|
||||||
|
fprintf(fp, "zlib data compression library %s\n", v);
|
||||||
#endif
|
#endif
|
||||||
fprintf(f,"Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer\n");
|
#if (WITH_LZMA)
|
||||||
fprintf(f,"Copyright (C) 1996-2006 Laszlo Molnar\n");
|
v = upx_lzma_version_string();
|
||||||
fprintf(f,"Copyright (C) 2000-2006 John F. Reiser\n");
|
if (v != NULL && v[0])
|
||||||
fprintf(f,"Copyright (C) 2002-2006 Jens Medoch\n");
|
fprintf(fp, "LZMA SDK version %s\n", v);
|
||||||
fprintf(f,"UPX comes with ABSOLUTELY NO WARRANTY; for details type `%s -L'.\n", progname);
|
#endif
|
||||||
|
fprintf(fp, "Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer\n");
|
||||||
|
fprintf(fp, "Copyright (C) 1996-2010 Laszlo Molnar\n");
|
||||||
|
fprintf(fp, "Copyright (C) 2000-2010 John F. Reiser\n");
|
||||||
|
fprintf(fp, "Copyright (C) 2002-2010 Jens Medoch\n");
|
||||||
|
#if (WITH_ZLIB)
|
||||||
|
fprintf(fp, "Copyright (C) 1995" "-2005 Jean-loup Gailly and Mark Adler\n");
|
||||||
|
#endif
|
||||||
|
#if (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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+11
-16
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_LEFILE_H
|
#ifndef __UPX_LEFILE_H
|
||||||
#define __UPX_LEFILE_H
|
#define __UPX_LEFILE_H 1
|
||||||
|
|
||||||
class InputFile;
|
class InputFile;
|
||||||
class OutputFile;
|
class OutputFile;
|
||||||
@@ -49,8 +49,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
enum { FIXUP_EXTRA = 3 };
|
enum { FIXUP_EXTRA = 3 };
|
||||||
|
|
||||||
struct le_header_t
|
__packed_struct(le_header_t)
|
||||||
{ // 0x00
|
// 0x00
|
||||||
char _[2]; // signature: 'LE' || 'LX'
|
char _[2]; // signature: 'LE' || 'LX'
|
||||||
char byte_order; // 0 little endian
|
char byte_order; // 0 little endian
|
||||||
char word_order; // 0 little endian
|
char word_order; // 0 little endian
|
||||||
@@ -117,28 +117,23 @@ protected:
|
|||||||
LE16 device_id;
|
LE16 device_id;
|
||||||
LE16 ddk_version;
|
LE16 ddk_version;
|
||||||
#endif
|
#endif
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct le_object_table_entry_t
|
__packed_struct(le_object_table_entry_t)
|
||||||
{
|
|
||||||
LE32 virtual_size;
|
LE32 virtual_size;
|
||||||
LE32 base_address;
|
LE32 base_address;
|
||||||
LE32 flags;
|
LE32 flags;
|
||||||
LE32 pagemap_index;
|
LE32 pagemap_index;
|
||||||
LE32 npages;
|
LE32 npages;
|
||||||
LE32 reserved;
|
LE32 reserved;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct le_pagemap_entry_t
|
__packed_struct(le_pagemap_entry_t)
|
||||||
{
|
|
||||||
unsigned char h;
|
unsigned char h;
|
||||||
unsigned char m;
|
unsigned char m;
|
||||||
unsigned char l;
|
unsigned char l;
|
||||||
unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
|
unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
virtual void readObjectTable();
|
virtual void readObjectTable();
|
||||||
virtual void writeObjectTable();
|
virtual void writeObjectTable();
|
||||||
|
|||||||
+852
-175
File diff suppressed because it is too large
Load Diff
+205
-48
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,73 +21,230 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_LINKER_H
|
#ifndef __UPX_LINKER_H
|
||||||
#define __UPX_LINKER_H
|
#define __UPX_LINKER_H 1
|
||||||
|
|
||||||
|
|
||||||
class Linker
|
/*************************************************************************
|
||||||
|
// ElfLinker
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
class ElfLinker : private noncopyable
|
||||||
{
|
{
|
||||||
|
friend class Packer;
|
||||||
public:
|
public:
|
||||||
Linker(const void *pdata, int plen, int pinfo);
|
const N_BELE_RTP::AbstractPolicy *bele; // target endianness
|
||||||
virtual ~Linker();
|
protected:
|
||||||
int addSection(const char *sect);
|
struct Section;
|
||||||
void addSection(const char *sname, const void *sdata, unsigned len);
|
struct Symbol;
|
||||||
const char *getLoader(int *llen);
|
struct Relocation;
|
||||||
int getSection(const char *name, int *slen) const;
|
|
||||||
int getLoaderSize() const { return olen; }
|
upx_byte *input;
|
||||||
void setLoaderAlignOffset(int phase);
|
int inputlen;
|
||||||
|
upx_byte *output;
|
||||||
|
int outputlen;
|
||||||
|
|
||||||
|
Section *head;
|
||||||
|
Section *tail;
|
||||||
|
|
||||||
|
Section **sections;
|
||||||
|
Symbol **symbols;
|
||||||
|
Relocation **relocations;
|
||||||
|
|
||||||
|
unsigned nsections;
|
||||||
|
unsigned nsections_capacity;
|
||||||
|
unsigned nsymbols;
|
||||||
|
unsigned nsymbols_capacity;
|
||||||
|
unsigned nrelocations;
|
||||||
|
unsigned nrelocations_capacity;
|
||||||
|
|
||||||
|
bool reloc_done;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// little endian
|
void preprocessSections(char *start, char *end);
|
||||||
virtual unsigned get32(const void *b) const { return get_le32(b); }
|
void preprocessSymbols(char *start, char *end);
|
||||||
virtual void set32(void *b, unsigned v) const { set_le32(b, v); }
|
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:
|
Symbol *addSymbol(const char *name, const char *section, unsigned offset);
|
||||||
struct section;
|
Relocation *addRelocation(const char *section, unsigned off, const char *type,
|
||||||
struct jump;
|
const char *symbol, unsigned add);
|
||||||
|
|
||||||
char *iloader, *oloader;
|
public:
|
||||||
int ilen, olen;
|
ElfLinker();
|
||||||
int info;
|
virtual ~ElfLinker();
|
||||||
jump *jumps;
|
|
||||||
int njumps;
|
|
||||||
section *sections;
|
|
||||||
int nsections;
|
|
||||||
int frozen;
|
|
||||||
int align_hack;
|
|
||||||
int align_offset;
|
|
||||||
|
|
||||||
private:
|
virtual void init(const void *pdata, int plen);
|
||||||
// disable copy and assignment
|
//virtual void setLoaderAlignOffset(int phase);
|
||||||
Linker(const Linker &); // {}
|
virtual int addLoader(const char *sname);
|
||||||
Linker& operator= (const Linker &); // { return *this; }
|
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);
|
||||||
|
|
||||||
|
// target endianness abstraction
|
||||||
|
unsigned get_te16(const void *p) const { return bele->get16(p); }
|
||||||
|
unsigned get_te32(const void *p) const { return bele->get32(p); }
|
||||||
|
acc_uint64l_t get_te64(const void *p) const { return bele->get64(p); }
|
||||||
|
void set_te16(void *p, unsigned v) const { bele->set16(p, v); }
|
||||||
|
void set_te32(void *p, unsigned v) const { bele->set32(p, v); }
|
||||||
|
void set_te64(void *p, acc_uint64l_t v) const { bele->set64(p, v); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BeLinker : public Linker
|
struct ElfLinker::Section : private noncopyable
|
||||||
{
|
{
|
||||||
typedef Linker super;
|
char *name;
|
||||||
public:
|
void *input;
|
||||||
BeLinker(const void *pdata, int plen, int pinfo) :
|
upx_byte *output;
|
||||||
super(pdata, plen, pinfo) { }
|
unsigned size;
|
||||||
|
unsigned offset;
|
||||||
|
unsigned p2align; // log2
|
||||||
|
Section *next;
|
||||||
|
|
||||||
protected:
|
Section(const char *n, const void *i, unsigned s, unsigned a=0);
|
||||||
// big endian
|
~Section();
|
||||||
virtual unsigned get32(const void *b) const { return get_be32(b); }
|
|
||||||
virtual void set32(void *b, unsigned v) const { set_be32(b, v); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// disable copy and assignment
|
|
||||||
BeLinker(const BeLinker &); // {}
|
|
||||||
BeLinker& operator= (const BeLinker &); // { return *this; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ElfLinker::Symbol : private 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 */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+383
-144
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2006 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,14 +22,14 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "mygetopt.h"
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
|
#include "p_elf.h"
|
||||||
|
|
||||||
|
|
||||||
#if 1 && defined(__DJGPP__)
|
#if 1 && defined(__DJGPP__)
|
||||||
@@ -42,23 +42,27 @@ int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;
|
|||||||
// options
|
// options
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void init_options(struct options_t *o)
|
void options_t::reset()
|
||||||
{
|
{
|
||||||
|
options_t *o = this;
|
||||||
memset(o, 0, sizeof(*o));
|
memset(o, 0, sizeof(*o));
|
||||||
memset(&o->crp, 0xff, sizeof(o->crp));
|
o->crp.reset();
|
||||||
|
|
||||||
o->cmd = CMD_NONE;
|
o->cmd = CMD_NONE;
|
||||||
o->method = -1;
|
o->method = M_NONE;
|
||||||
o->level = -1;
|
o->level = -1;
|
||||||
o->filter = -1;
|
o->filter = FT_NONE;
|
||||||
|
|
||||||
o->backup = -1;
|
o->backup = -1;
|
||||||
o->overlay = -1;
|
o->overlay = -1;
|
||||||
|
o->preserve_mode = true;
|
||||||
|
o->preserve_ownership = true;
|
||||||
|
o->preserve_timestamp = true;
|
||||||
|
|
||||||
o->console = CON_FILE;
|
o->console = CON_FILE;
|
||||||
#if defined(__DJGPP__)
|
#if defined(__DJGPP__)
|
||||||
o->console = CON_INIT;
|
o->console = CON_INIT;
|
||||||
#elif defined(USE_SCREEN_WIN32)
|
#elif (USE_SCREEN_WIN32)
|
||||||
o->console = CON_INIT;
|
o->console = CON_INIT;
|
||||||
#elif 1 && defined(__linux__)
|
#elif 1 && defined(__linux__)
|
||||||
o->console = CON_INIT;
|
o->console = CON_INIT;
|
||||||
@@ -75,8 +79,8 @@ void init_options(struct options_t *o)
|
|||||||
o->win32_pe.keep_resource = "";
|
o->win32_pe.keep_resource = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct options_t global_options;
|
static options_t global_options;
|
||||||
struct options_t *opt = &global_options;
|
options_t *opt = &global_options;
|
||||||
|
|
||||||
static int done_output_name = 0;
|
static int done_output_name = 0;
|
||||||
static int done_script_name = 0;
|
static int done_script_name = 0;
|
||||||
@@ -85,6 +89,19 @@ static int done_script_name = 0;
|
|||||||
const char *argv0 = "";
|
const char *argv0 = "";
|
||||||
const char *progname = "";
|
const char *progname = "";
|
||||||
|
|
||||||
|
static acc_getopt_t mfx_getopt;
|
||||||
|
#define mfx_optarg mfx_getopt.optarg
|
||||||
|
#define mfx_optind mfx_getopt.optind
|
||||||
|
#define mfx_option acc_getopt_longopt_t
|
||||||
|
static void handle_opterr(acc_getopt_p g, const char *f, void *v)
|
||||||
|
{
|
||||||
|
struct A { va_list ap; };
|
||||||
|
struct A *a = (struct A *) v;
|
||||||
|
fprintf( stderr, "%s: ", g->progname);
|
||||||
|
vfprintf(stderr, f, a->ap);
|
||||||
|
fprintf( stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int num_files = -1;
|
static int num_files = -1;
|
||||||
static int exit_code = EXIT_OK;
|
static int exit_code = EXIT_OK;
|
||||||
@@ -181,7 +198,7 @@ static void e_method(int m, int l)
|
|||||||
static void e_optarg(const char *n)
|
static void e_optarg(const char *n)
|
||||||
{
|
{
|
||||||
fflush(con_term);
|
fflush(con_term);
|
||||||
fprintf(stderr,"%s: invalid argument in option `%s'\n", argv0, n);
|
fprintf(stderr,"%s: invalid argument in option '%s'\n", argv0, n);
|
||||||
e_exit(EXIT_USAGE);
|
e_exit(EXIT_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +206,7 @@ static void e_optarg(const char *n)
|
|||||||
static void e_optval(const char *n)
|
static void e_optval(const char *n)
|
||||||
{
|
{
|
||||||
fflush(con_term);
|
fflush(con_term);
|
||||||
fprintf(stderr,"%s: invalid value for option `%s'\n", argv0, n);
|
fprintf(stderr,"%s: invalid value for option '%s'\n", argv0, n);
|
||||||
e_exit(EXIT_USAGE);
|
e_exit(EXIT_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,10 +216,10 @@ void e_envopt(const char *n)
|
|||||||
{
|
{
|
||||||
fflush(con_term);
|
fflush(con_term);
|
||||||
if (n)
|
if (n)
|
||||||
fprintf(stderr,"%s: invalid string `%s' in environment variable `%s'\n",
|
fprintf(stderr,"%s: invalid string '%s' in environment variable '%s'\n",
|
||||||
argv0, n, OPTIONS_VAR);
|
argv0, n, OPTIONS_VAR);
|
||||||
else
|
else
|
||||||
fprintf(stderr,"%s: illegal option in environment variable `%s'\n",
|
fprintf(stderr,"%s: illegal option in environment variable '%s'\n",
|
||||||
argv0, OPTIONS_VAR);
|
argv0, OPTIONS_VAR);
|
||||||
e_exit(EXIT_USAGE);
|
e_exit(EXIT_USAGE);
|
||||||
}
|
}
|
||||||
@@ -225,7 +242,7 @@ void check_not_both(bool e1, bool e2, const char *c1, const char *c2)
|
|||||||
if (e1 && e2)
|
if (e1 && e2)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"%s: ",argv0);
|
fprintf(stderr,"%s: ",argv0);
|
||||||
fprintf(stderr,"cannot use both `%s' and `%s'\n", c1, c2);
|
fprintf(stderr,"cannot use both '%s' and '%s'\n", c1, c2);
|
||||||
e_usage();
|
e_usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,12 +252,24 @@ void check_options(int i, int argc)
|
|||||||
{
|
{
|
||||||
assert(i <= argc);
|
assert(i <= argc);
|
||||||
|
|
||||||
|
if (opt->cmd != CMD_COMPRESS)
|
||||||
|
{
|
||||||
|
// invalidate compression options
|
||||||
|
opt->method = 0;
|
||||||
|
opt->level = 0;
|
||||||
|
opt->exact = 0;
|
||||||
|
opt->small = 0;
|
||||||
|
opt->crp.reset();
|
||||||
|
}
|
||||||
|
|
||||||
// set default overlay action
|
// set default overlay action
|
||||||
if (!(opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS))
|
if (!(opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS))
|
||||||
opt->overlay = opt->COPY_OVERLAY;
|
opt->overlay = opt->COPY_OVERLAY;
|
||||||
else if (opt->overlay < 0)
|
else if (opt->overlay < 0)
|
||||||
opt->overlay = opt->COPY_OVERLAY;
|
opt->overlay = opt->COPY_OVERLAY;
|
||||||
|
|
||||||
|
check_not_both(opt->exact, opt->overlay == opt->STRIP_OVERLAY, "--exact", "--overlay=strip");
|
||||||
|
|
||||||
// set default backup option
|
// set default backup option
|
||||||
if (opt->backup < 0)
|
if (opt->backup < 0)
|
||||||
opt->backup = 0;
|
opt->backup = 0;
|
||||||
@@ -250,14 +279,14 @@ void check_options(int i, int argc)
|
|||||||
check_not_both(opt->to_stdout, opt->output_name != NULL, "--stdout", "-o");
|
check_not_both(opt->to_stdout, opt->output_name != NULL, "--stdout", "-o");
|
||||||
if (opt->to_stdout && opt->cmd == CMD_COMPRESS)
|
if (opt->to_stdout && opt->cmd == CMD_COMPRESS)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"%s: cannot use `--stdout' when compressing\n", argv0);
|
fprintf(stderr,"%s: cannot use '--stdout' when compressing\n", argv0);
|
||||||
e_usage();
|
e_usage();
|
||||||
}
|
}
|
||||||
if (opt->to_stdout || opt->output_name)
|
if (opt->to_stdout || opt->output_name)
|
||||||
{
|
{
|
||||||
if (i + 1 != argc)
|
if (i + 1 != argc)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"%s: need exactly one argument when using `%s'\n",
|
fprintf(stderr,"%s: need exactly one argument when using '%s'\n",
|
||||||
argv0, opt->to_stdout ? "--stdout" : "-o");
|
argv0, opt->to_stdout ? "--stdout" : "-o");
|
||||||
e_usage();
|
e_usage();
|
||||||
}
|
}
|
||||||
@@ -298,8 +327,14 @@ static bool set_method(int m, int l)
|
|||||||
{
|
{
|
||||||
if (!Packer::isValidCompressionMethod(m))
|
if (!Packer::isValidCompressionMethod(m))
|
||||||
return false;
|
return false;
|
||||||
opt->method = m;
|
#if 1
|
||||||
opt->all_methods = false;
|
// something like "--brute --lzma" should not disable "--brute"
|
||||||
|
if (!opt->all_methods)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
opt->method = m;
|
||||||
|
opt->all_methods = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (l > 0)
|
if (l > 0)
|
||||||
opt->level = l;
|
opt->level = l;
|
||||||
@@ -313,7 +348,7 @@ static void set_output_name(const char *n, bool allow_m)
|
|||||||
#if 1
|
#if 1
|
||||||
if (done_output_name > 0)
|
if (done_output_name > 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"%s: option `-o' more than once given\n",argv0);
|
fprintf(stderr,"%s: option '-o' more than once given\n",argv0);
|
||||||
e_usage();
|
e_usage();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -336,7 +371,7 @@ static void set_script_name(const char *n, bool allow_m)
|
|||||||
#if 1
|
#if 1
|
||||||
if (done_script_name > 0)
|
if (done_script_name > 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"%s: option `--script' more than once given\n",argv0);
|
fprintf(stderr,"%s: option '--script' more than once given\n",argv0);
|
||||||
e_usage();
|
e_usage();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -404,28 +439,58 @@ char* prepare_shortopts(char *buf, const char *n,
|
|||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
int getoptvar(T *var, const T minval, const T maxval)
|
int getoptvar(T *var, const T min_value, const T max_value, const char *arg_fatal)
|
||||||
{
|
{
|
||||||
const char *p = mfx_optarg;
|
const char *p = mfx_optarg;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
int r = 0;
|
||||||
|
long n;
|
||||||
|
T v;
|
||||||
|
|
||||||
if (!p || !p[0])
|
if (!p || !p[0])
|
||||||
return -1;
|
{ r = -1; goto error; }
|
||||||
// avoid interpretation as octal value
|
// avoid interpretation as octal value
|
||||||
while (p[0] == '0' && isdigit(p[1]))
|
while (p[0] == '0' && isdigit(p[1]))
|
||||||
p++;
|
p++;
|
||||||
long n = strtol(p, &endptr, 0);
|
n = strtol(p, &endptr, 0);
|
||||||
if (*endptr != '\0')
|
if (*endptr != '\0')
|
||||||
return -2;
|
{ r = -2; goto error; }
|
||||||
T v = (T) n;
|
v = (T) n;
|
||||||
if (v < minval)
|
if (v < min_value)
|
||||||
return -3;
|
{ r = -3; goto error; }
|
||||||
if (v > maxval)
|
if (v > max_value)
|
||||||
return -4;
|
{ r = -4; goto error; }
|
||||||
*var = v;
|
*var = v;
|
||||||
return 0;
|
goto done;
|
||||||
|
error:
|
||||||
|
if (arg_fatal != NULL)
|
||||||
|
e_optval(arg_fatal);
|
||||||
|
done:
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1 && (ACC_CC_GNUC >= 0x030300)
|
||||||
|
template <class T, T default_value, T min_value, T max_value>
|
||||||
|
int getoptvar(OptVar<T,default_value,min_value,max_value> *var, const char *arg_fatal)
|
||||||
|
{
|
||||||
|
T v = default_value;
|
||||||
|
int r = getoptvar(&v, min_value, max_value, arg_fatal);
|
||||||
|
if (r == 0)
|
||||||
|
*var = v;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <class T>
|
||||||
|
int getoptvar(T *var, const char *arg_fatal)
|
||||||
|
{
|
||||||
|
typename T::Type v = T::default_value_c;
|
||||||
|
int r = getoptvar(&v, T::min_value_c, T::max_value_c, arg_fatal);
|
||||||
|
if (r == 0)
|
||||||
|
*var = v;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int do_option(int optc, const char *arg)
|
static int do_option(int optc, const char *arg)
|
||||||
{
|
{
|
||||||
@@ -449,7 +514,7 @@ static int do_option(int optc, const char *arg)
|
|||||||
case 'f':
|
case 'f':
|
||||||
opt->force++;
|
opt->force++;
|
||||||
break;
|
break;
|
||||||
case 902:
|
case 909:
|
||||||
set_cmd(CMD_FILEINFO);
|
set_cmd(CMD_FILEINFO);
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
@@ -458,10 +523,13 @@ static int do_option(int optc, const char *arg)
|
|||||||
set_cmd(CMD_HELP);
|
set_cmd(CMD_HELP);
|
||||||
break;
|
break;
|
||||||
case 'h'+256:
|
case 'h'+256:
|
||||||
#if 0
|
#if 1
|
||||||
/* according to GNU standards */
|
if (!acc_isatty(STDOUT_FILENO))
|
||||||
set_term(stdout);
|
{
|
||||||
opt->console = CON_FILE;
|
/* according to GNU standards */
|
||||||
|
set_term(stdout);
|
||||||
|
opt->console = CON_FILE;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
show_help(1);
|
show_help(1);
|
||||||
e_exit(EXIT_OK);
|
e_exit(EXIT_OK);
|
||||||
@@ -500,17 +568,32 @@ static int do_option(int optc, const char *arg)
|
|||||||
|
|
||||||
// method
|
// method
|
||||||
case 702:
|
case 702:
|
||||||
|
opt->method_nrv2b_seen = true;
|
||||||
if (!set_method(M_NRV2B_LE32, -1))
|
if (!set_method(M_NRV2B_LE32, -1))
|
||||||
e_method(M_NRV2B_LE32, opt->level);
|
e_method(M_NRV2B_LE32, opt->level);
|
||||||
break;
|
break;
|
||||||
case 704:
|
case 704:
|
||||||
|
opt->method_nrv2d_seen = true;
|
||||||
if (!set_method(M_NRV2D_LE32, -1))
|
if (!set_method(M_NRV2D_LE32, -1))
|
||||||
e_method(M_NRV2D_LE32, opt->level);
|
e_method(M_NRV2D_LE32, opt->level);
|
||||||
break;
|
break;
|
||||||
case 705:
|
case 705:
|
||||||
|
opt->method_nrv2e_seen = true;
|
||||||
if (!set_method(M_NRV2E_LE32, -1))
|
if (!set_method(M_NRV2E_LE32, -1))
|
||||||
e_method(M_NRV2E_LE32, opt->level);
|
e_method(M_NRV2E_LE32, opt->level);
|
||||||
break;
|
break;
|
||||||
|
case 721:
|
||||||
|
opt->method_lzma_seen = true;
|
||||||
|
opt->all_methods_use_lzma = true;
|
||||||
|
if (!set_method(M_LZMA, -1))
|
||||||
|
e_method(M_LZMA, opt->level);
|
||||||
|
break;
|
||||||
|
case 722:
|
||||||
|
opt->method_lzma_seen = false;
|
||||||
|
opt->all_methods_use_lzma = false;
|
||||||
|
if (M_IS_LZMA(opt->method))
|
||||||
|
opt->method = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
// compression level
|
// compression level
|
||||||
case '1':
|
case '1':
|
||||||
@@ -526,12 +609,16 @@ static int do_option(int optc, const char *arg)
|
|||||||
e_method(opt->method, optc);
|
e_method(opt->method, optc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 902: // --ultra-brute
|
||||||
|
opt->ultra_brute = true;
|
||||||
|
/* fallthrough */
|
||||||
case 901: // --brute
|
case 901: // --brute
|
||||||
opt->all_methods = true;
|
opt->all_methods = true;
|
||||||
|
opt->all_methods_use_lzma = true;
|
||||||
opt->method = -1;
|
opt->method = -1;
|
||||||
opt->all_filters = true;
|
opt->all_filters = true;
|
||||||
opt->filter = -1;
|
opt->filter = -1;
|
||||||
opt->crp.m_size = 999999;
|
opt->crp.crp_ucl.m_size = 999999;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 900: // --best
|
case 900: // --best
|
||||||
if (!set_method(-1, 10))
|
if (!set_method(-1, 10))
|
||||||
@@ -554,6 +641,20 @@ static int do_option(int optc, const char *arg)
|
|||||||
e_optarg(arg);
|
e_optarg(arg);
|
||||||
opt->debug.dump_stub_loader = mfx_optarg;
|
opt->debug.dump_stub_loader = mfx_optarg;
|
||||||
break;
|
break;
|
||||||
|
case 545:
|
||||||
|
opt->debug.disable_random_id = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// mp (meta)
|
||||||
|
case 501:
|
||||||
|
getoptvar(&opt->mp_compress_task, 1, 999999, arg);
|
||||||
|
break;
|
||||||
|
case 502:
|
||||||
|
opt->mp_query_format = true;
|
||||||
|
break;
|
||||||
|
case 503:
|
||||||
|
opt->mp_query_num_tasks = true;
|
||||||
|
break;
|
||||||
|
|
||||||
// misc
|
// misc
|
||||||
case 512:
|
case 512:
|
||||||
@@ -571,6 +672,15 @@ static int do_option(int optc, const char *arg)
|
|||||||
case 519:
|
case 519:
|
||||||
opt->no_env = true;
|
opt->no_env = true;
|
||||||
break;
|
break;
|
||||||
|
case 526:
|
||||||
|
opt->preserve_mode = false;
|
||||||
|
break;
|
||||||
|
case 527:
|
||||||
|
opt->preserve_ownership = false;
|
||||||
|
break;
|
||||||
|
case 528:
|
||||||
|
opt->preserve_timestamp = false;
|
||||||
|
break;
|
||||||
// compression settings
|
// compression settings
|
||||||
case 520: // --small
|
case 520: // --small
|
||||||
if (opt->small < 0)
|
if (opt->small < 0)
|
||||||
@@ -578,7 +688,7 @@ static int do_option(int optc, const char *arg)
|
|||||||
opt->small++;
|
opt->small++;
|
||||||
break;
|
break;
|
||||||
case 521: // --filter=
|
case 521: // --filter=
|
||||||
getoptvar(&opt->filter, 0, 255);
|
getoptvar(&opt->filter, 0, 255, arg);
|
||||||
opt->all_filters = false;
|
opt->all_filters = false;
|
||||||
break;
|
break;
|
||||||
case 522: // --no-filter
|
case 522: // --no-filter
|
||||||
@@ -592,37 +702,64 @@ static int do_option(int optc, const char *arg)
|
|||||||
break;
|
break;
|
||||||
case 524: // --all-methods
|
case 524: // --all-methods
|
||||||
opt->all_methods = true;
|
opt->all_methods = true;
|
||||||
|
opt->all_methods_use_lzma = true;
|
||||||
opt->method = -1;
|
opt->method = -1;
|
||||||
break;
|
break;
|
||||||
// compression parms
|
case 525: // --exact
|
||||||
case 531:
|
opt->exact = true;
|
||||||
getoptvar(&opt->crp.c_flags, 0, 3);
|
|
||||||
break;
|
break;
|
||||||
case 532:
|
// compression runtime parameters
|
||||||
getoptvar(&opt->crp.s_level, 0, 2);
|
case 801:
|
||||||
|
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
|
||||||
break;
|
break;
|
||||||
case 533:
|
case 802:
|
||||||
getoptvar(&opt->crp.h_level, 0, 1);
|
getoptvar(&opt->crp.crp_ucl.s_level, 0, 2, arg);
|
||||||
break;
|
break;
|
||||||
case 534:
|
case 803:
|
||||||
getoptvar(&opt->crp.p_level, 0, 7);
|
getoptvar(&opt->crp.crp_ucl.h_level, 0, 1, arg);
|
||||||
break;
|
break;
|
||||||
case 535:
|
case 804:
|
||||||
getoptvar(&opt->crp.max_offset, 256u, ~0u);
|
getoptvar(&opt->crp.crp_ucl.p_level, 0, 7, arg);
|
||||||
break;
|
break;
|
||||||
case 536:
|
case 805:
|
||||||
getoptvar(&opt->crp.max_match, 16u, ~0u);
|
getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u, arg);
|
||||||
break;
|
break;
|
||||||
case 537:
|
case 806:
|
||||||
if (getoptvar(&opt->crp.m_size, 10000u, 999999u) != 0)
|
getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u, arg);
|
||||||
e_optval("--crp-ms=");
|
break;
|
||||||
|
case 807:
|
||||||
|
getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u, arg);
|
||||||
|
break;
|
||||||
|
case 811:
|
||||||
|
getoptvar(&opt->crp.crp_lzma.pos_bits, arg);
|
||||||
|
break;
|
||||||
|
case 812:
|
||||||
|
getoptvar(&opt->crp.crp_lzma.lit_pos_bits, arg);
|
||||||
|
break;
|
||||||
|
case 813:
|
||||||
|
getoptvar(&opt->crp.crp_lzma.lit_context_bits, arg);
|
||||||
|
break;
|
||||||
|
case 814:
|
||||||
|
getoptvar(&opt->crp.crp_lzma.dict_size, arg);
|
||||||
|
break;
|
||||||
|
case 816:
|
||||||
|
getoptvar(&opt->crp.crp_lzma.num_fast_bytes, arg);
|
||||||
|
break;
|
||||||
|
case 821:
|
||||||
|
getoptvar(&opt->crp.crp_zlib.mem_level, arg);
|
||||||
|
break;
|
||||||
|
case 822:
|
||||||
|
getoptvar(&opt->crp.crp_zlib.window_bits, arg);
|
||||||
|
break;
|
||||||
|
case 823:
|
||||||
|
getoptvar(&opt->crp.crp_zlib.strategy, arg);
|
||||||
break;
|
break;
|
||||||
// backup
|
// backup
|
||||||
case 'k':
|
case 'k':
|
||||||
opt->backup = 1;
|
opt->backup = 1;
|
||||||
break;
|
break;
|
||||||
case 541:
|
case 541:
|
||||||
if (opt->backup != 1) // do not overide `--backup'
|
if (opt->backup != 1) // do not overide '--backup'
|
||||||
opt->backup = 0;
|
opt->backup = 0;
|
||||||
break;
|
break;
|
||||||
// overlay
|
// overlay
|
||||||
@@ -680,18 +817,20 @@ static int do_option(int optc, const char *arg)
|
|||||||
break;
|
break;
|
||||||
case 630:
|
case 630:
|
||||||
opt->win32_pe.compress_exports = 1;
|
opt->win32_pe.compress_exports = 1;
|
||||||
getoptvar(&opt->win32_pe.compress_exports, 0, 1);
|
if (mfx_optarg && mfx_optarg[0])
|
||||||
|
getoptvar(&opt->win32_pe.compress_exports, 0, 1, arg);
|
||||||
//printf("compress_exports: %d\n", opt->win32_pe.compress_exports);
|
//printf("compress_exports: %d\n", opt->win32_pe.compress_exports);
|
||||||
break;
|
break;
|
||||||
case 631:
|
case 631:
|
||||||
opt->win32_pe.compress_icons = 1;
|
opt->win32_pe.compress_icons = 1;
|
||||||
getoptvar(&opt->win32_pe.compress_icons, 0, 2);
|
if (mfx_optarg && mfx_optarg[0])
|
||||||
|
getoptvar(&opt->win32_pe.compress_icons, 0, 3, arg);
|
||||||
//printf("compress_icons: %d\n", opt->win32_pe.compress_icons);
|
//printf("compress_icons: %d\n", opt->win32_pe.compress_icons);
|
||||||
break;
|
break;
|
||||||
case 632:
|
case 632:
|
||||||
opt->win32_pe.compress_resources = true;
|
opt->win32_pe.compress_resources = 1;
|
||||||
if (mfx_optarg && strcmp(mfx_optarg,"0") == 0)
|
if (mfx_optarg && mfx_optarg[0])
|
||||||
opt->win32_pe.compress_resources = false;
|
getoptvar(&opt->win32_pe.compress_resources, 0, 1, arg);
|
||||||
//printf("compress_resources: %d\n", opt->win32_pe.compress_resources);
|
//printf("compress_resources: %d\n", opt->win32_pe.compress_resources);
|
||||||
break;
|
break;
|
||||||
case 633:
|
case 633:
|
||||||
@@ -699,8 +838,8 @@ static int do_option(int optc, const char *arg)
|
|||||||
break;
|
break;
|
||||||
case 634:
|
case 634:
|
||||||
opt->win32_pe.strip_relocs = 1;
|
opt->win32_pe.strip_relocs = 1;
|
||||||
if (mfx_optarg && strcmp(mfx_optarg,"0") == 0)
|
if (mfx_optarg && mfx_optarg[0])
|
||||||
opt->win32_pe.strip_relocs = 0;
|
getoptvar(&opt->win32_pe.strip_relocs, 0, 1, arg);
|
||||||
//printf("strip_relocs: %d\n", opt->win32_pe.strip_relocs);
|
//printf("strip_relocs: %d\n", opt->win32_pe.strip_relocs);
|
||||||
break;
|
break;
|
||||||
case 635:
|
case 635:
|
||||||
@@ -712,7 +851,7 @@ static int do_option(int optc, const char *arg)
|
|||||||
opt->atari_tos.split_segments = true;
|
opt->atari_tos.split_segments = true;
|
||||||
break;
|
break;
|
||||||
case 660:
|
case 660:
|
||||||
getoptvar(&opt->o_unix.blocksize, 8192u, ~0u);
|
getoptvar(&opt->o_unix.blocksize, 8192u, ~0u, arg);
|
||||||
break;
|
break;
|
||||||
case 661:
|
case 661:
|
||||||
opt->o_unix.force_execve = true;
|
opt->o_unix.force_execve = true;
|
||||||
@@ -720,7 +859,7 @@ static int do_option(int optc, const char *arg)
|
|||||||
case 662:
|
case 662:
|
||||||
opt->o_unix.script_name = "/usr/local/lib/upx/upxX";
|
opt->o_unix.script_name = "/usr/local/lib/upx/upxX";
|
||||||
if (mfx_optarg && mfx_optarg[0])
|
if (mfx_optarg && mfx_optarg[0])
|
||||||
set_script_name(mfx_optarg,1);
|
set_script_name(mfx_optarg, 1);
|
||||||
break;
|
break;
|
||||||
case 663:
|
case 663:
|
||||||
opt->o_unix.is_ptinterp = true;
|
opt->o_unix.is_ptinterp = true;
|
||||||
@@ -731,6 +870,18 @@ static int do_option(int optc, const char *arg)
|
|||||||
case 665:
|
case 665:
|
||||||
opt->o_unix.make_ptinterp = true;
|
opt->o_unix.make_ptinterp = true;
|
||||||
break;
|
break;
|
||||||
|
case 666: // Linux
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
|
||||||
|
break;
|
||||||
|
case 667: // FreeBSD
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_FREEBSD;
|
||||||
|
break;
|
||||||
|
case 668: // NetBSD
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_NETBSD;
|
||||||
|
break;
|
||||||
|
case 669: // OpenBSD
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_OPENBSD;
|
||||||
|
break;
|
||||||
case 670:
|
case 670:
|
||||||
opt->ps1_exe.boot_only = true;
|
opt->ps1_exe.boot_only = true;
|
||||||
break;
|
break;
|
||||||
@@ -741,13 +892,19 @@ static int do_option(int optc, const char *arg)
|
|||||||
case 672:
|
case 672:
|
||||||
opt->ps1_exe.do_8bit = true;
|
opt->ps1_exe.do_8bit = true;
|
||||||
break;
|
break;
|
||||||
|
case 673:
|
||||||
|
opt->ps1_exe.do_8mib = false;
|
||||||
|
break;
|
||||||
|
case 674:
|
||||||
|
opt->o_unix.unmap_all_pages = true; // val ?
|
||||||
|
break;
|
||||||
|
|
||||||
case '\0':
|
case '\0':
|
||||||
return -1;
|
return -1;
|
||||||
case ':':
|
case ':':
|
||||||
return -2;
|
return -2;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"%s: internal error in getopt (%d)\n",argv0,optc);
|
fprintf(stderr,"%s: internal error in getopt (%d)\n", argv0, optc);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,10 +921,11 @@ static const struct mfx_option longopts[] =
|
|||||||
// commands
|
// commands
|
||||||
{"best", 0x10, 0, 900}, // compress best
|
{"best", 0x10, 0, 900}, // compress best
|
||||||
{"brute", 0x10, 0, 901}, // compress best, brute force
|
{"brute", 0x10, 0, 901}, // compress best, brute force
|
||||||
|
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
|
||||||
{"decompress", 0, 0, 'd'}, // decompress
|
{"decompress", 0, 0, 'd'}, // decompress
|
||||||
{"fast", 0x10, 0, '1'}, // compress faster
|
{"fast", 0x10, 0, '1'}, // compress faster
|
||||||
{"fileinfo", 0x10, 0, 902}, // display info about file
|
{"fileinfo", 0x10, 0, 909}, // display info about file
|
||||||
{"file-info", 0x10, 0, 902}, // display info about file
|
{"file-info", 0x10, 0, 909}, // display info about file
|
||||||
{"help", 0, 0, 'h'+256}, // give help
|
{"help", 0, 0, 'h'+256}, // give help
|
||||||
{"license", 0, 0, 'L'}, // display software license
|
{"license", 0, 0, 'L'}, // display software license
|
||||||
{"list", 0, 0, 'l'}, // list compressed exe
|
{"list", 0, 0, 'l'}, // list compressed exe
|
||||||
@@ -780,7 +938,10 @@ static const struct mfx_option longopts[] =
|
|||||||
{"force-compress", 0, 0, 'f'}, // and compression of suspicious files
|
{"force-compress", 0, 0, 'f'}, // and compression of suspicious files
|
||||||
{"info", 0, 0, 'i'}, // info mode
|
{"info", 0, 0, 'i'}, // info mode
|
||||||
{"no-env", 0x10, 0, 519}, // no environment var
|
{"no-env", 0x10, 0, 519}, // no environment var
|
||||||
|
{"no-mode", 0x10, 0, 526}, // do not preserve mode (permissions)
|
||||||
|
{"no-owner", 0x10, 0, 527}, // do not preserve ownership
|
||||||
{"no-progress", 0, 0, 516}, // no progress bar
|
{"no-progress", 0, 0, 516}, // no progress bar
|
||||||
|
{"no-time", 0x10, 0, 528}, // do not preserve timestamp
|
||||||
{"output", 0x21, 0, 'o'},
|
{"output", 0x21, 0, 'o'},
|
||||||
{"quiet", 0, 0, 'q'}, // quiet mode
|
{"quiet", 0, 0, 'q'}, // quiet mode
|
||||||
{"silent", 0, 0, 'q'}, // quiet mode
|
{"silent", 0, 0, 'q'}, // quiet mode
|
||||||
@@ -796,18 +957,19 @@ static const struct mfx_option longopts[] =
|
|||||||
{"dump-stub-loader" ,0x31, 0, 544}, // for internal debugging
|
{"dump-stub-loader" ,0x31, 0, 544}, // for internal debugging
|
||||||
{"fake-stub-version",0x31, 0, 542}, // for internal debugging
|
{"fake-stub-version",0x31, 0, 542}, // for internal debugging
|
||||||
{"fake-stub-year" ,0x31, 0, 543}, // for internal debugging
|
{"fake-stub-year" ,0x31, 0, 543}, // for internal debugging
|
||||||
|
{"disable-random-id",0x10, 0, 545}, // for internal debugging
|
||||||
|
|
||||||
// backup options
|
// backup options
|
||||||
{"backup", 0, 0, 'k'},
|
{"backup", 0x10, 0, 'k'},
|
||||||
{"keep", 0, 0, 'k'},
|
{"keep", 0x10, 0, 'k'},
|
||||||
{"no-backup", 0, 0, 541},
|
{"no-backup", 0x10, 0, 541},
|
||||||
|
|
||||||
// overlay options
|
// overlay options
|
||||||
{"overlay", 0x31, 0, 551}, // --overlay=
|
{"overlay", 0x31, 0, 551}, // --overlay=
|
||||||
{"skip-overlay", 0, 0, 552},
|
{"skip-overlay", 0x10, 0, 552},
|
||||||
{"no-overlay", 0, 0, 552}, // old name
|
{"no-overlay", 0x10, 0, 552}, // old name
|
||||||
{"copy-overlay", 0, 0, 553},
|
{"copy-overlay", 0x10, 0, 553},
|
||||||
{"strip-overlay", 0, 0, 554},
|
{"strip-overlay", 0x10, 0, 554},
|
||||||
|
|
||||||
// CPU options
|
// CPU options
|
||||||
{"cpu", 0x31, 0, 560}, // --cpu=
|
{"cpu", 0x31, 0, 560}, // --cpu=
|
||||||
@@ -816,33 +978,53 @@ static const struct mfx_option longopts[] =
|
|||||||
{"486", 0x10, 0, 564},
|
{"486", 0x10, 0, 564},
|
||||||
|
|
||||||
// color options
|
// color options
|
||||||
{"no-color", 0, 0, 512},
|
{"no-color", 0x10, 0, 512},
|
||||||
{"mono", 0, 0, 513},
|
{"mono", 0x10, 0, 513},
|
||||||
{"color", 0, 0, 514},
|
{"color", 0x10, 0, 514},
|
||||||
|
|
||||||
// compression method
|
// compression method
|
||||||
{"nrv2b", 0x10, 0, 702}, // --nrv2b
|
{"nrv2b", 0x10, 0, 702}, // --nrv2b
|
||||||
{"nrv2d", 0x10, 0, 704}, // --nrv2d
|
{"nrv2d", 0x10, 0, 704}, // --nrv2d
|
||||||
{"nrv2e", 0x10, 0, 705}, // --nrv2e
|
{"nrv2e", 0x10, 0, 705}, // --nrv2e
|
||||||
|
{"lzma", 0x10, 0, 721}, // --lzma
|
||||||
|
{"no-lzma", 0x10, 0, 722}, // (disable all_methods_use_lzma)
|
||||||
// compression settings
|
// compression settings
|
||||||
{"all-filters", 0x10, 0, 523},
|
{"all-filters", 0x10, 0, 523},
|
||||||
{"all-methods", 0x10, 0, 524},
|
{"all-methods", 0x10, 0, 524},
|
||||||
|
{"exact", 0x10, 0, 525}, // user requires byte-identical decompression
|
||||||
{"filter", 0x31, 0, 521}, // --filter=
|
{"filter", 0x31, 0, 521}, // --filter=
|
||||||
{"no-filter", 0x10, 0, 522},
|
{"no-filter", 0x10, 0, 522},
|
||||||
{"small", 0x10, 0, 520},
|
{"small", 0x10, 0, 520},
|
||||||
// compression runtime parameters
|
// compression runtime parameters
|
||||||
{"crp-cf", 0x31, 0, 531},
|
{"crp-nrv-cf", 0x31, 0, 801},
|
||||||
{"crp-sl", 0x31, 0, 532},
|
{"crp-nrv-sl", 0x31, 0, 802},
|
||||||
{"crp-hl", 0x31, 0, 533},
|
{"crp-nrv-hl", 0x31, 0, 803},
|
||||||
{"crp-pl", 0x31, 0, 534},
|
{"crp-nrv-pl", 0x31, 0, 804},
|
||||||
{"crp-mo", 0x31, 0, 535},
|
{"crp-nrv-mo", 0x31, 0, 805},
|
||||||
{"crp-mm", 0x31, 0, 536},
|
{"crp-nrv-mm", 0x31, 0, 806},
|
||||||
{"crp-ms", 0x31, 0, 537},
|
{"crp-nrv-ms", 0x31, 0, 807},
|
||||||
|
{"crp-ucl-cf", 0x31, 0, 801},
|
||||||
|
{"crp-ucl-sl", 0x31, 0, 802},
|
||||||
|
{"crp-ucl-hl", 0x31, 0, 803},
|
||||||
|
{"crp-ucl-pl", 0x31, 0, 804},
|
||||||
|
{"crp-ucl-mo", 0x31, 0, 805},
|
||||||
|
{"crp-ucl-mm", 0x31, 0, 806},
|
||||||
|
{"crp-ucl-ms", 0x31, 0, 807},
|
||||||
|
{"crp-lzma-pb", 0x31, 0, 811},
|
||||||
|
{"crp-lzma-lp", 0x31, 0, 812},
|
||||||
|
{"crp-lzma-lc", 0x31, 0, 813},
|
||||||
|
{"crp-lzma-ds", 0x31, 0, 814},
|
||||||
|
{"crp-lzma-fb", 0x31, 0, 816},
|
||||||
|
{"crp-zlib-ml", 0x31, 0, 821},
|
||||||
|
{"crp-zlib-wb", 0x31, 0, 822},
|
||||||
|
{"crp-zlib-st", 0x31, 0, 823},
|
||||||
|
// [deprecated - only for compatibility with UPX 2.0x]
|
||||||
|
{"crp-ms", 0x31, 0, 807},
|
||||||
|
|
||||||
// atari/tos
|
// atari/tos
|
||||||
{"split-segments", 0x10, 0, 650},
|
{"split-segments", 0x10, 0, 650},
|
||||||
// djgpp2/coff
|
// djgpp2/coff
|
||||||
{"coff", 0, 0, 610}, // produce COFF output
|
{"coff", 0x10, 0, 610}, // produce COFF output
|
||||||
// dos/com
|
// dos/com
|
||||||
// dos/exe
|
// dos/exe
|
||||||
//{"force-stub", 0x10, 0, 600},
|
//{"force-stub", 0x10, 0, 600},
|
||||||
@@ -854,11 +1036,20 @@ static const struct mfx_option longopts[] =
|
|||||||
#if 0
|
#if 0
|
||||||
{"script", 0x31, 0, 662}, // --script=
|
{"script", 0x31, 0, 662}, // --script=
|
||||||
#endif
|
#endif
|
||||||
{"is_ptinterp", 0, 0, 663}, // linux/elf386 PT_INTERP program
|
{"is_ptinterp", 0x10, 0, 663}, // linux/elf386 PT_INTERP program
|
||||||
{"use_ptinterp", 0, 0, 664}, // linux/elf386 PT_INTERP program
|
{"use_ptinterp", 0x10, 0, 664}, // linux/elf386 PT_INTERP program
|
||||||
{"make_ptinterp", 0, 0, 665}, // linux/elf386 PT_INTERP program
|
{"make_ptinterp", 0x10, 0, 665}, // linux/elf386 PT_INTERP program
|
||||||
|
{"Linux", 0x10, 0, 666},
|
||||||
|
{"linux", 0x10, 0, 666},
|
||||||
|
{"FreeBSD", 0x10, 0, 667},
|
||||||
|
{"freebsd", 0x10, 0, 667},
|
||||||
|
{"NetBSD", 0x10, 0, 668},
|
||||||
|
{"netbsd", 0x10, 0, 668},
|
||||||
|
{"OpenBSD", 0x10, 0, 669},
|
||||||
|
{"openbsd", 0x10, 0, 669},
|
||||||
|
{"unmap-all-pages", 0x10, 0, 674}, // linux /proc/self/exe vanishes
|
||||||
// watcom/le
|
// watcom/le
|
||||||
{"le", 0, 0, 620}, // produce LE output
|
{"le", 0x10, 0, 620}, // produce LE output
|
||||||
// win32/pe
|
// win32/pe
|
||||||
{"compress-exports", 2, 0, 630},
|
{"compress-exports", 2, 0, 630},
|
||||||
{"compress-icons", 2, 0, 631},
|
{"compress-icons", 2, 0, 631},
|
||||||
@@ -870,17 +1061,26 @@ static const struct mfx_option longopts[] =
|
|||||||
{"boot-only", 0x10, 0, 670},
|
{"boot-only", 0x10, 0, 670},
|
||||||
{"no-align", 0x10, 0, 671},
|
{"no-align", 0x10, 0, 671},
|
||||||
{"8-bit", 0x10, 0, 672},
|
{"8-bit", 0x10, 0, 672},
|
||||||
|
{"8mib-ram", 0x10, 0, 673},
|
||||||
|
{"8mb-ram", 0x10, 0, 673},
|
||||||
|
|
||||||
|
// mp (meta) options
|
||||||
|
{"mp-compress-task", 0x31, 0, 501},
|
||||||
|
{"mp-query-format", 0x10, 0, 502},
|
||||||
|
{"mp-query-num-tasks", 0x10, 0, 503},
|
||||||
|
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
int optc, longind;
|
int optc, longind;
|
||||||
char buf[256];
|
char shortopts[256];
|
||||||
|
|
||||||
prepare_shortopts(buf,"123456789hH?V",longopts),
|
prepare_shortopts(shortopts, "123456789hH?V", longopts),
|
||||||
mfx_optind = 0;
|
acc_getopt_init(&mfx_getopt, 1, argc, argv);
|
||||||
mfx_opterr = 1;
|
mfx_getopt.progname = progname;
|
||||||
while ((optc = mfx_getopt_long(argc, argv, buf, longopts, &longind)) >= 0)
|
mfx_getopt.opterr = handle_opterr;
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
|
||||||
|
while ((optc = acc_getopt(&mfx_getopt, shortopts, longopts, &longind)) >= 0)
|
||||||
{
|
{
|
||||||
if (do_option(optc, argv[mfx_optind-1]) != 0)
|
if (do_option(optc, argv[mfx_optind-1]) != 0)
|
||||||
e_usage();
|
e_usage();
|
||||||
@@ -901,6 +1101,7 @@ static const struct mfx_option longopts[] =
|
|||||||
// commands
|
// commands
|
||||||
{"best", 0x10, 0, 900}, // compress best
|
{"best", 0x10, 0, 900}, // compress best
|
||||||
{"brute", 0x10, 0, 901}, // compress best, brute force
|
{"brute", 0x10, 0, 901}, // compress best, brute force
|
||||||
|
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
|
||||||
{"fast", 0x10, 0, '1'}, // compress faster
|
{"fast", 0x10, 0, '1'}, // compress faster
|
||||||
|
|
||||||
// options
|
// options
|
||||||
@@ -910,17 +1111,20 @@ static const struct mfx_option longopts[] =
|
|||||||
{"silent", 0, 0, 'q'}, // quiet mode
|
{"silent", 0, 0, 'q'}, // quiet mode
|
||||||
{"verbose", 0, 0, 'v'}, // verbose mode
|
{"verbose", 0, 0, 'v'}, // verbose mode
|
||||||
|
|
||||||
|
// debug options
|
||||||
|
{"disable-random-id",0x10, 0, 545}, // for internal debugging
|
||||||
|
|
||||||
// backup options
|
// backup options
|
||||||
{"backup", 0, 0, 'k'},
|
{"backup", 0x10, 0, 'k'},
|
||||||
{"keep", 0, 0, 'k'},
|
{"keep", 0x10, 0, 'k'},
|
||||||
{"no-backup", 0x10, 0, 541},
|
{"no-backup", 0x10, 0, 541},
|
||||||
|
|
||||||
// overlay options
|
// overlay options
|
||||||
{"overlay", 0x31, 0, 551}, // --overlay=
|
{"overlay", 0x31, 0, 551}, // --overlay=
|
||||||
{"skip-overlay", 0, 0, 552},
|
{"skip-overlay", 0x10, 0, 552},
|
||||||
{"no-overlay", 0, 0, 552}, // old name
|
{"no-overlay", 0x10, 0, 552}, // old name
|
||||||
{"copy-overlay", 0, 0, 553},
|
{"copy-overlay", 0x10, 0, 553},
|
||||||
{"strip-overlay", 0, 0, 554},
|
{"strip-overlay", 0x10, 0, 554},
|
||||||
|
|
||||||
// CPU options
|
// CPU options
|
||||||
{"cpu", 0x31, 0, 560}, // --cpu=
|
{"cpu", 0x31, 0, 560}, // --cpu=
|
||||||
@@ -929,18 +1133,21 @@ static const struct mfx_option longopts[] =
|
|||||||
{"486", 0x10, 0, 564},
|
{"486", 0x10, 0, 564},
|
||||||
|
|
||||||
// color options
|
// color options
|
||||||
{"no-color", 0, 0, 512},
|
{"no-color", 0x10, 0, 512},
|
||||||
{"mono", 0, 0, 513},
|
{"mono", 0x10, 0, 513},
|
||||||
{"color", 0, 0, 514},
|
{"color", 0x10, 0, 514},
|
||||||
|
|
||||||
|
// compression settings
|
||||||
|
{"exact", 0x10, 0, 525}, // user requires byte-identical decompression
|
||||||
|
|
||||||
|
// compression method
|
||||||
|
{"nrv2b", 0x10, 0, 702}, // --nrv2b
|
||||||
|
{"nrv2d", 0x10, 0, 704}, // --nrv2d
|
||||||
|
{"nrv2e", 0x10, 0, 705}, // --nrv2e
|
||||||
|
{"lzma", 0x10, 0, 721}, // --lzma
|
||||||
|
{"no-lzma", 0x10, 0, 722}, // (disable all_methods_use_lzma)
|
||||||
|
// compression settings
|
||||||
// compression runtime parameters
|
// compression runtime parameters
|
||||||
{"crp-cf", 0x31, 0, 531},
|
|
||||||
{"crp-sl", 0x31, 0, 532},
|
|
||||||
{"crp-hl", 0x31, 0, 533},
|
|
||||||
{"crp-pl", 0x31, 0, 534},
|
|
||||||
{"crp-mo", 0x31, 0, 535},
|
|
||||||
{"crp-mm", 0x31, 0, 536},
|
|
||||||
{"crp-ms", 0x31, 0, 537},
|
|
||||||
|
|
||||||
// win32/pe
|
// win32/pe
|
||||||
{"compress-exports", 2, 0, 630},
|
{"compress-exports", 2, 0, 630},
|
||||||
@@ -959,7 +1166,7 @@ static const struct mfx_option longopts[] =
|
|||||||
int targc;
|
int targc;
|
||||||
char **targv = NULL;
|
char **targv = NULL;
|
||||||
static const char sep[] = " \t";
|
static const char sep[] = " \t";
|
||||||
char buf[256];
|
char shortopts[256];
|
||||||
|
|
||||||
var = getenv(OPTIONS_VAR);
|
var = getenv(OPTIONS_VAR);
|
||||||
if (var == NULL || !var[0])
|
if (var == NULL || !var[0])
|
||||||
@@ -1015,10 +1222,11 @@ static const struct mfx_option longopts[] =
|
|||||||
e_envopt(targv[i]);
|
e_envopt(targv[i]);
|
||||||
|
|
||||||
/* handle options */
|
/* handle options */
|
||||||
prepare_shortopts(buf,"123456789",longopts);
|
prepare_shortopts(shortopts, "123456789", longopts);
|
||||||
mfx_optind = 0;
|
acc_getopt_init(&mfx_getopt, 1, targc, targv);
|
||||||
mfx_opterr = 1;
|
mfx_getopt.progname = progname;
|
||||||
while ((optc = mfx_getopt_long(targc, targv, buf, longopts, &longind)) >= 0)
|
mfx_getopt.opterr = handle_opterr;
|
||||||
|
while ((optc = acc_getopt(&mfx_getopt, shortopts, longopts, &longind)) >= 0)
|
||||||
{
|
{
|
||||||
if (do_option(optc, targv[mfx_optind-1]) != 0)
|
if (do_option(optc, targv[mfx_optind-1]) != 0)
|
||||||
e_envopt(NULL);
|
e_envopt(NULL);
|
||||||
@@ -1064,9 +1272,29 @@ static void first_options(int argc, char **argv)
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
template <class T> struct TestBELE {
|
template <class T> struct TestBELE {
|
||||||
static int test(void)
|
static bool test(void)
|
||||||
{
|
{
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(T)
|
||||||
|
__packed_struct(test1_t) char a; T b; __packed_struct_end()
|
||||||
|
__packed_struct(test2_t) char a; T b[3]; __packed_struct_end()
|
||||||
|
test1_t t1[7]; UNUSED(t1); test2_t t2[7]; UNUSED(t2);
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(test1_t)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7*sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(test2_t) == 1 + 3*sizeof(T))
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(test2_t)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21*sizeof(T))
|
||||||
|
#if defined(__acc_alignof)
|
||||||
|
COMPILE_TIME_ASSERT(__acc_alignof(t1) == 1)
|
||||||
|
COMPILE_TIME_ASSERT(__acc_alignof(t2) == 1)
|
||||||
|
#endif
|
||||||
|
#if 1 && (ACC_CC_WATCOMC)
|
||||||
|
test1_t t11; COMPILE_TIME_ASSERT(sizeof(t11.a) <= sizeof(t11.b))
|
||||||
|
test2_t t22; COMPILE_TIME_ASSERT(sizeof(t22.a) <= sizeof(t22.b))
|
||||||
|
#endif
|
||||||
|
#if 1 && !defined(UPX_OFFICIAL_BUILD)
|
||||||
T allbits; allbits = 0; allbits -= 1;
|
T allbits; allbits = 0; allbits -= 1;
|
||||||
|
//++allbits; allbits++; --allbits; allbits--;
|
||||||
T v1; v1 = 1; v1 *= 2; v1 -= 1;
|
T v1; v1 = 1; v1 *= 2; v1 -= 1;
|
||||||
T v2; v2 = 1;
|
T v2; v2 = 1;
|
||||||
assert( (v1 == v2)); assert(!(v1 != v2));
|
assert( (v1 == v2)); assert(!(v1 != v2));
|
||||||
@@ -1080,7 +1308,9 @@ static int test(void)
|
|||||||
assert(v1 == 1); assert(v2 == 0);
|
assert(v1 == 1); assert(v2 == 0);
|
||||||
v1 <<= 1; v1 |= v2; v1 >>= 1; v2 &= v1; v2 /= v1; v2 *= v1;
|
v1 <<= 1; v1 |= v2; v1 >>= 1; v2 &= v1; v2 /= v1; v2 *= v1;
|
||||||
assert(v1 == 1); assert(v2 == 0);
|
assert(v1 == 1); assert(v2 == 0);
|
||||||
return (v1 ^ v2) == 1;
|
if ((v1 ^ v2) != 1) return false;
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
@@ -1112,12 +1342,12 @@ void upx_sanity_check(void)
|
|||||||
COMPILE_TIME_ASSERT(sizeof(LE32) == 4)
|
COMPILE_TIME_ASSERT(sizeof(LE32) == 4)
|
||||||
COMPILE_TIME_ASSERT(sizeof(LE64) == 8)
|
COMPILE_TIME_ASSERT(sizeof(LE64) == 8)
|
||||||
|
|
||||||
COMPILE_TIME_ASSERT_ALIGNOF(BE16, char)
|
COMPILE_TIME_ASSERT_ALIGNED1(BE16)
|
||||||
COMPILE_TIME_ASSERT_ALIGNOF(BE32, char)
|
COMPILE_TIME_ASSERT_ALIGNED1(BE32)
|
||||||
COMPILE_TIME_ASSERT_ALIGNOF(BE64, char)
|
COMPILE_TIME_ASSERT_ALIGNED1(BE64)
|
||||||
COMPILE_TIME_ASSERT_ALIGNOF(LE16, char)
|
COMPILE_TIME_ASSERT_ALIGNED1(LE16)
|
||||||
COMPILE_TIME_ASSERT_ALIGNOF(LE32, char)
|
COMPILE_TIME_ASSERT_ALIGNED1(LE32)
|
||||||
COMPILE_TIME_ASSERT_ALIGNOF(LE64, char)
|
COMPILE_TIME_ASSERT_ALIGNED1(LE64)
|
||||||
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1)
|
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1)
|
||||||
assert(strlen(UPX_VERSION_STRING4) == 4);
|
assert(strlen(UPX_VERSION_STRING4) == 4);
|
||||||
@@ -1128,37 +1358,49 @@ void upx_sanity_check(void)
|
|||||||
assert(memcmp(UPX_VERSION_DATE + strlen(UPX_VERSION_DATE) - 4, UPX_VERSION_YEAR, 4) == 0);
|
assert(memcmp(UPX_VERSION_DATE + strlen(UPX_VERSION_DATE) - 4, UPX_VERSION_YEAR, 4) == 0);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
# if 1 && !defined(UPX_OFFICIAL_BUILD)
|
|
||||||
assert(TestBELE<LE16>::test());
|
assert(TestBELE<LE16>::test());
|
||||||
assert(TestBELE<LE32>::test());
|
assert(TestBELE<LE32>::test());
|
||||||
assert(TestBELE<LE64>::test());
|
assert(TestBELE<LE64>::test());
|
||||||
assert(TestBELE<BE16>::test());
|
assert(TestBELE<BE16>::test());
|
||||||
assert(TestBELE<BE32>::test());
|
assert(TestBELE<BE32>::test());
|
||||||
assert(TestBELE<BE64>::test());
|
assert(TestBELE<BE64>::test());
|
||||||
# endif
|
|
||||||
{
|
{
|
||||||
static const unsigned char dd[32] = { 0, 0, 0, 0, 0, 0, 0,
|
static const unsigned char dd[32]
|
||||||
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
|
#if 1 && (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE) && defined(__ELF__)
|
||||||
0, 0, 0, 0,
|
__attribute__((__aligned__(16)))
|
||||||
0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
|
#endif
|
||||||
|
= { 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
|
||||||
0, 0, 0, 0, 0 };
|
0, 0, 0, 0, 0 };
|
||||||
const unsigned char *d;
|
const unsigned char *d;
|
||||||
|
const N_BELE_RTP::AbstractPolicy *bele;
|
||||||
d = dd + 7;
|
d = dd + 7;
|
||||||
assert(upx_adler32(d, 4) == 0x09f003f7);
|
assert(upx_adler32(d, 4) == 0x09f003f7);
|
||||||
assert(upx_adler32(d, 4, 0) == 0x09ec03f6);
|
assert(upx_adler32(d, 4, 0) == 0x09ec03f6);
|
||||||
assert(upx_adler32(d, 4, 1) == 0x09f003f7);
|
assert(upx_adler32(d, 4, 1) == 0x09f003f7);
|
||||||
|
bele = &N_BELE_RTP::be_policy;
|
||||||
assert(get_be16(d) == 0xfffe);
|
assert(get_be16(d) == 0xfffe);
|
||||||
|
assert(bele->get16(d) == 0xfffe);
|
||||||
assert(get_be16_signed(d) == -2);
|
assert(get_be16_signed(d) == -2);
|
||||||
assert(get_be24(d) == 0xfffefd);
|
assert(get_be24(d) == 0xfffefd);
|
||||||
|
assert(bele->get24(d) == 0xfffefd);
|
||||||
assert(get_be24_signed(d) == -259);
|
assert(get_be24_signed(d) == -259);
|
||||||
assert(get_be32(d) == 0xfffefdfc);
|
assert(get_be32(d) == 0xfffefdfc);
|
||||||
|
assert(bele->get32(d) == 0xfffefdfc);
|
||||||
assert(get_be32_signed(d) == -66052);
|
assert(get_be32_signed(d) == -66052);
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
assert(get_le16(d) == 0xfeff);
|
assert(get_le16(d) == 0xfeff);
|
||||||
|
assert(bele->get16(d) == 0xfeff);
|
||||||
assert(get_le16_signed(d) == -257);
|
assert(get_le16_signed(d) == -257);
|
||||||
assert(get_le24(d) == 0xfdfeff);
|
assert(get_le24(d) == 0xfdfeff);
|
||||||
|
assert(bele->get24(d) == 0xfdfeff);
|
||||||
assert(get_le24_signed(d) == -131329);
|
assert(get_le24_signed(d) == -131329);
|
||||||
assert(get_le32(d) == 0xfcfdfeff);
|
assert(get_le32(d) == 0xfcfdfeff);
|
||||||
|
assert(bele->get32(d) == 0xfcfdfeff);
|
||||||
assert(get_le32_signed(d) == -50462977);
|
assert(get_le32_signed(d) == -50462977);
|
||||||
|
assert(get_le64_signed(d) == ACC_INT64_C(-506097522914230529));
|
||||||
assert(find_be16(d, 2, 0xfffe) == 0);
|
assert(find_be16(d, 2, 0xfffe) == 0);
|
||||||
assert(find_le16(d, 2, 0xfeff) == 0);
|
assert(find_le16(d, 2, 0xfeff) == 0);
|
||||||
assert(find_be32(d, 4, 0xfffefdfc) == 0);
|
assert(find_be32(d, 4, 0xfffefdfc) == 0);
|
||||||
@@ -1167,6 +1409,7 @@ void upx_sanity_check(void)
|
|||||||
assert(get_be16_signed(d) == 32638);
|
assert(get_be16_signed(d) == 32638);
|
||||||
assert(get_be24_signed(d) == 8355453);
|
assert(get_be24_signed(d) == 8355453);
|
||||||
assert(get_be32_signed(d) == 2138996092);
|
assert(get_be32_signed(d) == 2138996092);
|
||||||
|
assert(get_be64_signed(d) == ACC_INT64_C(9186918263483431288));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1176,7 +1419,11 @@ void upx_sanity_check(void)
|
|||||||
// main entry point
|
// main entry point
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if !defined(WITH_GUI)
|
#if !(WITH_GUI)
|
||||||
|
|
||||||
|
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||||
|
extern "C" { extern long _stksize; long _stksize = 256 * 1024L; }
|
||||||
|
#endif
|
||||||
|
|
||||||
int __acc_cdecl_main main(int argc, char *argv[])
|
int __acc_cdecl_main main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -1191,7 +1438,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
|||||||
acc_wildargv(&argc, &argv);
|
acc_wildargv(&argc, &argv);
|
||||||
|
|
||||||
upx_sanity_check();
|
upx_sanity_check();
|
||||||
init_options(opt);
|
opt->reset();
|
||||||
|
|
||||||
if (!argv[0] || !argv[0][0])
|
if (!argv[0] || !argv[0][0])
|
||||||
argv[0] = default_argv0;
|
argv[0] = default_argv0;
|
||||||
@@ -1222,7 +1469,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
|||||||
|
|
||||||
set_term(stderr);
|
set_term(stderr);
|
||||||
|
|
||||||
#if defined(WITH_UCL)
|
#if (WITH_UCL)
|
||||||
if (ucl_init() != UCL_E_OK)
|
if (ucl_init() != UCL_E_OK)
|
||||||
{
|
{
|
||||||
show_head();
|
show_head();
|
||||||
@@ -1233,7 +1480,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
|||||||
e_exit(EXIT_INIT);
|
e_exit(EXIT_INIT);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_NRV)
|
#if (WITH_NRV)
|
||||||
if (nrv_init() != NRV_E_OK || NRV_VERSION != nrv_version())
|
if (nrv_init() != NRV_E_OK || NRV_VERSION != nrv_version())
|
||||||
{
|
{
|
||||||
show_head();
|
show_head();
|
||||||
@@ -1292,14 +1539,6 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt->cmd != CMD_COMPRESS)
|
|
||||||
{
|
|
||||||
// invalidate compression options
|
|
||||||
opt->method = 0;
|
|
||||||
opt->level = 0;
|
|
||||||
memset(&opt->crp, 0xff, sizeof(opt->crp));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
e_help();
|
e_help();
|
||||||
@@ -1318,7 +1557,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
|||||||
set_term(stdout);
|
set_term(stdout);
|
||||||
do_files(i,argc,argv);
|
do_files(i,argc,argv);
|
||||||
|
|
||||||
#if 0 && (UPX_VERSION_HEX < 0x020000)
|
#if 0 && (UPX_VERSION_HEX < 0x030000)
|
||||||
{
|
{
|
||||||
FILE *f = stdout;
|
FILE *f = stdout;
|
||||||
int fg = con_fg(f,FG_RED);
|
int fg = con_fg(f,FG_RED);
|
||||||
@@ -1334,7 +1573,7 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
|||||||
return exit_code;
|
return exit_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !defined(WITH_GUI) */
|
#endif /* !(WITH_GUI) */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+24
-13
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ static int mcheck_init()
|
|||||||
if (use_mcheck < 0)
|
if (use_mcheck < 0)
|
||||||
{
|
{
|
||||||
use_mcheck = 1;
|
use_mcheck = 1;
|
||||||
#if defined(WITH_VALGRIND) && defined(RUNNING_ON_VALGRIND)
|
#if (WITH_VALGRIND) && defined(RUNNING_ON_VALGRIND)
|
||||||
if (RUNNING_ON_VALGRIND)
|
if (RUNNING_ON_VALGRIND)
|
||||||
{
|
{
|
||||||
//fprintf(stderr, "upx: detected RUNNING_ON_VALGRIND\n");
|
//fprintf(stderr, "upx: detected RUNNING_ON_VALGRIND\n");
|
||||||
@@ -101,16 +101,15 @@ void MemBuffer::dealloc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MemBuffer::allocForCompression(unsigned uncompressed_size, unsigned extra)
|
unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned extra)
|
||||||
{
|
{
|
||||||
assert((int)uncompressed_size > 0);
|
assert((int)uncompressed_size > 0);
|
||||||
assert((int)extra >= 0);
|
assert((int)extra >= 0);
|
||||||
unsigned size = uncompressed_size + uncompressed_size/8 + 256 + extra;
|
unsigned size = uncompressed_size + uncompressed_size/8 + 256 + extra;
|
||||||
alloc(size);
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned MemBuffer::getSizeForUncompression(unsigned uncompressed_size, unsigned extra)
|
||||||
void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra)
|
|
||||||
{
|
{
|
||||||
assert((int)uncompressed_size > 0);
|
assert((int)uncompressed_size > 0);
|
||||||
assert((int)extra >= 0);
|
assert((int)extra >= 0);
|
||||||
@@ -120,6 +119,20 @@ void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra
|
|||||||
#if (ACC_ARCH_I386)
|
#if (ACC_ARCH_I386)
|
||||||
size += 3;
|
size += 3;
|
||||||
#endif
|
#endif
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MemBuffer::allocForCompression(unsigned uncompressed_size, unsigned extra)
|
||||||
|
{
|
||||||
|
unsigned size = getSizeForCompression(uncompressed_size, extra);
|
||||||
|
alloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra)
|
||||||
|
{
|
||||||
|
unsigned size = getSizeForUncompression(uncompressed_size, extra);
|
||||||
alloc(size);
|
alloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,11 +192,7 @@ void MemBuffer::alloc(unsigned size)
|
|||||||
assert((int)total > 0);
|
assert((int)total > 0);
|
||||||
unsigned char *p = (unsigned char *) malloc(total);
|
unsigned char *p = (unsigned char *) malloc(total);
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
throwOutOfMemoryException();
|
||||||
//throw bad_alloc();
|
|
||||||
throw OutOfMemoryException("out of memory");
|
|
||||||
//exit(1);
|
|
||||||
}
|
|
||||||
b_size = size;
|
b_size = size;
|
||||||
if (use_mcheck)
|
if (use_mcheck)
|
||||||
{
|
{
|
||||||
@@ -196,6 +205,8 @@ void MemBuffer::alloc(unsigned size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
b = p ;
|
b = p ;
|
||||||
|
|
||||||
|
//fill(0, b_size, (rand() & 0xff) | 1); // debug
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_MEM_H
|
#ifndef __UPX_MEM_H
|
||||||
#define __UPX_MEM_H
|
#define __UPX_MEM_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -38,9 +38,12 @@ class MemBuffer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemBuffer();
|
MemBuffer();
|
||||||
MemBuffer(unsigned size);
|
explicit MemBuffer(unsigned size);
|
||||||
~MemBuffer();
|
~MemBuffer();
|
||||||
|
|
||||||
|
static unsigned getSizeForCompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
|
static unsigned getSizeForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
|
|
||||||
void alloc(unsigned size);
|
void alloc(unsigned size);
|
||||||
void allocForCompression(unsigned uncompressed_size, unsigned extra=0);
|
void allocForCompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
void allocForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
void allocForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
|
|||||||
+929
-378
File diff suppressed because it is too large
Load Diff
+4
-4
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ void printClearLine(FILE *f)
|
|||||||
fflush(stdout); fflush(stderr);
|
fflush(stdout); fflush(stderr);
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
f = stdout;
|
f = stdout;
|
||||||
con_fprintf(f,clear_line_msg);
|
con_fprintf(f, "%s", clear_line_msg);
|
||||||
fflush(f);
|
fflush(f);
|
||||||
printSetNl(0);
|
printSetNl(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,706 +0,0 @@
|
|||||||
/* Getopt for GNU.
|
|
||||||
NOTE: getopt is now part of the C library, so if you don't know what
|
|
||||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
|
||||||
before changing it!
|
|
||||||
|
|
||||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
|
|
||||||
Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
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 the
|
|
||||||
Free Software Foundation; either version 2, 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; if not, write to the Free Software
|
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#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
|
|
||||||
long-named option. Because this is not POSIX.2 compliant, it is
|
|
||||||
being phased out. */
|
|
||||||
/* #define GETOPT_COMPAT */
|
|
||||||
#undef GETOPT_COMPAT
|
|
||||||
|
|
||||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
|
||||||
but it behaves differently for the user, since it allows the user
|
|
||||||
to intersperse the options with the other arguments.
|
|
||||||
|
|
||||||
As `getopt' works, it permutes the elements of ARGV so that,
|
|
||||||
when it is done, all the options precede everything else. Thus
|
|
||||||
all application programs are extended to handle flexible argument order.
|
|
||||||
|
|
||||||
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
|
||||||
Then the behavior is completely standard.
|
|
||||||
|
|
||||||
GNU application programs can use a third alternative mode in which
|
|
||||||
they can distinguish the relative order of options and other arguments. */
|
|
||||||
|
|
||||||
#include "mygetopt.h"
|
|
||||||
#define option mfx_option
|
|
||||||
#define optarg mfx_optarg
|
|
||||||
#define optind mfx_optind
|
|
||||||
#define opterr mfx_opterr
|
|
||||||
#define optopt mfx_optopt
|
|
||||||
#undef BAD_OPTION
|
|
||||||
|
|
||||||
/* For communication from `getopt' to the caller.
|
|
||||||
When `getopt' finds an option that takes an argument,
|
|
||||||
the argument value is returned here.
|
|
||||||
Also, when `ordering' is RETURN_IN_ORDER,
|
|
||||||
each non-option ARGV-element is returned here. */
|
|
||||||
|
|
||||||
char *optarg = NULL;
|
|
||||||
|
|
||||||
/* Index in ARGV of the next element to be scanned.
|
|
||||||
This is used for communication to and from the caller
|
|
||||||
and for communication between successive calls to `getopt'.
|
|
||||||
|
|
||||||
On entry to `getopt', zero means this is the first call; initialize.
|
|
||||||
|
|
||||||
When `getopt' returns EOF, this is the index of the first of the
|
|
||||||
non-option elements that the caller should itself scan.
|
|
||||||
|
|
||||||
Otherwise, `optind' communicates from one call to the next
|
|
||||||
how much of ARGV has been scanned so far. */
|
|
||||||
|
|
||||||
/* XXX 1003.2 says this must be 1 before any call. */
|
|
||||||
int optind = 0;
|
|
||||||
|
|
||||||
/* The next char to be scanned in the option-element
|
|
||||||
in which the last option character we returned was found.
|
|
||||||
This allows us to pick up the scan where we left off.
|
|
||||||
|
|
||||||
If this is zero, or a null string, it means resume the scan
|
|
||||||
by advancing to the next ARGV-element. */
|
|
||||||
|
|
||||||
static char *nextchar;
|
|
||||||
|
|
||||||
/* Callers store zero here to inhibit the error message
|
|
||||||
for unrecognized options. */
|
|
||||||
|
|
||||||
int opterr = 1;
|
|
||||||
|
|
||||||
/* Set to an option character which was unrecognized.
|
|
||||||
This must be initialized on some systems to avoid linking in the
|
|
||||||
system's own getopt implementation. */
|
|
||||||
|
|
||||||
#define BAD_OPTION '\0'
|
|
||||||
int optopt = BAD_OPTION;
|
|
||||||
|
|
||||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
|
||||||
|
|
||||||
If the caller did not specify anything,
|
|
||||||
the default is REQUIRE_ORDER if the environment variable
|
|
||||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
|
||||||
|
|
||||||
REQUIRE_ORDER means don't recognize them as options;
|
|
||||||
stop option processing when the first non-option is seen.
|
|
||||||
This is what Unix does.
|
|
||||||
This mode of operation is selected by either setting the environment
|
|
||||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
|
||||||
of the list of option characters.
|
|
||||||
|
|
||||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
|
||||||
so that eventually all the non-options are at the end. This allows options
|
|
||||||
to be given in any order, even with programs that were not written to
|
|
||||||
expect this.
|
|
||||||
|
|
||||||
RETURN_IN_ORDER is an option available to programs that were written
|
|
||||||
to expect options and other ARGV-elements in any order and that care about
|
|
||||||
the ordering of the two. We describe each non-option ARGV-element
|
|
||||||
as if it were the argument of an option with character code 1.
|
|
||||||
Using `-' as the first character of the list of option characters
|
|
||||||
selects this mode of operation.
|
|
||||||
|
|
||||||
The special argument `--' forces an end of option-scanning regardless
|
|
||||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
|
||||||
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
|
||||||
|
|
||||||
static enum
|
|
||||||
{
|
|
||||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
|
||||||
} ordering;
|
|
||||||
|
|
||||||
/* Handle permutation of arguments. */
|
|
||||||
|
|
||||||
/* Describe the part of ARGV that contains non-options that have
|
|
||||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
|
||||||
`last_nonopt' is the index after the last of them. */
|
|
||||||
|
|
||||||
static int first_nonopt;
|
|
||||||
static int last_nonopt;
|
|
||||||
|
|
||||||
/* Exchange two adjacent subsequences of ARGV.
|
|
||||||
One subsequence is elements [first_nonopt,last_nonopt)
|
|
||||||
which contains all the non-options that have been skipped so far.
|
|
||||||
The other is elements [last_nonopt,optind), which contains all
|
|
||||||
the options processed since those non-options were skipped.
|
|
||||||
|
|
||||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
|
||||||
the new indices of the non-options in ARGV after they are moved.
|
|
||||||
|
|
||||||
To perform the swap, we first reverse the order of all elements. So
|
|
||||||
all options now come before all non options, but they are in the
|
|
||||||
wrong order. So we put back the options and non options in original
|
|
||||||
order by reversing them again. For example:
|
|
||||||
original input: a b c -x -y
|
|
||||||
reverse all: -y -x c b a
|
|
||||||
reverse options: -x -y c b a
|
|
||||||
reverse non options: -x -y a b c
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
static void exchange (char **argv)
|
|
||||||
{
|
|
||||||
char *temp; char **first, **last;
|
|
||||||
|
|
||||||
/* Reverse all the elements [first_nonopt, optind) */
|
|
||||||
first = &argv[first_nonopt];
|
|
||||||
last = &argv[optind-1];
|
|
||||||
while (first < last) {
|
|
||||||
temp = *first; *first = *last; *last = temp; first++; last--;
|
|
||||||
}
|
|
||||||
/* Put back the options in order */
|
|
||||||
first = &argv[first_nonopt];
|
|
||||||
first_nonopt += (optind - last_nonopt);
|
|
||||||
last = &argv[first_nonopt - 1];
|
|
||||||
while (first < last) {
|
|
||||||
temp = *first; *first = *last; *last = temp; first++; last--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put back the non options in order */
|
|
||||||
first = &argv[first_nonopt];
|
|
||||||
last_nonopt = optind;
|
|
||||||
last = &argv[last_nonopt-1];
|
|
||||||
while (first < last) {
|
|
||||||
temp = *first; *first = *last; *last = temp; first++; last--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
|
||||||
given in OPTSTRING.
|
|
||||||
|
|
||||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
|
||||||
then it is an option element. The characters of this element
|
|
||||||
(aside from the initial '-') are option characters. If `getopt'
|
|
||||||
is called repeatedly, it returns successively each of the option characters
|
|
||||||
from each of the option elements.
|
|
||||||
|
|
||||||
If `getopt' finds another option character, it returns that character,
|
|
||||||
updating `optind' and `nextchar' so that the next call to `getopt' can
|
|
||||||
resume the scan with the following option character or ARGV-element.
|
|
||||||
|
|
||||||
If there are no more option characters, `getopt' returns `EOF'.
|
|
||||||
Then `optind' is the index in ARGV of the first ARGV-element
|
|
||||||
that is not an option. (The ARGV-elements have been permuted
|
|
||||||
so that those that are not options now come last.)
|
|
||||||
|
|
||||||
OPTSTRING is a string containing the legitimate option characters.
|
|
||||||
If an option character is seen that is not listed in OPTSTRING,
|
|
||||||
return BAD_OPTION after printing an error message. If you set `opterr' to
|
|
||||||
zero, the error message is suppressed but we still return BAD_OPTION.
|
|
||||||
|
|
||||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
|
||||||
so the following text in the same ARGV-element, or the text of the following
|
|
||||||
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
|
||||||
wants an optional arg; if there is text in the current ARGV-element,
|
|
||||||
it is returned in `optarg', otherwise `optarg' is set to zero.
|
|
||||||
|
|
||||||
If OPTSTRING starts with `-' or `+', it requests different methods of
|
|
||||||
handling the non-option ARGV-elements.
|
|
||||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
|
||||||
|
|
||||||
Long-named options begin with `--' instead of `-'.
|
|
||||||
Their names may be abbreviated as long as the abbreviation is unique
|
|
||||||
or is an exact match for some defined option. If they have an
|
|
||||||
argument, it follows the option name in the same ARGV-element, separated
|
|
||||||
from the option name by a `=', or else the in next ARGV-element.
|
|
||||||
When `getopt' finds a long-named option, it returns 0 if that option's
|
|
||||||
`flag' field is nonzero, the value of the option's `val' field
|
|
||||||
if the `flag' field is zero.
|
|
||||||
|
|
||||||
LONGOPTS is a vector of `struct option' terminated by an
|
|
||||||
element containing a name which is zero.
|
|
||||||
|
|
||||||
LONGIND returns the index in LONGOPT of the long-named option found.
|
|
||||||
It is only valid when a long-named option has been found by the most
|
|
||||||
recent call.
|
|
||||||
|
|
||||||
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
|
||||||
long-named options. */
|
|
||||||
|
|
||||||
static int _getopt_internal (int argc, char **argv, const char *optstring,
|
|
||||||
const struct option *longopts, int *longind,
|
|
||||||
int long_only)
|
|
||||||
{
|
|
||||||
static char empty_string[1];
|
|
||||||
int option_index;
|
|
||||||
|
|
||||||
if (longind != NULL)
|
|
||||||
*longind = -1;
|
|
||||||
|
|
||||||
optarg = 0;
|
|
||||||
|
|
||||||
/* Initialize the internal data when the first call is made.
|
|
||||||
Start processing options with ARGV-element 1 (since ARGV-element 0
|
|
||||||
is the program name); the sequence of previously skipped
|
|
||||||
non-option ARGV-elements is empty. */
|
|
||||||
|
|
||||||
if (optind == 0)
|
|
||||||
{
|
|
||||||
first_nonopt = last_nonopt = optind = 1;
|
|
||||||
|
|
||||||
nextchar = NULL;
|
|
||||||
|
|
||||||
/* Determine how to handle the ordering of options and nonoptions. */
|
|
||||||
|
|
||||||
if (optstring[0] == '-')
|
|
||||||
{
|
|
||||||
ordering = RETURN_IN_ORDER;
|
|
||||||
++optstring;
|
|
||||||
}
|
|
||||||
else if (optstring[0] == '+')
|
|
||||||
{
|
|
||||||
ordering = REQUIRE_ORDER;
|
|
||||||
++optstring;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
else if (getenv ("POSIXLY_CORRECT") != NULL)
|
|
||||||
ordering = REQUIRE_ORDER;
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
ordering = PERMUTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextchar == NULL || *nextchar == '\0')
|
|
||||||
{
|
|
||||||
if (ordering == PERMUTE)
|
|
||||||
{
|
|
||||||
/* If we have just processed some options following some non-options,
|
|
||||||
exchange them so that the options come first. */
|
|
||||||
|
|
||||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
|
||||||
exchange (argv);
|
|
||||||
else if (last_nonopt != optind)
|
|
||||||
first_nonopt = optind;
|
|
||||||
|
|
||||||
/* Now skip any additional non-options
|
|
||||||
and extend the range of non-options previously skipped. */
|
|
||||||
|
|
||||||
while (optind < argc
|
|
||||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
|
||||||
#ifdef GETOPT_COMPAT
|
|
||||||
&& (longopts == NULL
|
|
||||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
|
||||||
#endif /* GETOPT_COMPAT */
|
|
||||||
)
|
|
||||||
optind++;
|
|
||||||
last_nonopt = optind;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Special ARGV-element `--' means premature end of options.
|
|
||||||
Skip it like a null option,
|
|
||||||
then exchange with previous non-options as if it were an option,
|
|
||||||
then skip everything else like a non-option. */
|
|
||||||
|
|
||||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
|
||||||
{
|
|
||||||
optind++;
|
|
||||||
|
|
||||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
|
||||||
exchange (argv);
|
|
||||||
else if (first_nonopt == last_nonopt)
|
|
||||||
first_nonopt = optind;
|
|
||||||
last_nonopt = argc;
|
|
||||||
|
|
||||||
optind = argc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we have done all the ARGV-elements, stop the scan
|
|
||||||
and back over any non-options that we skipped and permuted. */
|
|
||||||
|
|
||||||
if (optind == argc)
|
|
||||||
{
|
|
||||||
/* Set the next-arg-index to point at the non-options
|
|
||||||
that we previously skipped, so the caller will digest them. */
|
|
||||||
if (first_nonopt != last_nonopt)
|
|
||||||
optind = first_nonopt;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we have come to a non-option and did not permute it,
|
|
||||||
either stop the scan or describe it to the caller and pass it by. */
|
|
||||||
|
|
||||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
|
|
||||||
#ifdef GETOPT_COMPAT
|
|
||||||
&& (longopts == NULL
|
|
||||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
|
||||||
#endif /* GETOPT_COMPAT */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (ordering == REQUIRE_ORDER)
|
|
||||||
return EOF;
|
|
||||||
optarg = argv[optind++];
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We have found another option-ARGV-element.
|
|
||||||
Start decoding its characters. */
|
|
||||||
|
|
||||||
nextchar = (argv[optind] + 1
|
|
||||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (longopts != NULL
|
|
||||||
&& ((argv[optind][0] == '-'
|
|
||||||
&& (argv[optind][1] == '-' || long_only))
|
|
||||||
#ifdef GETOPT_COMPAT
|
|
||||||
|| argv[optind][0] == '+'
|
|
||||||
#endif /* GETOPT_COMPAT */
|
|
||||||
))
|
|
||||||
{
|
|
||||||
const struct option *p;
|
|
||||||
char *s = nextchar;
|
|
||||||
int exact = 0;
|
|
||||||
int ambig = 0;
|
|
||||||
const struct option *pfound = NULL;
|
|
||||||
int indfound = 0;
|
|
||||||
int needexact = 0;
|
|
||||||
|
|
||||||
/* allow `--option#value' because you cannout assign a '='
|
|
||||||
to an environment variable under DOS command.com */
|
|
||||||
while (*s && *s != '=' && * s != '#')
|
|
||||||
s++;
|
|
||||||
|
|
||||||
/* Test all options for either exact match or abbreviated matches. */
|
|
||||||
for (p = longopts, option_index = 0; p->name;
|
|
||||||
p++, option_index++)
|
|
||||||
if (!strncmp (p->name, nextchar, (unsigned) (s - nextchar)))
|
|
||||||
{
|
|
||||||
if (p->has_arg & 0x10)
|
|
||||||
needexact = 1;
|
|
||||||
if ((unsigned) (s - nextchar) == strlen (p->name))
|
|
||||||
{
|
|
||||||
/* Exact match found. */
|
|
||||||
pfound = p;
|
|
||||||
indfound = option_index;
|
|
||||||
exact = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (pfound == NULL)
|
|
||||||
{
|
|
||||||
/* First nonexact match found. */
|
|
||||||
pfound = p;
|
|
||||||
indfound = option_index;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* Second nonexact match found. */
|
|
||||||
ambig = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* don't allow nonexact longoptions */
|
|
||||||
if (needexact && !exact)
|
|
||||||
{
|
|
||||||
if (opterr)
|
|
||||||
fprintf (stderr, "%s: unrecognized option `%s'\n",
|
|
||||||
PROGNAME(argv[0]), argv[optind]);
|
|
||||||
nextchar += strlen (nextchar);
|
|
||||||
optind++;
|
|
||||||
return BAD_OPTION;
|
|
||||||
}
|
|
||||||
if (ambig && !exact)
|
|
||||||
{
|
|
||||||
if (opterr)
|
|
||||||
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
|
||||||
PROGNAME(argv[0]), argv[optind]);
|
|
||||||
nextchar += strlen (nextchar);
|
|
||||||
optind++;
|
|
||||||
return BAD_OPTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pfound != NULL)
|
|
||||||
{
|
|
||||||
int have_arg = (s[0] != '\0');
|
|
||||||
if (have_arg && (pfound->has_arg & 0xf))
|
|
||||||
have_arg = (s[1] != '\0');
|
|
||||||
option_index = indfound;
|
|
||||||
optind++;
|
|
||||||
if (have_arg)
|
|
||||||
{
|
|
||||||
/* Don't test has_arg with >, because some C compilers don't
|
|
||||||
allow it to be used on enums. */
|
|
||||||
if (pfound->has_arg & 0xf)
|
|
||||||
optarg = s + 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (opterr)
|
|
||||||
{
|
|
||||||
if (argv[optind - 1][1] == '-')
|
|
||||||
/* --option */
|
|
||||||
fprintf (stderr,
|
|
||||||
"%s: option `--%s' doesn't allow an argument\n",
|
|
||||||
PROGNAME(argv[0]), pfound->name);
|
|
||||||
else
|
|
||||||
/* +option or -option */
|
|
||||||
fprintf (stderr,
|
|
||||||
"%s: option `%c%s' doesn't allow an argument\n",
|
|
||||||
PROGNAME(argv[0]), argv[optind - 1][0], pfound->name);
|
|
||||||
}
|
|
||||||
nextchar += strlen (nextchar);
|
|
||||||
return BAD_OPTION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((pfound->has_arg & 0xf) == 1)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
if (optind < argc)
|
|
||||||
#else
|
|
||||||
if (optind < argc && (pfound->has_arg & 0x20) == 0)
|
|
||||||
#endif
|
|
||||||
optarg = argv[optind++];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (opterr)
|
|
||||||
fprintf (stderr, "%s: option `--%s%s' requires an argument\n",
|
|
||||||
PROGNAME(argv[0]), pfound->name,
|
|
||||||
(pfound->has_arg & 0x20) ? "=" : "");
|
|
||||||
nextchar += strlen (nextchar);
|
|
||||||
return optstring[0] == ':' ? ':' : BAD_OPTION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nextchar += strlen (nextchar);
|
|
||||||
if (longind != NULL)
|
|
||||||
*longind = option_index;
|
|
||||||
if (pfound->flag)
|
|
||||||
{
|
|
||||||
*(pfound->flag) = pfound->val;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return pfound->val;
|
|
||||||
}
|
|
||||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
|
||||||
or the option starts with '--' or is not a valid short
|
|
||||||
option, then it's an error.
|
|
||||||
Otherwise interpret it as a short option. */
|
|
||||||
if (!long_only || argv[optind][1] == '-'
|
|
||||||
#ifdef GETOPT_COMPAT
|
|
||||||
|| argv[optind][0] == '+'
|
|
||||||
#endif /* GETOPT_COMPAT */
|
|
||||||
|| strchr (optstring, *nextchar) == NULL)
|
|
||||||
{
|
|
||||||
if (opterr)
|
|
||||||
{
|
|
||||||
if (argv[optind][1] == '-')
|
|
||||||
/* --option */
|
|
||||||
fprintf (stderr, "%s: unrecognized option `--%s'\n",
|
|
||||||
PROGNAME(argv[0]), nextchar);
|
|
||||||
else
|
|
||||||
/* +option or -option */
|
|
||||||
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
|
||||||
PROGNAME(argv[0]), argv[optind][0], nextchar);
|
|
||||||
}
|
|
||||||
nextchar = empty_string;
|
|
||||||
optind++;
|
|
||||||
return BAD_OPTION;
|
|
||||||
}
|
|
||||||
(void) &ambig; /* UNUSED */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look at and handle the next option-character. */
|
|
||||||
|
|
||||||
{
|
|
||||||
char c = *nextchar++;
|
|
||||||
const char *temp = strchr (optstring, c);
|
|
||||||
|
|
||||||
/* Increment `optind' when we start to process its last character. */
|
|
||||||
if (*nextchar == '\0')
|
|
||||||
++optind;
|
|
||||||
|
|
||||||
if (temp == NULL || c == ':')
|
|
||||||
{
|
|
||||||
if (opterr)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
if (c < 040 || c >= 0177)
|
|
||||||
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
|
||||||
PROGNAME(argv[0]), c);
|
|
||||||
else
|
|
||||||
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", PROGNAME(argv[0]), c);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
optopt = c;
|
|
||||||
return BAD_OPTION;
|
|
||||||
}
|
|
||||||
if (temp[1] == ':')
|
|
||||||
{
|
|
||||||
if (temp[2] == ':')
|
|
||||||
{
|
|
||||||
/* This is an option that accepts an argument optionally. */
|
|
||||||
if (*nextchar != '\0')
|
|
||||||
{
|
|
||||||
optarg = nextchar;
|
|
||||||
optind++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
optarg = 0;
|
|
||||||
nextchar = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This is an option that requires an argument. */
|
|
||||||
if (*nextchar != '\0')
|
|
||||||
{
|
|
||||||
optarg = nextchar;
|
|
||||||
/* If we end this ARGV-element by taking the rest as an arg,
|
|
||||||
we must advance to the next element now. */
|
|
||||||
optind++;
|
|
||||||
}
|
|
||||||
else if (optind == argc)
|
|
||||||
{
|
|
||||||
if (opterr)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
|
||||||
PROGNAME(argv[0]), c);
|
|
||||||
#else
|
|
||||||
/* 1003.2 specifies the format of this message. */
|
|
||||||
fprintf (stderr, "%s: option requires an argument -- %c\n",
|
|
||||||
PROGNAME(argv[0]), c);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
optopt = c;
|
|
||||||
if (optstring[0] == ':')
|
|
||||||
c = ':';
|
|
||||||
else
|
|
||||||
c = BAD_OPTION;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* We already incremented `optind' once;
|
|
||||||
increment it again when taking next ARGV-elt as argument. */
|
|
||||||
optarg = argv[optind++];
|
|
||||||
nextchar = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int mfx_getopt(int argc, char **argv, const char *optstring)
|
|
||||||
{
|
|
||||||
return _getopt_internal (argc, argv, optstring,
|
|
||||||
(const struct option *) 0,
|
|
||||||
(int *) 0,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int mfx_getopt_long(int argc, char **argv, const char *options,
|
|
||||||
const struct option *long_options, int *opt_index)
|
|
||||||
{
|
|
||||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TEST
|
|
||||||
|
|
||||||
/* Compile with -DTEST to make an executable for use in testing
|
|
||||||
the above definition of `getopt'. */
|
|
||||||
|
|
||||||
int
|
|
||||||
main (argc, argv)
|
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
int digit_optind = 0;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
int this_option_optind = optind ? optind : 1;
|
|
||||||
|
|
||||||
c = getopt (argc, argv, "abc:d:0123456789");
|
|
||||||
if (c == EOF)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
case '8':
|
|
||||||
case '9':
|
|
||||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
|
||||||
printf ("digits occur in two different argv-elements.\n");
|
|
||||||
digit_optind = this_option_optind;
|
|
||||||
printf ("option %c\n", c);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'a':
|
|
||||||
printf ("option a\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'b':
|
|
||||||
printf ("option b\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'c':
|
|
||||||
printf ("option c with value `%s'\n", optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BAD_OPTION:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optind < argc)
|
|
||||||
{
|
|
||||||
printf ("non-option ARGV-elements: ");
|
|
||||||
while (optind < argc)
|
|
||||||
printf ("%s ", argv[optind++]);
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
exit (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* TEST */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
vi:ts=4:et:nowrap
|
|
||||||
*/
|
|
||||||
|
|
||||||
-102
@@ -1,102 +0,0 @@
|
|||||||
/* Declarations for getopt.
|
|
||||||
Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
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 the
|
|
||||||
Free Software Foundation; either version 2, 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; if not, write to the Free Software
|
|
||||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|
||||||
|
|
||||||
#ifndef __MFX_GETOPT_H
|
|
||||||
#define __MFX_GETOPT_H 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
/* extern "C" { */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* For communication from `getopt' to the caller.
|
|
||||||
When `getopt' finds an option that takes an argument,
|
|
||||||
the argument value is returned here.
|
|
||||||
Also, when `ordering' is RETURN_IN_ORDER,
|
|
||||||
each non-option ARGV-element is returned here. */
|
|
||||||
|
|
||||||
extern char *mfx_optarg;
|
|
||||||
|
|
||||||
/* Index in ARGV of the next element to be scanned.
|
|
||||||
This is used for communication to and from the caller
|
|
||||||
and for communication between successive calls to `getopt'.
|
|
||||||
|
|
||||||
On entry to `getopt', zero means this is the first call; initialize.
|
|
||||||
|
|
||||||
When `getopt' returns EOF, this is the index of the first of the
|
|
||||||
non-option elements that the caller should itself scan.
|
|
||||||
|
|
||||||
Otherwise, `optind' communicates from one call to the next
|
|
||||||
how much of ARGV has been scanned so far. */
|
|
||||||
|
|
||||||
extern int mfx_optind;
|
|
||||||
|
|
||||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
|
||||||
for unrecognized options. */
|
|
||||||
|
|
||||||
extern int mfx_opterr;
|
|
||||||
|
|
||||||
/* Set to an option character which was unrecognized. */
|
|
||||||
|
|
||||||
extern int mfx_optopt;
|
|
||||||
|
|
||||||
/* Describe the long-named options requested by the application.
|
|
||||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
|
||||||
of `struct option' terminated by an element containing a name which is
|
|
||||||
zero.
|
|
||||||
|
|
||||||
The field `has_arg' is:
|
|
||||||
no_argument (or 0) if the option does not take an argument,
|
|
||||||
required_argument (or 1) if the option requires an argument,
|
|
||||||
optional_argument (or 2) if the option takes an optional argument.
|
|
||||||
|
|
||||||
If the field `flag' is not NULL, it points to a variable that is set
|
|
||||||
to the value given in the field `val' when the option is found, but
|
|
||||||
left unchanged if the option is not found.
|
|
||||||
|
|
||||||
To have a long-named option do something other than set an `int' to
|
|
||||||
a compiled-in constant, such as set a value from `optarg', set the
|
|
||||||
option's `flag' field to zero and its `val' field to a nonzero
|
|
||||||
value (the equivalent single-letter option character, if there is
|
|
||||||
one). For long options that have a zero `flag' field, `getopt'
|
|
||||||
returns the contents of the `val' field. */
|
|
||||||
|
|
||||||
struct mfx_option
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
/* has_arg can't be an enum because some compilers complain about
|
|
||||||
type mismatches in all the code that assumes it is an int. */
|
|
||||||
int has_arg;
|
|
||||||
int *flag;
|
|
||||||
int val;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
|
||||||
|
|
||||||
#define mfx_no_argument 0
|
|
||||||
#define mfx_required_argument 1
|
|
||||||
#define mfx_optional_argument 2
|
|
||||||
#define mfx_exact_argument 0x10 /* no abbrev. */
|
|
||||||
|
|
||||||
int mfx_getopt(int argc, char **argv, const char *shortopts);
|
|
||||||
int mfx_getopt_long(int argc, char **argv, const char *shortopts,
|
|
||||||
const struct mfx_option *longopts, int *longind);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
/* } */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __MFX_GETOPT_H */
|
|
||||||
+38
-19
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_OPTIONS_H
|
#ifndef __UPX_OPTIONS_H
|
||||||
#define __UPX_OPTIONS_H
|
#define __UPX_OPTIONS_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -45,13 +45,25 @@ enum {
|
|||||||
struct options_t {
|
struct options_t {
|
||||||
int cmd;
|
int cmd;
|
||||||
|
|
||||||
|
// mp (meta) options
|
||||||
|
int mp_compress_task;
|
||||||
|
bool mp_query_format;
|
||||||
|
bool mp_query_num_tasks;
|
||||||
|
|
||||||
// compression options
|
// compression options
|
||||||
int method;
|
int method;
|
||||||
int level; // compression level 1..10
|
bool method_lzma_seen;
|
||||||
int filter; // preferred filter from Packer::getFilters()
|
bool method_nrv2b_seen;
|
||||||
bool all_methods; // try all available compression methods ?
|
bool method_nrv2d_seen;
|
||||||
bool all_filters; // try all available filters ?
|
bool method_nrv2e_seen;
|
||||||
bool no_filter; // force no filter
|
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
|
// other options
|
||||||
int backup;
|
int backup;
|
||||||
@@ -62,6 +74,9 @@ struct options_t {
|
|||||||
bool no_env;
|
bool no_env;
|
||||||
bool no_progress;
|
bool no_progress;
|
||||||
const char *output_name;
|
const char *output_name;
|
||||||
|
bool preserve_mode;
|
||||||
|
bool preserve_ownership;
|
||||||
|
bool preserve_timestamp;
|
||||||
int small;
|
int small;
|
||||||
int verbose;
|
int verbose;
|
||||||
bool to_stdout;
|
bool to_stdout;
|
||||||
@@ -69,6 +84,7 @@ struct options_t {
|
|||||||
// debug options
|
// debug options
|
||||||
struct {
|
struct {
|
||||||
int debug_level;
|
int debug_level;
|
||||||
|
bool disable_random_id; // for Packer::getRandomId()
|
||||||
const char *dump_stub_loader;
|
const char *dump_stub_loader;
|
||||||
char fake_stub_version[4+1]; // for internal debugging
|
char fake_stub_version[4+1]; // for internal debugging
|
||||||
char fake_stub_year[4+1]; // for internal debugging
|
char fake_stub_year[4+1]; // for internal debugging
|
||||||
@@ -82,16 +98,14 @@ struct options_t {
|
|||||||
};
|
};
|
||||||
int overlay;
|
int overlay;
|
||||||
|
|
||||||
// compression runtime parameters - see struct ucl_compress_config_t
|
// compression runtime parameters - see struct XXX_compress_config_t
|
||||||
struct {
|
struct crp_t {
|
||||||
upx_uint max_offset;
|
lzma_compress_config_t crp_lzma;
|
||||||
upx_uint max_match;
|
ucl_compress_config_t crp_ucl;
|
||||||
int s_level;
|
zlib_compress_config_t crp_zlib;
|
||||||
int h_level;
|
void reset() { crp_lzma.reset(); crp_ucl.reset(); crp_zlib.reset(); }
|
||||||
int p_level;
|
};
|
||||||
int c_flags;
|
crp_t crp;
|
||||||
upx_uint m_size;
|
|
||||||
} crp;
|
|
||||||
|
|
||||||
// CPU
|
// CPU
|
||||||
enum {
|
enum {
|
||||||
@@ -120,6 +134,7 @@ struct options_t {
|
|||||||
bool boot_only;
|
bool boot_only;
|
||||||
bool no_align;
|
bool no_align;
|
||||||
bool do_8bit;
|
bool do_8bit;
|
||||||
|
bool do_8mib;
|
||||||
} ps1_exe;
|
} ps1_exe;
|
||||||
struct {
|
struct {
|
||||||
unsigned blocksize;
|
unsigned blocksize;
|
||||||
@@ -127,6 +142,8 @@ struct options_t {
|
|||||||
bool is_ptinterp; // is PT_INTERP, so don't adjust auxv_t
|
bool is_ptinterp; // is PT_INTERP, so don't adjust auxv_t
|
||||||
bool use_ptinterp; // use PT_INTERP /opt/upx/run
|
bool use_ptinterp; // use PT_INTERP /opt/upx/run
|
||||||
bool make_ptinterp; // make PT_INTERP [ignore current file!]
|
bool make_ptinterp; // make PT_INTERP [ignore current file!]
|
||||||
|
bool unmap_all_pages; // thus /proc/self/exe vanishes
|
||||||
|
unsigned char osabi0; // replacement if 0==.e_ident[EI_OSABI]
|
||||||
enum { SCRIPT_MAX = 32 };
|
enum { SCRIPT_MAX = 32 };
|
||||||
const char *script_name;
|
const char *script_name;
|
||||||
} o_unix;
|
} o_unix;
|
||||||
@@ -141,6 +158,8 @@ struct options_t {
|
|||||||
int strip_relocs;
|
int strip_relocs;
|
||||||
const char *keep_resource;
|
const char *keep_resource;
|
||||||
} win32_pe;
|
} win32_pe;
|
||||||
|
|
||||||
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct options_t *opt;
|
extern struct options_t *opt;
|
||||||
|
|||||||
+138
-1523
File diff suppressed because it is too large
Load Diff
+15
-198
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,231 +21,48 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_ARMPE_H
|
#ifndef __UPX_P_ARMPE_H
|
||||||
#define __UPX_P_ARMPE_H
|
#define __UPX_P_ARMPE_H 1
|
||||||
|
|
||||||
|
|
||||||
class PackArmPe_Interval;
|
|
||||||
class PackArmPe_Reloc;
|
|
||||||
class PackArmPe_Resource;
|
|
||||||
class PackArmPe_Export;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// arm/pe
|
// arm/pe
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PackArmPe : public Packer
|
class PackArmPe : public PeFile
|
||||||
{
|
{
|
||||||
typedef Packer super;
|
typedef PeFile super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PackArmPe(InputFile *f);
|
PackArmPe(InputFile *f);
|
||||||
~PackArmPe();
|
virtual ~PackArmPe();
|
||||||
virtual int getVersion() const { return 13; }
|
|
||||||
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
|
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
|
||||||
virtual const char *getName() const { return "arm/pe"; }
|
virtual const char *getName() const { return "arm/pe"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "arm-wince.pe"; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
virtual void pack(OutputFile *fo);
|
virtual void pack(OutputFile *fo);
|
||||||
virtual void unpack(OutputFile *fo);
|
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual int canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
// unpacker capabilities
|
|
||||||
virtual bool canUnpackVersion(int version) const
|
|
||||||
{ return version == 13; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int readFileHeader();
|
virtual void buildLoader(const Filter *ft);
|
||||||
virtual bool testUnpackVersion(int version) const;
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual unsigned processImports();
|
||||||
|
virtual void processImports(unsigned, unsigned);
|
||||||
|
virtual void rebuildImports(upx_byte *&);
|
||||||
|
|
||||||
unsigned pe_offset;
|
virtual void processTls(Interval *);
|
||||||
|
|
||||||
unsigned processImports();
|
|
||||||
void processImports(unsigned, unsigned);
|
|
||||||
void rebuildImports(upx_byte *&);
|
|
||||||
upx_byte *oimport;
|
|
||||||
unsigned soimport;
|
|
||||||
upx_byte *oimpdlls;
|
|
||||||
unsigned soimpdlls;
|
|
||||||
|
|
||||||
void processRelocs();
|
|
||||||
void processRelocs(PackArmPe_Reloc *);
|
|
||||||
void rebuildRelocs(upx_byte *&);
|
|
||||||
upx_byte *orelocs;
|
|
||||||
unsigned sorelocs;
|
|
||||||
upx_byte *oxrelocs;
|
|
||||||
unsigned soxrelocs;
|
|
||||||
|
|
||||||
void processExports(PackArmPe_Export *);
|
|
||||||
void processExports(PackArmPe_Export *,unsigned);
|
|
||||||
void rebuildExports();
|
|
||||||
upx_byte *oexport;
|
|
||||||
unsigned soexport;
|
|
||||||
|
|
||||||
void processResources(PackArmPe_Resource *);
|
|
||||||
void processResources(PackArmPe_Resource *, unsigned);
|
|
||||||
void rebuildResources(upx_byte *&);
|
|
||||||
upx_byte *oresources;
|
|
||||||
unsigned soresources;
|
|
||||||
|
|
||||||
void processTls(PackArmPe_Interval *);
|
|
||||||
void processTls(PackArmPe_Reloc *,const PackArmPe_Interval *,unsigned);
|
|
||||||
void rebuildTls();
|
|
||||||
upx_byte *otls;
|
|
||||||
unsigned sotls;
|
|
||||||
|
|
||||||
unsigned stripDebug(unsigned);
|
|
||||||
|
|
||||||
unsigned icondir_offset;
|
|
||||||
int icondir_count;
|
|
||||||
|
|
||||||
bool importbyordinal;
|
|
||||||
bool kernel32ordinal;
|
|
||||||
unsigned tlsindex;
|
|
||||||
unsigned rvamin;
|
|
||||||
unsigned cimports; // rva of preprocessed imports
|
|
||||||
unsigned crelocs; // rva of preprocessed fixups
|
|
||||||
int big_relocs;
|
|
||||||
|
|
||||||
bool use_thumb_stub;
|
bool use_thumb_stub;
|
||||||
|
|
||||||
void createLinker(const void *pdata, int plen, int pinfo);
|
|
||||||
int rpatch_le32(void *b, int blen, const void *old, unsigned new_,
|
|
||||||
PackArmPe_Reloc &, unsigned);
|
|
||||||
|
|
||||||
struct pe_header_t
|
|
||||||
{
|
|
||||||
// 0x0
|
|
||||||
char _[4]; // pemagic
|
|
||||||
LE16 cpu;
|
|
||||||
LE16 objects;
|
|
||||||
char __[12]; // timestamp + reserved
|
|
||||||
LE16 opthdrsize;
|
|
||||||
LE16 flags;
|
|
||||||
// optional header
|
|
||||||
char ___[4]; // coffmagic + linkerversion
|
|
||||||
LE32 codesize;
|
|
||||||
// 0x20
|
|
||||||
LE32 datasize;
|
|
||||||
LE32 bsssize;
|
|
||||||
LE32 entry;
|
|
||||||
LE32 codebase;
|
|
||||||
// 0x30
|
|
||||||
LE32 database;
|
|
||||||
// nt specific fields
|
|
||||||
LE32 imagebase;
|
|
||||||
LE32 objectalign;
|
|
||||||
LE32 filealign; // should set to 0x200 ?
|
|
||||||
// 0x40
|
|
||||||
char ____[16]; // versions
|
|
||||||
// 0x50
|
|
||||||
LE32 imagesize;
|
|
||||||
LE32 headersize;
|
|
||||||
LE32 chksum; // should set to 0
|
|
||||||
LE16 subsystem;
|
|
||||||
LE16 dllflags;
|
|
||||||
// 0x60
|
|
||||||
char _____[20]; // stack + heap sizes
|
|
||||||
// 0x74
|
|
||||||
LE32 ddirsentries; // usually 16
|
|
||||||
|
|
||||||
struct ddirs_t
|
|
||||||
{
|
|
||||||
LE32 vaddr;
|
|
||||||
LE32 size;
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct ddirs_t ddirs[16];
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct pe_section_t
|
|
||||||
{
|
|
||||||
char name[8];
|
|
||||||
LE32 vsize;
|
|
||||||
LE32 vaddr;
|
|
||||||
LE32 size;
|
|
||||||
LE32 rawdataptr;
|
|
||||||
char _[12];
|
|
||||||
LE32 flags;
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
pe_header_t ih, oh;
|
|
||||||
pe_section_t *isection;
|
|
||||||
|
|
||||||
static unsigned virta2objnum (unsigned, pe_section_t *, unsigned);
|
|
||||||
unsigned tryremove (unsigned, unsigned);
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PEDIR_EXPORT = 0,
|
|
||||||
PEDIR_IMPORT = 1,
|
|
||||||
PEDIR_RESOURCE = 2,
|
|
||||||
PEDIR_EXCEPTION = 3, // Exception table
|
|
||||||
PEDIR_SEC = 4, // Certificate table (file pointer)
|
|
||||||
PEDIR_RELOC = 5,
|
|
||||||
PEDIR_DEBUG = 6,
|
|
||||||
PEDIR_COPYRIGHT = 7, // Architecture-specific data
|
|
||||||
PEDIR_GLOBALPTR = 8, // Global pointer
|
|
||||||
PEDIR_TLS = 9,
|
|
||||||
PEDIR_LOADCONF = 10, // Load Config Table
|
|
||||||
PEDIR_BOUNDIM = 11,
|
|
||||||
PEDIR_IAT = 12,
|
|
||||||
PEDIR_DELAYIMP = 13, // Delay Import Descriptor
|
|
||||||
PEDIR_COMRT = 14 // Com+ Runtime Header
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PEFL_CODE = 0x20,
|
|
||||||
PEFL_DATA = 0x40,
|
|
||||||
PEFL_BSS = 0x80,
|
|
||||||
PEFL_INFO = 0x200,
|
|
||||||
PEFL_EXTRELS = 0x01000000, // extended relocations
|
|
||||||
PEFL_DISCARD = 0x02000000,
|
|
||||||
PEFL_NOCACHE = 0x04000000,
|
|
||||||
PEFL_NOPAGE = 0x08000000,
|
|
||||||
PEFL_SHARED = 0x10000000,
|
|
||||||
PEFL_EXEC = 0x20000000,
|
|
||||||
PEFL_READ = 0x40000000,
|
|
||||||
PEFL_WRITE = 0x80000000
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
RELOCS_STRIPPED = 0x0001,
|
|
||||||
EXECUTABLE = 0x0002,
|
|
||||||
LNUM_STRIPPED = 0x0004,
|
|
||||||
LSYMS_STRIPPED = 0x0008,
|
|
||||||
AGGRESSIVE_TRIM = 0x0010,
|
|
||||||
TWO_GIGS_AWARE = 0x0020,
|
|
||||||
FLITTLE_ENDIAN = 0x0080,
|
|
||||||
BITS_32_MACHINE = 0x0100,
|
|
||||||
DEBUG_STRIPPED = 0x0200,
|
|
||||||
REMOVABLE_SWAP = 0x0400,
|
|
||||||
SYSTEM_PROGRAM = 0x1000,
|
|
||||||
DLL_FLAG = 0x2000,
|
|
||||||
FBIG_ENDIAN = 0x8000
|
|
||||||
};
|
|
||||||
|
|
||||||
// predefined resource types
|
|
||||||
enum {
|
|
||||||
RT_CURSOR = 1, RT_BITMAP, RT_ICON, RT_MENU, RT_DIALOG, RT_STRING,
|
|
||||||
RT_FONTDIR, RT_FONT, RT_ACCELERATOR, RT_RCDATA, RT_MESSAGETABLE,
|
|
||||||
RT_GROUP_CURSOR, RT_GROUP_ICON = 14, RT_VERSION = 16, RT_DLGINCLUDE,
|
|
||||||
RT_PLUGPLAY = 19, RT_VXD, RT_ANICURSOR, RT_ANIICON, RT_HTML,
|
|
||||||
RT_MANIFEST, RT_LAST
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+34
-37
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -31,11 +31,12 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_com.h"
|
#include "p_com.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_com.h"
|
#include "stub/i086-dos16.com.h"
|
||||||
|
|
||||||
//#define TESTING
|
//#define TESTING 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -44,16 +45,11 @@ static const
|
|||||||
|
|
||||||
const int *PackCom::getCompressionMethods(int method, int level) const
|
const int *PackCom::getCompressionMethods(int method, int level) const
|
||||||
{
|
{
|
||||||
static const int m_nrv2b[] = { M_NRV2B_LE16, -1 };
|
static const int m_nrv2b[] = { M_NRV2B_LE16, M_END };
|
||||||
if (M_IS_NRV2B(method))
|
|
||||||
return m_nrv2b;
|
|
||||||
#if 0
|
#if 0
|
||||||
// NOT IMPLEMENTED
|
static const int m_nrv2d[] = { M_NRV2D_LE16, M_END };
|
||||||
static const int m_nrv2d[] = { M_NRV2D_LE16, -1 };
|
|
||||||
if (M_IS_NRV2D(method))
|
|
||||||
return m_nrv2d;
|
|
||||||
#endif
|
#endif
|
||||||
UNUSED(level);
|
UNUSED(method); UNUSED(level);
|
||||||
return m_nrv2b;
|
return m_nrv2b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +58,7 @@ const int *PackCom::getFilters() const
|
|||||||
{
|
{
|
||||||
static const int filters[] = {
|
static const int filters[] = {
|
||||||
0x06, 0x03, 0x04, 0x01, 0x05, 0x02,
|
0x06, 0x03, 0x04, 0x01, 0x05, 0x02,
|
||||||
-1 };
|
FT_END };
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,10 +94,9 @@ void PackCom::patchLoader(OutputFile *fo,
|
|||||||
upx_byte *loader, int lsize,
|
upx_byte *loader, int lsize,
|
||||||
unsigned calls)
|
unsigned calls)
|
||||||
{
|
{
|
||||||
const int filter_id = ph.filter;
|
|
||||||
const int e_len = getLoaderSectionStart("COMCUTPO");
|
const int e_len = getLoaderSectionStart("COMCUTPO");
|
||||||
const int d_len = lsize - e_len;
|
const int d_len = lsize - e_len;
|
||||||
assert(e_len > 0 && e_len < 256);
|
assert(e_len > 0 && e_len < 128);
|
||||||
assert(d_len > 0 && d_len < 256);
|
assert(d_len > 0 && d_len < 256);
|
||||||
|
|
||||||
const unsigned upper_end = ph.u_len + ph.overlap_overhead + d_len + 0x100;
|
const unsigned upper_end = ph.u_len + ph.overlap_overhead + d_len + 0x100;
|
||||||
@@ -111,22 +106,19 @@ void PackCom::patchLoader(OutputFile *fo,
|
|||||||
if (upper_end + stacksize > 0xfffe)
|
if (upper_end + stacksize > 0xfffe)
|
||||||
throwCantPack("file is too big for dos/com");
|
throwCantPack("file is too big for dos/com");
|
||||||
|
|
||||||
if (filter_id)
|
linker->defineSymbol("calltrick_calls", calls);
|
||||||
{
|
linker->defineSymbol("sp_limit", upper_end + stacksize);
|
||||||
assert(calls > 0);
|
linker->defineSymbol("bytes_to_copy", ph.c_len + lsize);
|
||||||
patch_le16(loader,lsize,"CT",calls);
|
linker->defineSymbol("copy_source", ph.c_len + lsize + 0x100);
|
||||||
}
|
linker->defineSymbol("copy_destination", upper_end);
|
||||||
|
linker->defineSymbol("neg_e_len", 0 - e_len);
|
||||||
|
linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead);
|
||||||
|
|
||||||
|
relocateLoader();
|
||||||
|
loader = getLoader();
|
||||||
|
|
||||||
|
// some day we could use the relocation stuff for patchPackHeader too
|
||||||
patchPackHeader(loader,e_len);
|
patchPackHeader(loader,e_len);
|
||||||
|
|
||||||
// NOTE: Depends on: decompr_start == cutpoint+1 !!!
|
|
||||||
patch_le16(loader,e_len,"JM",upper_end - 0xff - d_len - getLoaderSection("UPX1HEAD"));
|
|
||||||
loader[getLoaderSectionStart("COMSUBSI") - 1] = (upx_byte) -e_len;
|
|
||||||
patch_le16(loader,e_len,"DI",upper_end);
|
|
||||||
patch_le16(loader,e_len,"SI",ph.c_len + lsize + 0x100);
|
|
||||||
patch_le16(loader,e_len,"CX",ph.c_len + lsize);
|
|
||||||
patch_le16(loader,e_len,"SP",upper_end + stacksize);
|
|
||||||
|
|
||||||
// write loader + compressed file
|
// write loader + compressed file
|
||||||
fo->write(loader,e_len); // entry
|
fo->write(loader,e_len); // entry
|
||||||
fo->write(obuf,ph.c_len);
|
fo->write(obuf,ph.c_len);
|
||||||
@@ -139,10 +131,10 @@ void PackCom::patchLoader(OutputFile *fo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackCom::buildLoader(const Filter *ft)
|
void PackCom::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
initLoader(stub_i086_dos16_com, sizeof(stub_i086_dos16_com));
|
||||||
addLoader("COMMAIN1,COMSUBSI",
|
addLoader("COMMAIN1",
|
||||||
ph.first_offset_found == 1 ? "COMSBBBP" : "",
|
ph.first_offset_found == 1 ? "COMSBBBP" : "",
|
||||||
"COMPSHDI",
|
"COMPSHDI",
|
||||||
ft->id ? "COMCALLT" : "",
|
ft->id ? "COMCALLT" : "",
|
||||||
@@ -150,7 +142,7 @@ int PackCom::buildLoader(const Filter *ft)
|
|||||||
ft->id ? "NRVDDONE" : "NRVDRETU",
|
ft->id ? "NRVDDONE" : "NRVDRETU",
|
||||||
"NRVDECO1",
|
"NRVDECO1",
|
||||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
||||||
"NRVDECO2,NRV2B169",
|
"NRVDECO2",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
@@ -158,7 +150,6 @@ int PackCom::buildLoader(const Filter *ft)
|
|||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
addFilter16(ft->id);
|
addFilter16(ft->id);
|
||||||
}
|
}
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -206,7 +197,7 @@ void PackCom::pack(OutputFile *fo)
|
|||||||
ft.addvalue = getCallTrickOffset();
|
ft.addvalue = getCallTrickOffset();
|
||||||
// compress
|
// compress
|
||||||
const unsigned overlap_range = ph.u_len < 0xFE00 - ft.addvalue ? 32 : 0;
|
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();
|
const int lsize = getLoaderSize();
|
||||||
MemBuffer loader(lsize);
|
MemBuffer loader(lsize);
|
||||||
@@ -270,6 +261,12 @@ void PackCom::unpack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackCom::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et
|
vi:ts=4:et
|
||||||
*/
|
*/
|
||||||
|
|||||||
+10
-7
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,13 +21,13 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_COM_H
|
#ifndef __UPX_P_COM_H
|
||||||
#define __UPX_P_COM_H
|
#define __UPX_P_COM_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -38,10 +38,12 @@ class PackCom : public Packer
|
|||||||
{
|
{
|
||||||
typedef Packer super;
|
typedef Packer super;
|
||||||
public:
|
public:
|
||||||
PackCom(InputFile *f) : super(f) { }
|
PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_DOS_COM; }
|
virtual int getFormat() const { return UPX_F_DOS_COM; }
|
||||||
virtual const char *getName() const { return "dos/com"; }
|
virtual const char *getName() const { return "dos/com"; }
|
||||||
|
//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 *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
@@ -53,9 +55,10 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual unsigned getCallTrickOffset() const { return 0x100; }
|
virtual unsigned getCallTrickOffset() const { return 0x100; }
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
|
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
|
||||||
virtual void addFilter16(int filter_id);
|
virtual void addFilter16(int filter_id);
|
||||||
};
|
};
|
||||||
|
|||||||
+62
-39
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -31,11 +31,12 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_djgpp2.h"
|
#include "p_djgpp2.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_djgpp2.h"
|
#include "stub/i386-dos32.djgpp2.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/stubify.h"
|
#include "stub/i386-dos32.djgpp2-stubify.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -45,13 +46,14 @@ static const
|
|||||||
PackDjgpp2::PackDjgpp2(InputFile *f) :
|
PackDjgpp2::PackDjgpp2(InputFile *f) :
|
||||||
super(f), coff_offset(0)
|
super(f), coff_offset(0)
|
||||||
{
|
{
|
||||||
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40);
|
bele = &N_BELE_RTP::le_policy;
|
||||||
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8);
|
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40)
|
||||||
COMPILE_TIME_ASSERT(sizeof(stubify_stub) == 2048);
|
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8)
|
||||||
COMPILE_TIME_ASSERT_ALIGNOF(external_scnhdr_t, char)
|
COMPILE_TIME_ASSERT_ALIGNED1(external_scnhdr_t)
|
||||||
COMPILE_TIME_ASSERT_ALIGNOF(coff_header_t, char)
|
COMPILE_TIME_ASSERT_ALIGNED1(coff_header_t)
|
||||||
COMPILE_TIME_ASSERT(STUBIFY_STUB_ADLER32 == 0xbf689ba8);
|
COMPILE_TIME_ASSERT(sizeof(stub_i386_dos32_djgpp2_stubify) == 2048)
|
||||||
COMPILE_TIME_ASSERT(STUBIFY_STUB_CRC32 == 0x2ae982b2);
|
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_ADLER32 == 0xbf689ba8)
|
||||||
|
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_CRC32 == 0x2ae982b2)
|
||||||
//printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
|
//printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
|
||||||
//assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
//assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
||||||
}
|
}
|
||||||
@@ -66,30 +68,40 @@ const int *PackDjgpp2::getCompressionMethods(int method, int level) const
|
|||||||
const int *PackDjgpp2::getFilters() const
|
const int *PackDjgpp2::getFilters() const
|
||||||
{
|
{
|
||||||
static const int filters[] = {
|
static const int filters[] = {
|
||||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
|
||||||
-1 };
|
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
|
||||||
|
FT_END };
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
|
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned range,
|
unsigned range,
|
||||||
unsigned upper_limit) const
|
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;
|
o = (o + 0x3ff) &~ 0x1ff;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackDjgpp2::buildLoader(const Filter *ft)
|
Linker* PackDjgpp2::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PackDjgpp2::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
|
||||||
addLoader("IDENTSTR,DJ2MAIN1",
|
addLoader("IDENTSTR,DJ2MAIN1",
|
||||||
ft->id ? "DJCALLT1" : "",
|
ft->id ? "DJCALLT1" : "",
|
||||||
"DJ2MAIN2",
|
ph.first_offset_found == 1 ? "DJ2MAIN2" : "",
|
||||||
getDecompressor(),
|
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "",
|
||||||
|
getDecompressorSections(),
|
||||||
|
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "",
|
||||||
"DJ2BSS00",
|
"DJ2BSS00",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
@@ -99,8 +111,7 @@ int PackDjgpp2::buildLoader(const Filter *ft)
|
|||||||
addLoader("DJCALLT2", NULL);
|
addLoader("DJCALLT2", NULL);
|
||||||
addFilter32(ft->id);
|
addFilter32(ft->id);
|
||||||
}
|
}
|
||||||
addLoader("DJRETURN,+40DXXXX,UPX1HEAD", NULL);
|
addLoader("DJRETURN,+40C,UPX1HEAD", NULL);
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -120,8 +131,8 @@ void PackDjgpp2::handleStub(OutputFile *fo)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// "stubify" stub
|
// "stubify" stub
|
||||||
info("Adding stub: %ld bytes", (long)sizeof(stubify_stub));
|
info("Adding stub: %ld bytes", (long)sizeof(stub_i386_dos32_djgpp2_stubify));
|
||||||
fo->write(stubify_stub, sizeof(stubify_stub));
|
fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,33 +301,35 @@ void PackDjgpp2::pack(OutputFile *fo)
|
|||||||
ft.buf_len = usize - data->size;
|
ft.buf_len = usize - data->size;
|
||||||
ft.addvalue = text->vaddr - hdrsize;
|
ft.addvalue = text->vaddr - hdrsize;
|
||||||
// compress
|
// compress
|
||||||
compressWithFilters(&ft, 512);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
// limit stack size needed for runtime decompression
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||||
|
compressWithFilters(&ft, 512, &cconf);
|
||||||
|
|
||||||
// patch coff header #2
|
// patch coff header #2
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
|
assert(lsize % 4 == 0);
|
||||||
text->size = lsize; // new size of .text
|
text->size = lsize; // new size of .text
|
||||||
data->size = ph.c_len; // new size of .data
|
data->size = ph.c_len; // new size of .data
|
||||||
|
|
||||||
if (bss->size < ph.overlap_overhead) // give it a .bss
|
unsigned stack = 1024 + ph.overlap_overhead + getDecompressorWrkmemSize();
|
||||||
bss->size = ph.overlap_overhead;
|
stack = ALIGN_UP(stack, 16u);
|
||||||
|
if (bss->size < stack) // give it a .bss
|
||||||
|
bss->size = stack;
|
||||||
|
|
||||||
text->scnptr = sizeof(coff_hdr);
|
text->scnptr = sizeof(coff_hdr);
|
||||||
data->scnptr = text->scnptr + text->size;
|
data->scnptr = text->scnptr + text->size;
|
||||||
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + ph.overlap_overhead - 0x200;
|
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + ph.overlap_overhead - 0x200;
|
||||||
coff_hdr.f_nscns = 3;
|
coff_hdr.f_nscns = 3;
|
||||||
|
|
||||||
// prepare loader
|
linker->defineSymbol("original_entry", coff_hdr.a_entry);
|
||||||
MemBuffer loader(lsize);
|
linker->defineSymbol("length_of_bss", ph.overlap_overhead / 4);
|
||||||
memcpy(loader, getLoader(), lsize);
|
defineDecompressorSymbols();
|
||||||
|
|
||||||
// patch loader
|
|
||||||
patchPackHeader(loader, lsize);
|
|
||||||
patch_le32(loader, lsize, "ENTR", coff_hdr.a_entry);
|
|
||||||
patchFilter32(loader, lsize, &ft);
|
|
||||||
patch_le32(loader, lsize, "BSSL", ph.overlap_overhead / 4);
|
|
||||||
assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
|
assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
|
||||||
patch_le32(loader, lsize, "OUTP", text->vaddr - hdrsize);
|
linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size);
|
||||||
patch_le32(loader, lsize, "INPP", data->vaddr);
|
linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize);
|
||||||
|
linker->defineSymbol("start_of_compressed", data->vaddr);
|
||||||
|
defineFilterSymbols(&ft);
|
||||||
|
|
||||||
// we should not overwrite our decompressor during unpacking
|
// we should not overwrite our decompressor during unpacking
|
||||||
// the original coff header (which is put just before the
|
// the original coff header (which is put just before the
|
||||||
@@ -333,9 +346,19 @@ void PackDjgpp2::pack(OutputFile *fo)
|
|||||||
memcpy(obuf+data->size, "UPX", 3);
|
memcpy(obuf+data->size, "UPX", 3);
|
||||||
data->size = ALIGN_UP(data->size, 4);
|
data->size = ALIGN_UP(data->size, 4);
|
||||||
|
|
||||||
|
linker->defineSymbol("DJ2MAIN1", coff_hdr.a_entry);
|
||||||
|
relocateLoader();
|
||||||
|
|
||||||
|
// prepare loader
|
||||||
|
MemBuffer loader(lsize);
|
||||||
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
patchPackHeader(loader, lsize);
|
||||||
|
|
||||||
// write coff header, loader and compressed file
|
// write coff header, loader and compressed file
|
||||||
fo->write(&coff_hdr, sizeof(coff_hdr));
|
fo->write(&coff_hdr, sizeof(coff_hdr));
|
||||||
fo->write(loader, lsize);
|
fo->write(loader, lsize);
|
||||||
|
if (opt->debug.dump_stub_loader)
|
||||||
|
OutputFile::dump(opt->debug.dump_stub_loader, loader, lsize);
|
||||||
fo->write(obuf, data->size);
|
fo->write(obuf, data->size);
|
||||||
#if 0
|
#if 0
|
||||||
printf("%-13s: coff hdr : %8ld bytes\n", getName(), (long) sizeof(coff_hdr));
|
printf("%-13s: coff hdr : %8ld bytes\n", getName(), (long) sizeof(coff_hdr));
|
||||||
@@ -367,7 +390,7 @@ int PackDjgpp2::canUnpack()
|
|||||||
if (is_dlm(fi, coff_offset))
|
if (is_dlm(fi, coff_offset))
|
||||||
throwCantUnpack("can't handle DLM");
|
throwCantUnpack("can't handle DLM");
|
||||||
fi->seek(coff_offset, SEEK_SET);
|
fi->seek(coff_offset, SEEK_SET);
|
||||||
return readPackHeader(1024) ? 1 : -1;
|
return readPackHeader(4096) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+13
-14
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,13 +21,13 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_DJGPP2_H
|
#ifndef __UPX_P_DJGPP2_H
|
||||||
#define __UPX_P_DJGPP2_H
|
#define __UPX_P_DJGPP2_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -43,6 +43,7 @@ public:
|
|||||||
virtual int getVersion() const { return 14; }
|
virtual int getVersion() const { return 14; }
|
||||||
virtual int getFormat() const { return UPX_F_DJGPP2_COFF; }
|
virtual int getFormat() const { return UPX_F_DJGPP2_COFF; }
|
||||||
virtual const char *getName() const { return "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 *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
@@ -57,25 +58,24 @@ protected:
|
|||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
|
|
||||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned range = 0,
|
unsigned range = 0,
|
||||||
unsigned upper_limit = ~0u) const;
|
unsigned upper_limit = ~0u) const;
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
long coff_offset;
|
long coff_offset;
|
||||||
|
|
||||||
struct external_scnhdr_t
|
__packed_struct(external_scnhdr_t)
|
||||||
{
|
|
||||||
char _[12]; // name, paddr
|
char _[12]; // name, paddr
|
||||||
LE32 vaddr;
|
LE32 vaddr;
|
||||||
LE32 size;
|
LE32 size;
|
||||||
LE32 scnptr;
|
LE32 scnptr;
|
||||||
char misc[12]; // relptr, lnnoptr, nreloc, nlnno
|
char misc[12]; // relptr, lnnoptr, nreloc, nlnno
|
||||||
char __[4]; // flags
|
char __[4]; // flags
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct coff_header_t
|
__packed_struct(coff_header_t)
|
||||||
{
|
|
||||||
// ext_file_hdr
|
// ext_file_hdr
|
||||||
LE16 f_magic;
|
LE16 f_magic;
|
||||||
LE16 f_nscns;
|
LE16 f_nscns;
|
||||||
@@ -96,8 +96,7 @@ protected:
|
|||||||
|
|
||||||
// section headers
|
// section headers
|
||||||
external_scnhdr_t sh[3];
|
external_scnhdr_t sh[3];
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
coff_header_t coff_hdr;
|
coff_header_t coff_hdr;
|
||||||
external_scnhdr_t *text,*data,*bss;
|
external_scnhdr_t *text,*data,*bss;
|
||||||
|
|||||||
+312
-239
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,25 +21,43 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_ELF_H
|
#ifndef __UPX_P_ELF_H
|
||||||
#define __UPX_P_ELF_H
|
#define __UPX_P_ELF_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// Some ELF type definitinons
|
// N_Elf
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
namespace TT_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.
|
// The ELF file header. This appears at the start of every ELF file.
|
||||||
template <class Word, class Addr, class Off, class Half>
|
template <class TElfITypes>
|
||||||
struct Ehdr
|
__packed_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 */
|
unsigned char e_ident[16]; /* Magic number and other info */
|
||||||
Half e_type; /* Object file type */
|
Half e_type; /* Object file type */
|
||||||
Half e_machine; /* Architecture */
|
Half e_machine; /* Architecture */
|
||||||
@@ -55,71 +73,72 @@ struct Ehdr
|
|||||||
Half e_shnum; /* Section header table entry count */
|
Half e_shnum; /* Section header table entry count */
|
||||||
Half e_shstrndx; /* Section header string table index */
|
Half e_shstrndx; /* Section header string table index */
|
||||||
|
|
||||||
enum { // e_ident[]
|
# define WANT_EHDR_ENUM 1
|
||||||
EI_CLASS = 4,
|
# include "p_elf_enum.h"
|
||||||
EI_DATA = 5, /* Data encoding */
|
__packed_struct_end()
|
||||||
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_LINUX = 3
|
|
||||||
};
|
|
||||||
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_PPC = 20,
|
|
||||||
EM_PPC64 = 21,
|
|
||||||
EM_ARM = 40,
|
|
||||||
EM_X86_64 = 62,
|
|
||||||
};
|
|
||||||
enum { // e_version
|
|
||||||
EV_CURRENT = 1,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
|
|
||||||
template <class Word, class Addr>
|
template <class TElfITypes>
|
||||||
struct Dyn
|
__packed_struct(Dyn)
|
||||||
{
|
typedef typename TElfITypes::Xword Xword;
|
||||||
Word d_tag;
|
typedef typename TElfITypes::Addr Addr;
|
||||||
|
|
||||||
|
Xword d_tag;
|
||||||
Addr d_val;
|
Addr d_val;
|
||||||
|
|
||||||
enum { // d_tag
|
# define WANT_DYN_ENUM 1
|
||||||
DT_NULL = 0, /* End flag */
|
# include "p_elf_enum.h"
|
||||||
DT_NEEDED = 1, /* Name of needed library */
|
__packed_struct_end()
|
||||||
DT_HASH = 4, /* Hash table of symbol names */
|
|
||||||
DT_STRTAB = 5, /* String table */
|
|
||||||
DT_SYMTAB = 6, /* Symbol table */
|
|
||||||
DT_STRSZ = 10, /* Sizeof string table */
|
|
||||||
};
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
} // namespace TT_Elf
|
|
||||||
|
|
||||||
|
|
||||||
namespace TT_Elf32 {
|
template <class TElfITypes>
|
||||||
|
__packed_struct(Rel)
|
||||||
|
typedef typename TElfITypes::Xword Xword;
|
||||||
|
typedef typename TElfITypes::Addr Addr;
|
||||||
|
|
||||||
|
Addr r_offset;
|
||||||
|
Xword r_info;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
|
||||||
|
template <class TElfITypes>
|
||||||
|
__packed_struct(Rela)
|
||||||
|
typedef typename TElfITypes::Xword Xword;
|
||||||
|
typedef typename TElfITypes::Addr Addr;
|
||||||
|
|
||||||
|
Addr r_offset;
|
||||||
|
Xword r_info;
|
||||||
|
Xword r_addend;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
|
||||||
|
template <class TElfITypes>
|
||||||
|
__packed_struct(External_Note)
|
||||||
|
typedef typename TElfITypes::Word Word;
|
||||||
|
|
||||||
|
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
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace N_Elf
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// N_Elf32
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
namespace N_Elf32 {
|
||||||
|
|
||||||
|
template <class TElfITypes>
|
||||||
|
__packed_struct(Phdr)
|
||||||
|
typedef typename TElfITypes::Word Word;
|
||||||
|
typedef typename TElfITypes::Addr Addr;
|
||||||
|
typedef typename TElfITypes::Off Off;
|
||||||
|
|
||||||
// Program segment header.
|
|
||||||
template <class Word, class Addr, class Off>
|
|
||||||
struct Phdr
|
|
||||||
{
|
|
||||||
Word p_type; /* Segment type */
|
Word p_type; /* Segment type */
|
||||||
Off p_offset; /* Segment file offset */
|
Off p_offset; /* Segment file offset */
|
||||||
Addr p_vaddr; /* Segment virtual address */
|
Addr p_vaddr; /* Segment virtual address */
|
||||||
@@ -129,24 +148,17 @@ struct Phdr
|
|||||||
Word p_flags; /* Segment flags */
|
Word p_flags; /* Segment flags */
|
||||||
Word p_align; /* Segment alignment */
|
Word p_align; /* Segment alignment */
|
||||||
|
|
||||||
enum { // p_type
|
# define WANT_PHDR_ENUM 1
|
||||||
PT_LOAD = 1, /* Loadable program segment */
|
# include "p_elf_enum.h"
|
||||||
PT_DYNAMIC = 2, /* Dynamic linking information */
|
__packed_struct_end()
|
||||||
PT_INTERP = 3, /* Name of program interpreter */
|
|
||||||
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 */
|
|
||||||
};
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
template <class Word, class Addr, class Off>
|
template <class TElfITypes>
|
||||||
struct Shdr
|
__packed_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_name; /* Section name (string tbl index) */
|
||||||
Word sh_type; /* Section type */
|
Word sh_type; /* Section type */
|
||||||
Word sh_flags; /* Section flags */
|
Word sh_flags; /* Section flags */
|
||||||
@@ -158,93 +170,50 @@ struct Shdr
|
|||||||
Word sh_addralign; /* Section alignment */
|
Word sh_addralign; /* Section alignment */
|
||||||
Word sh_entsize; /* Entry size if section holds table */
|
Word sh_entsize; /* Entry size if section holds table */
|
||||||
|
|
||||||
enum { // sh_type
|
# define WANT_SHDR_ENUM 1
|
||||||
SHT_NULL = 0, /* Section header table entry unused */
|
# include "p_elf_enum.h"
|
||||||
SHT_PROGBITS = 1, /* Program data */
|
__packed_struct_end()
|
||||||
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 */
|
|
||||||
};
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
template <class TT16, class TT32, class TT64>
|
template <class TElfITypes>
|
||||||
struct Sym
|
__packed_struct(Sym)
|
||||||
{
|
typedef typename TElfITypes::Word Word;
|
||||||
TT32 st_name; /* symbol name (index into string table) */
|
typedef typename TElfITypes::Addr Addr;
|
||||||
TT32 st_value; /* symbol value */
|
typedef typename TElfITypes::Section Section;
|
||||||
TT32 st_size; /* symbol size */
|
|
||||||
|
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_info; /* symbol type and binding */
|
||||||
unsigned char st_other; /* symbol visibility */
|
unsigned char st_other; /* symbol visibility */
|
||||||
TT16 st_shndx; /* section index */
|
Section st_shndx; /* section index */
|
||||||
|
|
||||||
unsigned int st_bind(unsigned int x) const { return 0xf & (x>>4); }
|
# define WANT_SYM_ENUM 1
|
||||||
unsigned int st_type(unsigned int x) const { return 0xf & x ; }
|
# include "p_elf_enum.h"
|
||||||
unsigned char St_info(unsigned bind, unsigned type) const { return (bind<<4) + (0xf & type); }
|
|
||||||
|
|
||||||
enum { // st_bind (high 4 bits of st_info)
|
static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
|
||||||
STB_LOCAL = 0, /* Local symbol */
|
static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
|
||||||
STB_GLOBAL = 1, /* Global symbol */
|
static unsigned char make_st_info(unsigned bind, unsigned type)
|
||||||
STB_WEAK = 2, /* Weak symbol */
|
{ return (unsigned char) (((bind<<4) + (0xf & type)) & 0xff); }
|
||||||
};
|
__packed_struct_end()
|
||||||
|
|
||||||
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)
|
} // namespace N_Elf32
|
||||||
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 */
|
|
||||||
};
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
} // namespace TT_Elf32
|
/*************************************************************************
|
||||||
|
// N_Elf64
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
namespace TT_Elf64 {
|
namespace N_Elf64 {
|
||||||
|
|
||||||
|
template <class TElfITypes>
|
||||||
|
__packed_struct(Phdr)
|
||||||
|
typedef typename TElfITypes::Word Word;
|
||||||
|
typedef typename TElfITypes::Xword Xword;
|
||||||
|
typedef typename TElfITypes::Addr Addr;
|
||||||
|
typedef typename TElfITypes::Off Off;
|
||||||
|
|
||||||
// Program segment header.
|
|
||||||
template <class Word, class Xword, class Addr, class Off>
|
|
||||||
struct Phdr
|
|
||||||
{
|
|
||||||
Word p_type; /* Segment type */
|
Word p_type; /* Segment type */
|
||||||
Word p_flags; /* Segment flags */
|
Word p_flags; /* Segment flags */
|
||||||
Off p_offset; /* Segment file offset */
|
Off p_offset; /* Segment file offset */
|
||||||
@@ -254,24 +223,18 @@ struct Phdr
|
|||||||
Xword p_memsz; /* Segment size in memory */
|
Xword p_memsz; /* Segment size in memory */
|
||||||
Xword p_align; /* Segment alignment */
|
Xword p_align; /* Segment alignment */
|
||||||
|
|
||||||
enum { // p_type
|
# define WANT_PHDR_ENUM 1
|
||||||
PT_LOAD = 1, /* Loadable program segment */
|
# include "p_elf_enum.h"
|
||||||
PT_DYNAMIC = 2, /* Dynamic linking information */
|
__packed_struct_end()
|
||||||
PT_INTERP = 3, /* Name of program interpreter */
|
|
||||||
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 */
|
|
||||||
};
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
template <class Word, class Xword, class Addr, class Off>
|
template <class TElfITypes>
|
||||||
struct Shdr
|
__packed_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_name; /* Section name (string tbl index) */
|
||||||
Word sh_type; /* Section type */
|
Word sh_type; /* Section type */
|
||||||
Xword sh_flags; /* Section flags */
|
Xword sh_flags; /* Section flags */
|
||||||
@@ -283,84 +246,194 @@ struct Shdr
|
|||||||
Xword sh_addralign; /* Section alignment */
|
Xword sh_addralign; /* Section alignment */
|
||||||
Xword sh_entsize; /* Entry size if section holds table */
|
Xword sh_entsize; /* Entry size if section holds table */
|
||||||
|
|
||||||
enum { // sh_type
|
# define WANT_SHDR_ENUM 1
|
||||||
SHT_NULL = 0, /* Section header table entry unused */
|
# include "p_elf_enum.h"
|
||||||
SHT_PROGBITS = 1, /* Program data */
|
__packed_struct_end()
|
||||||
SHT_SYMTAB = 2, /* Symbol table */
|
|
||||||
SHT_STRTAB = 3, /* String table */
|
|
||||||
SHT_RELA = 4, /* Relocation entries with addends */
|
template <class TElfITypes>
|
||||||
SHT_HASH = 5, /* Symbol hash table */
|
__packed_struct(Sym)
|
||||||
SHT_DYNAMIC = 6, /* Dynamic linking information */
|
typedef typename TElfITypes::Word Word;
|
||||||
SHT_NOTE = 7, /* Notes */
|
typedef typename TElfITypes::Xword Xword;
|
||||||
SHT_NOBITS = 8, /* Program space with no data (bss) */
|
typedef typename TElfITypes::Addr Addr;
|
||||||
SHT_REL = 9, /* Relocation entries, no addends */
|
typedef typename TElfITypes::Section Section;
|
||||||
SHT_SHLIB = 10, /* Reserved */
|
|
||||||
SHT_DYNSYM = 11, /* Dynamic linker symbol table */
|
Word st_name; /* symbol name (index into string table) */
|
||||||
/* 12, 13 hole */
|
unsigned char st_info; /* symbol type and binding */
|
||||||
SHT_INIT_ARRAY = 14, /* Array of constructors */
|
unsigned char st_other; /* symbol visibility */
|
||||||
SHT_FINI_ARRAY = 15, /* Array of destructors */
|
Section st_shndx; /* section index */
|
||||||
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
|
Addr st_value; /* symbol value */
|
||||||
SHT_GROUP = 17, /* Section group */
|
Xword st_size; /* symbol size */
|
||||||
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
|
|
||||||
SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */
|
# define WANT_SYM_ENUM 1
|
||||||
};
|
# include "p_elf_enum.h"
|
||||||
}
|
|
||||||
__attribute_packed;
|
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 (unsigned char) (((bind<<4) + (0xf & type)) & 0xff); }
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace N_Elf64
|
||||||
|
|
||||||
} // namespace TT_Elf64
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// now for the actual types
|
// aggregate types into an ElfClass
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
typedef TT_Elf ::Ehdr<LE32,LE32,LE32,LE16> Elf_LE32_Ehdr;
|
namespace N_Elf {
|
||||||
typedef TT_Elf32::Phdr<LE32,LE32,LE32> Elf_LE32_Phdr;
|
|
||||||
typedef TT_Elf32::Shdr<LE32,LE32,LE32> Elf_LE32_Shdr;
|
|
||||||
typedef TT_Elf ::Dyn <LE32,LE32> Elf_LE32_Dyn;
|
|
||||||
typedef TT_Elf32::Sym <LE16,LE32,void> Elf_LE32_Sym;
|
|
||||||
|
|
||||||
typedef TT_Elf ::Ehdr<unsigned int,unsigned int,unsigned int,unsigned short> Elf32_Ehdr;
|
template <class TP>
|
||||||
typedef TT_Elf32::Phdr<unsigned int,unsigned int,unsigned int> Elf32_Phdr;
|
struct ElfClass_32
|
||||||
typedef TT_Elf32::Shdr<unsigned int,unsigned int,unsigned int> Elf32_Shdr;
|
{
|
||||||
typedef TT_Elf ::Dyn <unsigned int,unsigned int> Elf32_Dyn;
|
typedef TP BeLePolicy;
|
||||||
typedef TT_Elf32::Sym <unsigned short,unsigned int,void> Elf32_Sym;
|
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Ehdr) == 52)
|
// integral types (target endianness)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Phdr) == 32)
|
typedef typename TP::U16 TE16;
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40)
|
typedef typename TP::U32 TE32;
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8)
|
typedef typename TP::U64 TE64;
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16)
|
typedef N_Elf::ElfITypes<TE16, TE32, TE32, TE32, TE32> ElfITypes;
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Ehdr) == 52)
|
// ELF types
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Phdr) == 32)
|
typedef N_Elf ::Ehdr<ElfITypes> Ehdr;
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Shdr) == 40)
|
typedef N_Elf32::Phdr<ElfITypes> Phdr;
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Dyn) == 8)
|
typedef N_Elf32::Shdr<ElfITypes> Shdr;
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Sym) == 16)
|
typedef N_Elf ::Dyn <ElfITypes> Dyn;
|
||||||
|
typedef N_Elf ::Rel <ElfITypes> Rel;
|
||||||
|
typedef N_Elf ::Rela<ElfITypes> Rela;
|
||||||
|
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(Rel) == 8)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(Rela) == 12)
|
||||||
|
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(Rel)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(Rela)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(Sym)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef TT_Elf ::Ehdr<LE32,LE64,LE64,LE16> Elf_LE64_Ehdr;
|
template <class TP>
|
||||||
typedef TT_Elf64::Phdr<LE32,LE64,LE64,LE64> Elf_LE64_Phdr;
|
struct ElfClass_64
|
||||||
typedef TT_Elf64::Shdr<LE32,LE64,LE64,LE64> Elf_LE64_Shdr;
|
{
|
||||||
typedef TT_Elf ::Dyn <LE64,LE64> Elf_LE64_Dyn;
|
typedef TP BeLePolicy;
|
||||||
|
|
||||||
typedef TT_Elf ::Ehdr<unsigned int,unsigned long long,
|
// integral types (target endianness)
|
||||||
unsigned long long,unsigned short> Elf64_Ehdr;
|
typedef typename TP::U16 TE16;
|
||||||
typedef TT_Elf64::Phdr<unsigned int,unsigned long long,
|
typedef typename TP::U32 TE32;
|
||||||
unsigned long long,unsigned long long> Elf64_Phdr;
|
typedef typename TP::U64 TE64;
|
||||||
typedef TT_Elf64::Shdr<unsigned int,unsigned long long,
|
typedef N_Elf::ElfITypes<TE16, TE32, TE64, TE64, TE64> ElfITypes;
|
||||||
unsigned long long,unsigned long long> Elf64_Shdr;
|
|
||||||
typedef TT_Elf ::Dyn <unsigned long long,unsigned long long> Elf64_Dyn;
|
// 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_Elf ::Rel <ElfITypes> Rel;
|
||||||
|
typedef N_Elf ::Rela<ElfITypes> Rela;
|
||||||
|
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(Rel) == 16)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(Rela) == 24)
|
||||||
|
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(Rel)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(Rela)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(Sym)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Ehdr) == 64)
|
} // namespace N_Elf
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Phdr) == 56)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Shdr) == 64)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Dyn) == 16)
|
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Ehdr) == 64)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Phdr) == 56)
|
typedef N_Elf::ElfClass_32<N_BELE_CTP::HostPolicy> ElfClass_Host32;
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Shdr) == 64)
|
typedef N_Elf::ElfClass_64<N_BELE_CTP::HostPolicy> ElfClass_Host64;
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Dyn) == 16)
|
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::Rel Elf32_Rel;
|
||||||
|
typedef ElfClass_Host32::Rela Elf32_Rela;
|
||||||
|
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::Rel Elf64_Rel;
|
||||||
|
typedef ElfClass_Host64::Rela Elf64_Rela;
|
||||||
|
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::Rel Elf_BE32_Rel;
|
||||||
|
typedef ElfClass_BE32::Rela Elf_BE32_Rela;
|
||||||
|
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::Rel Elf_BE64_Rel;
|
||||||
|
typedef ElfClass_BE64::Rela Elf_BE64_Rela;
|
||||||
|
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::Rel Elf_LE32_Rel;
|
||||||
|
typedef ElfClass_LE32::Rela Elf_LE32_Rela;
|
||||||
|
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::Rel Elf_LE64_Rel;
|
||||||
|
typedef ElfClass_LE64::Rela Elf_LE64_Rela;
|
||||||
|
typedef ElfClass_LE64::Sym Elf_LE64_Sym;
|
||||||
|
typedef ElfClass_LE64::External_Note Elf_LE64_External_Note;
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|||||||
@@ -0,0 +1,201 @@
|
|||||||
|
/* p_elf_enum.h --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2010 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_RELA = 7, /* Relocations which do contain an addend */
|
||||||
|
DT_RELAENT = 9, /* Size of one RELA relocation */
|
||||||
|
DT_INIT = 12, /* Address of init function */
|
||||||
|
DT_REL = 17, /* Relocations which contain no addend */
|
||||||
|
DT_RELENT = 19, /* Size of one Rel relocation */
|
||||||
|
DT_STRSZ = 10, /* Sizeof string table */
|
||||||
|
DT_PLTREL = 20, /* Type of reloc in PLT */
|
||||||
|
DT_JMPREL = 23, /* Address of PLT relocs */
|
||||||
|
DT_CHECKSUM = 0x6ffffdf8, /* Only for prelink? */
|
||||||
|
DT_GNU_HASH = 0x6ffffef5, /* GNU-style hash table */
|
||||||
|
DT_VERSYM = 0x6ffffff0, /* version[] for each symbol */
|
||||||
|
DT_VERDEF = 0x6ffffffc, /* version definitions[] */
|
||||||
|
DT_VERNEEDED= 0x6ffffffe /* version[] needed */
|
||||||
|
};
|
||||||
|
#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
|
||||||
|
*/
|
||||||
|
|
||||||
+11
-11
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -94,13 +94,12 @@ void PackElks8086::readKernel()
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int PackElks8086::buildLoader(const Filter *ft)
|
void PackElks8086::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||||
// FIXME
|
// FIXME
|
||||||
UNUSED(ft);
|
UNUSED(ft);
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -113,7 +112,7 @@ void PackElks8086::pack(OutputFile *fo)
|
|||||||
ft.buf_len = ph.u_len;
|
ft.buf_len = ph.u_len;
|
||||||
ft.addvalue = kernel_entry;
|
ft.addvalue = kernel_entry;
|
||||||
// compress
|
// compress
|
||||||
compressWithFilters(&ft, overlap_range);
|
compressWithFilters(&ft, overlap_range, NULL_cconf);
|
||||||
|
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
MemBuffer loader(lsize);
|
MemBuffer loader(lsize);
|
||||||
@@ -122,10 +121,11 @@ void PackElks8086::pack(OutputFile *fo)
|
|||||||
patchPackHeader(loader, lsize);
|
patchPackHeader(loader, lsize);
|
||||||
#if 0
|
#if 0
|
||||||
// FIXME
|
// FIXME
|
||||||
patchFilter32(loader, lsize, &ft);
|
defineFilterSymbols(&ft);
|
||||||
patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
defineDecompressorSymbols();
|
||||||
patch_le32(loader, lsize, "KEIP", kernel_entry);
|
//patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
||||||
patch_le32(loader, lsize, "STAK", stack_during_uncompression);
|
//patch_le32(loader, lsize, "KEIP", kernel_entry);
|
||||||
|
//patch_le32(loader, lsize, "STAK", stack_during_uncompression);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
||||||
|
|||||||
+268
-113
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -31,9 +31,10 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_exe.h"
|
#include "p_exe.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_exe.h"
|
#include "stub/i086-dos16.exe.h"
|
||||||
|
|
||||||
#define RSFCRI 4096 // Reserved Space For Compressed Relocation Info
|
#define RSFCRI 4096 // Reserved Space For Compressed Relocation Info
|
||||||
#define MAXMATCH 0x2000
|
#define MAXMATCH 0x2000
|
||||||
@@ -49,14 +50,22 @@ static const
|
|||||||
PackExe::PackExe(InputFile *f) :
|
PackExe::PackExe(InputFile *f) :
|
||||||
super(f)
|
super(f)
|
||||||
{
|
{
|
||||||
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32);
|
bele = &N_BELE_RTP::le_policy;
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(exe_header_t)
|
||||||
ih_exesize = ih_imagesize = ih_overlay = 0;
|
ih_exesize = ih_imagesize = ih_overlay = 0;
|
||||||
|
stack_for_lzma = 0;
|
||||||
|
use_clear_dirty_stack = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int *PackExe::getCompressionMethods(int method, int level) const
|
const int *PackExe::getCompressionMethods(int method, int level) const
|
||||||
{
|
{
|
||||||
bool small = ih_imagesize <= 256*1024;
|
bool small = ih_imagesize <= 256*1024;
|
||||||
|
// disable lzma for "--brute" unless explicitly given "--lzma"
|
||||||
|
// WARNING: this side effect persists for later files!
|
||||||
|
if (opt->all_methods_use_lzma && !opt->method_lzma_seen)
|
||||||
|
opt->all_methods_use_lzma = false;
|
||||||
return Packer::getDefaultCompressionMethods_8(method, level, small);
|
return Packer::getDefaultCompressionMethods_8(method, level, small);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +81,7 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
|||||||
#define oh (*eh)
|
#define oh (*eh)
|
||||||
// fill new exe header
|
// fill new exe header
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
if (!opt->dos_exe.no_reloc)
|
if (!opt->dos_exe.no_reloc && !M_IS_LZMA(ph.method))
|
||||||
flag |= USEJUMP;
|
flag |= USEJUMP;
|
||||||
if (ih.relocs == 0)
|
if (ih.relocs == 0)
|
||||||
flag |= NORELOC;
|
flag |= NORELOC;
|
||||||
@@ -81,7 +90,16 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
|||||||
oh.ident = 'M' + 'Z' * 256;
|
oh.ident = 'M' + 'Z' * 256;
|
||||||
oh.headsize16 = 2;
|
oh.headsize16 = 2;
|
||||||
|
|
||||||
oh.sp = ih.sp > 0x200 ? (unsigned) 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;
|
unsigned destpara = (ph.u_len + ph.overlap_overhead - ph.c_len + 31) / 16;
|
||||||
oh.ss = ph.c_len/16 + destpara;
|
oh.ss = ph.c_len/16 + destpara;
|
||||||
@@ -93,67 +111,14 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
|||||||
|
|
||||||
if (oh.ss != ih.ss)
|
if (oh.ss != ih.ss)
|
||||||
flag |= SS;
|
flag |= SS;
|
||||||
if (oh.sp != ih.sp)
|
if (oh.sp != ih.sp || M_IS_LZMA(ph.method))
|
||||||
flag |= SP;
|
flag |= SP;
|
||||||
return flag;
|
return flag;
|
||||||
#undef oh
|
#undef oh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackExe::addLoaderEpilogue(int flag)
|
||||||
int PackExe::buildLoader(const Filter *)
|
|
||||||
{
|
{
|
||||||
struct exe_header_t tmp_oh;
|
|
||||||
int flag = fillExeHeader(&tmp_oh);
|
|
||||||
|
|
||||||
// prepare loader
|
|
||||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
|
||||||
if (device_driver)
|
|
||||||
addLoader("DEVICEENTRY", NULL);
|
|
||||||
addLoader("EXEENTRY",
|
|
||||||
device_driver ? "DEVICESUB" : "EXESUB",
|
|
||||||
"JNCDOCOPY",
|
|
||||||
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);
|
addLoader("EXEMAIN5", NULL);
|
||||||
if (relocsize)
|
if (relocsize)
|
||||||
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
|
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
|
||||||
@@ -176,7 +141,132 @@ int PackExe::buildLoader(const Filter *)
|
|||||||
"EXERETIP",
|
"EXERETIP",
|
||||||
NULL
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -235,6 +325,9 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||||||
const upx_byte *relocs, const unsigned nrelocs,
|
const upx_byte *relocs, const unsigned nrelocs,
|
||||||
upx_byte *crel, bool *has_9a)
|
upx_byte *crel, bool *has_9a)
|
||||||
{
|
{
|
||||||
|
if (opt->exact)
|
||||||
|
throwCantPackExact();
|
||||||
|
|
||||||
upx_byte * const crel_save = crel;
|
upx_byte * const crel_save = crel;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned seg_high = 0;
|
unsigned seg_high = 0;
|
||||||
@@ -309,7 +402,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
unsigned offs = addr - es*16;
|
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++)
|
for (t = di; t < offs-3; t++)
|
||||||
if (b[es*16+t] == 0x9a && get_le16(b+es*16+t+3) <= seg_high)
|
if (b[es*16+t] == 0x9a && get_le16(b+es*16+t+3) <= seg_high)
|
||||||
@@ -386,7 +479,7 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
for (ic = 0; ic < ih.relocs; ic++)
|
for (ic = 0; ic < ih.relocs; ic++)
|
||||||
{
|
{
|
||||||
unsigned jc = get_le32(wr+4*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);
|
qsort(wr,ih.relocs,4,le32_compare);
|
||||||
relocsize = optimize_relocs(ibuf, ih_imagesize, wr, ih.relocs, w, &has_9a);
|
relocsize = optimize_relocs(ibuf, ih_imagesize, wr, ih.relocs, w, &has_9a);
|
||||||
@@ -411,12 +504,17 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
ph.u_len = ih_imagesize + relocsize;
|
ph.u_len = ih_imagesize + relocsize;
|
||||||
// prepare filter
|
// prepare filter
|
||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
// compress
|
// compress (max_match = 8192)
|
||||||
compressWithFilters(&ft, 32, 0, NULL, 0, MAXMATCH);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
cconf.conf_ucl.max_match = MAXMATCH;
|
||||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||||
|
compressWithFilters(&ft, 32, &cconf);
|
||||||
|
|
||||||
#ifdef TESTING
|
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");
|
||||||
|
|
||||||
|
#if TESTING
|
||||||
if (opt->debug.debug_level)
|
if (opt->debug.debug_level)
|
||||||
{
|
{
|
||||||
printf("image+relocs %d -> %d\n",ih_imagesize+relocsize,ph.c_len);
|
printf("image+relocs %d -> %d\n",ih_imagesize+relocsize,ph.c_len);
|
||||||
@@ -480,72 +578,60 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
extra_info[eisize++] = (unsigned char) flag;
|
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
|
// patch loader
|
||||||
if (flag & USEJUMP)
|
if (flag & USEJUMP)
|
||||||
{
|
{
|
||||||
// I use a relocation entry to set the original cs
|
// I use a relocation entry to set the original cs
|
||||||
unsigned n = find_le32(loader,lsize,get_le32("IPCS"));
|
unsigned n = getLoaderSectionStart("EXEJUMPF") + 1;
|
||||||
patch_le32(loader,lsize,get_le32("IPCS"), ih.cs*0x10000 + ih.ip);
|
|
||||||
n += packedsize + 2;
|
n += packedsize + 2;
|
||||||
oh.relocs = 1;
|
oh.relocs = 1;
|
||||||
oh.firstreloc = (n&0xf) + ((n>>4)<<16);
|
oh.firstreloc = (n & 0xf) + ((n >> 4) << 16);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
patch_le16(loader,lsize,"IP",ih.ip);
|
|
||||||
if (ih.cs)
|
|
||||||
patch_le16(loader,lsize,"CS",ih.cs);
|
|
||||||
oh.relocs = 0;
|
oh.relocs = 0;
|
||||||
oh.firstreloc = ih.cs*0x10000 + ih.ip;
|
oh.firstreloc = ih.cs * 0x10000 + ih.ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
// g++ 3.1 does not like the following line...
|
// g++ 3.1 does not like the following line...
|
||||||
// oh.relocoffs = offsetof(exe_header_t, firstreloc);
|
// oh.relocoffs = offsetof(exe_header_t, firstreloc);
|
||||||
oh.relocoffs = ptr_diff(&oh.firstreloc, &oh);
|
oh.relocoffs = ptr_diff(&oh.firstreloc, &oh);
|
||||||
|
|
||||||
if (flag & SP)
|
linker->defineSymbol("destination_segment", oh.ss - ph.c_len / 16 - e_len / 16);
|
||||||
patch_le16(loader,lsize,"SP",ih.sp);
|
linker->defineSymbol("source_segment", e_len / 16 + (copysize - firstcopy) / 16);
|
||||||
if (flag & SS)
|
linker->defineSymbol("copy_offset", firstcopy - 2);
|
||||||
patch_le16(loader,lsize,"SS",ih.ss);
|
linker->defineSymbol("words_to_copy",firstcopy / 2);
|
||||||
if (relocsize)
|
|
||||||
patch_le16(loader,lsize,"RS",(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? 0 : MAXRELOCS) - relocsize);
|
|
||||||
|
|
||||||
patchPackHeader(loader,e_len);
|
linker->defineSymbol("exe_stack_sp", oh.sp);
|
||||||
|
linker->defineSymbol("exe_stack_ss", oh.ss);
|
||||||
patch_le16(loader,e_len,"BX",0x800F + 0x10*((packedsize&15)+1) - 0x10);
|
linker->defineSymbol("interrupt", get_le16(ibuf + 8));
|
||||||
patch_le16(loader,e_len,"BP",(packedsize&15)+1);
|
linker->defineSymbol("attribute", get_le16(ibuf + 4));
|
||||||
|
linker->defineSymbol("orig_strategy", get_le16(ibuf + 6));
|
||||||
unsigned destpara = oh.ss - ph.c_len/16;
|
|
||||||
patch_le16(loader,e_len,"ES",destpara-e_len/16);
|
|
||||||
patch_le16(loader,e_len,"DS",e_len/16+(copysize-firstcopy)/16);
|
|
||||||
patch_le16(loader,e_len,"SI",firstcopy-2);
|
|
||||||
patch_le16(loader,e_len,"CX",firstcopy/2);
|
|
||||||
|
|
||||||
// finish --stub support
|
|
||||||
//if (ih.relocoffs >= 0x40 && memcmp(&ih.relocoffs,">TIPPACH",8))
|
|
||||||
// throwCantPack("FIXME");
|
|
||||||
|
|
||||||
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
||||||
oh.m512 = outputlen & 511;
|
oh.m512 = outputlen & 511;
|
||||||
oh.p512 = (outputlen + 511) >> 9;
|
oh.p512 = (outputlen + 511) >> 9;
|
||||||
|
|
||||||
oh.ip = 0;
|
const char *exeentry = M_IS_LZMA(ph.method) ? "LZMAENTRY" : "EXEENTRY";
|
||||||
if (device_driver)
|
oh.ip = device_driver ? getLoaderSection(exeentry) - 2 : 0;
|
||||||
{
|
|
||||||
patch_le16(loader, e_len, "OP", oh.sp);
|
|
||||||
patch_le16(loader, e_len, "OS", oh.ss);
|
|
||||||
// copy .sys header
|
|
||||||
memcpy(loader + 4, ibuf + 4, 2);
|
|
||||||
memcpy(loader + 8, ibuf + 8, 2);
|
|
||||||
// copy original strategy
|
|
||||||
memcpy(loader + 10, ibuf + 6, 2);
|
|
||||||
oh.ip = getLoaderSection("EXEENTRY") - 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//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);
|
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
|
// write header + write loader + compressed file
|
||||||
#ifdef TESTING
|
#if TESTING
|
||||||
if (opt->debug.debug_level)
|
if (opt->debug.debug_level)
|
||||||
printf("\n%d %d %d %d\n",(int)sizeof(oh),e_len,packedsize,d_len);
|
printf("\n%d %d %d %d\n",(int)sizeof(oh),e_len,packedsize,d_len);
|
||||||
#endif
|
#endif
|
||||||
@@ -586,7 +672,7 @@ int PackExe::canUnpack()
|
|||||||
return false;
|
return false;
|
||||||
const off_t off = ih.headsize16 * 16;
|
const off_t off = ih.headsize16 * 16;
|
||||||
fi->seek(off, SEEK_SET);
|
fi->seek(off, SEEK_SET);
|
||||||
bool b = readPackHeader(256);
|
bool b = readPackHeader(4096);
|
||||||
return b && (off + (off_t) ph.c_len <= file_size);
|
return b && (off + (off_t) ph.c_len <= file_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -716,6 +802,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
|
vi:ts=4:et
|
||||||
*/
|
*/
|
||||||
|
|||||||
+15
-10
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,13 +21,13 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_EXE_H
|
#ifndef __UPX_P_EXE_H
|
||||||
#define __UPX_P_EXE_H
|
#define __UPX_P_EXE_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -42,6 +42,8 @@ public:
|
|||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_DOS_EXE; }
|
virtual int getFormat() const { return UPX_F_DOS_EXE; }
|
||||||
virtual const char *getName() const { return "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 *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
@@ -68,10 +70,11 @@ protected:
|
|||||||
virtual int readFileHeader(void);
|
virtual int readFileHeader(void);
|
||||||
|
|
||||||
virtual int fillExeHeader(struct exe_header_t *) const;
|
virtual int fillExeHeader(struct exe_header_t *) const;
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
void addLoaderEpilogue(int flag);
|
||||||
|
|
||||||
struct exe_header_t
|
__packed_struct(exe_header_t)
|
||||||
{
|
|
||||||
LE16 ident;
|
LE16 ident;
|
||||||
LE16 m512;
|
LE16 m512;
|
||||||
LE16 p512;
|
LE16 p512;
|
||||||
@@ -87,8 +90,7 @@ protected:
|
|||||||
LE16 relocoffs;
|
LE16 relocoffs;
|
||||||
char __[2]; // overlnum
|
char __[2]; // overlnum
|
||||||
LE32 firstreloc;
|
LE32 firstreloc;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
exe_header_t ih, oh;
|
exe_header_t ih, oh;
|
||||||
|
|
||||||
@@ -108,6 +110,9 @@ protected:
|
|||||||
MINMEM = 16,
|
MINMEM = 16,
|
||||||
MAXMEM = 32
|
MAXMEM = 32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned stack_for_lzma; // stack size required for lzma
|
||||||
|
bool use_clear_dirty_stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2056
-990
File diff suppressed because it is too large
Load Diff
+291
-128
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2010 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
John F. Reiser
|
John F. Reiser
|
||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_LX_ELF_H //{
|
#ifndef __UPX_P_LX_ELF_H //{
|
||||||
#define __UPX_P_LX_ELF_H
|
#define __UPX_P_LX_ELF_H 1
|
||||||
|
|
||||||
|
|
||||||
class PackLinuxElf : public PackUnix
|
class PackLinuxElf : public PackUnix
|
||||||
@@ -40,7 +40,7 @@ class PackLinuxElf : public PackUnix
|
|||||||
public:
|
public:
|
||||||
PackLinuxElf(InputFile *f);
|
PackLinuxElf(InputFile *f);
|
||||||
virtual ~PackLinuxElf();
|
virtual ~PackLinuxElf();
|
||||||
/*virtual int buildLoader(const Filter *);*/
|
/*virtual void buildLoader(const Filter *);*/
|
||||||
virtual bool canUnpackVersion(int version) const { return (version >= 11); }
|
virtual bool canUnpackVersion(int version) const { return (version >= 11); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -51,19 +51,42 @@ protected:
|
|||||||
|
|
||||||
virtual void pack1(OutputFile *, Filter &) = 0; // generate executable header
|
virtual void pack1(OutputFile *, Filter &) = 0; // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &) = 0; // append compressed data
|
virtual void pack2(OutputFile *, Filter &) = 0; // append compressed data
|
||||||
//virtual void pack3(OutputFile *, Filter &) = 0; // append loader
|
virtual void pack3(OutputFile *, Filter &) = 0; // append loader
|
||||||
virtual void pack4(OutputFile *, Filter &) = 0; // append pack header
|
//virtual void pack4(OutputFile *, Filter &) = 0; // append pack header
|
||||||
|
|
||||||
virtual void generateElfHdr(
|
virtual void generateElfHdr(
|
||||||
OutputFile *,
|
OutputFile *,
|
||||||
void const *proto,
|
void const *proto,
|
||||||
unsigned const brka
|
unsigned const brka
|
||||||
) = 0;
|
) = 0;
|
||||||
virtual void unpack(OutputFile *fo) = 0;
|
virtual void defineSymbols(Filter const *);
|
||||||
|
virtual void addStubEntrySections(Filter const *);
|
||||||
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
|
virtual unsigned elf_get_offset_from_address(acc_uint64l_t) const = 0;
|
||||||
|
virtual void const *elf_find_dynamic(unsigned) const = 0;
|
||||||
|
virtual acc_uint64l_t elf_unsigned_dynamic(unsigned) const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
unsigned e_phnum; /* Program header table entry count */
|
||||||
|
char *file_image; // if ET_DYN investigation
|
||||||
|
char const *dynstr; // from DT_STRTAB
|
||||||
|
|
||||||
unsigned sz_phdrs; // sizeof Phdr[]
|
unsigned sz_phdrs; // sizeof Phdr[]
|
||||||
unsigned sz_elf_hdrs; // all Elf headers
|
unsigned sz_elf_hdrs; // all Elf headers
|
||||||
|
unsigned sz_pack2; // after pack2(), before loader
|
||||||
|
unsigned lg2_page; // log2(PAGE_SIZE)
|
||||||
|
unsigned page_size; // 1u<<lg2_page
|
||||||
|
unsigned xct_off; // shared library: file offset of SHT_EXECINSTR
|
||||||
|
unsigned hatch_off; // file offset of escape hatch
|
||||||
|
acc_uint64l_t load_va; // PT_LOAD[0].p_vaddr
|
||||||
|
acc_uint64l_t xct_va; // minimum SHT_EXECINSTR virtual address
|
||||||
|
|
||||||
|
unsigned short e_machine;
|
||||||
|
unsigned char ei_class;
|
||||||
|
unsigned char ei_data;
|
||||||
|
unsigned char ei_osabi;
|
||||||
|
char const *osabi_note;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PackLinuxElf32 : public PackLinuxElf
|
class PackLinuxElf32 : public PackLinuxElf
|
||||||
@@ -73,15 +96,17 @@ public:
|
|||||||
PackLinuxElf32(InputFile *f);
|
PackLinuxElf32(InputFile *f);
|
||||||
virtual ~PackLinuxElf32();
|
virtual ~PackLinuxElf32();
|
||||||
protected:
|
protected:
|
||||||
virtual int checkEhdr(
|
virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
|
||||||
Elf32_Ehdr const *ehdr,
|
virtual bool canPack();
|
||||||
unsigned char e_machine,
|
|
||||||
unsigned char ei_class,
|
// These ARM routines are essentially common to big/little endian,
|
||||||
unsigned char ei_data) const;
|
// but the class hierarchy splits after this class.
|
||||||
|
virtual void ARM_defineSymbols(Filter const *ft);
|
||||||
|
virtual void ARM_updateLoader(OutputFile *);
|
||||||
|
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||||
//virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
virtual void pack4(OutputFile *, Filter &); // append pack header
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
@@ -90,6 +115,13 @@ protected:
|
|||||||
void const *proto,
|
void const *proto,
|
||||||
unsigned const brka
|
unsigned const brka
|
||||||
);
|
);
|
||||||
|
virtual void buildLinuxLoader(
|
||||||
|
upx_byte const *const proto, // assembly-only sections
|
||||||
|
unsigned const szproto,
|
||||||
|
upx_byte const *const fold, // linked assembly + C section
|
||||||
|
unsigned const szfold,
|
||||||
|
Filter const *ft
|
||||||
|
);
|
||||||
virtual off_t getbrk(const Elf32_Phdr *phdr, int e_phnum) const;
|
virtual off_t getbrk(const Elf32_Phdr *phdr, int e_phnum) const;
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
virtual void updateLoader(OutputFile *fo);
|
virtual void updateLoader(OutputFile *fo);
|
||||||
@@ -97,32 +129,68 @@ protected:
|
|||||||
unsigned const e_phnum);
|
unsigned const e_phnum);
|
||||||
virtual off_t getbase(const Elf32_Phdr *phdr, int e_phnum) const;
|
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 Elf32_Sym const *elf_lookup(char const *) const;
|
||||||
|
virtual unsigned elf_get_offset_from_address(acc_uint64l_t) const;
|
||||||
|
Elf32_Shdr const *elf_find_section_name(char const *) const;
|
||||||
|
Elf32_Shdr const *elf_find_section_type(unsigned) const;
|
||||||
|
void const *elf_find_dynamic(unsigned) const;
|
||||||
|
acc_uint64l_t elf_unsigned_dynamic(unsigned) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Elf32_Ehdr ehdri; // from input file
|
Elf32_Ehdr ehdri; // from input file
|
||||||
Elf32_Phdr *phdri; // for input file
|
Elf32_Phdr *phdri; // for input file
|
||||||
|
Elf32_Shdr const *shdri; // from input file
|
||||||
|
unsigned page_mask; // AND clears the offset-within-page
|
||||||
|
|
||||||
struct cprElfHdr1 {
|
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;
|
||||||
|
|
||||||
|
__packed_struct(cprElfHdr1)
|
||||||
Elf32_Ehdr ehdr;
|
Elf32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[1];
|
Elf32_Phdr phdr[1];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct cprElfHdr2 {
|
__packed_struct(cprElfHdr2)
|
||||||
Elf32_Ehdr ehdr;
|
Elf32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[2];
|
Elf32_Phdr phdr[2];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct cprElfHdr3 {
|
__packed_struct(cprElfHdr3)
|
||||||
Elf32_Ehdr ehdr;
|
Elf32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[3];
|
Elf32_Phdr phdr[3];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
cprElfHdr3 elfout;
|
cprElfHdr3 elfout;
|
||||||
|
|
||||||
|
struct Elf32_Note {
|
||||||
|
unsigned namesz; // 8
|
||||||
|
unsigned descsz; // 4
|
||||||
|
unsigned type; // 1
|
||||||
|
char text[0x18 - 4*4]; // "OpenBSD"
|
||||||
|
unsigned end; // 0
|
||||||
|
} elfnote;
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -132,18 +200,14 @@ class PackLinuxElf64 : public PackLinuxElf
|
|||||||
public:
|
public:
|
||||||
PackLinuxElf64(InputFile *f);
|
PackLinuxElf64(InputFile *f);
|
||||||
virtual ~PackLinuxElf64();
|
virtual ~PackLinuxElf64();
|
||||||
/*virtual int buildLoader(const Filter *);*/
|
/*virtual void buildLoader(const Filter *);*/
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int checkEhdr(
|
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
|
||||||
Elf64_Ehdr const *ehdr,
|
|
||||||
unsigned char e_machine,
|
|
||||||
unsigned char ei_class,
|
|
||||||
unsigned char ei_data) const;
|
|
||||||
|
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||||
//virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
virtual void pack4(OutputFile *, Filter &); // append pack header
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
@@ -152,82 +216,103 @@ protected:
|
|||||||
void const *proto,
|
void const *proto,
|
||||||
unsigned const brka
|
unsigned const brka
|
||||||
);
|
);
|
||||||
|
virtual void buildLinuxLoader(
|
||||||
|
upx_byte const *const proto, // assembly-only sections
|
||||||
|
unsigned const szproto,
|
||||||
|
upx_byte const *const fold, // linked assembly + C section
|
||||||
|
unsigned const szfold,
|
||||||
|
Filter const *ft
|
||||||
|
);
|
||||||
virtual off_t getbrk(const Elf64_Phdr *phdr, int e_phnum) const;
|
virtual off_t getbrk(const Elf64_Phdr *phdr, int e_phnum) const;
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
virtual void updateLoader(OutputFile *fo);
|
virtual void updateLoader(OutputFile *fo);
|
||||||
virtual unsigned find_LOAD_gap(Elf64_Phdr const *const phdri, unsigned const k,
|
virtual unsigned find_LOAD_gap(Elf64_Phdr const *const phdri, unsigned const k,
|
||||||
unsigned const e_phnum);
|
unsigned const e_phnum);
|
||||||
|
|
||||||
|
virtual unsigned elf_get_offset_from_address(acc_uint64l_t) const;
|
||||||
|
Elf64_Shdr const *elf_find_section_name(char const *) const;
|
||||||
|
Elf64_Shdr const *elf_find_section_type(unsigned) const;
|
||||||
|
void const *elf_find_dynamic(unsigned) const;
|
||||||
|
acc_uint64l_t elf_unsigned_dynamic(unsigned) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Elf64_Ehdr ehdri; // from input file
|
Elf64_Ehdr ehdri; // from input file
|
||||||
Elf64_Phdr *phdri; // for input file
|
Elf64_Phdr *phdri; // for input file
|
||||||
|
Elf64_Shdr const *shdri; // from input file
|
||||||
|
acc_uint64l_t page_mask; // AND clears the offset-within-page
|
||||||
|
|
||||||
struct cprElfHdr1 {
|
Elf64_Dyn const *dynseg; // from PT_DYNAMIC
|
||||||
|
unsigned int const *hashtab; // from DT_HASH
|
||||||
|
unsigned int const *gashtab; // from DT_GNU_HASH
|
||||||
|
Elf64_Sym const *dynsym; // from DT_SYMTAB
|
||||||
|
char const *shstrtab; // via Elf64_Shdr
|
||||||
|
int n_elf_shnum; // via e_shnum
|
||||||
|
|
||||||
|
Elf64_Shdr const *sec_strndx;
|
||||||
|
Elf64_Shdr const *sec_dynsym;
|
||||||
|
Elf64_Shdr const *sec_dynstr;
|
||||||
|
|
||||||
|
__packed_struct(cprElfHdr1)
|
||||||
Elf64_Ehdr ehdr;
|
Elf64_Ehdr ehdr;
|
||||||
Elf64_Phdr phdr[1];
|
Elf64_Phdr phdr[1];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct cprElfHdr2 {
|
__packed_struct(cprElfHdr2)
|
||||||
Elf64_Ehdr ehdr;
|
Elf64_Ehdr ehdr;
|
||||||
Elf64_Phdr phdr[2];
|
Elf64_Phdr phdr[2];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct cprElfHdr3 {
|
__packed_struct(cprElfHdr3)
|
||||||
Elf64_Ehdr ehdr;
|
Elf64_Ehdr ehdr;
|
||||||
Elf64_Phdr phdr[3];
|
Elf64_Phdr phdr[3];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
cprElfHdr3 elfout;
|
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
|
class PackLinuxElf32Be : public PackLinuxElf32
|
||||||
{
|
{
|
||||||
typedef PackLinuxElf32 super;
|
typedef PackLinuxElf32 super;
|
||||||
protected:
|
protected:
|
||||||
PackLinuxElf32Be(InputFile *f) : super(f) { }
|
PackLinuxElf32Be(InputFile *f) : super(f) {
|
||||||
|
bele = &N_BELE_RTP::be_policy;
|
||||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
|
e_phnum = get_te16(&ehdri.e_phnum);
|
||||||
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
|
class PackLinuxElf32Le : public PackLinuxElf32
|
||||||
{
|
{
|
||||||
typedef PackLinuxElf32 super;
|
typedef PackLinuxElf32 super;
|
||||||
protected:
|
protected:
|
||||||
PackLinuxElf32Le(InputFile *f) : super(f) { }
|
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); }
|
e_phnum = get_te16(&ehdri.e_phnum);
|
||||||
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
}
|
||||||
virtual unsigned get_native16(const void *b) const { return get_le16(b); }
|
|
||||||
virtual void set_native64(void *b, acc_uint64l_t v) const { set_le64(b, v); }
|
|
||||||
virtual void set_native32(void *b, unsigned v) const { set_le32(b, v); }
|
|
||||||
virtual void set_native16(void *b, unsigned v) const { set_le16(b, v); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PackLinuxElf64Le : public PackLinuxElf64
|
class PackLinuxElf64Le : public PackLinuxElf64
|
||||||
{
|
{
|
||||||
typedef PackLinuxElf64 super;
|
typedef PackLinuxElf64 super;
|
||||||
protected:
|
protected:
|
||||||
PackLinuxElf64Le(InputFile *f) : super(f) { }
|
PackLinuxElf64Le(InputFile *f) : super(f) {
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
e_phnum = get_te16(&ehdri.e_phnum);
|
||||||
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
|
// linux/elf64amd
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -240,26 +325,18 @@ public:
|
|||||||
virtual ~PackLinuxElf64amd();
|
virtual ~PackLinuxElf64amd();
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_ELF64_AMD; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELF64_AMD; }
|
||||||
virtual const char *getName() const { return "linux/ElfAMD"; }
|
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 const int *getFilters() const;
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
protected:
|
protected:
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
//virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
virtual int buildLoader(const Filter *);
|
virtual void buildLoader(const Filter *);
|
||||||
virtual int buildLinuxLoader(
|
virtual Linker* newLinker() const;
|
||||||
upx_byte const *const proto, // assembly-only sections
|
virtual void defineSymbols(Filter const *);
|
||||||
unsigned const szproto,
|
|
||||||
upx_byte const *const fold, // linked assembly + C section
|
|
||||||
unsigned const szfold,
|
|
||||||
Filter const *ft
|
|
||||||
);
|
|
||||||
virtual void generateElfHdr(
|
|
||||||
OutputFile *,
|
|
||||||
void const *proto,
|
|
||||||
unsigned const brka
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// linux/elf32ppc
|
// linux/elf32ppc
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -272,26 +349,15 @@ public:
|
|||||||
virtual ~PackLinuxElf32ppc();
|
virtual ~PackLinuxElf32ppc();
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
|
||||||
virtual const char *getName() const { return "linux/ElfPPC"; }
|
virtual const char *getName() const { return "linux/ElfPPC"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "powerpc-linux.elf"; }
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
virtual bool canPack();
|
|
||||||
protected:
|
protected:
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual void buildLoader(const Filter *);
|
||||||
virtual int buildLoader(const Filter *);
|
virtual Linker* newLinker() const;
|
||||||
virtual int 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 void generateElfHdr(
|
|
||||||
OutputFile *,
|
|
||||||
void const *proto,
|
|
||||||
unsigned const brka
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// linux/elf386
|
// linux/elf386
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -302,54 +368,151 @@ class PackLinuxElf32x86 : public PackLinuxElf32Le
|
|||||||
public:
|
public:
|
||||||
PackLinuxElf32x86(InputFile *f);
|
PackLinuxElf32x86(InputFile *f);
|
||||||
virtual ~PackLinuxElf32x86();
|
virtual ~PackLinuxElf32x86();
|
||||||
virtual int getVersion() const { return 13; }
|
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; }
|
||||||
virtual const char *getName() const { return "linux/elf386"; }
|
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 const int *getFilters() const;
|
||||||
|
|
||||||
virtual void unpack(OutputFile *fo);
|
|
||||||
|
|
||||||
virtual bool canPack();
|
|
||||||
virtual bool canUnpackVersion(int version) const
|
|
||||||
{ return (version >= 11); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
|
||||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
|
||||||
|
|
||||||
virtual void patchLoader();
|
virtual void buildLoader(const Filter *);
|
||||||
virtual int buildLoader(const Filter *);
|
virtual void addStubEntrySections(Filter const *);
|
||||||
virtual int buildLinuxLoader(
|
virtual Linker* newLinker() const;
|
||||||
upx_byte const *const proto, // assembly-only sections
|
virtual void defineSymbols(Filter const *);
|
||||||
unsigned const szproto,
|
};
|
||||||
upx_byte const *const fold, // linked assembly + C section
|
|
||||||
unsigned const szfold,
|
class PackBSDElf32x86 : public PackLinuxElf32x86
|
||||||
Filter const *ft
|
{
|
||||||
);
|
typedef PackLinuxElf32x86 super;
|
||||||
|
public:
|
||||||
|
PackBSDElf32x86(InputFile *f);
|
||||||
|
virtual ~PackBSDElf32x86();
|
||||||
|
virtual int getFormat() const { return UPX_F_BSD_ELF_i386; }
|
||||||
|
virtual const char *getName() const { return "BSD/elf386"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
|
|
||||||
|
virtual void buildLoader(const Filter *);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackFreeBSDElf32x86 : public PackBSDElf32x86
|
||||||
|
{
|
||||||
|
typedef PackBSDElf32x86 super;
|
||||||
|
public:
|
||||||
|
PackFreeBSDElf32x86(InputFile *f);
|
||||||
|
virtual ~PackFreeBSDElf32x86();
|
||||||
|
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(
|
virtual void generateElfHdr(
|
||||||
OutputFile *,
|
OutputFile *,
|
||||||
void const *proto,
|
void const *proto,
|
||||||
unsigned const brka
|
unsigned const brka
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
Elf32_Ehdr ehdri; // from input file
|
|
||||||
Elf32_Phdr *phdri; // for input file
|
|
||||||
unsigned sz_phdrs; // sizeof Phdr[]
|
|
||||||
|
|
||||||
char *file_image; // if ET_DYN investigation
|
/*************************************************************************
|
||||||
Elf32_Dyn const *dynseg; // from PT_DYNAMIC
|
// linux/elfarm
|
||||||
unsigned int const *hashtab; // from DT_HASH
|
**************************************************************************/
|
||||||
char const *dynstr; // from DT_STRTAB
|
|
||||||
Elf32_Sym const *dynsym; // from DT_SYMTAB
|
|
||||||
|
|
||||||
static unsigned elf_hash(char const *) /*const*/;
|
class PackLinuxElf32armLe : public PackLinuxElf32Le
|
||||||
virtual void const *elf_find_dynamic(unsigned) const;
|
{
|
||||||
virtual Elf32_Sym const *elf_lookup(char const *) const;
|
typedef PackLinuxElf32Le super;
|
||||||
virtual unsigned elf_get_offset_from_address(unsigned) const;
|
public:
|
||||||
virtual unsigned find_LOAD_gap(Elf32_Phdr const *const phdri, unsigned const k,
|
PackLinuxElf32armLe(InputFile *f);
|
||||||
unsigned const e_phnum);
|
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 *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+241
-123
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2006 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2001-2006 John F. Reiser
|
Copyright (C) 2001-2010 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
John F. Reiser
|
John F. Reiser
|
||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
@@ -54,10 +54,35 @@
|
|||||||
// linux/386 (generic "execve" format)
|
// linux/386 (generic "execve" format)
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
PackLinuxI386::PackLinuxI386(InputFile *f) : super(f),
|
||||||
|
ei_osabi(Elf32_Ehdr::ELFOSABI_LINUX), osabi_note(NULL)
|
||||||
|
{
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackBSDI386::PackBSDI386(InputFile *f) : super(f)
|
||||||
|
{
|
||||||
|
// Shell scripts need help specifying the target operating system.
|
||||||
|
// Elf input will override this with .e_ident[EI_OSABI] or PT_NOTE.
|
||||||
|
// [2006-09-27: Today's only runtime stub for shell is for linux.]
|
||||||
|
if (Elf32_Ehdr::ELFOSABI_LINUX==opt->o_unix.osabi0) {
|
||||||
|
// Disallow an incompatibility.
|
||||||
|
ei_osabi = Elf32_Ehdr::ELFOSABI_NONE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ei_osabi = opt->o_unix.osabi0; // might be ELFOSABI_NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_lx_exec86.h"
|
#include "stub/i386-linux.elf.execve-entry.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/fold_exec86.h"
|
#include "stub/i386-linux.elf.execve-fold.h"
|
||||||
|
|
||||||
|
static const
|
||||||
|
#include "stub/i386-bsd.elf.execve-entry.h"
|
||||||
|
static const
|
||||||
|
#include "stub/i386-bsd.elf.execve-fold.h"
|
||||||
|
|
||||||
|
|
||||||
const int *PackLinuxI386::getCompressionMethods(int method, int level) const
|
const int *PackLinuxI386::getCompressionMethods(int method, int level) const
|
||||||
@@ -69,21 +94,37 @@ const int *PackLinuxI386::getFilters() const
|
|||||||
{
|
{
|
||||||
static const int filters[] = {
|
static const int filters[] = {
|
||||||
0x49, 0x46,
|
0x49, 0x46,
|
||||||
// FIXME 2002-11-11: We use stub/fold_exec86.asm, which calls the
|
|
||||||
// decompressor multiple times, and unfilter is independent of decompress.
|
|
||||||
// Currently only filters 0x49, 0x46, 0x80..0x87 can handle this;
|
|
||||||
// and 0x80..0x87 are regarded as "untested".
|
|
||||||
#if 0
|
|
||||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
||||||
#endif
|
|
||||||
#if 0
|
#if 0
|
||||||
|
// 0x80..0x87 are regarded as "untested".
|
||||||
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
|
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
|
||||||
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
||||||
#endif
|
#endif
|
||||||
-1 };
|
FT_END };
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_stub_brk(Elf_LE32_Phdr *const phdr1, unsigned brka)
|
||||||
|
{
|
||||||
|
#define PAGE_MASK (~0ul<<12)
|
||||||
|
// linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary
|
||||||
|
unsigned const brkb = brka | ((0==(~PAGE_MASK & brka)) ? 0x20 : 0);
|
||||||
|
phdr1->p_type = PT_LOAD; // be sure
|
||||||
|
phdr1->p_offset = ~PAGE_MASK & brkb;
|
||||||
|
phdr1->p_vaddr = brkb;
|
||||||
|
phdr1->p_paddr = brkb;
|
||||||
|
phdr1->p_filesz = 0;
|
||||||
|
phdr1->p_memsz = 0;
|
||||||
|
if (0==phdr1->p_flags) {
|
||||||
|
phdr1->p_flags = Elf32_Phdr::PF_R|Elf32_Phdr::PF_W;
|
||||||
|
}
|
||||||
|
if (0==phdr1->p_align) {
|
||||||
|
phdr1->p_align = 0x1000;
|
||||||
|
}
|
||||||
|
#undef PAGE_MASK
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PackLinuxI386::generateElfHdr(
|
PackLinuxI386::generateElfHdr(
|
||||||
OutputFile *fo,
|
OutputFile *fo,
|
||||||
@@ -91,9 +132,8 @@ PackLinuxI386::generateElfHdr(
|
|||||||
unsigned const brka
|
unsigned const brka
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
cprElfHdr1 *const h1 = (cprElfHdr1 *)&elfout;
|
cprElfHdr2 *const h2 = (cprElfHdr2 *)(void *)&elfout;
|
||||||
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout;
|
cprElfHdr3 *const h3 = (cprElfHdr3 *)(void *)&elfout;
|
||||||
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;
|
|
||||||
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
|
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
|
||||||
|
|
||||||
assert(h2->ehdr.e_phoff == sizeof(Elf32_Ehdr));
|
assert(h2->ehdr.e_phoff == sizeof(Elf32_Ehdr));
|
||||||
@@ -111,32 +151,19 @@ PackLinuxI386::generateElfHdr(
|
|||||||
|
|
||||||
// Info for OS kernel to set the brk()
|
// Info for OS kernel to set the brk()
|
||||||
if (brka) {
|
if (brka) {
|
||||||
#define PAGE_MASK (~0ul<<12)
|
set_stub_brk(&h2->phdr[1], brka);
|
||||||
// linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary
|
|
||||||
unsigned const brkb = brka | ((0==(~PAGE_MASK & brka)) ? 0x20 : 0);
|
|
||||||
h2->phdr[1].p_type = PT_LOAD; // be sure
|
|
||||||
h2->phdr[1].p_offset = ~PAGE_MASK & brkb;
|
|
||||||
h2->phdr[1].p_vaddr = brkb;
|
|
||||||
h2->phdr[1].p_paddr = brkb;
|
|
||||||
h2->phdr[1].p_filesz = 0;
|
|
||||||
h2->phdr[1].p_memsz = 0;
|
|
||||||
if (0==h2->phdr[1].p_flags) {
|
|
||||||
h2->phdr[1].p_flags = Elf32_Phdr::PF_R|Elf32_Phdr::PF_W;
|
|
||||||
}
|
|
||||||
if (0==h2->phdr[1].p_align) {
|
|
||||||
h2->phdr[1].p_align = 0x1000;
|
|
||||||
}
|
|
||||||
#undef PAGE_MASK
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ph.format==UPX_F_LINUX_i386 ) {
|
if (ph.format==UPX_F_LINUX_i386
|
||||||
assert(h1->ehdr.e_phnum==1);
|
|| ph.format==UPX_F_LINUX_SH_i386
|
||||||
memset(&h1->linfo, 0, sizeof(h1->linfo));
|
|| ph.format==UPX_F_BSD_i386
|
||||||
fo->write(h1, sizeof(*h1));
|
) {
|
||||||
}
|
// SELinux, PAx, grSecurity demand no PF_W if PF_X.
|
||||||
else if (ph.format==UPX_F_LINUX_SH_i386) {
|
// kernel-2.6.12-2.3.legacy_FC3 has a bug which demands
|
||||||
assert(h2->ehdr.e_phnum==1);
|
// a PT_LOAD with PF_W, else SIGSEGV when clearing page fragment
|
||||||
h2->ehdr.e_phnum = 1;
|
// 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));
|
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
||||||
fo->write(h2, sizeof(*h2));
|
fo->write(h2, sizeof(*h2));
|
||||||
}
|
}
|
||||||
@@ -156,7 +183,16 @@ PackLinuxI386::pack1(OutputFile *fo, Filter &)
|
|||||||
// create a pseudo-unique program id for our paranoid stub
|
// create a pseudo-unique program id for our paranoid stub
|
||||||
progid = getRandomId();
|
progid = getRandomId();
|
||||||
|
|
||||||
generateElfHdr(fo, linux_i386exec_fold, 0);
|
generateElfHdr(fo, stub_i386_linux_elf_execve_fold, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PackBSDI386::pack1(OutputFile *fo, Filter &)
|
||||||
|
{
|
||||||
|
// create a pseudo-unique program id for our paranoid stub
|
||||||
|
progid = getRandomId();
|
||||||
|
|
||||||
|
generateElfHdr(fo, stub_i386_bsd_elf_execve_fold, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -166,10 +202,11 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
|||||||
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||||
sizeof(l_info) +
|
sizeof(l_info) +
|
||||||
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
|
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
|
||||||
unsigned len = fo->getBytesWritten();
|
unsigned nw = fo->getBytesWritten();
|
||||||
set_native32(&elfout.phdr[0].p_filesz, len);
|
elfout.phdr[0].p_filesz = nw;
|
||||||
|
nw = 0u-((0u-elfout.phdr[0].p_align) & (0u-nw)); // ALIGN_UP
|
||||||
super::pack4(fo, ft); // write PackHeader and overlay_offset
|
super::pack4(fo, ft); // write PackHeader and overlay_offset
|
||||||
|
set_stub_brk(&elfout.phdr[1], nw + elfout.phdr[0].p_vaddr);
|
||||||
|
|
||||||
#if 0 // {
|
#if 0 // {
|
||||||
// /usr/bin/strip from RedHat 8.0 (binutils-2.13.90.0.2-2)
|
// /usr/bin/strip from RedHat 8.0 (binutils-2.13.90.0.2-2)
|
||||||
@@ -186,38 +223,38 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
|||||||
|
|
||||||
// Supply a "linking view" that covers everything,
|
// Supply a "linking view" that covers everything,
|
||||||
// so that 'strip' does not omit everything.
|
// so that 'strip' does not omit everything.
|
||||||
Elf32_Shdr shdr;
|
Elf_LE32_Shdr shdr;
|
||||||
// The section header string table.
|
// The section header string table.
|
||||||
char const shstrtab[] = "\0.\0.shstrtab";
|
char const shstrtab[] = "\0.\0.shstrtab";
|
||||||
|
|
||||||
unsigned eod = elfout.phdr[0].p_filesz;
|
unsigned eod = elfout.phdr[0].p_filesz;
|
||||||
set_native32(&elfout.ehdr.e_shoff, eod);
|
elfout.ehdr.e_shoff = eod;
|
||||||
set_native16(&elfout.ehdr.e_shentsize, sizeof(shdr));
|
elfout.ehdr.e_shentsize = sizeof(shdr);
|
||||||
set_native16(&elfout.ehdr.e_shnum, 3);
|
elfout.ehdr.e_shnum = 3;
|
||||||
set_native16(&elfout.ehdr.e_shstrndx, 2);
|
elfout.ehdr.e_shstrndx = 2;
|
||||||
|
|
||||||
// An empty Elf32_Shdr for space as a null index.
|
// An empty Elf32_Shdr for space as a null index.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
memset(&shdr, 0, sizeof(shdr));
|
||||||
set_native32(&shdr.sh_type, Elf32_Shdr::SHT_NULL);
|
shdr.sh_type = Elf32_Shdr::SHT_NULL;
|
||||||
fo->write(&shdr, sizeof(shdr));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
// Cover all the bits we need at runtime.
|
// Cover all the bits we need at runtime.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
memset(&shdr, 0, sizeof(shdr));
|
||||||
set_native32(&shdr.sh_name, 1);
|
shdr.sh_name = 1;
|
||||||
set_native32(&shdr.sh_type, Elf32_Shdr::SHT_PROGBITS);
|
shdr.sh_type = Elf32_Shdr::SHT_PROGBITS;
|
||||||
set_native32(&shdr.sh_flags, Elf32_Shdr::SHF_ALLOC);
|
shdr.sh_flags = Elf32_Shdr::SHF_ALLOC;
|
||||||
set_native32(&shdr.sh_addr, elfout.phdr[0].p_vaddr);
|
shdr.sh_addr = elfout.phdr[0].p_vaddr;
|
||||||
set_native32(&shdr.sh_offset, overlay_offset);
|
shdr.sh_offset = overlay_offset;
|
||||||
set_native32(&shdr.sh_size, eod - overlay_offset);
|
shdr.sh_size = eod - overlay_offset;
|
||||||
set_native32(&shdr.sh_addralign, 4096);
|
shdr.sh_addralign = 4096;
|
||||||
fo->write(&shdr, sizeof(shdr));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
// A section header for the section header string table.
|
// A section header for the section header string table.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
memset(&shdr, 0, sizeof(shdr));
|
||||||
set_native32(&shdr.sh_name, 3);
|
shdr.sh_name = 3;
|
||||||
set_native32(&shdr.sh_type, Elf32_Shdr::SHT_STRTAB);
|
shdr.sh_type = Elf32_Shdr::SHT_STRTAB;
|
||||||
set_native32(&shdr.sh_offset, 3*sizeof(shdr) + eod);
|
shdr.sh_offset = 3*sizeof(shdr) + eod;
|
||||||
set_native32(&shdr.sh_size, sizeof(shstrtab));
|
shdr.sh_size = sizeof(shstrtab);
|
||||||
fo->write(&shdr, sizeof(shdr));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
fo->write(shstrtab, sizeof(shstrtab));
|
fo->write(shstrtab, sizeof(shstrtab));
|
||||||
@@ -251,7 +288,12 @@ umax(unsigned a, unsigned b)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
Linker *PackLinuxI386::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
PackLinuxI386::buildLinuxLoader(
|
PackLinuxI386::buildLinuxLoader(
|
||||||
upx_byte const *const proto,
|
upx_byte const *const proto,
|
||||||
unsigned const szproto,
|
unsigned const szproto,
|
||||||
@@ -262,7 +304,6 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
{
|
{
|
||||||
initLoader(proto, szproto);
|
initLoader(proto, szproto);
|
||||||
|
|
||||||
struct b_info h; memset(&h, 0, sizeof(h));
|
|
||||||
unsigned fold_hdrlen = 0;
|
unsigned fold_hdrlen = 0;
|
||||||
if (0 < szfold) {
|
if (0 < szfold) {
|
||||||
cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
|
cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
|
||||||
@@ -272,40 +313,29 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
||||||
fold_hdrlen = umax(0x80, fold_hdrlen);
|
fold_hdrlen = umax(0x80, fold_hdrlen);
|
||||||
}
|
}
|
||||||
h.sz_unc = (szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen);
|
|
||||||
h.b_method = (unsigned char) ph.method;
|
|
||||||
h.b_ftid = (unsigned char) ph.filter;
|
|
||||||
h.b_cto8 = (unsigned char) ph.filter_cto;
|
|
||||||
}
|
|
||||||
unsigned char const *const uncLoader = fold_hdrlen + fold;
|
|
||||||
|
|
||||||
unsigned char *const cprLoader = new unsigned char[h.sz_unc];
|
|
||||||
if (0 < szfold) {
|
|
||||||
unsigned sz_cpr = h.sz_unc;
|
|
||||||
memcpy(cprLoader, uncLoader, sz_cpr);
|
|
||||||
h.sz_cpr = sz_cpr;
|
|
||||||
}
|
}
|
||||||
// This adds the definition to the "library", to be used later.
|
// This adds the definition to the "library", to be used later.
|
||||||
linker->addSection("FOLDEXEC", cprLoader, h.sz_cpr);
|
// NOTE: the stub is NOT compressed! The savings is not worth it.
|
||||||
delete [] cprLoader;
|
linker->addSection("FOLDEXEC", fold + fold_hdrlen, szfold - fold_hdrlen, 0);
|
||||||
|
|
||||||
n_mru = ft->n_mru;
|
n_mru = ft->n_mru;
|
||||||
|
|
||||||
// Here is a quick summary of the format of the output file:
|
// Rely on "+80CXXXX" [etc] in getDecompressorSections() packer_c.cpp */
|
||||||
linker->setLoaderAlignOffset(
|
// // Here is a quick summary of the format of the output file:
|
||||||
// Elf32_Edhr
|
// linker->setLoaderAlignOffset(
|
||||||
sizeof(elfout.ehdr) +
|
// // Elf32_Edhr
|
||||||
// Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
|
// sizeof(elfout.ehdr) +
|
||||||
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
// // Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
|
||||||
// checksum UPX! lsize version format
|
// (elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||||
sizeof(l_info) +
|
// // checksum UPX! lsize version format
|
||||||
// PT_DYNAMIC with DT_NEEDED "forwarded" from original file
|
// sizeof(l_info) +
|
||||||
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) +
|
// // PT_DYNAMIC with DT_NEEDED "forwarded" from original file
|
||||||
// p_progid, p_filesize, p_blocksize
|
// ((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) +
|
||||||
sizeof(p_info) +
|
// // p_progid, p_filesize, p_blocksize
|
||||||
// compressed data
|
// sizeof(p_info) +
|
||||||
b_len + ph.c_len );
|
// // compressed data
|
||||||
// entry to stub
|
// b_len + ph.c_len );
|
||||||
|
// // entry to stub
|
||||||
addLoader("LEXEC000", NULL);
|
addLoader("LEXEC000", NULL);
|
||||||
|
|
||||||
if (ft->id) {
|
if (ft->id) {
|
||||||
@@ -314,7 +344,11 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
addLoader("LEXEC010", NULL);
|
addLoader("LEXEC010", NULL);
|
||||||
addLoader(getDecompressor(), NULL);
|
linker->defineSymbol("filter_cto", ft->cto);
|
||||||
|
linker->defineSymbol("filter_length",
|
||||||
|
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||||
|
ft->lastcall - ft->calls * 4);
|
||||||
|
addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LEXEC015", NULL);
|
addLoader("LEXEC015", NULL);
|
||||||
if (ft->id) {
|
if (ft->id) {
|
||||||
{ // decompr, unfilter not separate
|
{ // decompr, unfilter not separate
|
||||||
@@ -339,25 +373,37 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
addLoader("IDENTSTR", NULL);
|
addLoader("IDENTSTR", NULL);
|
||||||
addLoader("LEXEC020", NULL);
|
addLoader("LEXEC020", NULL);
|
||||||
addLoader("FOLDEXEC", NULL);
|
addLoader("FOLDEXEC", NULL);
|
||||||
|
if (M_IS_LZMA(ph.method)) {
|
||||||
char *ptr_cto = (char *)const_cast<unsigned char *>(getLoader());
|
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
|
||||||
int sz_cto = getLoaderSize();
|
acc_uint32e_t properties = // lc, lp, pb, dummy
|
||||||
if (0x20==(ft->id & 0xF0) || 0x30==(ft->id & 0xF0)) { // push byte '?' ; cto8
|
(res->lit_context_bits << 0) |
|
||||||
patch_le16(ptr_cto, sz_cto, "\x6a?", 0x6a + (ft->cto << 8));
|
(res->lit_pos_bits << 8) |
|
||||||
checkPatch(NULL, 0, 0, 0); // reset
|
(res->pos_bits << 16);
|
||||||
|
if (linker->bele->isBE()) // big endian - bswap32
|
||||||
|
acc_swab32s(&properties);
|
||||||
|
linker->defineSymbol("lzma_properties", properties);
|
||||||
|
// -2 for properties
|
||||||
|
linker->defineSymbol("lzma_c_len", ph.c_len - 2);
|
||||||
|
linker->defineSymbol("lzma_u_len", ph.u_len);
|
||||||
|
unsigned const stack = getDecompressorWrkmemSize();
|
||||||
|
linker->defineSymbol("lzma_stack_adjust", 0u - stack);
|
||||||
}
|
}
|
||||||
// PackHeader and overlay_offset at the end of the output file,
|
if (0x80==(ft->id & 0xF0)) {
|
||||||
// after the compressed data.
|
int const mru = ft->n_mru ? 1+ ft->n_mru : 0;
|
||||||
|
if (mru && mru!=256) {
|
||||||
return getLoaderSize();
|
unsigned const is_pwr2 = (0==((mru -1) & mru));
|
||||||
|
linker->defineSymbol("NMRU", mru - is_pwr2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
relocateLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
PackLinuxI386::buildLoader(Filter const *ft)
|
PackLinuxI386::buildLoader(Filter const *ft)
|
||||||
{
|
{
|
||||||
unsigned const sz_fold = sizeof(linux_i386exec_fold);
|
unsigned const sz_fold = sizeof(stub_i386_linux_elf_execve_fold);
|
||||||
MemBuffer buf(sz_fold);
|
MemBuffer buf(sz_fold);
|
||||||
memcpy(buf, linux_i386exec_fold, sz_fold);
|
memcpy(buf, stub_i386_linux_elf_execve_fold, sz_fold);
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
// note: we only can use /proc/<pid>/fd when exetype > 0.
|
// note: we only can use /proc/<pid>/fd when exetype > 0.
|
||||||
@@ -367,8 +413,28 @@ PackLinuxI386::buildLoader(Filter const *ft)
|
|||||||
patch_le32(buf,sz_fold,"UPX3",progid);
|
patch_le32(buf,sz_fold,"UPX3",progid);
|
||||||
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
|
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
|
||||||
|
|
||||||
return buildLinuxLoader(
|
buildLinuxLoader(
|
||||||
linux_i386exec_loader, sizeof(linux_i386exec_loader),
|
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 );
|
buf, sz_fold, ft );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +450,7 @@ int PackLinuxI386::getLoaderPrefixSize() const
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
// basic check of an Linux ELF Ehdr
|
// basic check of an Linux ELF Ehdr
|
||||||
int PackLinuxI386::checkEhdr(const Elf32_Ehdr *ehdr) const
|
int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
|
||||||
{
|
{
|
||||||
const unsigned char * const buf = ehdr->e_ident;
|
const unsigned char * const buf = ehdr->e_ident;
|
||||||
|
|
||||||
@@ -434,9 +500,10 @@ bool PackLinuxI386::canPack()
|
|||||||
if (exetype != 0)
|
if (exetype != 0)
|
||||||
return super::canPack();
|
return super::canPack();
|
||||||
|
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
unsigned char *buf = ehdr.e_ident;
|
unsigned char *buf = ehdr.e_ident;
|
||||||
|
|
||||||
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(&ehdr, sizeof(ehdr));
|
fi->readx(&ehdr, sizeof(ehdr));
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
|
|
||||||
@@ -444,12 +511,61 @@ bool PackLinuxI386::canPack()
|
|||||||
const unsigned l = get_le32(buf);
|
const unsigned l = get_le32(buf);
|
||||||
|
|
||||||
int elf = checkEhdr(&ehdr);
|
int elf = checkEhdr(&ehdr);
|
||||||
if (elf >= 0)
|
if (elf >= 0) {
|
||||||
{
|
|
||||||
// NOTE: ELF executables are now handled by p_lx_elf.cpp,
|
// NOTE: ELF executables are now handled by p_lx_elf.cpp,
|
||||||
// so we only handle them here if force_execve
|
// so we only handle them here if force_execve
|
||||||
if (elf == 0 && opt->o_unix.force_execve)
|
if (elf == 0 && opt->o_unix.force_execve) {
|
||||||
exetype = 1;
|
exetype = 1;
|
||||||
|
|
||||||
|
unsigned osabi0 = ehdr.e_ident[Elf32_Ehdr::EI_OSABI];
|
||||||
|
switch (osabi0) {
|
||||||
|
case Elf32_Ehdr::ELFOSABI_LINUX:
|
||||||
|
case Elf32_Ehdr::ELFOSABI_FREEBSD:
|
||||||
|
case Elf32_Ehdr::ELFOSABI_NETBSD:
|
||||||
|
case Elf32_Ehdr::ELFOSABI_OPENBSD:
|
||||||
|
ei_osabi = osabi0; // Proudly declares its osabi in Ehdr.
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
unsigned const e_phnum = get_te16(&ehdr.e_phnum);
|
||||||
|
if (e_phnum<=(512/sizeof(Elf32_Phdr))) {
|
||||||
|
union {
|
||||||
|
unsigned char buf2[512];
|
||||||
|
//Elf32_Phdr phdr;
|
||||||
|
} u;
|
||||||
|
fi->seek(get_te32(&ehdr.e_phoff), SEEK_SET);
|
||||||
|
fi->readx(u.buf2, sizeof(u.buf2));
|
||||||
|
fi->seek(0, SEEK_SET);
|
||||||
|
Elf32_Phdr const *phdr = (Elf32_Phdr *) u.buf2;
|
||||||
|
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
||||||
|
if (phdr->PT_NOTE == get_te32(&phdr->p_type)) {
|
||||||
|
unsigned const offset = get_te32(&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_te32(¬e.descsz)
|
||||||
|
&& 1==get_te32(¬e.type)
|
||||||
|
&& 0==note.end ) {
|
||||||
|
if (0==strcmp("NetBSD", (char const *)note.text)) {
|
||||||
|
ei_osabi = Elf32_Ehdr::ELFOSABI_NETBSD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (0==strcmp("OpenBSD", (char const *)note.text)) {
|
||||||
|
ei_osabi = Elf32_Ehdr::ELFOSABI_OPENBSD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (UPX_F_BSD_i386==getFormat()
|
||||||
|
&& !(Elf32_Ehdr::ELFOSABI_FREEBSD==ei_osabi
|
||||||
|
|| Elf32_Ehdr::ELFOSABI_NETBSD ==ei_osabi
|
||||||
|
|| Elf32_Ehdr::ELFOSABI_OPENBSD==ei_osabi )) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (l == 0x00640107 || l == 0x00640108 || l == 0x0064010b || l == 0x006400cc)
|
else if (l == 0x00640107 || l == 0x00640108 || l == 0x0064010b || l == 0x006400cc)
|
||||||
{
|
{
|
||||||
@@ -458,15 +574,17 @@ bool PackLinuxI386::canPack()
|
|||||||
// FIXME: N_TRSIZE, N_DRSIZE
|
// FIXME: N_TRSIZE, N_DRSIZE
|
||||||
// FIXME: check for aout shared libraries
|
// FIXME: check for aout shared libraries
|
||||||
}
|
}
|
||||||
#if defined(__linux__)
|
else { // shell scripts and other interpreters
|
||||||
// only compress scripts when running under Linux
|
if (Elf32_Ehdr::ELFOSABI_LINUX!=ei_osabi) {
|
||||||
else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh
|
return false; // so far, only Linux has runtime stub for shell
|
||||||
exetype = -1;
|
}
|
||||||
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh
|
||||||
exetype = -1;
|
exetype = -1;
|
||||||
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
||||||
exetype = -2;
|
exetype = -1;
|
||||||
#endif
|
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
||||||
|
exetype = -2;
|
||||||
|
}
|
||||||
|
|
||||||
return super::canPack();
|
return super::canPack();
|
||||||
}
|
}
|
||||||
@@ -477,7 +595,7 @@ void PackLinuxI386::patchLoader() { }
|
|||||||
|
|
||||||
void PackLinuxI386::patchLoaderChecksum()
|
void PackLinuxI386::patchLoaderChecksum()
|
||||||
{
|
{
|
||||||
unsigned char *const ptr = const_cast<unsigned char *>(getLoader());
|
unsigned char *const ptr = getLoader();
|
||||||
l_info *const lp = (l_info *)(sizeof(elfout.ehdr) +
|
l_info *const lp = (l_info *)(sizeof(elfout.ehdr) +
|
||||||
(elfout.ehdr.e_phnum * elfout.ehdr.e_phentsize) + (char *)&elfout );
|
(elfout.ehdr.e_phnum * elfout.ehdr.e_phentsize) + (char *)&elfout );
|
||||||
// checksum for loader + p_info
|
// checksum for loader + p_info
|
||||||
|
|||||||
+55
-23
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
John F. Reiser
|
John F. Reiser
|
||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_LX_EXC_H
|
#ifndef __UPX_P_LX_EXC_H
|
||||||
#define __UPX_P_LX_EXC_H
|
#define __UPX_P_LX_EXC_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -41,7 +41,7 @@ class PackLinuxI386 : public PackUnixLe32
|
|||||||
{
|
{
|
||||||
typedef PackUnixLe32 super;
|
typedef PackUnixLe32 super;
|
||||||
public:
|
public:
|
||||||
PackLinuxI386(InputFile *f) : super(f) { }
|
PackLinuxI386(InputFile *f);
|
||||||
virtual void generateElfHdr(
|
virtual void generateElfHdr(
|
||||||
OutputFile *,
|
OutputFile *,
|
||||||
void const *proto,
|
void const *proto,
|
||||||
@@ -49,9 +49,10 @@ public:
|
|||||||
);
|
);
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_i386; }
|
virtual int getFormat() const { return UPX_F_LINUX_i386; }
|
||||||
virtual const char *getName() const { return "linux/386"; }
|
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 *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
virtual int buildLoader(const Filter *);
|
virtual void buildLoader(const Filter *);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
|
|
||||||
@@ -62,8 +63,9 @@ protected:
|
|||||||
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
|
||||||
// loader util
|
// loader util
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
virtual int getLoaderPrefixSize() const;
|
virtual int getLoaderPrefixSize() const;
|
||||||
virtual int buildLinuxLoader(
|
virtual void buildLinuxLoader(
|
||||||
upx_byte const *const proto, // assembly-only sections
|
upx_byte const *const proto, // assembly-only sections
|
||||||
unsigned const szproto,
|
unsigned const szproto,
|
||||||
upx_byte const *const fold, // linked assembly + C section
|
upx_byte const *const fold, // linked assembly + C section
|
||||||
@@ -77,7 +79,7 @@ protected:
|
|||||||
virtual void updateLoader(OutputFile *);
|
virtual void updateLoader(OutputFile *);
|
||||||
|
|
||||||
// ELF util
|
// ELF util
|
||||||
virtual int checkEhdr(const Elf32_Ehdr *ehdr) const;
|
virtual int checkEhdr(const Elf_LE32_Ehdr *ehdr) const;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
|
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
|
||||||
@@ -85,32 +87,62 @@ protected:
|
|||||||
|
|
||||||
unsigned n_mru;
|
unsigned n_mru;
|
||||||
|
|
||||||
struct cprElfHdr1 {
|
__packed_struct(cprElfHdr1)
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[1];
|
Elf_LE32_Phdr phdr[1];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct cprElfHdr2 {
|
__packed_struct(cprElfHdr2)
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[2];
|
Elf_LE32_Phdr phdr[2];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct cprElfHdr3 {
|
__packed_struct(cprElfHdr3)
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[3];
|
Elf_LE32_Phdr phdr[3];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
cprElfHdr3 elfout;
|
cprElfHdr3 elfout;
|
||||||
|
|
||||||
|
struct Elf32_Note {
|
||||||
|
unsigned namesz; // 8
|
||||||
|
unsigned descsz; // 4
|
||||||
|
unsigned type; // 1
|
||||||
|
char text[0x18 - 4*4]; // "OpenBSD"
|
||||||
|
unsigned end; // 0
|
||||||
|
} elfnote;
|
||||||
|
|
||||||
|
unsigned char ei_osabi;
|
||||||
|
char const *osabi_note;
|
||||||
|
|
||||||
|
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 */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+27
-24
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2006 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2000-2006 John F. Reiser
|
Copyright (C) 2000-2010 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
John F. Reiser
|
John F. Reiser
|
||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
@@ -51,9 +51,9 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_lx_pti86.h"
|
#include "stub/i386-linux.elf.interp-entry.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/fold_pti86.h"
|
#include "stub/i386-linux.elf.interp-fold.h"
|
||||||
|
|
||||||
PackLinuxElf32x86interp::PackLinuxElf32x86interp(InputFile *f) :
|
PackLinuxElf32x86interp::PackLinuxElf32x86interp(InputFile *f) :
|
||||||
super(f)
|
super(f)
|
||||||
@@ -147,26 +147,26 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
|||||||
}
|
}
|
||||||
elfout.phdr[0].p_paddr = elfout.phdr[0].p_vaddr = base - sz;
|
elfout.phdr[0].p_paddr = elfout.phdr[0].p_vaddr = base - sz;
|
||||||
if (opt->o_unix.make_ptinterp) {
|
if (opt->o_unix.make_ptinterp) {
|
||||||
initLoader(linux_i386pti_loader, sizeof(linux_i386pti_loader));
|
initLoader(stub_i386_linux_elf_interp_entry, sizeof(stub_i386_linux_elf_interp_entry));
|
||||||
linker->addSection("FOLDEXEC", linux_i386pti_fold, sizeof(linux_i386pti_fold));
|
linker->addSection("FOLDEXEC", stub_i386_linux_elf_interp_fold, sizeof(stub_i386_linux_elf_interp_fold), 0);
|
||||||
|
|
||||||
addLoader("LXPTI000", NULL);
|
addLoader("LXPTI000", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI040", NULL);
|
addLoader("LXPTI040", NULL);
|
||||||
ph.method = M_NRV2B_LE32; addLoader(getDecompressor(), NULL);
|
ph.method = M_NRV2B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI041", NULL);
|
addLoader("LXPTI041", NULL);
|
||||||
ph.method = M_NRV2D_LE32; addLoader(getDecompressor(), NULL);
|
ph.method = M_NRV2D_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI042", NULL);
|
addLoader("LXPTI042", NULL);
|
||||||
ph.method = M_NRV2E_LE32; addLoader(getDecompressor(), NULL);
|
ph.method = M_NRV2E_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI043", NULL);
|
//addLoader("LXPTI043", NULL);
|
||||||
ph.method = M_CL1B_LE32; addLoader(getDecompressor(), NULL);
|
//ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
//addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI091", NULL);
|
addLoader("LXPTI091", NULL);
|
||||||
|
|
||||||
@@ -197,15 +197,18 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
|||||||
void PackLinuxElf32x86interp::unpack(OutputFile *fo)
|
void PackLinuxElf32x86interp::unpack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
#define MAX_INTERP_HDR 512
|
#define MAX_INTERP_HDR 512
|
||||||
char bufehdr[MAX_INTERP_HDR];
|
union {
|
||||||
Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)bufehdr;
|
unsigned char buf[MAX_INTERP_HDR];
|
||||||
Elf32_Phdr const *phdr = (Elf32_Phdr *)(1+ehdr);
|
//struct { Elf32_Ehdr ehdr; Elf32_Phdr phdr; } e;
|
||||||
|
} u;
|
||||||
|
Elf32_Ehdr *const ehdr = (Elf32_Ehdr *) u.buf;
|
||||||
|
Elf32_Phdr const *phdr = (Elf32_Phdr *) (u.buf + sizeof(*ehdr));
|
||||||
|
|
||||||
unsigned szb_info = sizeof(b_info);
|
unsigned szb_info = sizeof(b_info);
|
||||||
{
|
{
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(bufehdr, MAX_INTERP_HDR);
|
fi->readx(u.buf, MAX_INTERP_HDR);
|
||||||
unsigned const e_entry = get_native32(&ehdr->e_entry);
|
unsigned const e_entry = get_te32(&ehdr->e_entry);
|
||||||
if (e_entry < 0x401180) { /* old style, 8-byte b_info */
|
if (e_entry < 0x401180) { /* old style, 8-byte b_info */
|
||||||
szb_info = 2*sizeof(unsigned);
|
szb_info = 2*sizeof(unsigned);
|
||||||
}
|
}
|
||||||
@@ -214,16 +217,16 @@ void PackLinuxElf32x86interp::unpack(OutputFile *fo)
|
|||||||
fi->seek(overlay_offset, SEEK_SET);
|
fi->seek(overlay_offset, SEEK_SET);
|
||||||
p_info hbuf;
|
p_info hbuf;
|
||||||
fi->readx(&hbuf, sizeof(hbuf));
|
fi->readx(&hbuf, sizeof(hbuf));
|
||||||
unsigned orig_file_size = get_native32(&hbuf.p_filesize);
|
unsigned orig_file_size = get_te32(&hbuf.p_filesize);
|
||||||
blocksize = get_native32(&hbuf.p_blocksize);
|
blocksize = get_te32(&hbuf.p_blocksize);
|
||||||
if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)
|
if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)
|
||||||
throwCantUnpack("file header corrupted");
|
throwCantUnpack("file header corrupted");
|
||||||
|
|
||||||
ibuf.alloc(blocksize + OVERHEAD);
|
ibuf.alloc(blocksize + OVERHEAD);
|
||||||
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
|
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
|
||||||
fi->readx(&bhdr, szb_info);
|
fi->readx(&bhdr, szb_info);
|
||||||
ph.u_len = get_native32(&bhdr.sz_unc);
|
ph.u_len = get_te32(&bhdr.sz_unc);
|
||||||
ph.c_len = get_native32(&bhdr.sz_cpr);
|
ph.c_len = get_te32(&bhdr.sz_cpr);
|
||||||
ph.filter_cto = bhdr.b_cto8;
|
ph.filter_cto = bhdr.b_cto8;
|
||||||
|
|
||||||
// Uncompress Ehdr and Phdrs.
|
// Uncompress Ehdr and Phdrs.
|
||||||
@@ -277,7 +280,7 @@ void PackLinuxElf32x86interp::unpack(OutputFile *fo)
|
|||||||
|
|
||||||
// check for end-of-file
|
// check for end-of-file
|
||||||
fi->readx(&bhdr, szb_info);
|
fi->readx(&bhdr, szb_info);
|
||||||
unsigned const sz_unc = ph.u_len = get_native32(&bhdr.sz_unc);
|
unsigned const sz_unc = ph.u_len = get_te32(&bhdr.sz_unc);
|
||||||
|
|
||||||
if (sz_unc == 0) { // uncompressed size 0 -> EOF
|
if (sz_unc == 0) { // uncompressed size 0 -> EOF
|
||||||
// note: magic is always stored le32
|
// note: magic is always stored le32
|
||||||
|
|||||||
+6
-5
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2010 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
John F. Reiser
|
John F. Reiser
|
||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_LX_INTERP_H //{
|
#ifndef __UPX_P_LX_INTERP_H //{
|
||||||
#define __UPX_P_LX_INTERP_H
|
#define __UPX_P_LX_INTERP_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -47,6 +47,7 @@ public:
|
|||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_ELFI_i386; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELFI_i386; }
|
||||||
virtual const char *getName() const { return "linux/elfi386"; }
|
virtual const char *getName() const { return "linux/elfi386"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf.interp"; }
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
/* p_lx_sep.cpp --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2006 Laszlo Molnar
|
|
||||||
Copyright (C) 2000-2006 John F. Reiser
|
|
||||||
All Rights Reserved.
|
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
|
||||||
and/or modify them under the terms of the GNU General Public License as
|
|
||||||
published by the Free Software Foundation; either version 2 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation, Inc.,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
|
||||||
|
|
||||||
John F. Reiser
|
|
||||||
<jreiser@users.sourceforge.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#include "file.h"
|
|
||||||
#include "packer.h"
|
|
||||||
#include "p_elf.h"
|
|
||||||
#include "p_unix.h"
|
|
||||||
#include "p_lx_exc.h"
|
|
||||||
#include "p_lx_elf.h"
|
|
||||||
#include "p_lx_sep.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
//#define SCRIPT_SIZE (opt->o_unix.SCRIPT_MAX + sizeof(l_info))
|
|
||||||
#define SCRIPT_SIZE (32 + sizeof(l_info))
|
|
||||||
|
|
||||||
const upx_byte *PackLinuxI386sep::getLoader() const
|
|
||||||
{
|
|
||||||
static char script[SCRIPT_SIZE];
|
|
||||||
|
|
||||||
memset(script, 0, sizeof(script));
|
|
||||||
char const *name = opt->o_unix.script_name;
|
|
||||||
if (0==name) {
|
|
||||||
name = "/usr/local/lib/upxX";
|
|
||||||
}
|
|
||||||
upx_snprintf(script, sizeof(script), "#!%s\n", name);
|
|
||||||
if (M_IS_NRV2B(ph.method)) {
|
|
||||||
script[strlen(script)-2] = 'b';
|
|
||||||
return (upx_byte const *)script;
|
|
||||||
}
|
|
||||||
if (M_IS_NRV2D(ph.method)) {
|
|
||||||
script[strlen(script)-2] = 'd';
|
|
||||||
return (upx_byte const *)script;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PackLinuxI386sep::getLoaderSize() const
|
|
||||||
{
|
|
||||||
if (M_IS_NRV2B(ph.method))
|
|
||||||
return SCRIPT_SIZE;
|
|
||||||
if (M_IS_NRV2D(ph.method))
|
|
||||||
return SCRIPT_SIZE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PackLinuxI386sep::getLoaderPrefixSize() const
|
|
||||||
{
|
|
||||||
return opt->o_unix.SCRIPT_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PackLinuxI386sep::patchLoader()
|
|
||||||
{
|
|
||||||
patchLoaderChecksum();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
vi:ts=4:et
|
|
||||||
*/
|
|
||||||
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/* p_lx_sep.h --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
|
||||||
All Rights Reserved.
|
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
|
||||||
and/or modify them under the terms of the GNU General Public License as
|
|
||||||
published by the Free Software Foundation; either version 2 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation, Inc.,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
|
||||||
|
|
||||||
John F. Reiser
|
|
||||||
<jreiser@users.sourceforge.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_LX_SEP_H //{
|
|
||||||
#define __UPX_P_LX_SEP_H
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// linux/sep386
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
class PackLinuxI386sep : public PackLinuxI386
|
|
||||||
{
|
|
||||||
typedef PackLinuxI386 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
+14
-14
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2006 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2000-2006 John F. Reiser
|
Copyright (C) 2000-2010 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
John F. Reiser
|
John F. Reiser
|
||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
@@ -48,9 +48,9 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_lx_sh86.h"
|
#include "stub/i386-linux.elf.shell-entry.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/fold_sh86.h"
|
#include "stub/i386-linux.elf.shell-fold.h"
|
||||||
|
|
||||||
|
|
||||||
PackLinuxI386sh::PackLinuxI386sh(InputFile *f) :
|
PackLinuxI386sh::PackLinuxI386sh(InputFile *f) :
|
||||||
@@ -71,12 +71,12 @@ umax(unsigned a, unsigned b)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
PackLinuxI386sh::buildLoader(Filter const *ft)
|
PackLinuxI386sh::buildLoader(Filter const *ft)
|
||||||
{
|
{
|
||||||
unsigned const sz_fold = sizeof(linux_i386sh_fold);
|
unsigned const sz_fold = sizeof(stub_i386_linux_elf_shell_fold);
|
||||||
MemBuffer buf(sz_fold);
|
MemBuffer buf(sz_fold);
|
||||||
memcpy(buf, linux_i386sh_fold, sz_fold);
|
memcpy(buf, stub_i386_linux_elf_shell_fold, sz_fold);
|
||||||
|
|
||||||
checkPatch(NULL, 0, 0, 0); // reset
|
checkPatch(NULL, 0, 0, 0); // reset
|
||||||
patch_le32(buf,sz_fold,"UPX3",l_shname);
|
patch_le32(buf,sz_fold,"UPX3",l_shname);
|
||||||
@@ -85,13 +85,13 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
|
|||||||
// get fresh filter
|
// get fresh filter
|
||||||
Filter fold_ft = *ft;
|
Filter fold_ft = *ft;
|
||||||
fold_ft.init(ft->id, ft->addvalue);
|
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;
|
fold_ft.preferred_ctos = preferred_ctos;
|
||||||
|
|
||||||
// filter
|
// filter
|
||||||
optimizeFilter(&fold_ft, buf, sz_fold);
|
optimizeFilter(&fold_ft, buf, sz_fold);
|
||||||
unsigned fold_hdrlen = sizeof(l_info) + sizeof(Elf32_Ehdr) +
|
unsigned fold_hdrlen = sizeof(l_info) + sizeof(Elf32_Ehdr) +
|
||||||
sizeof(Elf32_Phdr) * get_native32(&((Elf32_Ehdr const *)(void *)buf)->e_phnum);
|
sizeof(Elf32_Phdr) * get_te32(&((Elf32_Ehdr const *)(void *)buf)->e_phnum);
|
||||||
if (0 == get_le32(fold_hdrlen + buf)) {
|
if (0 == get_le32(fold_hdrlen + buf)) {
|
||||||
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
||||||
fold_hdrlen = umax(0x80, fold_hdrlen);
|
fold_hdrlen = umax(0x80, fold_hdrlen);
|
||||||
@@ -99,8 +99,8 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
|
|||||||
bool success = fold_ft.filter(buf + fold_hdrlen, sz_fold - fold_hdrlen);
|
bool success = fold_ft.filter(buf + fold_hdrlen, sz_fold - fold_hdrlen);
|
||||||
UNUSED(success);
|
UNUSED(success);
|
||||||
|
|
||||||
return buildLinuxLoader(
|
buildLinuxLoader(
|
||||||
linux_i386sh_loader, sizeof(linux_i386sh_loader),
|
stub_i386_linux_elf_shell_entry, sizeof(stub_i386_linux_elf_shell_entry),
|
||||||
buf, sz_fold, ft );
|
buf, sz_fold, ft );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ bool PackLinuxI386sh::canPack()
|
|||||||
void
|
void
|
||||||
PackLinuxI386sh::pack1(OutputFile *fo, Filter &)
|
PackLinuxI386sh::pack1(OutputFile *fo, Filter &)
|
||||||
{
|
{
|
||||||
generateElfHdr(fo, linux_i386sh_fold, 0x08048000);
|
generateElfHdr(fo, stub_i386_linux_elf_shell_fold, 0x08048000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
+7
-6
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2010 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
John F. Reiser
|
John F. Reiser
|
||||||
<jreiser@users.sourceforge.net>
|
<jreiser@users.sourceforge.net>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_LX_SH_H //{
|
#ifndef __UPX_P_LX_SH_H //{
|
||||||
#define __UPX_P_LX_SH_H
|
#define __UPX_P_LX_SH_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -47,8 +47,9 @@ public:
|
|||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_SH_i386; }
|
virtual int getFormat() const { return UPX_F_LINUX_SH_i386; }
|
||||||
virtual const char *getName() const { return "linux/sh386"; }
|
virtual const char *getName() const { return "linux/sh386"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "i386-linux.elf.shell"; }
|
||||||
virtual const int *getFilters() const { return NULL; }
|
virtual const int *getFilters() const { return NULL; }
|
||||||
virtual int buildLoader(const Filter *);
|
virtual void buildLoader(const Filter *);
|
||||||
|
|
||||||
virtual void pack1(OutputFile *fo, Filter &ft);
|
virtual void pack1(OutputFile *fo, Filter &ft);
|
||||||
virtual void pack3(OutputFile *fo, Filter &ft);
|
virtual void pack3(OutputFile *fo, Filter &ft);
|
||||||
|
|||||||
+1237
-125
File diff suppressed because it is too large
Load Diff
+773
-133
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,190 +21,830 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_MACHO_H
|
#ifndef __UPX_P_MACHO_H
|
||||||
#define __UPX_P_MACHO_H
|
#define __UPX_P_MACHO_H 1
|
||||||
|
|
||||||
|
|
||||||
|
__packed_struct(Mach_fat_header)
|
||||||
|
BE32 magic;
|
||||||
|
enum { // note conflict with java bytecode PackLinuxI386
|
||||||
|
FAT_MAGIC = 0xcafebabe,
|
||||||
|
FAT_MAGIC_SWAB = 0xbebafeca
|
||||||
|
};
|
||||||
|
BE32 nfat_arch; // Number of Mach_fat_arch which follow.
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
__packed_struct(Mach_fat_arch)
|
||||||
|
BE32 cputype;
|
||||||
|
BE32 cpusubtype;
|
||||||
|
BE32 offset;
|
||||||
|
BE32 size;
|
||||||
|
BE32 align; /* shift count; log base 2 */
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// Mach Mach Object executable
|
// Mach Mach Object executable; all structures are target-endian
|
||||||
|
// 'otool' is the Mach analog of 'readelf' (convert executable file to ASCII).
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
struct Mach_header {
|
namespace N_Mach {
|
||||||
BE32 magic;
|
|
||||||
enum {
|
|
||||||
MH_MAGIC = 0xfeedface
|
|
||||||
};
|
|
||||||
BE32 cputype;
|
|
||||||
enum {
|
|
||||||
CPU_TYPE_POWERPC = 18
|
|
||||||
};
|
|
||||||
BE32 cpysubtype;
|
|
||||||
BE32 filetype;
|
|
||||||
enum {
|
|
||||||
MH_EXECUTE = 2
|
|
||||||
};
|
|
||||||
BE32 ncmds;
|
|
||||||
BE32 sizeofcmds;
|
|
||||||
BE32 flags;
|
|
||||||
enum {
|
|
||||||
MH_NOUNDEFS = 1
|
|
||||||
};
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct Mach_segment_command {
|
// integral types
|
||||||
BE32 cmd;
|
template <class TWord, class TXword, class TAddr, class TOff>
|
||||||
enum {
|
struct MachITypes
|
||||||
LC_SEGMENT = 0x1,
|
{
|
||||||
LC_THREAD = 0x4,
|
typedef TWord Word;
|
||||||
LC_UNIXTHREAD = 0x5,
|
typedef TXword Xword;
|
||||||
LC_LOAD_DYLINKER = 0xe
|
typedef TAddr Addr;
|
||||||
};
|
typedef TOff Off;
|
||||||
BE32 cmdsize;
|
|
||||||
char segname[16];
|
|
||||||
BE32 vmaddr;
|
|
||||||
BE32 vmsize;
|
|
||||||
BE32 fileoff;
|
|
||||||
BE32 filesize;
|
|
||||||
BE32 maxprot;
|
|
||||||
enum {
|
|
||||||
VM_PROT_READ = 1,
|
|
||||||
VM_PROT_WRITE = 2,
|
|
||||||
VM_PROT_EXECUTE = 4
|
|
||||||
};
|
|
||||||
BE32 initprot;
|
|
||||||
BE32 nsects;
|
|
||||||
BE32 flags;
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct Mach_section {
|
|
||||||
char sectname[16];
|
|
||||||
char segname[16];
|
|
||||||
BE32 addr; /* memory address */
|
|
||||||
BE32 size; /* size in bytes */
|
|
||||||
BE32 offset; /* file offset */
|
|
||||||
BE32 align; /* power of 2 */
|
|
||||||
BE32 reloff; /* file offset of relocation entries */
|
|
||||||
BE32 nreloc; /* number of relocation entries */
|
|
||||||
BE32 flags; /* section type and attributes */
|
|
||||||
enum {
|
|
||||||
S_REGULAR = 0,
|
|
||||||
S_ZEROFILL,
|
|
||||||
S_CSTRING_LITERALS,
|
|
||||||
S_4BYTE_LITERALS,
|
|
||||||
S_8BYTE_LITERALS,
|
|
||||||
S_LITERAL_POINTERS,
|
|
||||||
S_NON_LAZY_SYMBOL_POINTERS,
|
|
||||||
S_LAZY_SYMBOL_POINTERS,
|
|
||||||
S_SYMBOL_STUBS,
|
|
||||||
S_MOD_INIT_FUNC_POINTERS,
|
|
||||||
S_MOD_TERM_FNC_POINTERS,
|
|
||||||
S_COALESCED
|
|
||||||
};
|
|
||||||
enum {
|
|
||||||
S_ATTR_PURE_INSTRUCTIONS = 0x80000000,
|
|
||||||
S_ATTR_NO_TOC = 0x40000000,
|
|
||||||
S_ATTR_STRIP_STATIC_SYMS = 0x20000000,
|
|
||||||
S_ATTR_SOME_INSTRUCTIONS = 0x00000400,
|
|
||||||
S_ATTR_EXT_RELOC = 0x00000200,
|
|
||||||
S_ATTR_LOC_RELOC = 0x00000100
|
|
||||||
};
|
|
||||||
BE32 reserved1;
|
|
||||||
BE32 reserved2;
|
|
||||||
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct Mach_ppc_thread_state {
|
|
||||||
BE32 srr0; /* Instruction address register (PC; entry addr) */
|
|
||||||
BE32 srr1; /* Machine state register (supervisor) */
|
|
||||||
BE32 r0, r1, r2, r3, r4, r5, r6, r7;
|
|
||||||
BE32 r8, r9,r10,r11,r12,r13,r14,r15;
|
|
||||||
BE32 r16,r17,r18,r19,r20,r21,r22,r23;
|
|
||||||
BE32 r24,r25,r26,r27,r28,r29,r30,r31;
|
|
||||||
|
|
||||||
BE32 cr; /* Condition register */
|
|
||||||
BE32 xer; /* User's integer exception register */
|
|
||||||
BE32 lr; /* Link register */
|
|
||||||
BE32 ctr; /* Count register */
|
|
||||||
BE32 mq; /* MQ register (601 only) */
|
|
||||||
|
|
||||||
BE32 vrsave; /* Vector Save Register */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Mach_thread_command {
|
template <class TMachITypes>
|
||||||
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
__packed_struct(Mach_header)
|
||||||
BE32 cmdsize; /* total size of this command */
|
typedef typename TMachITypes::Word Word;
|
||||||
BE32 flavor;
|
|
||||||
enum {
|
|
||||||
PPC_THREAD_STATE = 1
|
|
||||||
};
|
|
||||||
BE32 count; /* sizeof(following_thread_state)/4 */
|
|
||||||
enum {
|
|
||||||
PPC_THREAD_STATE_COUNT = sizeof(struct Mach_ppc_thread_state)/4
|
|
||||||
};
|
|
||||||
struct Mach_ppc_thread_state state;
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
|
Word magic;
|
||||||
|
Word cputype;
|
||||||
|
Word cpysubtype;
|
||||||
|
Word filetype;
|
||||||
|
Word ncmds;
|
||||||
|
Word sizeofcmds;
|
||||||
|
Word flags;
|
||||||
|
#define WANT_MACH_HEADER_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_header64)
|
||||||
|
// only difference is padding to 0 mod 8
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
|
||||||
|
Word magic;
|
||||||
|
Word cputype;
|
||||||
|
Word cpysubtype;
|
||||||
|
Word filetype;
|
||||||
|
Word ncmds;
|
||||||
|
Word sizeofcmds;
|
||||||
|
Word flags;
|
||||||
|
Word reserved; // pad to 0 mod 8
|
||||||
|
#define WANT_MACH_HEADER_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_segment_command)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Addr Addr;
|
||||||
|
typedef typename TMachITypes::Off Off;
|
||||||
|
|
||||||
|
Word cmd;
|
||||||
|
Word cmdsize;
|
||||||
|
char segname[16];
|
||||||
|
Addr vmaddr;
|
||||||
|
Addr vmsize;
|
||||||
|
Off fileoff;
|
||||||
|
Off filesize;
|
||||||
|
Word maxprot;
|
||||||
|
Word initprot;
|
||||||
|
Word nsects;
|
||||||
|
Word flags;
|
||||||
|
#define WANT_MACH_SEGMENT_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_section_command)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Addr Addr;
|
||||||
|
typedef typename TMachITypes::Off Off;
|
||||||
|
|
||||||
|
char sectname[16];
|
||||||
|
char segname[16];
|
||||||
|
Addr addr; /* memory address */
|
||||||
|
Addr size; /* size in bytes */
|
||||||
|
Word offset; /* file offset */
|
||||||
|
Word align; /* power of 2 */
|
||||||
|
Word reloff; /* file offset of relocation entries */
|
||||||
|
Word nreloc; /* number of relocation entries */
|
||||||
|
Word flags; /* section type and attributes */
|
||||||
|
Word reserved1; /* for offset or index */
|
||||||
|
Word reserved2; /* for count or sizeof */
|
||||||
|
#define WANT_MACH_SECTION_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_section_command_64)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Addr Addr;
|
||||||
|
typedef typename TMachITypes::Off Off;
|
||||||
|
typedef typename TMachITypes::Word Off32;
|
||||||
|
typedef typename TMachITypes::Xword Xword;
|
||||||
|
|
||||||
|
char sectname[16];
|
||||||
|
char segname[16];
|
||||||
|
Addr addr; /* memory address */
|
||||||
|
Addr size; /* size in bytes */
|
||||||
|
Off32 offset; /* file offset */
|
||||||
|
Word align; /* power of 2 */
|
||||||
|
Word reloff; /* file offset of relocation entries */
|
||||||
|
Word nreloc; /* number of relocation entries */
|
||||||
|
Word flags; /* section type and attributes */
|
||||||
|
Word reserved1; /* for offset or index */
|
||||||
|
Word reserved2; /* for count or sizeof */
|
||||||
|
Word reserved3; /* NOT IN 32-bit VERSION!! */
|
||||||
|
#define WANT_MACH_SECTION_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_symtab_command)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Off Off;
|
||||||
|
typedef typename TMachITypes::Word Off32;
|
||||||
|
|
||||||
|
Word cmd; /* LC_SYMTAB */
|
||||||
|
Word cmdsize; /* sizeof(struct Mach_symtab_command) */
|
||||||
|
Off32 symoff; /* symbol table offset */
|
||||||
|
Word nsyms; /* number of symbol table entries */
|
||||||
|
Off32 stroff; /* string table offset */
|
||||||
|
Word strsize; /* string table size in bytes */
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_dysymtab_command)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Off Off;
|
||||||
|
typedef typename TMachITypes::Word Off32;
|
||||||
|
|
||||||
|
Word cmd; /* LC_DYSYMTAB */
|
||||||
|
Word cmdsize; /* sizeof(struct Mach_dysymtab_command) */
|
||||||
|
Word ilocalsym; /* index to local symbols */
|
||||||
|
Word nlocalsym; /* number of local symbols */
|
||||||
|
Word iextdefsym; /* index to externally defined symbols */
|
||||||
|
Word nextdefsym; /* number of externally defined symbols */
|
||||||
|
Word iundefsym; /* index to undefined symbols */
|
||||||
|
Word nundefsym; /* number of undefined symbols */
|
||||||
|
Off32 tocoff; /* file offset to table of contents */
|
||||||
|
Word ntoc; /* number of entries in table of contents */
|
||||||
|
Off32 modtaboff; /* file offset to module table */
|
||||||
|
Word nmodtab; /* number of module table entries */
|
||||||
|
Off32 extrefsymoff; /* offset to referenced symbol table */
|
||||||
|
Word nextrefsymoff; /* number of referenced symbol table entries */
|
||||||
|
Off32 indirectsymoff; /* file offset to the indirect symbol table */
|
||||||
|
Word nindirectsyms; /* number of indirect symbol table entries */
|
||||||
|
Off32 extreloff; /* offset to external relocation entries */
|
||||||
|
Word nextrel; /* number of external relocation entries */
|
||||||
|
Off32 locreloff; /* offset to local relocation entries */
|
||||||
|
Word nlocrel; /* number of local relocation entries */
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_segsplit_info_command)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Off Off;
|
||||||
|
|
||||||
|
Word cmd; /* LC_SEGMENT_SPLIT_INFO */
|
||||||
|
Word cmdsize; /* sizeof(struct Mach_segsplit_info_command) */
|
||||||
|
Off dataoff;
|
||||||
|
Word datasize;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_routines_command)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Addr Addr;
|
||||||
|
|
||||||
|
Word cmd;
|
||||||
|
Word cmdsize;
|
||||||
|
Addr init_address;
|
||||||
|
Word init_module;
|
||||||
|
Word reserved1;
|
||||||
|
Word reserved2;
|
||||||
|
Word reserved3;
|
||||||
|
Word reserved4;
|
||||||
|
Word reserved5;
|
||||||
|
Word reserved6;
|
||||||
|
#define WANT_MACH_SEGMENT_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_routines_command_64)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Addr Addr;
|
||||||
|
typedef typename TMachITypes::Xword Xword;
|
||||||
|
|
||||||
|
Word cmd;
|
||||||
|
Word cmdsize;
|
||||||
|
Addr init_address;
|
||||||
|
Xword init_module;
|
||||||
|
Xword reserved1;
|
||||||
|
Xword reserved2;
|
||||||
|
Xword reserved3;
|
||||||
|
Xword reserved4;
|
||||||
|
Xword reserved5;
|
||||||
|
Xword reserved6;
|
||||||
|
#define WANT_MACH_SEGMENT_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_twolevel_hints_command)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Addr Addr;
|
||||||
|
typedef typename TMachITypes::Off Off;
|
||||||
|
|
||||||
|
Word cmd;
|
||||||
|
Word cmdsize;
|
||||||
|
Off offset; /* offset to the hint table */
|
||||||
|
Word nhints; /* number of hints */
|
||||||
|
#define WANT_MACH_SEGMENT_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_ppc_thread_state)
|
||||||
|
typedef typename TMachITypes::Addr Addr;
|
||||||
|
|
||||||
|
Addr srr0; /* Instruction address register (PC; entry addr) */
|
||||||
|
Addr srr1; /* Machine state register (supervisor) */
|
||||||
|
Addr r0, r1, r2, r3, r4, r5, r6, r7;
|
||||||
|
Addr r8, r9,r10,r11,r12,r13,r14,r15;
|
||||||
|
Addr r16,r17,r18,r19,r20,r21,r22,r23;
|
||||||
|
Addr r24,r25,r26,r27,r28,r29,r30,r31;
|
||||||
|
|
||||||
|
Addr cr; /* Condition register */ // FIXME: Word?
|
||||||
|
Addr xer; /* User's integer exception register */
|
||||||
|
Addr lr; /* Link register */
|
||||||
|
Addr ctr; /* Count register */
|
||||||
|
Addr mq; /* MQ register (601 only) */
|
||||||
|
|
||||||
|
Addr vrsave; /* Vector Save Register */
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_i386_thread_state)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
|
||||||
|
Word eax, ebx, ecx, edx;
|
||||||
|
Word edi, esi, ebp;
|
||||||
|
Word esp, ss;
|
||||||
|
Word eflags;
|
||||||
|
Word eip, cs;
|
||||||
|
Word ds, es, fs, gs;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_AMD64_thread_state)
|
||||||
|
typedef typename TMachITypes::Xword Xword;
|
||||||
|
|
||||||
|
Xword rax, rbx, rcx, rdx;
|
||||||
|
Xword rdi, rsi, rbp, rsp;
|
||||||
|
Xword r8, r9, r10, r11;
|
||||||
|
Xword r12, r13, r14, r15;
|
||||||
|
Xword rip, rflags;
|
||||||
|
Xword cs, fs, gs;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_i386_new_thread_state)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
|
||||||
|
Word gs, fs, es, ds;
|
||||||
|
Word edi, esi, ebp, esp;
|
||||||
|
Word ebx, edx, ecx, eax;
|
||||||
|
Word eip, cs, efl;
|
||||||
|
Word uesp, ss;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_ARM_thread_state)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
|
||||||
|
Word r[13]; // r0-r12
|
||||||
|
Word sp; // r13
|
||||||
|
Word lr; // r14
|
||||||
|
Word pc; // r15
|
||||||
|
Word cpsr;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
} // namespace N_Mach
|
||||||
|
|
||||||
|
namespace N_Mach32 {
|
||||||
|
|
||||||
|
} // namespace N_Mach32
|
||||||
|
|
||||||
|
namespace N_Mach64 {
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
__packed_struct(Mach_ppc_thread_state64)
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Xword Xword;
|
||||||
|
|
||||||
|
Xword srr0; /* Instruction address register (PC; entry addr) */
|
||||||
|
Xword srr1; /* Machine state register (supervisor) */
|
||||||
|
Xword r0, r1, r2, r3, r4, r5, r6, r7;
|
||||||
|
Xword r8, r9,r10,r11,r12,r13,r14,r15;
|
||||||
|
Xword r16,r17,r18,r19,r20,r21,r22,r23;
|
||||||
|
Xword r24,r25,r26,r27,r28,r29,r30,r31;
|
||||||
|
|
||||||
|
Word cr; /* Condition register */ // FIXME: Xword?
|
||||||
|
Xword xer; /* User's integer exception register */
|
||||||
|
Xword lr; /* Link register */
|
||||||
|
Xword ctr; /* Count register */
|
||||||
|
|
||||||
|
Word vrsave; /* Vector Save Register */
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
} // namespace N_Mach64
|
||||||
|
|
||||||
|
namespace N_Mach {
|
||||||
|
|
||||||
|
template <class TP>
|
||||||
|
struct MachClass_32
|
||||||
|
{
|
||||||
|
typedef TP BeLePolicy;
|
||||||
|
|
||||||
|
// integral types (target endianness)
|
||||||
|
typedef typename TP::U16 TE16;
|
||||||
|
typedef typename TP::U32 TE32;
|
||||||
|
typedef typename TP::U64 TE64;
|
||||||
|
typedef N_Mach::MachITypes<TE32, TE64, TE32, TE32> MachITypes;
|
||||||
|
#if (ACC_CC_BORLANDC)
|
||||||
|
typedef TE32 Addr;
|
||||||
|
#else
|
||||||
|
typedef typename MachITypes::Addr Addr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Mach types
|
||||||
|
typedef N_Mach::Mach_header<MachITypes> Mach_header;
|
||||||
|
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
|
||||||
|
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
|
||||||
|
typedef N_Mach::Mach_symtab_command<MachITypes> Mach_symtab_command;
|
||||||
|
typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command;
|
||||||
|
typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command;
|
||||||
|
typedef N_Mach::Mach_routines_command<MachITypes> Mach_routines_command;
|
||||||
|
typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
|
||||||
|
typedef N_Mach::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state;
|
||||||
|
typedef N_Mach::Mach_i386_thread_state<MachITypes> Mach_i386_thread_state;
|
||||||
|
typedef N_Mach::Mach_AMD64_thread_state<MachITypes> Mach_AMD64_thread_state;
|
||||||
|
typedef N_Mach::Mach_ARM_thread_state<MachITypes> Mach_ARM_thread_state;
|
||||||
|
|
||||||
|
static void compileTimeAssertions() {
|
||||||
|
BeLePolicy::compileTimeAssertions();
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(Addr) == 4)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class TP>
|
||||||
|
struct MachClass_64
|
||||||
|
{
|
||||||
|
typedef TP BeLePolicy;
|
||||||
|
|
||||||
|
// integral types (target endianness)
|
||||||
|
typedef typename TP::U16 TE16;
|
||||||
|
typedef typename TP::U32 TE32;
|
||||||
|
typedef typename TP::U64 TE64;
|
||||||
|
typedef N_Mach::MachITypes<TE32, TE64, TE64, TE64> MachITypes;
|
||||||
|
#if (ACC_CC_BORLANDC)
|
||||||
|
typedef TE64 Addr;
|
||||||
|
#else
|
||||||
|
typedef typename MachITypes::Addr Addr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Mach types
|
||||||
|
typedef N_Mach::Mach_header64<MachITypes> Mach_header;
|
||||||
|
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
|
||||||
|
typedef N_Mach::Mach_section_command_64<MachITypes> Mach_section_command;
|
||||||
|
typedef N_Mach::Mach_symtab_command<MachITypes> Mach_symtab_command;
|
||||||
|
typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command;
|
||||||
|
typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command;
|
||||||
|
typedef N_Mach::Mach_routines_command_64<MachITypes> Mach_routines_command;
|
||||||
|
typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
|
||||||
|
|
||||||
|
static void compileTimeAssertions() {
|
||||||
|
BeLePolicy::compileTimeAssertions();
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(Addr) == 8)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace N_Mach
|
||||||
|
|
||||||
|
typedef N_Mach::MachClass_32<N_BELE_CTP::HostPolicy> MachClass_Host32;
|
||||||
|
typedef N_Mach::MachClass_64<N_BELE_CTP::HostPolicy> MachClass_Host64;
|
||||||
|
typedef N_Mach::MachClass_32<N_BELE_CTP::BEPolicy> MachClass_BE32;
|
||||||
|
typedef N_Mach::MachClass_64<N_BELE_CTP::BEPolicy> MachClass_BE64;
|
||||||
|
typedef N_Mach::MachClass_32<N_BELE_CTP::LEPolicy> MachClass_LE32;
|
||||||
|
typedef N_Mach::MachClass_64<N_BELE_CTP::LEPolicy> MachClass_LE64;
|
||||||
|
|
||||||
|
// shortcuts
|
||||||
|
typedef MachClass_Host32::Mach_segment_command Mach32_segment_command;
|
||||||
|
typedef MachClass_Host32::Mach_section_command Mach32_section_command;
|
||||||
|
typedef MachClass_Host32::Mach_symtab_command Mach32_symtab_command;
|
||||||
|
typedef MachClass_Host32::Mach_dysymtab_command Mach32_dysymtab_command;
|
||||||
|
typedef MachClass_Host32::Mach_segsplit_info_command Mach32_segsplit_info_command;
|
||||||
|
typedef MachClass_Host32::Mach_routines_command Mach32_routines_command;
|
||||||
|
typedef MachClass_Host32::Mach_twolevel_hints_command Mach32_twolevel_hints_command;
|
||||||
|
|
||||||
|
typedef MachClass_Host64::Mach_segment_command Mach64_segment_command;
|
||||||
|
typedef MachClass_Host64::Mach_section_command Mach64_section_command;
|
||||||
|
typedef MachClass_Host64::Mach_symtab_command Mach64_symtab_command;
|
||||||
|
typedef MachClass_Host64::Mach_dysymtab_command Mach64_dysymtab_command;
|
||||||
|
typedef MachClass_Host64::Mach_segsplit_info_command Mach64_segsplit_info_command;
|
||||||
|
typedef MachClass_Host64::Mach_routines_command Mach64_routines_command;
|
||||||
|
typedef MachClass_Host64::Mach_twolevel_hints_command Mach64_twolevel_hints_command;
|
||||||
|
|
||||||
|
typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command;
|
||||||
|
typedef MachClass_BE32::Mach_section_command MachBE32_section_command;
|
||||||
|
typedef MachClass_BE32::Mach_symtab_command MachBE32_symtab_command;
|
||||||
|
typedef MachClass_BE32::Mach_dysymtab_command MachBE32_dysymtab_command;
|
||||||
|
typedef MachClass_BE32::Mach_segsplit_info_command MachBE32_segsplit_info_command;
|
||||||
|
typedef MachClass_BE32::Mach_routines_command MachBE32_routines_command;
|
||||||
|
typedef MachClass_BE32::Mach_twolevel_hints_command MachBE32_twolevel_hints_command;
|
||||||
|
|
||||||
|
typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command;
|
||||||
|
typedef MachClass_BE64::Mach_section_command MachBE64_section_command;
|
||||||
|
typedef MachClass_BE64::Mach_symtab_command MachBE64_symtab_command;
|
||||||
|
typedef MachClass_BE64::Mach_dysymtab_command MachBE64_dysymtab_command;
|
||||||
|
typedef MachClass_BE64::Mach_segsplit_info_command MachBE64_segsplit_info_command;
|
||||||
|
typedef MachClass_BE64::Mach_routines_command MachBE64_routines_command;
|
||||||
|
typedef MachClass_BE64::Mach_twolevel_hints_command MachBE64_twolevel_hints_command;
|
||||||
|
|
||||||
|
typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command;
|
||||||
|
typedef MachClass_LE32::Mach_section_command MachLE32_section_command;
|
||||||
|
typedef MachClass_LE32::Mach_symtab_command MachLE32_symtab_command;
|
||||||
|
typedef MachClass_LE32::Mach_dysymtab_command MachLE32_dysymtab_command;
|
||||||
|
typedef MachClass_LE32::Mach_segsplit_info_command MachLE32_segsplit_info_command;
|
||||||
|
typedef MachClass_LE32::Mach_routines_command MachLE32_routines_command;
|
||||||
|
typedef MachClass_LE32::Mach_twolevel_hints_command MachLE32_twolevel_hints_command;
|
||||||
|
|
||||||
|
typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command;
|
||||||
|
typedef MachClass_LE64::Mach_section_command MachLE64_section_command;
|
||||||
|
typedef MachClass_LE64::Mach_symtab_command MachLE64_symtab_command;
|
||||||
|
typedef MachClass_LE64::Mach_dysymtab_command MachLE64_dysymtab_command;
|
||||||
|
typedef MachClass_LE64::Mach_segsplit_info_command MachLE64_segsplit_info_command;
|
||||||
|
typedef MachClass_LE64::Mach_routines_command MachLE64_routines_command;
|
||||||
|
typedef MachClass_LE64::Mach_twolevel_hints_command MachLE64_twolevel_hints_command;
|
||||||
|
|
||||||
|
typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state;
|
||||||
|
typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state;
|
||||||
|
typedef MachClass_LE32::Mach_AMD64_thread_state Mach_AMD64_thread_state; // FIXME LE32 vs AMD64
|
||||||
|
typedef MachClass_LE32::Mach_ARM_thread_state Mach_ARM_thread_state;
|
||||||
#include "p_unix.h"
|
#include "p_unix.h"
|
||||||
|
|
||||||
|
|
||||||
class PackMachPPC32 : public PackUnixBe32
|
template <class TMachClass>
|
||||||
|
class PackMachBase : public PackUnix
|
||||||
{
|
{
|
||||||
typedef PackUnixBe32 super;
|
typedef PackUnix super;
|
||||||
|
protected:
|
||||||
|
typedef TMachClass MachClass;
|
||||||
|
typedef typename MachClass::BeLePolicy BeLePolicy;
|
||||||
|
typedef typename MachClass::MachITypes MachITypes;
|
||||||
|
// integral types (target endianness)
|
||||||
|
typedef typename MachClass::TE16 TE16;
|
||||||
|
typedef typename MachClass::TE32 TE32;
|
||||||
|
typedef typename MachClass::TE64 TE64;
|
||||||
|
typedef typename MachClass::Addr Addr;
|
||||||
|
// Mach types
|
||||||
|
typedef typename MachClass::Mach_header Mach_header;
|
||||||
|
typedef typename MachClass::Mach_segment_command Mach_segment_command;
|
||||||
|
typedef typename MachClass::Mach_section_command Mach_section_command;
|
||||||
|
typedef typename MachClass::Mach_symtab_command Mach_symtab_command;
|
||||||
|
typedef typename MachClass::Mach_dysymtab_command Mach_dysymtab_command;
|
||||||
|
typedef typename MachClass::Mach_segsplit_info_command Mach_segsplit_info_command;
|
||||||
|
typedef typename MachClass::Mach_routines_command Mach_routines_command;
|
||||||
|
typedef typename MachClass::Mach_twolevel_hints_command Mach_twolevel_hints_command;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PackMachPPC32(InputFile *f);
|
PackMachBase(InputFile *, unsigned cpuid, unsigned filetype,
|
||||||
virtual ~PackMachPPC32();
|
unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size);
|
||||||
|
virtual ~PackMachBase();
|
||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_MACH_PPC32; }
|
|
||||||
virtual const char *getName() const { return "Mach/ppc32"; }
|
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
|
||||||
|
|
||||||
// called by the generic pack()
|
// called by the generic pack()
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack3(OutputFile *, Filter &) = 0; // append loader
|
||||||
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
virtual void pack4(OutputFile *, Filter &) = 0; // append PackHeader
|
||||||
|
|
||||||
|
virtual void pack4dylib(OutputFile *, Filter &, Addr init_address);
|
||||||
|
|
||||||
|
virtual void pack1_setup_threado(OutputFile *const fo) = 0;
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual unsigned find_SEGMENT_gap(unsigned const k);
|
virtual unsigned find_SEGMENT_gap(unsigned const k);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int buildLoader(const Filter *ft);
|
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
virtual void patchLoaderChecksum();
|
virtual void patchLoaderChecksum();
|
||||||
virtual void updateLoader(OutputFile *);
|
virtual void updateLoader(OutputFile *);
|
||||||
virtual int buildMachLoader(
|
virtual void buildMachLoader(
|
||||||
upx_byte const *const proto,
|
upx_byte const *const proto,
|
||||||
unsigned const szproto,
|
unsigned const szproto,
|
||||||
upx_byte const *const fold,
|
upx_byte const *const fold,
|
||||||
unsigned const szfold,
|
unsigned const szfold,
|
||||||
Filter const *ft );
|
Filter const *ft );
|
||||||
|
virtual void defineSymbols(Filter const *);
|
||||||
|
virtual void addStubEntrySections(Filter const *);
|
||||||
|
|
||||||
|
static int __acc_cdecl_qsort compare_segment_command(void const *aa, void const *bb);
|
||||||
|
|
||||||
|
unsigned my_cputype;
|
||||||
|
unsigned my_filetype;
|
||||||
|
unsigned my_thread_flavor;
|
||||||
|
unsigned my_thread_state_word_count;
|
||||||
|
unsigned my_thread_command_size;
|
||||||
|
|
||||||
unsigned n_segment;
|
unsigned n_segment;
|
||||||
unsigned sz_segment;
|
unsigned sz_segment;
|
||||||
unsigned sz_mach_headers;
|
unsigned sz_mach_headers;
|
||||||
Mach_segment_command *rawmseg; // as input, with sections
|
Mach_segment_command *rawmseg; // as input, with sections
|
||||||
Mach_segment_command *msegcmd; // LC_SEGMENT first, without sections
|
Mach_segment_command *msegcmd; // LC_SEGMENT first, without sections
|
||||||
|
unsigned o_routines_cmd; // file offset to LC_ROUINTES
|
||||||
|
acc_uint64l_t prev_init_address;
|
||||||
Mach_header mhdri;
|
Mach_header mhdri;
|
||||||
|
|
||||||
Mach_header mhdro;
|
Mach_header mhdro;
|
||||||
Mach_segment_command segcmdo;
|
Mach_segment_command segcmdo;
|
||||||
Mach_thread_command threado;
|
|
||||||
|
__packed_struct(b_info) // 12-byte header before each compressed block
|
||||||
|
TE32 sz_unc; // uncompressed_size
|
||||||
|
TE32 sz_cpr; // compressed_size
|
||||||
|
unsigned char b_method; // compression algorithm
|
||||||
|
unsigned char b_ftid; // filter id
|
||||||
|
unsigned char b_cto8; // filter parameter
|
||||||
|
unsigned char b_unused;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
__packed_struct(l_info) // 12-byte trailer in header for loader
|
||||||
|
TE32 l_checksum;
|
||||||
|
LE32 l_magic;
|
||||||
|
TE16 l_lsize;
|
||||||
|
unsigned char l_version;
|
||||||
|
unsigned char l_format;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
__packed_struct(p_info) // 12-byte packed program header
|
||||||
|
TE32 p_progid;
|
||||||
|
TE32 p_filesize;
|
||||||
|
TE32 p_blocksize;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
struct l_info linfo;
|
struct l_info linfo;
|
||||||
|
|
||||||
|
static void compileTimeAssertions() {
|
||||||
|
MachClass::compileTimeAssertions();
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(b_info) == 12)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(l_info) == 12)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(p_info) == 12)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(b_info)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(l_info)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(p_info)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PackMachPPC32 : public PackMachBase<MachClass_BE32>
|
||||||
|
{
|
||||||
|
typedef PackMachBase<MachClass_BE32> super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PackMachPPC32(InputFile *f);
|
||||||
|
|
||||||
|
virtual int getFormat() const { return UPX_F_MACH_PPC32; }
|
||||||
|
virtual const char *getName() const { return "Mach/ppc32"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.macho"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
virtual void pack1_setup_threado(OutputFile *const fo);
|
||||||
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
|
||||||
|
__packed_struct(Mach_thread_command)
|
||||||
|
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
||||||
|
BE32 cmdsize; /* total size of this command */
|
||||||
|
BE32 flavor;
|
||||||
|
BE32 count; /* sizeof(following_thread_state)/4 */
|
||||||
|
Mach_ppc_thread_state state;
|
||||||
|
#define WANT_MACH_THREAD_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
Mach_thread_command threado;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackDylibPPC32 : public PackMachPPC32
|
||||||
|
{
|
||||||
|
typedef PackMachPPC32 super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PackDylibPPC32(InputFile *f);
|
||||||
|
|
||||||
|
virtual int getFormat() const { return UPX_F_DYLIB_PPC32; }
|
||||||
|
virtual const char *getName() const { return "Dylib/ppc32"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.dylib"; }
|
||||||
|
protected:
|
||||||
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackMachI386 : public PackMachBase<MachClass_LE32>
|
||||||
|
{
|
||||||
|
typedef PackMachBase<MachClass_LE32> super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PackMachI386(InputFile *f);
|
||||||
|
|
||||||
|
virtual int getFormat() const { return UPX_F_MACH_i386; }
|
||||||
|
virtual const char *getName() const { return "Mach/i386"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "i386-darwin.macho"; }
|
||||||
|
protected:
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
virtual void pack1_setup_threado(OutputFile *const fo);
|
||||||
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual void addStubEntrySections(Filter const *);
|
||||||
|
|
||||||
|
__packed_struct(Mach_thread_command)
|
||||||
|
LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
||||||
|
LE32 cmdsize; /* total size of this command */
|
||||||
|
LE32 flavor;
|
||||||
|
LE32 count; /* sizeof(following_thread_state)/4 */
|
||||||
|
Mach_i386_thread_state state;
|
||||||
|
#define WANT_MACH_THREAD_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
Mach_thread_command threado;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackDylibI386 : public PackMachI386
|
||||||
|
{
|
||||||
|
typedef PackMachI386 super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PackDylibI386(InputFile *f);
|
||||||
|
|
||||||
|
virtual int getFormat() const { return UPX_F_DYLIB_i386; }
|
||||||
|
virtual const char *getName() const { return "Dylib/i386"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "i386-darwin.dylib"; }
|
||||||
|
protected:
|
||||||
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackMachAMD64 : public PackMachBase<MachClass_LE64>
|
||||||
|
{
|
||||||
|
typedef PackMachBase<MachClass_LE64> super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PackMachAMD64(InputFile *f);
|
||||||
|
|
||||||
|
virtual int getFormat() const { return UPX_F_MACH_AMD64; }
|
||||||
|
virtual const char *getName() const { return "Mach/AMD64"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "AMD64-darwin.macho"; }
|
||||||
|
protected:
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
virtual void pack1_setup_threado(OutputFile *const fo);
|
||||||
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual void addStubEntrySections(Filter const *);
|
||||||
|
|
||||||
|
__packed_struct(Mach_thread_command)
|
||||||
|
LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
||||||
|
LE32 cmdsize; /* total size of this command */
|
||||||
|
LE32 flavor;
|
||||||
|
LE32 count; /* sizeof(following_thread_state)/4 */
|
||||||
|
Mach_AMD64_thread_state state;
|
||||||
|
#define WANT_MACH_THREAD_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
Mach_thread_command threado;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackDylibAMD64 : public PackMachAMD64
|
||||||
|
{
|
||||||
|
typedef PackMachAMD64 super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PackDylibAMD64(InputFile *f);
|
||||||
|
|
||||||
|
virtual int getFormat() const { return UPX_F_DYLIB_AMD64; }
|
||||||
|
virtual const char *getName() const { return "Dylib/AMD64"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "AMD64-darwin.dylib"; }
|
||||||
|
protected:
|
||||||
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackMachARMEL : public PackMachBase<MachClass_LE32>
|
||||||
|
{
|
||||||
|
typedef PackMachBase<MachClass_LE32> super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PackMachARMEL(InputFile *f);
|
||||||
|
|
||||||
|
virtual int getFormat() const { return UPX_F_MACH_ARMEL; }
|
||||||
|
virtual const char *getName() const { return "Mach/ARMEL"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "ARMEL-darwin.macho"; }
|
||||||
|
protected:
|
||||||
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
virtual void pack1_setup_threado(OutputFile *const fo);
|
||||||
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual void addStubEntrySections(Filter const *);
|
||||||
|
|
||||||
|
__packed_struct(Mach_thread_command)
|
||||||
|
LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
||||||
|
LE32 cmdsize; /* total size of this command */
|
||||||
|
LE32 flavor;
|
||||||
|
LE32 count; /* sizeof(following_thread_state)/4 */
|
||||||
|
Mach_ARM_thread_state state;
|
||||||
|
#define WANT_MACH_THREAD_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
Mach_thread_command threado;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackMachFat : public Packer
|
||||||
|
{
|
||||||
|
typedef Packer super;
|
||||||
|
public:
|
||||||
|
PackMachFat(InputFile *f);
|
||||||
|
virtual ~PackMachFat();
|
||||||
|
|
||||||
|
virtual int getVersion() const { return 13; }
|
||||||
|
virtual int getFormat() const { return UPX_F_MACH_FAT; }
|
||||||
|
virtual const char *getName() const { return "Mach/fat"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "fat-darwin.macho"; }
|
||||||
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// implementation
|
||||||
|
virtual void pack(OutputFile *fo);
|
||||||
|
virtual void unpack(OutputFile *fo);
|
||||||
|
virtual void list();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool canPack();
|
||||||
|
virtual int canUnpack();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// loader core
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
|
#if (ACC_CC_BORLANDC)
|
||||||
|
public:
|
||||||
|
#endif
|
||||||
|
enum { N_FAT_ARCH = 5 };
|
||||||
|
protected:
|
||||||
|
__packed_struct(Fat_head)
|
||||||
|
struct Mach_fat_header fat;
|
||||||
|
struct Mach_fat_arch arch[N_FAT_ARCH];
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
Fat_head fat_head;
|
||||||
|
|
||||||
|
// UI handler
|
||||||
|
UiPacker *uip;
|
||||||
|
|
||||||
|
// linker
|
||||||
|
Linker *linker;
|
||||||
|
#define WANT_MACH_HEADER_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
/* p_mach_enum.h --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 2007-2010 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.
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@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_MACH_HEADER_ENUM /*{*/
|
||||||
|
#undef WANT_MACH_HEADER_ENUM
|
||||||
|
enum { // magic
|
||||||
|
MH_MAGIC = 0xfeedface
|
||||||
|
};
|
||||||
|
enum { // cputype
|
||||||
|
CPU_TYPE_I386 = 7,
|
||||||
|
CPU_TYPE_X86_64 = 0x01000007,
|
||||||
|
CPU_TYPE_ARM = 12,
|
||||||
|
CPU_TYPE_POWERPC = 0x00000012,
|
||||||
|
CPU_TYPE_POWERPC64 = 0x01000012
|
||||||
|
};
|
||||||
|
enum { // cpusubtype
|
||||||
|
CPU_SUBTYPE_ARM_ALL = 0,
|
||||||
|
CPU_SUBTYPE_ARM_V4T = 5,
|
||||||
|
CPU_SUBTYPE_ARM_V6 = 6
|
||||||
|
};
|
||||||
|
enum { // filetype
|
||||||
|
MH_EXECUTE = 2,
|
||||||
|
MH_DYLIB = 6
|
||||||
|
};
|
||||||
|
enum { // flags
|
||||||
|
MH_NOUNDEFS = 1
|
||||||
|
};
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
#ifdef WANT_MACH_SEGMENT_ENUM /*{*/
|
||||||
|
#undef WANT_MACH_SEGMENT_ENUM
|
||||||
|
enum { // cmd
|
||||||
|
LC_SEGMENT = 0x1,
|
||||||
|
LC_SYMTAB = 0x2,
|
||||||
|
LC_THREAD = 0x4,
|
||||||
|
LC_UNIXTHREAD = 0x5,
|
||||||
|
LC_DYSYMTAB = 0xb,
|
||||||
|
LC_LOAD_DYLIB = 0xc,
|
||||||
|
LC_ID_DYLIB = 0xd,
|
||||||
|
LC_LOAD_DYLINKER = 0xe,
|
||||||
|
LC_ROUTINES = 0x11,
|
||||||
|
LC_TWOLEVEL_HINTS= 0x16,
|
||||||
|
LC_SEGMENT_64 = 0x19,
|
||||||
|
LC_ROUTINES_64 = 0x1a,
|
||||||
|
LC_UUID = 0x1b,
|
||||||
|
LC_RPATH = 0x1c,
|
||||||
|
LC_CODE_SIGNATURE = 0x1d,
|
||||||
|
LC_SEGMENT_SPLIT_INFO = 0x1e,
|
||||||
|
LC_REEXPORT_DYLIB = 0x1f,
|
||||||
|
LC_LAZY_LOAD_DYLIB= 0X20,
|
||||||
|
LC_ENCRYPTION_INFO= 0X21,
|
||||||
|
LC_DYLD_INFO = 0X22, // compressed dyld information (10.6.x)
|
||||||
|
LC_REQ_DYLD = 0x80000000 // OR'ed ==> must not ignore
|
||||||
|
};
|
||||||
|
enum { // maxprot
|
||||||
|
VM_PROT_READ = 1,
|
||||||
|
VM_PROT_WRITE = 2,
|
||||||
|
VM_PROT_EXECUTE = 4
|
||||||
|
};
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
#ifdef WANT_MACH_SECTION_ENUM /*{*/
|
||||||
|
#undef WANT_MACH_SECTION_ENUM
|
||||||
|
enum { // section type (low byte only)
|
||||||
|
S_REGULAR = 0,
|
||||||
|
S_ZEROFILL,
|
||||||
|
S_CSTRING_LITERALS,
|
||||||
|
S_4BYTE_LITERALS,
|
||||||
|
S_8BYTE_LITERALS,
|
||||||
|
S_LITERAL_POINTERS,
|
||||||
|
S_NON_LAZY_SYMBOL_POINTERS, // sectname __nl_symbol_ptr
|
||||||
|
S_LAZY_SYMBOL_POINTERS, // sectname __la_symbol_ptr
|
||||||
|
S_SYMBOL_STUBS,
|
||||||
|
S_MOD_INIT_FUNC_POINTERS, // sectname __mod_init_func
|
||||||
|
S_MOD_TERM_FUNC_POINTERS,
|
||||||
|
S_COALESCED,
|
||||||
|
S_GB_ZEROFILL,
|
||||||
|
S_INTERPOSING,
|
||||||
|
S_16BYTE_LITERALS,
|
||||||
|
S_DTRACE_DOF
|
||||||
|
};
|
||||||
|
enum { // section flags (high 24 bits)
|
||||||
|
S_ATTR_PURE_INSTRUCTIONS = 0x80000000,
|
||||||
|
S_ATTR_NO_TOC = 0x40000000,
|
||||||
|
S_ATTR_STRIP_STATIC_SYMS = 0x20000000,
|
||||||
|
S_ATTR_NO_DEAD_STRIP = 0x10000000,
|
||||||
|
S_ATTR_LIVE_SUPPORT = 0x08000000,
|
||||||
|
S_ATTR_SELF_MODIFYING_CODE = 0x04000000,
|
||||||
|
S_ATTR_DEBUG = 0x02000000,
|
||||||
|
S_ATTR_SOME_INSTRUCTIONS = 0x00000400,
|
||||||
|
S_ATTR_EXT_RELOC = 0x00000200,
|
||||||
|
S_ATTR_LOC_RELOC = 0x00000100
|
||||||
|
};
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
#ifdef WANT_MACH_THREAD_ENUM /*{*/
|
||||||
|
#undef WANT_MACH_THREAD_ENUM
|
||||||
|
enum { // thread flavor
|
||||||
|
PPC_THREAD_STATE = 1,
|
||||||
|
PPC_THREAD_STATE64 = 5,
|
||||||
|
x86_THREAD_STATE32 = 1,
|
||||||
|
x86_THREAD_STATE64 = 4,
|
||||||
|
i386_OLD_THREAD_STATE = -1,
|
||||||
|
ARM_THREAD_STATE = 1
|
||||||
|
};
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
vi:ts=4:et
|
||||||
|
*/
|
||||||
|
|
||||||
+429
-193
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2006 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2002-2006 Jens Medoch
|
Copyright (C) 2002-2010 Jens Medoch
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
Jens Medoch
|
Jens Medoch
|
||||||
<jssg@users.sourceforge.net>
|
<jssg@users.sourceforge.net>
|
||||||
@@ -35,30 +35,31 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_ps1.h"
|
#include "p_ps1.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_ps1b.h"
|
#include "stub/mipsel.r3000-ps1.h"
|
||||||
static const
|
|
||||||
#include "stub/l_ps1c.h"
|
|
||||||
|
|
||||||
|
#define CD_SEC 2048
|
||||||
|
#define PS_HDR_SIZE CD_SEC
|
||||||
|
#define PS_RAM_SIZE ram_size
|
||||||
|
#define PS_MIN_SIZE (PS_HDR_SIZE*3)
|
||||||
|
#define PS_MAX_SIZE ((PS_RAM_SIZE*95) / 100)
|
||||||
|
#define PS_STACK_SIZE (PS_RAM_SIZE / 256)
|
||||||
|
|
||||||
#define MIPS_HI(a) ((a) >> 16)
|
#define SZ_IH_BKUP (10 * sizeof(LE32))
|
||||||
#define MIPS_LO(a) ((a) & 0xffff)
|
#define HD_CODE_OFS (sizeof(ps1_exe_t) + sz_cbh)
|
||||||
#define MIPS_JP(a) ((0x08 << 24) | (((a) & 0x0fffffff) >> 2))
|
|
||||||
#define TIL_ALIGNED(a,b) (((b) - ((a) & ((b) - 1))) & (b) - 1)
|
|
||||||
|
|
||||||
#define CD_SEC 2048
|
#define K0_BS (0x80000000)
|
||||||
#define PS_HDR_SIZE CD_SEC
|
#define K1_BS (0xa0000000)
|
||||||
#define PS_RAM_SIZE 0x200000
|
#define EXE_BS (ih.epc & K0_BS)
|
||||||
#define PS_MIN_SIZE (PS_HDR_SIZE*3)
|
#define FIX_PSVR ((K1_BS - EXE_BS) + (PS_HDR_SIZE - HD_CODE_OFS))
|
||||||
#define PS_MAX_SIZE 0x1e8000
|
|
||||||
|
|
||||||
#define SZ_IH_BKUP (10 * sizeof(LE32))
|
// lui / addiu
|
||||||
#define HD_CODE_OFS (sizeof(ps1_exe_t))
|
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
|
||||||
|
#define MIPS_LO(a) ((a) & 0xffff)
|
||||||
#define K0_BS (0x80000000)
|
#define MIPS_PC16(a) ((a) >> 2)
|
||||||
#define K1_BS (0xa0000000)
|
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
|
||||||
#define FIX_PSVR (K1_BS - (ih.epc & K0_BS)) + (PS_HDR_SIZE - HD_CODE_OFS)
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -78,20 +79,24 @@ static const
|
|||||||
PackPs1::PackPs1(InputFile *f) :
|
PackPs1::PackPs1(InputFile *f) :
|
||||||
super(f),
|
super(f),
|
||||||
isCon(!opt->ps1_exe.boot_only), is32Bit(!opt->ps1_exe.do_8bit),
|
isCon(!opt->ps1_exe.boot_only), is32Bit(!opt->ps1_exe.do_8bit),
|
||||||
overlap(0), sa_cnt(0)
|
buildPart2(0), foundBss(0), sa_cnt(0), overlap(0), sz_lunc(0), sz_lcpr(0),
|
||||||
|
pad_code(0), bss_start(0), bss_end(0)
|
||||||
{
|
{
|
||||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 188);
|
bele = &N_BELE_RTP::le_policy;
|
||||||
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t));
|
|
||||||
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40);
|
|
||||||
#if 1 || defined(WITH_NRV)
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(nrv_boot_loader) == 3935);
|
|
||||||
COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0x0ac25782);
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(nrv_con_loader) == 2829);
|
|
||||||
COMPILE_TIME_ASSERT(NRV_CON_LOADER_CRC32 == 0x923b55c4);
|
|
||||||
#endif
|
|
||||||
fdata_size = file_size - PS_HDR_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 136)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(ps1_exe_hb_t) == 44)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(ps1_exe_chb_t) == 5)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(ps1_exe_t)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(ps1_exe_hb_t)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(ps1_exe_chb_t)
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t))
|
||||||
|
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40)
|
||||||
|
|
||||||
|
fdata_size = file_size - PS_HDR_SIZE;
|
||||||
|
ram_size = !opt->ps1_exe.do_8mib ? 0x200000 : 0x800000;
|
||||||
|
}
|
||||||
|
|
||||||
const int *PackPs1::getCompressionMethods(int method, int level) const
|
const int *PackPs1::getCompressionMethods(int method, int level) const
|
||||||
{
|
{
|
||||||
@@ -101,12 +106,16 @@ const int *PackPs1::getCompressionMethods(int method, int level) const
|
|||||||
return Packer::getDefaultCompressionMethods_8(method, level);
|
return Packer::getDefaultCompressionMethods_8(method, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int *PackPs1::getFilters() const
|
const int *PackPs1::getFilters() const
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker* PackPs1::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerMipsLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// util
|
// util
|
||||||
@@ -118,14 +127,88 @@ int PackPs1::readFileHeader()
|
|||||||
{
|
{
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(&ih, sizeof(ih));
|
fi->readx(&ih, sizeof(ih));
|
||||||
if (memcmp(&ih.id,"PS-X EXE",8) != 0 &&
|
if (memcmp(&ih.id[0], "PS-X EXE", 8) != 0 &&
|
||||||
memcmp(&ih.id,"EXE X-SP",8) != 0)
|
memcmp(&ih.id[0], "EXE X-SP", 8) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (ih.text != 0 || ih.data != 0)
|
if (ih.text != 0 || ih.data != 0)
|
||||||
return 0;
|
return 0;
|
||||||
return UPX_F_PS1_EXE;
|
return UPX_F_PS1_EXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PackPs1::readBkupHeader()
|
||||||
|
{
|
||||||
|
fi->seek(sizeof(ps1_exe_t)+8, SEEK_SET);
|
||||||
|
fi->readx(&bh, sizeof(bh));
|
||||||
|
|
||||||
|
if (bh.ih_csum != upx_adler32(&bh, SZ_IH_BKUP))
|
||||||
|
{
|
||||||
|
unsigned char buf[sizeof(bh)];
|
||||||
|
fi->seek(sizeof(ps1_exe_t), SEEK_SET);
|
||||||
|
fi->readx(buf, sizeof(bh));
|
||||||
|
if (!getBkupHeader(buf, (unsigned char *)&bh))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INIT_BH_BKUP(p, l) {(p)->id = '1'; (p)->len = l;}
|
||||||
|
#define ADLER16(a) (((a) >> 16) ^ ((a) & 0xffff))
|
||||||
|
|
||||||
|
void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len)
|
||||||
|
{
|
||||||
|
unsigned sz_cbh = MemBuffer::getSizeForCompression(SZ_IH_BKUP);
|
||||||
|
|
||||||
|
if (src && dst)
|
||||||
|
{
|
||||||
|
unsigned char *cpr_bh = new unsigned char[sz_cbh];
|
||||||
|
|
||||||
|
memset(cpr_bh, 0, sizeof(bh));
|
||||||
|
ps1_exe_chb_t * p = (ps1_exe_chb_t * )cpr_bh;
|
||||||
|
|
||||||
|
int r = upx_compress(src, SZ_IH_BKUP,
|
||||||
|
&p->ih_bkup, &sz_cbh, NULL, M_NRV2E_8, 10, NULL, NULL );
|
||||||
|
if (r != UPX_E_OK || sz_cbh >= SZ_IH_BKUP)
|
||||||
|
throwInternalError("header compression failed");
|
||||||
|
INIT_BH_BKUP(p, sz_cbh);
|
||||||
|
*len = ALIGN_UP(sz_cbh + (unsigned) sizeof(ps1_exe_chb_t) - 1, 4u);
|
||||||
|
p->ih_csum = ADLER16(upx_adler32(&ih.epc, SZ_IH_BKUP));
|
||||||
|
memcpy(dst, cpr_bh, SZ_IH_BKUP);
|
||||||
|
delete [] cpr_bh;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throwInternalError("header compression failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ADLER16_HI(a, b) ((((a) & 0xffff) ^ (b)) << 16)
|
||||||
|
#define ADLER16_LO(a, b) (((a) >> 16) ^ (b))
|
||||||
|
#define RE_ADLER16(a, b) (ADLER16_HI(a,b) | ADLER16_LO(a,b))
|
||||||
|
|
||||||
|
bool PackPs1::getBkupHeader(unsigned char *p, unsigned char *dst)
|
||||||
|
{
|
||||||
|
ps1_exe_chb_t *src = (ps1_exe_chb_t*)p;
|
||||||
|
|
||||||
|
if (src && (src->id == '1' && src->len < SZ_IH_BKUP) && dst)
|
||||||
|
{
|
||||||
|
unsigned char *unc_bh = new unsigned char[MemBuffer::getSizeForUncompression(SZ_IH_BKUP)];
|
||||||
|
|
||||||
|
unsigned sz_bh = SZ_IH_BKUP;
|
||||||
|
int r = upx_decompress((const unsigned char *)&src->ih_bkup, src->len,
|
||||||
|
unc_bh, &sz_bh, M_NRV2E_8, NULL );
|
||||||
|
if (r == UPX_E_OUT_OF_MEMORY)
|
||||||
|
throwOutOfMemoryException();
|
||||||
|
if (r != UPX_E_OK || sz_bh != SZ_IH_BKUP)
|
||||||
|
throwInternalError("header decompression failed");
|
||||||
|
unsigned ad = upx_adler32(unc_bh, SZ_IH_BKUP);
|
||||||
|
unsigned ch = src->ih_csum;
|
||||||
|
if (ad != RE_ADLER16(ad,ch))
|
||||||
|
throwInternalError("backup header damaged");
|
||||||
|
memcpy(dst, unc_bh, SZ_IH_BKUP);
|
||||||
|
delete [] unc_bh;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool PackPs1::checkFileHeader()
|
bool PackPs1::checkFileHeader()
|
||||||
{
|
{
|
||||||
@@ -148,57 +231,24 @@ bool PackPs1::checkFileHeader()
|
|||||||
infoWarning("unsupported header field entry");
|
infoWarning("unsupported header field entry");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!opt->force && ih.is_ptr == 0)
|
if (ih.is_ptr < (EXE_BS | (PS_RAM_SIZE - PS_STACK_SIZE)))
|
||||||
{
|
{
|
||||||
infoWarning("stack pointer field empty");
|
if (!opt->force)
|
||||||
return false;
|
return false;
|
||||||
|
else
|
||||||
|
infoWarning("%s: stack pointer offset low", fi->getName());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// patch util
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
void PackPs1::patch_mips_le(void *b, int blen, const void *old, unsigned new_)
|
|
||||||
{
|
|
||||||
size_t patch_len = strlen((const char*)old);
|
|
||||||
|
|
||||||
if (patch_len == 2)
|
|
||||||
{
|
|
||||||
unsigned char w[2];
|
|
||||||
|
|
||||||
set_le16(w, get_be16(old));
|
|
||||||
patch_le16(b, blen, w, MIPS_LO(new_));
|
|
||||||
}
|
|
||||||
else if (patch_len == 4)
|
|
||||||
{
|
|
||||||
unsigned char w[4];
|
|
||||||
|
|
||||||
set_le32(w, get_be32(old));
|
|
||||||
int boff = find(b, blen, w, 4);
|
|
||||||
|
|
||||||
if (boff == -1)
|
|
||||||
{
|
|
||||||
patch_le16(b, blen, &w[0], MIPS_LO(new_));
|
|
||||||
patch_le16(b, blen, &w[2], MIPS_HI(new_));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
patch_le32((unsigned char *)b + boff, (blen-boff), &w, new_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throwInternalError("bad marker length");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackPs1::canPack()
|
bool PackPs1::canPack()
|
||||||
{
|
{
|
||||||
unsigned char buf[PS_HDR_SIZE-HD_CODE_OFS];
|
unsigned char buf[PS_HDR_SIZE - sizeof(ps1_exe_t)];
|
||||||
|
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
@@ -206,8 +256,9 @@ bool PackPs1::canPack()
|
|||||||
fi->readx(buf, sizeof(buf));
|
fi->readx(buf, sizeof(buf));
|
||||||
checkAlreadyPacked(buf, sizeof(buf));
|
checkAlreadyPacked(buf, sizeof(buf));
|
||||||
|
|
||||||
for (unsigned i = 0; i < sizeof(buf); i++)
|
for (size_t i = 0; i < sizeof(buf); i++)
|
||||||
if (buf[i] != 0)
|
if (buf[i] != 0)
|
||||||
|
{
|
||||||
if (!opt->force)
|
if (!opt->force)
|
||||||
throwCantPack("unknown data in header (try --force)");
|
throwCantPack("unknown data in header (try --force)");
|
||||||
else
|
else
|
||||||
@@ -217,11 +268,12 @@ bool PackPs1::canPack()
|
|||||||
opt->backup = 1;
|
opt->backup = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!checkFileHeader())
|
if (!checkFileHeader())
|
||||||
throwCantPack("unsupported header flags (try --force)");
|
throwCantPack("unsupported header flags (try --force)");
|
||||||
if (!opt->force && file_size < PS_MIN_SIZE)
|
if (!opt->force && file_size < PS_MIN_SIZE)
|
||||||
throwCantPack("file is too small (try --force)");
|
throwCantPack("file is too small (try --force)");
|
||||||
if (!opt->force && file_size > PS_MAX_SIZE)
|
if (!opt->force && file_size > (off_t) PS_MAX_SIZE)
|
||||||
throwCantPack("file is too big (try --force)");
|
throwCantPack("file is too big (try --force)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -231,44 +283,189 @@ bool PackPs1::canPack()
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int PackPs1::buildLoader(const Filter *)
|
void PackPs1::buildLoader(const Filter *)
|
||||||
{
|
{
|
||||||
if (isCon)
|
const char *method = NULL;
|
||||||
initLoader(nrv_con_loader,sizeof(nrv_con_loader));
|
|
||||||
else
|
|
||||||
initLoader(nrv_boot_loader,sizeof(nrv_boot_loader));
|
|
||||||
|
|
||||||
addLoader("PS1START",
|
|
||||||
isCon ? ph.c_len & 3 ? "PS1PADCD" : "" : "PS1ENTRY",
|
|
||||||
ih.tx_ptr & 0xffff ? "PS1CONHL" : "PS1CONHI",
|
|
||||||
isCon ? "PS1ENTRY" : "",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (ph.method == M_NRV2B_8)
|
if (ph.method == M_NRV2B_8)
|
||||||
addLoader("PS1N2B08", NULL);
|
method = isCon ? "nrv2b.small,8bit.sub,nrv.done" :
|
||||||
|
"nrv2b.8bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2D_8)
|
else if (ph.method == M_NRV2D_8)
|
||||||
addLoader("PS1N2D08", NULL);
|
method = isCon ? "nrv2d.small,8bit.sub,nrv.done" :
|
||||||
|
"nrv2d.8bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2E_8)
|
else if (ph.method == M_NRV2E_8)
|
||||||
addLoader("PS1N2E08", NULL);
|
method = isCon ? "nrv2e.small,8bit.sub,nrv.done" :
|
||||||
|
"nrv2e.8bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2B_LE32)
|
else if (ph.method == M_NRV2B_LE32)
|
||||||
addLoader("PS1N2B32", NULL);
|
method = isCon ? "nrv2b.small,32bit.sub,nrv.done" :
|
||||||
|
"nrv2b.32bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2D_LE32)
|
else if (ph.method == M_NRV2D_LE32)
|
||||||
addLoader("PS1N2D32", NULL);
|
method = isCon ? "nrv2d.small,32bit.sub,nrv.done" :
|
||||||
|
"nrv2d.32bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2E_LE32)
|
else if (ph.method == M_NRV2E_LE32)
|
||||||
addLoader("PS1N2E32", NULL);
|
method = isCon ? "nrv2e.small,32bit.sub,nrv.done" :
|
||||||
|
"nrv2e.32bit,nrv.done";
|
||||||
|
else if (M_IS_LZMA(ph.method))
|
||||||
|
method = "nrv2b.small,8bit.sub,nrv.done,lzma.prep";
|
||||||
else
|
else
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
|
|
||||||
if (sa_cnt)
|
unsigned sa_tmp = sa_cnt;
|
||||||
addLoader(sa_cnt > (0x10000 << 2) ? "PS1MSETB" : "PS1MSETS",
|
if (ph.overlap_overhead > sa_cnt)
|
||||||
ih.tx_len & 3 ? "PS1MSETU" : "PS1MSETA",
|
{
|
||||||
NULL);
|
if (!opt->force)
|
||||||
|
{
|
||||||
|
infoWarning("not in-place decompressible");
|
||||||
|
throwCantPack("packed data overlap (try --force)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp), 4u);
|
||||||
|
}
|
||||||
|
|
||||||
addLoader("PS1EXITC", "IDENTSTR", "PS1PAHDR",
|
if (isCon || M_IS_LZMA(ph.method))
|
||||||
isCon ? "PS1SREGS" : "",
|
foundBss = findBssSection();
|
||||||
NULL);
|
|
||||||
|
|
||||||
return getLoaderSize();
|
if (M_IS_LZMA(ph.method) && !buildPart2)
|
||||||
|
{
|
||||||
|
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
|
||||||
|
addLoader("decompressor.start",
|
||||||
|
isCon ? "LZMA_DEC20" : "LZMA_DEC10", "lzma.init", NULL);
|
||||||
|
addLoader(sa_tmp > (0x10000 << 2) ? "memset.long" : "memset.short",
|
||||||
|
!foundBss ? "con.exit" : "bss.exit", NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (M_IS_LZMA(ph.method) && buildPart2)
|
||||||
|
{
|
||||||
|
sz_lcpr = MemBuffer::getSizeForCompression(sz_lunc);
|
||||||
|
unsigned char *cprLoader = new unsigned char[sz_lcpr];
|
||||||
|
int r = upx_compress(getLoader(), sz_lunc, cprLoader, &sz_lcpr,
|
||||||
|
NULL, M_NRV2B_8, 10, NULL, NULL );
|
||||||
|
if (r != UPX_E_OK || sz_lcpr >= sz_lunc)
|
||||||
|
throwInternalError("loader compression failed");
|
||||||
|
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1),
|
||||||
|
isCon || !M_IS_LZMA(ph.method) ? 0 : 1);
|
||||||
|
linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0);
|
||||||
|
delete [] cprLoader;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
|
||||||
|
|
||||||
|
pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4u);
|
||||||
|
assert(pad_code < 4);
|
||||||
|
static const unsigned char pad_buffer[4] = { 0, 0, 0, 0 };
|
||||||
|
linker->addSection("pad.code", pad_buffer, pad_code, 0);
|
||||||
|
|
||||||
|
if (isCon)
|
||||||
|
{
|
||||||
|
if (M_IS_LZMA(ph.method))
|
||||||
|
addLoader(!foundBss ? "con.start" : "bss.con.start",
|
||||||
|
method,
|
||||||
|
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||||
|
"con.entry", "pad.code", "lzma.exec", NULL);
|
||||||
|
else
|
||||||
|
addLoader(!foundBss ? "con.start" : "bss.con.start", "con.mcpy",
|
||||||
|
ph.c_len & 3 ? "con.padcd" : "",
|
||||||
|
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||||
|
"con.entry", method,
|
||||||
|
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
|
||||||
|
!foundBss ? "con.exit" : "bss.exit",
|
||||||
|
"pad.code", NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (M_IS_LZMA(ph.method))
|
||||||
|
addLoader(!foundBss ? "cdb.start.lzma" : "bss.cdb.start.lzma", "pad.code",
|
||||||
|
!foundBss ? "cdb.entry.lzma" : "bss.cdb.entry.lzma",
|
||||||
|
method, "cdb.lzma.cpr",
|
||||||
|
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||||
|
"lzma.exec", NULL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(foundBss != true);
|
||||||
|
addLoader("cdb.start", "pad.code", "cdb.entry",
|
||||||
|
ih.tx_ptr & 0xffff ? "cdb.dec.ptr" : "cdb.dec.ptr.hi",
|
||||||
|
method,
|
||||||
|
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
|
||||||
|
"cdb.exit", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addLoader("UPX1HEAD", "IDENTSTR", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OPTYPE(x) (((x) >> 13) & 0x7)
|
||||||
|
#define OPCODE(x) (((x) >> 10) & 0x7)
|
||||||
|
#define REG1(x) (((x) >> 5) & 0x1f)
|
||||||
|
#define REG2(x) ((x) & 0x1f)
|
||||||
|
|
||||||
|
#define MIPS_IMM(a,b) ((((a) - (((b) & 0x8000) >> 15)) << 16) | (b))
|
||||||
|
|
||||||
|
// Type
|
||||||
|
#define REGIMM 1
|
||||||
|
#define STORE 5
|
||||||
|
// Op
|
||||||
|
#define LUI 7
|
||||||
|
#define ADDIU 1
|
||||||
|
#define SW 3
|
||||||
|
|
||||||
|
#define IS_LUI(a) ((OPTYPE(a) == REGIMM && OPCODE(a) == LUI))
|
||||||
|
#define IS_ADDIU(a) ((OPTYPE(a) == REGIMM && OPCODE(a) == ADDIU))
|
||||||
|
#define IS_SW_ZERO(a) ((OPTYPE(a) == STORE && OPCODE(a) == SW) && REG2(a) == 0)
|
||||||
|
|
||||||
|
#define BSS_CHK_LIMIT (18)
|
||||||
|
|
||||||
|
bool PackPs1::findBssSection()
|
||||||
|
{
|
||||||
|
unsigned char reg;
|
||||||
|
LE32 *p1 = (LE32 *)(ibuf + (ih.epc - ih.tx_ptr));
|
||||||
|
|
||||||
|
if ((ih.epc - ih.tx_ptr + (BSS_CHK_LIMIT * 4)) > fdata_size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check 18 opcodes for sw zero,0(x)
|
||||||
|
for (signed i = BSS_CHK_LIMIT; i >= 0; i--)
|
||||||
|
{
|
||||||
|
unsigned short op = p1[i] >> 16;
|
||||||
|
if (IS_SW_ZERO(op))
|
||||||
|
{
|
||||||
|
// found! get reg (x) for bss_start
|
||||||
|
reg = REG1(op);
|
||||||
|
for (; i >= 0; i--)
|
||||||
|
{
|
||||||
|
bss_nfo *p = (bss_nfo *)(void *)&p1[i];
|
||||||
|
unsigned short op1 = p->op1, op2 = p->op2;
|
||||||
|
|
||||||
|
// check for la (x),bss_start
|
||||||
|
if ((IS_LUI(op1) && REG2(op1) == reg) &&
|
||||||
|
(IS_ADDIU(op2) && REG1(op2) == reg))
|
||||||
|
{
|
||||||
|
op1 = p->op3, op2 = p->op4;
|
||||||
|
|
||||||
|
// check for la (y),bss_end
|
||||||
|
if (IS_LUI(op1) && IS_ADDIU(op2))
|
||||||
|
{
|
||||||
|
// bss section info found!
|
||||||
|
bss_start = MIPS_IMM(p->hi1, p->lo1);
|
||||||
|
bss_end = MIPS_IMM(p->hi2, p->lo2);
|
||||||
|
|
||||||
|
if (0 < ALIGN_DOWN(bss_end - bss_start, 4u))
|
||||||
|
{
|
||||||
|
unsigned wkmem_sz = M_IS_LZMA(ph.method) ? 32768 : 800;
|
||||||
|
unsigned end_offs = ih.tx_ptr + fdata_size + overlap;
|
||||||
|
if (bss_end > (end_offs + wkmem_sz))
|
||||||
|
return isCon || (!isCon && M_IS_LZMA(ph.method));
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -280,7 +477,7 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
{
|
{
|
||||||
ibuf.alloc(fdata_size);
|
ibuf.alloc(fdata_size);
|
||||||
obuf.allocForCompression(fdata_size);
|
obuf.allocForCompression(fdata_size);
|
||||||
const upx_byte *p_scan = ibuf+fdata_size;
|
const upx_byte *p_scan = ibuf + fdata_size;
|
||||||
|
|
||||||
// read file
|
// read file
|
||||||
fi->seek(PS_HDR_SIZE,SEEK_SET);
|
fi->seek(PS_HDR_SIZE,SEEK_SET);
|
||||||
@@ -288,12 +485,12 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
|
|
||||||
// scan EOF for 2048 bytes sector alignment
|
// scan EOF for 2048 bytes sector alignment
|
||||||
// the removed space will secure in-place decompression
|
// the removed space will secure in-place decompression
|
||||||
while (!(*--p_scan)) { if (sa_cnt++ > (0x10000<<5) || sa_cnt >= fdata_size-1024) break; }
|
while (!(*--p_scan)) { if (sa_cnt++ > (0x10000 << 5) || sa_cnt >= fdata_size - 1024) break; }
|
||||||
|
|
||||||
if (sa_cnt > (0x10000<<2))
|
if (sa_cnt > (0x10000 << 2))
|
||||||
sa_cnt = ALIGN_DOWN(sa_cnt,32);
|
sa_cnt = ALIGN_DOWN(sa_cnt, 32u);
|
||||||
else
|
else
|
||||||
sa_cnt = ALIGN_DOWN(sa_cnt,4);
|
sa_cnt = ALIGN_DOWN(sa_cnt, 4u);
|
||||||
|
|
||||||
// prepare packheader
|
// prepare packheader
|
||||||
ph.u_len = (fdata_size - sa_cnt);
|
ph.u_len = (fdata_size - sa_cnt);
|
||||||
@@ -301,29 +498,47 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
|
|
||||||
// compress (max_match = 65535)
|
// compress (max_match = 65535)
|
||||||
compressWithFilters(&ft, 512, 0, NULL, 0, 65535);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
cconf.conf_ucl.max_match = 65535;
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||||
|
compressWithFilters(&ft, sa_cnt, &cconf);
|
||||||
|
|
||||||
if (ph.overlap_overhead > sa_cnt)
|
if (overlap)
|
||||||
{
|
{
|
||||||
if (!opt->force)
|
opt->info_mode += !opt->info_mode ? 1 : 0;
|
||||||
{
|
infoWarning("overlap - relocating load address (+%d bytes)", overlap);
|
||||||
infoWarning("not in-place decompressible");
|
sa_cnt += overlap;
|
||||||
throwCantPack("packed data overlap (try --force)");
|
}
|
||||||
}
|
|
||||||
else
|
/*
|
||||||
{
|
if (bss_start && bss_end && !foundBss)
|
||||||
overlap = ALIGN_UP((ph.overlap_overhead-sa_cnt),4);
|
infoWarning("%s: .bss section too small - use stack", fi->getName());
|
||||||
opt->info_mode += !opt->info_mode ? 1 : 0;
|
*/
|
||||||
infoWarning("%s: memory overlap %d bytes",fi->getName(),overlap);
|
|
||||||
}
|
unsigned lzma_init = 0;
|
||||||
|
|
||||||
|
if (M_IS_LZMA(ph.method))
|
||||||
|
{
|
||||||
|
sz_lunc = getLoaderSize();
|
||||||
|
|
||||||
|
lzma_init = 0u - (sz_lunc - linker->getSymbolOffset("lzma.init"));
|
||||||
|
defineDecompressorSymbols();
|
||||||
|
linker->defineSymbol("entry", ih.epc);
|
||||||
|
linker->defineSymbol("SC",
|
||||||
|
sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2);
|
||||||
|
relocateLoader();
|
||||||
|
|
||||||
|
buildPart2 = true;
|
||||||
|
buildLoader(&ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&oh, &ih, sizeof(ih));
|
memcpy(&oh, &ih, sizeof(ih));
|
||||||
memcpy(&oh.ih_bkup, &ih.epc, SZ_IH_BKUP);
|
|
||||||
oh.ih_csum = upx_adler32(&ih.epc, SZ_IH_BKUP);
|
|
||||||
|
|
||||||
if (ih.is_ptr == 0)
|
unsigned sz_cbh;
|
||||||
oh.is_ptr = PS_RAM_SIZE-0x10;
|
putBkupHeader((const unsigned char *)&ih.epc, (unsigned char *)&bh, &sz_cbh);
|
||||||
|
|
||||||
|
if (ih.is_ptr < (EXE_BS | (PS_RAM_SIZE - PS_STACK_SIZE)))
|
||||||
|
oh.is_ptr = (EXE_BS | (PS_RAM_SIZE - 16));
|
||||||
|
|
||||||
if (ih.da_ptr != 0 || ih.da_len != 0 ||
|
if (ih.da_ptr != 0 || ih.da_len != 0 ||
|
||||||
ih.bs_ptr != 0 || ih.bs_len != 0)
|
ih.bs_ptr != 0 || ih.bs_len != 0)
|
||||||
@@ -331,49 +546,52 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
oh.bs_ptr = oh.bs_len = 0;
|
oh.bs_ptr = oh.bs_len = 0;
|
||||||
|
|
||||||
const int lsize = getLoaderSize();
|
const int lsize = getLoaderSize();
|
||||||
MemBuffer loader(lsize);
|
|
||||||
memcpy(loader, getLoader(), lsize);
|
|
||||||
|
|
||||||
patchPackHeader(loader,lsize);
|
|
||||||
|
|
||||||
unsigned pad = 0;
|
|
||||||
unsigned filelen = ALIGN_UP(ih.tx_len, 4);
|
unsigned filelen = ALIGN_UP(ih.tx_len, 4);
|
||||||
unsigned pad_code = TIL_ALIGNED(ph.c_len, 4);
|
|
||||||
|
|
||||||
const unsigned decomp_data_start = ih.tx_ptr;
|
const unsigned decomp_data_start = ih.tx_ptr;
|
||||||
const unsigned comp_data_start = ((decomp_data_start + filelen + overlap) - ph.c_len);
|
const unsigned comp_data_start = (decomp_data_start + filelen + overlap) - ph.c_len;
|
||||||
|
|
||||||
const int h_len = lsize - getLoaderSectionStart("IDENTSTR");
|
const int h_len = lsize - getLoaderSectionStart("UPX1HEAD");
|
||||||
const int c_len = lsize - h_len;
|
|
||||||
int d_len = 0;
|
int d_len = 0;
|
||||||
int e_len = 0;
|
int e_len = 0;
|
||||||
|
|
||||||
if (isCon)
|
if (isCon)
|
||||||
{
|
{
|
||||||
e_len = lsize - h_len;
|
e_len = lsize - h_len;
|
||||||
d_len = e_len - getLoaderSectionStart("PS1ENTRY");
|
d_len = e_len - getLoaderSectionStart("con.entry");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_len = (lsize - h_len) - getLoaderSectionStart("PS1ENTRY");
|
const char* entry_lzma = !foundBss ? "cdb.entry.lzma" : "bss.cdb.entry.lzma";
|
||||||
|
|
||||||
|
d_len = (lsize - h_len) - getLoaderSectionStart(M_IS_LZMA(ph.method) ? entry_lzma : "cdb.entry");
|
||||||
e_len = (lsize - d_len) - h_len;
|
e_len = (lsize - d_len) - h_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
patch_mips_le(loader,c_len,"JPEP",MIPS_JP(ih.epc));
|
linker->defineSymbol("entry", ih.epc);
|
||||||
if (sa_cnt)
|
linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ?
|
||||||
patch_mips_le(loader,c_len,"SC",
|
sa_cnt >> 5 : sa_cnt >> 2));
|
||||||
MIPS_LO(sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2));
|
linker->defineSymbol("DECO", decomp_data_start);
|
||||||
if (ih.tx_ptr & 0xffff)
|
linker->defineSymbol("ldr_sz", M_IS_LZMA(ph.method) ? sz_lunc + 16 : (d_len-pad_code));
|
||||||
patch_mips_le(loader,c_len,"DECO",decomp_data_start);
|
|
||||||
else
|
|
||||||
patch_mips_le(loader,c_len,"DE",MIPS_HI(decomp_data_start));
|
|
||||||
|
|
||||||
const unsigned entry = comp_data_start - e_len - pad_code;
|
if (foundBss)
|
||||||
oh.tx_ptr = entry;
|
{
|
||||||
oh.tx_len = ph.c_len + e_len + pad_code;
|
if (M_IS_LZMA(ph.method))
|
||||||
oh.epc = comp_data_start - e_len - pad_code;
|
linker->defineSymbol("wrkmem", bss_end - 160 - getDecompressorWrkmemSize()
|
||||||
|
- (sz_lunc + 16));
|
||||||
|
else
|
||||||
|
linker->defineSymbol("wrkmem", bss_end - 16 - (d_len - pad_code));
|
||||||
|
}
|
||||||
|
|
||||||
if (!opt->ps1_exe.no_align)
|
|
||||||
|
const unsigned entry = comp_data_start - e_len;
|
||||||
|
oh.epc = oh.tx_ptr = entry;
|
||||||
|
oh.tx_len = ph.c_len + e_len;
|
||||||
|
|
||||||
|
unsigned pad = 0;
|
||||||
|
|
||||||
|
if (!opt->ps1_exe.no_align || !isCon)
|
||||||
{
|
{
|
||||||
pad = oh.tx_len;
|
pad = oh.tx_len;
|
||||||
oh.tx_len = ALIGN_UP(oh.tx_len, CD_SEC);
|
oh.tx_len = ALIGN_UP(oh.tx_len, CD_SEC);
|
||||||
@@ -384,43 +602,57 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
ibuf.clear(0,fdata_size);
|
ibuf.clear(0,fdata_size);
|
||||||
upx_bytep paddata = ibuf;
|
upx_bytep paddata = ibuf;
|
||||||
|
|
||||||
|
if (M_IS_LZMA(ph.method))
|
||||||
|
{
|
||||||
|
linker->defineSymbol("lzma_init_off", lzma_init);
|
||||||
|
linker->defineSymbol("gb_e", linker->getSymbolOffset("gb8_e"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (isCon)
|
||||||
|
linker->defineSymbol("gb_e", linker->getSymbolOffset(is32Bit ? "gb32_e" : "gb8_e"));
|
||||||
|
|
||||||
if (isCon)
|
if (isCon)
|
||||||
{
|
{
|
||||||
if (pad_code)
|
linker->defineSymbol("PAD", pad_code);
|
||||||
patch_mips_le(loader, c_len, "PC", pad_code);
|
if (M_IS_LZMA(ph.method))
|
||||||
patch_mips_le(loader, c_len, "DCRT", entry + (e_len - d_len));
|
linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec")));
|
||||||
patch_mips_le(loader, c_len, "LS",
|
else
|
||||||
d_len + get_le32(&loader[getLoaderSectionStart("PS1SREGS")]));
|
linker->defineSymbol("DCRT", (entry + (e_len - d_len)));
|
||||||
|
|
||||||
// ps1_exe_t structure 188 bytes
|
|
||||||
fo->write(&oh,sizeof(oh));
|
|
||||||
// id & upx header
|
|
||||||
fo->write(loader + e_len,h_len);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
patch_mips_le(loader, c_len, "CPDO", comp_data_start);
|
linker->defineSymbol("PSVR", FIX_PSVR);
|
||||||
patch_mips_le(loader, e_len, "PSVR", FIX_PSVR);
|
linker->defineSymbol("CPDO", comp_data_start);
|
||||||
|
if (M_IS_LZMA(ph.method))
|
||||||
|
{
|
||||||
|
unsigned entry_lzma = getLoaderSectionStart( !foundBss ? "cdb.entry.lzma" :
|
||||||
|
"bss.cdb.entry.lzma");
|
||||||
|
|
||||||
// ps1_exe_t structure 188 bytes
|
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec") - entry_lzma);
|
||||||
fo->write(&oh,sizeof(oh));
|
}
|
||||||
// decompressor
|
|
||||||
fo->write(loader + e_len, d_len);
|
|
||||||
// id & upx header
|
|
||||||
fo->write(loader + e_len + d_len, h_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// header size is 2048 bytes
|
relocateLoader();
|
||||||
fo->write(paddata, PS_HDR_SIZE - fo->getBytesWritten());
|
//linker->dumpSymbols();
|
||||||
// sector alignment
|
MemBuffer loader(lsize);
|
||||||
if (pad)
|
assert(lsize == getLoaderSize());
|
||||||
fo->write(paddata, pad);
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
patchPackHeader(loader, lsize);
|
||||||
|
|
||||||
|
if (!isCon && M_IS_LZMA(ph.method) && (HD_CODE_OFS + d_len + h_len) > CD_SEC)
|
||||||
|
throwInternalError("lzma --boot-only loader > 2048");
|
||||||
|
|
||||||
|
// ps1_exe_t structure
|
||||||
|
fo->write(&oh, sizeof(oh));
|
||||||
|
fo->write(&bh, sz_cbh);
|
||||||
|
// decompressor
|
||||||
|
fo->write(loader + e_len, isCon ? h_len : (d_len + h_len));
|
||||||
|
|
||||||
|
// header size is 2048 bytes + sector alignment
|
||||||
|
fo->write(paddata, (pad + PS_HDR_SIZE) - fo->getBytesWritten());
|
||||||
// entry
|
// entry
|
||||||
fo->write(loader, e_len);
|
fo->write(loader, e_len);
|
||||||
// code must be aligned to 4!
|
// compressed body
|
||||||
if (pad_code)
|
|
||||||
fo->write(paddata, pad_code);
|
|
||||||
// compressed binary / data
|
|
||||||
fo->write(obuf, ph.c_len);
|
fo->write(obuf, ph.c_len);
|
||||||
|
|
||||||
verifyOverlappingDecompression();
|
verifyOverlappingDecompression();
|
||||||
@@ -428,15 +660,23 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
throwNotCompressible();
|
throwNotCompressible();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("%-13s: uncompressed : %8ld bytes\n", getName(), (long) ph.u_len);
|
printf("%-13s: uncompressed : %8ld bytes\n", getName(), (long) ph.u_len);
|
||||||
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len);
|
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len);
|
||||||
printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) lsize - h_len);
|
printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) lsize - h_len - pad_code);
|
||||||
printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc);
|
printf("%-13s: header comp : %8ld bytes\n", getName(), (long) sz_cbh);
|
||||||
printf("%-13s: load address : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr);
|
printf("%-13s: overlap : %8ld bytes\n", getName(), (long) overlap);
|
||||||
printf("%-13s: eof in mem IF: %08X bytes\n", getName(), (unsigned int) ih.tx_ptr+ih.tx_len);
|
printf("%-13s: load address : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr);
|
||||||
printf("%-13s: eof in mem OF: %08X bytes\n", getName(), (unsigned int) oh.tx_ptr+oh.tx_len);
|
printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc);
|
||||||
|
printf("%-13s: bbs start : %08X bytes\n", getName(), (unsigned int) bss_start);
|
||||||
|
printf("%-13s: bbs end : %08X bytes\n", getName(), (unsigned int) bss_end);
|
||||||
|
printf("%-13s: eof in mem IF : %08X bytes\n", getName(), (unsigned int) ih.tx_ptr + ih.tx_len);
|
||||||
|
printf("%-13s: eof in mem OF : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr + oh.tx_len);
|
||||||
|
unsigned char i = 0;
|
||||||
|
if (isCon) { if (foundBss) i = 1; }
|
||||||
|
else { i = 2; if (M_IS_LZMA(ph.method)) { if (!foundBss) i = 3; else i = 4; } }
|
||||||
|
const char *loader_method[] = { "con/stack", "con/bss", "cdb", "cdb/stack", "cdb/bss" };
|
||||||
char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);
|
char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);
|
||||||
printf("%-13s: compressor : %s\n", getName(), method_name);
|
printf("%-13s: methods : %s, %s\n", getName(), method_name, loader_method[i]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,11 +689,10 @@ int PackPs1::canUnpack()
|
|||||||
{
|
{
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
if (!readPackHeader(1024))
|
if (!readPackHeader(CD_SEC))
|
||||||
return false;
|
return false;
|
||||||
// check header as set by packer
|
// check header as set by packer
|
||||||
if (ih.ih_csum != upx_adler32(&ih.ih_bkup, SZ_IH_BKUP) &&
|
if (!readBkupHeader() || ph.c_len >= fdata_size)
|
||||||
(ph.c_len >= fdata_size))
|
|
||||||
throwCantUnpack("header damaged");
|
throwCantUnpack("header damaged");
|
||||||
// generic check
|
// generic check
|
||||||
if (!checkFileHeader())
|
if (!checkFileHeader())
|
||||||
@@ -470,7 +709,7 @@ void PackPs1::unpack(OutputFile *fo)
|
|||||||
{
|
{
|
||||||
// restore orig exec hdr
|
// restore orig exec hdr
|
||||||
memcpy(&oh, &ih, sizeof(ih));
|
memcpy(&oh, &ih, sizeof(ih));
|
||||||
memcpy(&oh.epc, &ih.ih_bkup, SZ_IH_BKUP);
|
memcpy(&oh.epc, &bh, SZ_IH_BKUP);
|
||||||
|
|
||||||
// check for removed sector alignment
|
// check for removed sector alignment
|
||||||
assert(oh.tx_len >= ph.u_len);
|
assert(oh.tx_len >= ph.u_len);
|
||||||
@@ -482,9 +721,6 @@ void PackPs1::unpack(OutputFile *fo)
|
|||||||
fi->seek(PS_HDR_SIZE, SEEK_SET);
|
fi->seek(PS_HDR_SIZE, SEEK_SET);
|
||||||
fi->readx(ibuf, fdata_size);
|
fi->readx(ibuf, fdata_size);
|
||||||
|
|
||||||
// clear backup and checksum of header
|
|
||||||
memset(&oh.ih_bkup, 0, SZ_IH_BKUP+4);
|
|
||||||
|
|
||||||
// decompress
|
// decompress
|
||||||
decompress(ibuf + (fdata_size - ph.c_len), obuf);
|
decompress(ibuf + (fdata_size - ph.c_len), obuf);
|
||||||
|
|
||||||
@@ -495,14 +731,14 @@ void PackPs1::unpack(OutputFile *fo)
|
|||||||
fo->write(&oh, sizeof(oh));
|
fo->write(&oh, sizeof(oh));
|
||||||
// align the ps exe header (mode 2 sector data size)
|
// align the ps exe header (mode 2 sector data size)
|
||||||
ibuf.clear();
|
ibuf.clear();
|
||||||
|
fo->write(ibuf, PS_HDR_SIZE - fo->getBytesWritten());
|
||||||
// write uncompressed data + pad
|
// write uncompressed data + pad
|
||||||
fo->write(ibuf, PS_HDR_SIZE - sizeof(oh));
|
|
||||||
obuf.clear(ph.u_len, pad);
|
obuf.clear(ph.u_len, pad);
|
||||||
fo->write(obuf, ph.u_len + pad);
|
fo->write(obuf, ph.u_len + pad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et:nowrap
|
vi:ts=4:et:nowrap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
+39
-20
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
Copyright (C) 2002-2004 Jens Medoch
|
Copyright (C) 2002-2010 Jens Medoch
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
Jens Medoch
|
Jens Medoch
|
||||||
<jssg@users.sourceforge.net>
|
<jssg@users.sourceforge.net>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_PS1_H
|
#ifndef __UPX_P_PS1_H
|
||||||
#define __UPX_P_PS1_H
|
#define __UPX_P_PS1_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -46,6 +46,7 @@ public:
|
|||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_PS1_EXE; }
|
virtual int getFormat() const { return UPX_F_PS1_EXE; }
|
||||||
virtual const char *getName() const { return "ps1/exe"; }
|
virtual const char *getName() const { return "ps1/exe"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "mipsel.r3000-ps1"; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
@@ -56,14 +57,17 @@ public:
|
|||||||
virtual int canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void patch_mips_le(void *b, int blen, const void *old, unsigned new_);
|
virtual void putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len);
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual bool getBkupHeader(unsigned char *src, unsigned char * dst);
|
||||||
|
virtual bool readBkupHeader();
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual bool findBssSection();
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
virtual bool checkFileHeader();
|
virtual bool checkFileHeader();
|
||||||
|
|
||||||
struct ps1_exe_t
|
__packed_struct(ps1_exe_t)
|
||||||
{
|
|
||||||
// ident string
|
// ident string
|
||||||
char id[8];
|
char id[8];
|
||||||
// is NULL
|
// is NULL
|
||||||
@@ -84,24 +88,41 @@ protected:
|
|||||||
LE32 sp, fp, gp0, ra, k0;
|
LE32 sp, fp, gp0, ra, k0;
|
||||||
// origin Jap/USA/Europe
|
// origin Jap/USA/Europe
|
||||||
char origin[60];
|
char origin[60];
|
||||||
|
|
||||||
// some safety space after that
|
|
||||||
char pad[8];
|
|
||||||
// backup of the original header (epc - is_len)
|
// backup of the original header (epc - is_len)
|
||||||
|
// id & the upx header ...
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
// for unpack
|
||||||
|
__packed_struct(ps1_exe_hb_t)
|
||||||
LE32 ih_bkup[10];
|
LE32 ih_bkup[10];
|
||||||
// plus checksum for the backup
|
// plus checksum for the backup
|
||||||
LE32 ih_csum;
|
LE32 ih_csum;
|
||||||
// id & the upx header.
|
__packed_struct_end()
|
||||||
}
|
|
||||||
__attribute_packed;
|
__packed_struct(ps1_exe_chb_t)
|
||||||
|
unsigned char id;
|
||||||
|
unsigned char len;
|
||||||
|
LE16 ih_csum;
|
||||||
|
unsigned char ih_bkup;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
__packed_struct(bss_nfo)
|
||||||
|
LE16 hi1, op1, lo1, op2;
|
||||||
|
LE16 hi2, op3, lo2, op4;
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
ps1_exe_t ih, oh;
|
ps1_exe_t ih, oh;
|
||||||
|
ps1_exe_hb_t bh;
|
||||||
|
|
||||||
bool isCon;
|
bool isCon;
|
||||||
bool is32Bit;
|
bool is32Bit;
|
||||||
unsigned overlap;
|
bool buildPart2;
|
||||||
unsigned sa_cnt;
|
bool foundBss;
|
||||||
|
unsigned ram_size;
|
||||||
|
unsigned sa_cnt, overlap;
|
||||||
|
unsigned sz_lunc, sz_lcpr;
|
||||||
|
unsigned pad_code;
|
||||||
|
unsigned bss_start, bss_end;
|
||||||
// filesize-PS_HDR_SIZE
|
// filesize-PS_HDR_SIZE
|
||||||
unsigned fdata_size;
|
unsigned fdata_size;
|
||||||
};
|
};
|
||||||
@@ -113,5 +134,3 @@ protected:
|
|||||||
/*
|
/*
|
||||||
vi:ts=4:et
|
vi:ts=4:et
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+24
-27
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -32,9 +32,10 @@
|
|||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_com.h"
|
#include "p_com.h"
|
||||||
#include "p_sys.h"
|
#include "p_sys.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_sys.h"
|
#include "stub/i086-dos16.sys.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -67,34 +68,31 @@ void PackSys::patchLoader(OutputFile *fo,
|
|||||||
upx_byte *loader, int lsize,
|
upx_byte *loader, int lsize,
|
||||||
unsigned calls)
|
unsigned calls)
|
||||||
{
|
{
|
||||||
const int filter_id = ph.filter;
|
|
||||||
const int e_len = getLoaderSectionStart("SYSCUTPO");
|
const int e_len = getLoaderSectionStart("SYSCUTPO");
|
||||||
const int d_len = lsize - e_len;
|
const int d_len = lsize - e_len;
|
||||||
assert(e_len > 0 && e_len < 256);
|
assert(e_len > 0 && e_len < 128);
|
||||||
assert(d_len > 0 && d_len < 256);
|
assert(d_len > 0 && d_len < 256);
|
||||||
|
|
||||||
if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe)
|
if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe)
|
||||||
throwNotCompressible();
|
throwNotCompressible();
|
||||||
|
|
||||||
memcpy(loader,ibuf,6); // copy from orig. header
|
// use some fields of the original file
|
||||||
memcpy(loader+8,ibuf+8,2); // opendos wants this word too
|
linker->defineSymbol("attribute", get_le16(ibuf + 4));
|
||||||
|
linker->defineSymbol("interrupt", get_le16(ibuf + 8));
|
||||||
|
|
||||||
unsigned copy_to = ph.u_len + d_len + ph.overlap_overhead;
|
unsigned copy_to = ph.u_len + d_len + ph.overlap_overhead;
|
||||||
|
|
||||||
patch_le16(loader,lsize,"JO",get_le16(ibuf+6)-copy_to-1);
|
linker->defineSymbol("calltrick_calls", calls);
|
||||||
if (filter_id)
|
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
||||||
{
|
linker->defineSymbol("copy_destination", copy_to);
|
||||||
assert(calls > 0);
|
linker->defineSymbol("neg_e_len", 0 - e_len);
|
||||||
patch_le16(loader,lsize,"CT",calls);
|
linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead + 1);
|
||||||
}
|
linker->defineSymbol("original_strategy", get_le16(ibuf + 6));
|
||||||
|
|
||||||
|
relocateLoader();
|
||||||
|
loader = getLoader();
|
||||||
|
|
||||||
patchPackHeader(loader,e_len);
|
patchPackHeader(loader,e_len);
|
||||||
|
|
||||||
const unsigned jmp_pos = find_le16(loader,e_len,get_le16("JM"));
|
|
||||||
patch_le16(loader,e_len,"JM",ph.u_len+ph.overlap_overhead+2-jmp_pos-2);
|
|
||||||
loader[getLoaderSectionStart("SYSSUBSI") - 1] = (upx_byte) -e_len;
|
|
||||||
patch_le16(loader,e_len,"DI",copy_to);
|
|
||||||
patch_le16(loader,e_len,"SI",ph.c_len+e_len+d_len-1);
|
|
||||||
|
|
||||||
// write loader + compressed file
|
// write loader + compressed file
|
||||||
fo->write(loader,e_len); // entry
|
fo->write(loader,e_len); // entry
|
||||||
fo->write(obuf,ph.c_len);
|
fo->write(obuf,ph.c_len);
|
||||||
@@ -102,17 +100,17 @@ void PackSys::patchLoader(OutputFile *fo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackSys::buildLoader(const Filter *ft)
|
void PackSys::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
initLoader(stub_i086_dos16_sys, sizeof(stub_i086_dos16_sys));
|
||||||
addLoader("SYSMAIN1",
|
addLoader("SYSMAIN1",
|
||||||
opt->cpu == opt->CPU_8086 ? "SYSI0861" : "SYSI2861",
|
opt->cpu == opt->CPU_8086 ? "SYSI0861" : "SYSI2861",
|
||||||
"SYSMAIN2,SYSSUBSI",
|
"SYSMAIN2",
|
||||||
ph.first_offset_found == 1 ? "SYSSBBBP" : "",
|
ph.first_offset_found == 1 ? "SYSSBBBP" : "",
|
||||||
ft->id ? "SYSCALLT" : "",
|
ft->id ? "SYSCALLT" : "",
|
||||||
"SYSMAIN3,UPX1HEAD,SYSCUTPO,NRV2B160,NRVDDONE,NRVDECO1",
|
"SYSMAIN3,UPX1HEAD,SYSCUTPO,NRV2B160,NRVDDONE,NRVDECO1",
|
||||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
||||||
"NRVDECO2,NRV2B169",
|
"NRVDECO2",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
@@ -125,7 +123,6 @@ int PackSys::buildLoader(const Filter *ft)
|
|||||||
"SYSJUMP1",
|
"SYSJUMP1",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+8
-6
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,13 +21,13 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_SYS_H
|
#ifndef __UPX_P_SYS_H
|
||||||
#define __UPX_P_SYS_H
|
#define __UPX_P_SYS_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -42,6 +42,8 @@ public:
|
|||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_DOS_SYS; }
|
virtual int getFormat() const { return UPX_F_DOS_SYS; }
|
||||||
virtual const char *getName() const { return "dos/sys"; }
|
virtual const char *getName() const { return "dos/sys"; }
|
||||||
|
//virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_8086 ? "i086-dos16.sys" : "i286-dos16.sys"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "i086-dos16.sys"; }
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
|
|
||||||
@@ -49,7 +51,7 @@ protected:
|
|||||||
virtual unsigned getCallTrickOffset() const { return 0; }
|
virtual unsigned getCallTrickOffset() const { return 0; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
|
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+49
-32
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -31,9 +31,10 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_tmt.h"
|
#include "p_tmt.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_tmt.h"
|
#include "stub/i386-dos32.tmt.h"
|
||||||
|
|
||||||
#define EXTRA_INFO 4 // original entry point
|
#define EXTRA_INFO 4 // original entry point
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ static const
|
|||||||
|
|
||||||
PackTmt::PackTmt(InputFile *f) : super(f)
|
PackTmt::PackTmt(InputFile *f) : super(f)
|
||||||
{
|
{
|
||||||
|
bele = &N_BELE_RTP::le_policy;
|
||||||
COMPILE_TIME_ASSERT(sizeof(tmt_header_t) == 44);
|
COMPILE_TIME_ASSERT(sizeof(tmt_header_t) == 44);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,34 +59,46 @@ const int *PackTmt::getCompressionMethods(int method, int level) const
|
|||||||
const int *PackTmt::getFilters() const
|
const int *PackTmt::getFilters() const
|
||||||
{
|
{
|
||||||
static const int filters[] = {
|
static const int filters[] = {
|
||||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x12, 0x15,
|
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
|
||||||
-1 };
|
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
|
||||||
|
FT_END };
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned PackTmt::findOverlapOverhead(const upx_bytep buf,
|
unsigned PackTmt::findOverlapOverhead(const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned range,
|
unsigned range,
|
||||||
unsigned upper_limit) const
|
unsigned upper_limit) const
|
||||||
{
|
{
|
||||||
// make sure the decompressor will be paragraph aligned
|
// make sure the decompressor will be paragraph aligned
|
||||||
unsigned o = super::findOverlapOverhead(buf, range, upper_limit);
|
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
|
||||||
o = ((o + 0x20) &~ 0xf) - (ph.u_len & 0xf);
|
o = ((o + 0x20) &~ 0xf) - (ph.u_len & 0xf);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackTmt::buildLoader(const Filter *ft)
|
Linker* PackTmt::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PackTmt::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
initLoader(stub_i386_dos32_tmt, sizeof(stub_i386_dos32_tmt));
|
||||||
addLoader("IDENTSTR,TMTMAIN1",
|
addLoader("IDENTSTR,TMTMAIN1",
|
||||||
|
ph.first_offset_found == 1 ? "TMTMAIN1A" : "",
|
||||||
|
"TMTMAIN1B",
|
||||||
ft->id ? "TMTCALT1" : "",
|
ft->id ? "TMTCALT1" : "",
|
||||||
"TMTMAIN2,UPX1HEAD,TMTCUTPO,+0XXXXXX",
|
"TMTMAIN2,UPX1HEAD,TMTCUTPO",
|
||||||
getDecompressor(),
|
NULL);
|
||||||
"TMTMAIN5",
|
|
||||||
NULL
|
// fake alignment for the start of the decompressor
|
||||||
);
|
linker->defineSymbol("TMTCUTPO", 0x1000);
|
||||||
|
|
||||||
|
addLoader(getDecompressorSections(), "TMTMAIN5", NULL);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
{
|
{
|
||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
@@ -96,7 +110,6 @@ int PackTmt::buildLoader(const Filter *ft)
|
|||||||
"RELOC32J,TMTJUMP1",
|
"RELOC32J,TMTJUMP1",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
return getLoaderSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -159,7 +172,7 @@ int PackTmt::readFileHeader()
|
|||||||
|
|
||||||
fi->seek(adam_offset,SEEK_SET);
|
fi->seek(adam_offset,SEEK_SET);
|
||||||
fi->readx(&ih,sizeof(ih));
|
fi->readx(&ih,sizeof(ih));
|
||||||
// FIXME: should add some checks for the values in `ih'
|
// FIXME: should add some checks for the values in 'ih'
|
||||||
|
|
||||||
return UPX_F_TMT_ADAM;
|
return UPX_F_TMT_ADAM;
|
||||||
#undef H4
|
#undef H4
|
||||||
@@ -227,33 +240,37 @@ void PackTmt::pack(OutputFile *fo)
|
|||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
ft.buf_len = usize;
|
ft.buf_len = usize;
|
||||||
// compress
|
// compress
|
||||||
compressWithFilters(&ft, 512);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
// limit stack size needed for runtime decompression
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||||
|
compressWithFilters(&ft, 512, &cconf);
|
||||||
|
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
MemBuffer loader(lsize);
|
|
||||||
memcpy(loader,getLoader(),lsize);
|
|
||||||
|
|
||||||
const unsigned s_point = getLoaderSection("TMTMAIN1");
|
const unsigned s_point = getLoaderSection("TMTMAIN1");
|
||||||
int e_len = getLoaderSectionStart("TMTCUTPO");
|
int e_len = getLoaderSectionStart("TMTCUTPO");
|
||||||
const unsigned d_len = lsize - e_len;
|
const unsigned d_len = lsize - e_len;
|
||||||
assert(e_len > 0 && s_point > 0);
|
assert(e_len > 0 && s_point > 0);
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
patch_le32(loader,lsize,"JMPO",ih.entry-(ph.u_len+ph.overlap_overhead+d_len));
|
linker->defineSymbol("original_entry", ih.entry);
|
||||||
patchFilter32(loader, lsize, &ft);
|
defineDecompressorSymbols();
|
||||||
patchPackHeader(loader,e_len);
|
defineFilterSymbols(&ft);
|
||||||
|
|
||||||
const unsigned jmp_pos = find_le32(loader,e_len,get_le32("JMPD"));
|
linker->defineSymbol("bytes_to_copy", ph.c_len + d_len);
|
||||||
patch_le32(loader,e_len,"JMPD",ph.u_len+ph.overlap_overhead-jmp_pos-4);
|
linker->defineSymbol("copy_dest", 0u - (ph.u_len + ph.overlap_overhead + d_len - 1));
|
||||||
|
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
||||||
patch_le32(loader,e_len,"ECX0",ph.c_len+d_len);
|
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x c_len=%x \n\n",
|
||||||
patch_le32(loader,e_len,"EDI0",ph.u_len+ph.overlap_overhead+d_len-1);
|
|
||||||
patch_le32(loader,e_len,"ESI0",ph.c_len+e_len+d_len-1);
|
|
||||||
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x clen=%x \n\n",
|
|
||||||
// e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len);
|
// e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len);
|
||||||
|
|
||||||
|
linker->defineSymbol("TMTCUTPO", ph.u_len + ph.overlap_overhead);
|
||||||
|
relocateLoader();
|
||||||
|
|
||||||
|
MemBuffer loader(lsize);
|
||||||
|
memcpy(loader,getLoader(),lsize);
|
||||||
|
patchPackHeader(loader,e_len);
|
||||||
|
|
||||||
memcpy(&oh,&ih,sizeof(oh));
|
memcpy(&oh,&ih,sizeof(oh));
|
||||||
oh.imagesize = ph.c_len+e_len+d_len; // new size
|
oh.imagesize = ph.c_len + lsize; // new size
|
||||||
oh.entry = s_point; // new entry point
|
oh.entry = s_point; // new entry point
|
||||||
oh.relocsize = 4;
|
oh.relocsize = 4;
|
||||||
|
|
||||||
|
|||||||
+9
-6
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,13 +21,13 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_TMT_H
|
#ifndef __UPX_P_TMT_H
|
||||||
#define __UPX_P_TMT_H
|
#define __UPX_P_TMT_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -42,6 +42,7 @@ public:
|
|||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_TMT_ADAM; }
|
virtual int getFormat() const { return UPX_F_TMT_ADAM; }
|
||||||
virtual const char *getName() const { return "tmt/adam"; }
|
virtual const char *getName() const { return "tmt/adam"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "i386-dos32.tmt.adam"; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
@@ -55,9 +56,11 @@ protected:
|
|||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
|
|
||||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned range = 0,
|
unsigned range = 0,
|
||||||
unsigned upper_limit = ~0u) const;
|
unsigned upper_limit = ~0u) const;
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
unsigned adam_offset;
|
unsigned adam_offset;
|
||||||
int big_relocs;
|
int big_relocs;
|
||||||
|
|||||||
+360
-267
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -32,21 +32,12 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_tos.h"
|
#include "p_tos.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_t_n2b.h"
|
#include "stub/m68k-atari.tos.h"
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2bs.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2d.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2ds.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2e.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2es.h"
|
|
||||||
|
|
||||||
// #define TESTING
|
//#define TESTING 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -58,6 +49,7 @@ static const
|
|||||||
PackTos::PackTos(InputFile *f) :
|
PackTos::PackTos(InputFile *f) :
|
||||||
super(f)
|
super(f)
|
||||||
{
|
{
|
||||||
|
bele = &N_BELE_RTP::be_policy;
|
||||||
COMPILE_TIME_ASSERT(FH_SIZE == 28);
|
COMPILE_TIME_ASSERT(FH_SIZE == 28);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,30 +67,180 @@ const int *PackTos::getFilters() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const upx_byte *PackTos::getLoader() const
|
Linker* PackTos::newLinker() const
|
||||||
{
|
{
|
||||||
if (M_IS_NRV2B(ph.method))
|
return new ElfLinkerM68k;
|
||||||
return opt->small ? nrv2b_loader_small : nrv2b_loader;
|
|
||||||
if (M_IS_NRV2D(ph.method))
|
|
||||||
return opt->small ? nrv2d_loader_small : nrv2d_loader;
|
|
||||||
if (M_IS_NRV2E(ph.method))
|
|
||||||
return opt->small ? nrv2e_loader_small : nrv2e_loader;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackTos::getLoaderSize() const
|
void PackTos::LinkerSymbols::LoopInfo::init(unsigned count_, bool allow_dbra)
|
||||||
{
|
{
|
||||||
if (M_IS_NRV2B(ph.method))
|
count = value = count_;
|
||||||
return opt->small ? sizeof(nrv2b_loader_small) : sizeof(nrv2b_loader);
|
if (count == 0)
|
||||||
if (M_IS_NRV2D(ph.method))
|
mode = LOOP_NONE;
|
||||||
return opt->small ? sizeof(nrv2d_loader_small) : sizeof(nrv2d_loader);
|
else if (count <= 65536 && allow_dbra)
|
||||||
if (M_IS_NRV2E(ph.method))
|
{
|
||||||
return opt->small ? sizeof(nrv2e_loader_small) : sizeof(nrv2e_loader);
|
mode = LOOP_DBRA;
|
||||||
|
value -= 1;
|
||||||
|
value &= 0xffff;
|
||||||
|
}
|
||||||
|
else if (count <= 65536)
|
||||||
|
{
|
||||||
|
mode = LOOP_SUBQ_W;
|
||||||
|
value &= 0xffff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mode = LOOP_SUBQ_L;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned PackTos::getDecomprOffset(int method, int small) const
|
||||||
|
{
|
||||||
|
UNUSED(small);
|
||||||
|
if (M_IS_NRV2B(method))
|
||||||
|
return 2; // FIXME: do not hardcode this value
|
||||||
|
else if (M_IS_NRV2D(method))
|
||||||
|
return 2; // FIXME: do not hardcode this value
|
||||||
|
else if (M_IS_NRV2E(method))
|
||||||
|
return 2; // FIXME: do not hardcode this value
|
||||||
|
else if (M_IS_LZMA(method))
|
||||||
|
return linker->getSectionSize("__mulsi3");
|
||||||
|
else
|
||||||
|
throwBadLoader();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PackTos::buildLoader(const Filter *ft)
|
||||||
|
{
|
||||||
|
assert(ft->id == 0);
|
||||||
|
|
||||||
|
initLoader(stub_m68k_atari_tos, sizeof(stub_m68k_atari_tos));
|
||||||
|
//linker->dumpSymbols();
|
||||||
|
|
||||||
|
//
|
||||||
|
// part 1a
|
||||||
|
//
|
||||||
|
|
||||||
|
addLoader("entry");
|
||||||
|
|
||||||
|
if (symbols.up21_a6 <= 32767)
|
||||||
|
addLoader("set_up21_a6.w");
|
||||||
|
else if (symbols.up21_d4 <= 32767)
|
||||||
|
addLoader("set_up21_d4.w");
|
||||||
|
else
|
||||||
|
addLoader("set_up21_d4.l");
|
||||||
|
|
||||||
|
assert(symbols.loop1.count || symbols.loop2.count);
|
||||||
|
if (symbols.loop1.count)
|
||||||
|
{
|
||||||
|
if (symbols.loop1.value <= 127)
|
||||||
|
addLoader("loop1_set_count.b");
|
||||||
|
else if (symbols.loop1.value <= 65535)
|
||||||
|
addLoader("loop1_set_count.w");
|
||||||
|
else
|
||||||
|
addLoader("loop1_set_count.l");
|
||||||
|
addLoader("loop1_label");
|
||||||
|
addLoader(opt->small ? "loop1.small" : "loop1.fast");
|
||||||
|
if (symbols.loop1.mode == symbols.LOOP_SUBQ_L)
|
||||||
|
addLoader("loop1_subql");
|
||||||
|
else if (symbols.loop1.mode == symbols.LOOP_SUBQ_W)
|
||||||
|
addLoader("loop1_subqw");
|
||||||
|
else if (symbols.loop1.mode == symbols.LOOP_DBRA)
|
||||||
|
addLoader("loop1_dbra");
|
||||||
|
else
|
||||||
|
throwBadLoader();
|
||||||
|
}
|
||||||
|
if (symbols.loop2.count)
|
||||||
|
{
|
||||||
|
assert(symbols.loop2.mode == symbols.LOOP_DBRA);
|
||||||
|
addLoader(opt->small ? "loop2.small" : "loop2.fast");
|
||||||
|
}
|
||||||
|
|
||||||
|
addLoader("copy_to_stack");
|
||||||
|
|
||||||
|
if (M_IS_NRV2B(ph.method))
|
||||||
|
addLoader("nrv2b.init");
|
||||||
|
else if (M_IS_NRV2D(ph.method))
|
||||||
|
addLoader("nrv2d.init");
|
||||||
|
else if (M_IS_NRV2E(ph.method))
|
||||||
|
addLoader("nrv2e.init");
|
||||||
|
else if (M_IS_LZMA(ph.method))
|
||||||
|
addLoader("lzma.init");
|
||||||
|
else
|
||||||
|
throwBadLoader();
|
||||||
|
|
||||||
|
symbols.up31_d4 = symbols.up31_base_d4 + getDecomprOffset(ph.method, opt->small);
|
||||||
|
symbols.up31_a6 = symbols.up31_base_a6 + getDecomprOffset(ph.method, opt->small);
|
||||||
|
if (symbols.up31_a6 <= 32767)
|
||||||
|
addLoader("jmp_decompressor_a6.w");
|
||||||
|
else if (symbols.up31_d4 <= 32767)
|
||||||
|
addLoader("jmp_decompressor_d4.w");
|
||||||
|
else if (symbols.up31_a6 <= 65534)
|
||||||
|
addLoader("jmp_decompressor_a6.w2");
|
||||||
|
else
|
||||||
|
addLoader("jmp_decompressor_d4.l");
|
||||||
|
|
||||||
|
//
|
||||||
|
// part 1b
|
||||||
|
//
|
||||||
|
|
||||||
|
addLoader("code_on_stack");
|
||||||
|
|
||||||
|
addLoader("clear_dirty_bss");
|
||||||
|
addLoader("loop3_label");
|
||||||
|
addLoader(opt->small ? "loop3.small" : "loop3.fast");
|
||||||
|
if (symbols.loop3.mode == symbols.LOOP_SUBQ_L)
|
||||||
|
addLoader("loop3_subql");
|
||||||
|
else if (symbols.loop3.mode == symbols.LOOP_SUBQ_W)
|
||||||
|
addLoader("loop3_subqw");
|
||||||
|
else if (symbols.loop3.mode == symbols.LOOP_DBRA)
|
||||||
|
addLoader("loop3_dbra");
|
||||||
|
else
|
||||||
|
throwBadLoader();
|
||||||
|
|
||||||
|
addLoader("flush_cache");
|
||||||
|
addLoader("restore_stack");
|
||||||
|
#if 0
|
||||||
|
addLoader("clear_dirty_stack");
|
||||||
|
#endif
|
||||||
|
addLoader("start_program");
|
||||||
|
|
||||||
|
addLoader("IDENTSTR,+40D,UPX1HEAD,CUTPOINT");
|
||||||
|
|
||||||
|
//
|
||||||
|
// part 2
|
||||||
|
//
|
||||||
|
|
||||||
|
if (M_IS_NRV2B(ph.method)) {
|
||||||
|
addLoader(opt->small ? "nrv2b_8.small" : "nrv2b_8.fast");
|
||||||
|
} else if (M_IS_NRV2D(ph.method)) {
|
||||||
|
addLoader(opt->small ? "nrv2d_8.small" : "nrv2d_8.fast");
|
||||||
|
} else if (M_IS_NRV2E(ph.method)) {
|
||||||
|
addLoader(opt->small ? "nrv2e_8.small" : "nrv2e_8.fast");
|
||||||
|
} else if (M_IS_LZMA(ph.method)) {
|
||||||
|
addLoader("__mulsi3");
|
||||||
|
addLoader(opt->small ? "lzma.small" : "lzma.fast");
|
||||||
|
addLoader("lzma.finish");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throwBadLoader();
|
||||||
|
|
||||||
|
if (symbols.need_reloc)
|
||||||
|
addLoader("reloc");
|
||||||
|
|
||||||
|
assert(symbols.loop3.count);
|
||||||
|
if (symbols.loop3.value <= 127)
|
||||||
|
addLoader("loop3_set_count.b");
|
||||||
|
else if (symbols.loop3.value <= 65535)
|
||||||
|
addLoader("loop3_set_count.w");
|
||||||
|
else
|
||||||
|
addLoader("loop3_set_count.l");
|
||||||
|
|
||||||
|
addLoader("jmp_stack");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -165,142 +307,25 @@ bool PackTos::checkFileHeader()
|
|||||||
if ((f & F_PROTMODE) != F_PROT_P)
|
if ((f & F_PROTMODE) != F_PROT_P)
|
||||||
{
|
{
|
||||||
if (opt->force < 1)
|
if (opt->force < 1)
|
||||||
throwCantPack("no private memory protection; use option `-f' to force packing");
|
throwCantPack("no private memory protection; use option '-f' to force packing");
|
||||||
}
|
}
|
||||||
if (f & F_SHTEXT)
|
if (f & F_SHTEXT)
|
||||||
{
|
{
|
||||||
if (opt->force < 1)
|
if (opt->force < 1)
|
||||||
throwCantPack("shared text segment; use option `-f' to force packing");
|
throwCantPack("shared text segment; use option '-f' to force packing");
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
// fh_reserved seems to be unused
|
// fh_reserved seems to be unused
|
||||||
if (ih.fh_reserved != 0)
|
if (ih.fh_reserved != 0)
|
||||||
{
|
{
|
||||||
if (opt->force < 1)
|
if (opt->force < 1)
|
||||||
throwCantPack("reserved header field set; use option `-f' to force packing");
|
throwCantPack("reserved header field set; use option '-f' to force packing");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// some 68000 opcodes for patching
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
enum m68k_reg_t {
|
|
||||||
REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7,
|
|
||||||
REG_A0, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned OP_DBRA(int d_reg)
|
|
||||||
{
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
return 0x51c8 | (d_reg & 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned OP_JMP(int a_reg)
|
|
||||||
{
|
|
||||||
// jmp (a0)
|
|
||||||
assert(a_reg >= REG_A0 && a_reg <= REG_A7);
|
|
||||||
return 0x4ed0 | (a_reg & 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned OP_MOVEI_L(int d_reg)
|
|
||||||
{
|
|
||||||
// movei.l #XXXXXXXX,d0
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
return 0x203c | ((d_reg & 7) << 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned OP_MOVEQ(int value, int d_reg)
|
|
||||||
{
|
|
||||||
// moveq.l #0,d0
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
assert(value >= -128 && value <= 127);
|
|
||||||
return 0x7000 | ((d_reg & 7) << 9) | (value & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned OP_SUBQ_L(int value, int d_reg)
|
|
||||||
{
|
|
||||||
// subq.l #X,d0
|
|
||||||
assert(value >= 1 && value <= 8);
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
return 0x5180 | ((value & 7) << 9) | (d_reg & 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned OP_SUBQ_W(int value, int d_reg)
|
|
||||||
{
|
|
||||||
// subq.w #X,d0
|
|
||||||
assert(value >= 1 && value <= 8);
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
return 0x5140 | ((value & 7) << 9) | (d_reg & 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
unsigned PackTos::patch_d_subq(void *b, int blen,
|
|
||||||
int d_reg, unsigned d_value,
|
|
||||||
const char *subq_marker)
|
|
||||||
{
|
|
||||||
// patch a "subq.l #1,d0" or "subq.w #1,d0".
|
|
||||||
// also convert into "dbra" if possible
|
|
||||||
assert(d_reg >= REG_D0 && d_reg <= REG_D7);
|
|
||||||
assert((int)d_value > 0);
|
|
||||||
|
|
||||||
int boff = find_be16(b, blen, get_be16(subq_marker));
|
|
||||||
if (boff < 0)
|
|
||||||
throwBadLoader();
|
|
||||||
|
|
||||||
upx_byte *p = (upx_byte *)b + boff;
|
|
||||||
if (p[2] == 0x66) // bne.b XXX
|
|
||||||
checkPatch(b, blen, boff, 4);
|
|
||||||
else
|
|
||||||
checkPatch(b, blen, boff, 2);
|
|
||||||
|
|
||||||
if (d_value > 65536)
|
|
||||||
{
|
|
||||||
set_be16(p, OP_SUBQ_L(1, d_reg)); // subq.l #1,d0
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (p[2] == 0x66) // bne.b XXX
|
|
||||||
{
|
|
||||||
set_be16(p, OP_DBRA(d_reg)); // dbra d0,XXX
|
|
||||||
// adjust and extend branch from 8 to 16 bits
|
|
||||||
int branch = (signed char) p[3];
|
|
||||||
set_be16(p+2, branch+2);
|
|
||||||
// adjust d0
|
|
||||||
d_value -= 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
set_be16(p, OP_SUBQ_W(1, d_reg)); // subq.w #1,d0
|
|
||||||
}
|
|
||||||
d_value &= 0xffff;
|
|
||||||
}
|
|
||||||
return d_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned PackTos::patch_d_loop(void *b, int blen,
|
|
||||||
int d_reg, unsigned d_value,
|
|
||||||
const char *d_marker, const char *subq_marker)
|
|
||||||
{
|
|
||||||
d_value = patch_d_subq(b, blen, d_reg, d_value, subq_marker);
|
|
||||||
|
|
||||||
int boff = find_be32(b, blen, get_be32(d_marker));
|
|
||||||
checkPatch(b, blen, boff, 4);
|
|
||||||
upx_byte *p = (upx_byte *)b + boff;
|
|
||||||
assert(get_be16(p - 2) == OP_MOVEI_L(d_reg)); // move.l #XXXXXXXX,d0
|
|
||||||
set_be32(p, d_value);
|
|
||||||
return d_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// relocs
|
// relocs
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -354,18 +379,6 @@ static int check_relocs(const upx_byte *relocs, unsigned rsize, unsigned isize,
|
|||||||
|
|
||||||
bool PackTos::canPack()
|
bool PackTos::canPack()
|
||||||
{
|
{
|
||||||
#if 0 // debug
|
|
||||||
# define p(x) printf("%-30s 0x%04x\n", #x, x)
|
|
||||||
p(OP_DBRA(REG_D0));
|
|
||||||
p(OP_MOVEI_L(REG_D0));
|
|
||||||
p(OP_MOVEQ(-1, REG_D0));
|
|
||||||
p(OP_MOVEQ(1, REG_D2));
|
|
||||||
p(OP_MOVEQ(1, REG_D3));
|
|
||||||
p(OP_SUBQ_W(1, REG_D0));
|
|
||||||
p(OP_SUBQ_L(1, REG_D0));
|
|
||||||
# undef p
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -386,10 +399,8 @@ void PackTos::fileInfo()
|
|||||||
{
|
{
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return;
|
return;
|
||||||
#if !defined(WITH_GUI)
|
|
||||||
con_fprintf(stdout, " text: %d, data: %d, sym: %d, bss: %d, flags=0x%x\n",
|
con_fprintf(stdout, " text: %d, data: %d, sym: %d, bss: %d, flags=0x%x\n",
|
||||||
(int)ih.fh_text, (int)ih.fh_data, (int)ih.fh_sym, (int)ih.fh_bss, (int)ih.fh_flag);
|
(int)ih.fh_text, (int)ih.fh_data, (int)ih.fh_sym, (int)ih.fh_bss, (int)ih.fh_flag);
|
||||||
#endif /* !defined(WITH_GUI) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -409,6 +420,17 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
const unsigned i_sym = ih.fh_sym;
|
const unsigned i_sym = ih.fh_sym;
|
||||||
const unsigned i_bss = ih.fh_bss;
|
const unsigned i_bss = ih.fh_bss;
|
||||||
|
|
||||||
|
symbols.reset();
|
||||||
|
symbols.need_reloc = false;
|
||||||
|
// prepare symbols for buildLoader() - worst case
|
||||||
|
symbols.loop1.init(65536 + 1);
|
||||||
|
symbols.loop2.init((160 - 1) / 4);
|
||||||
|
symbols.loop3.init(65536 + 1);
|
||||||
|
symbols.up21_d4 = 65536 + 1;
|
||||||
|
symbols.up21_a6 = 65536 + 1;
|
||||||
|
symbols.up31_base_d4 = 65536 + 1;
|
||||||
|
symbols.up31_base_a6 = 65536 + 1;
|
||||||
|
|
||||||
// read file
|
// read file
|
||||||
const unsigned isize = file_size - i_sym;
|
const unsigned isize = file_size - i_sym;
|
||||||
ibuf.alloc(isize);
|
ibuf.alloc(isize);
|
||||||
@@ -417,12 +439,14 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
t = i_text + i_data;
|
t = i_text + i_data;
|
||||||
fi->readx(ibuf,t);
|
fi->readx(ibuf,t);
|
||||||
// skip symbols
|
// skip symbols
|
||||||
|
if (i_sym && opt->exact)
|
||||||
|
throwCantPackExact();
|
||||||
fi->seek(i_sym,SEEK_CUR);
|
fi->seek(i_sym,SEEK_CUR);
|
||||||
// read relocations + overlay
|
// read relocations + overlay
|
||||||
overlay = file_size - (FH_SIZE + i_text + i_data + i_sym);
|
overlay = file_size - (FH_SIZE + i_text + i_data + i_sym);
|
||||||
fi->readx(ibuf+t,overlay);
|
fi->readx(ibuf+t,overlay);
|
||||||
|
|
||||||
#if 0 || defined(TESTING)
|
#if 0 || (TESTING)
|
||||||
printf("text: %d, data: %d, sym: %d, bss: %d, flags=0x%x\n",
|
printf("text: %d, data: %d, sym: %d, bss: %d, flags=0x%x\n",
|
||||||
i_text, i_data, i_sym, i_bss, (int)ih.fh_flag);
|
i_text, i_data, i_sym, i_bss, (int)ih.fh_flag);
|
||||||
printf("xx1 reloc: %d, overlay: %d, fixup: %d\n", relocsize, overlay, overlay >= 4 ? (int)get_be32(ibuf+t) : -1);
|
printf("xx1 reloc: %d, overlay: %d, fixup: %d\n", relocsize, overlay, overlay >= 4 ? (int)get_be32(ibuf+t) : -1);
|
||||||
@@ -430,7 +454,6 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
|
|
||||||
// Check relocs (see load_and_reloc() in freemint/sys/memory.c).
|
// Check relocs (see load_and_reloc() in freemint/sys/memory.c).
|
||||||
// Must work around TOS bugs and lots of broken programs.
|
// Must work around TOS bugs and lots of broken programs.
|
||||||
int r = 0;
|
|
||||||
if (overlay < 4)
|
if (overlay < 4)
|
||||||
{
|
{
|
||||||
// Bug workaround: Whatever this is, silently keep it in
|
// Bug workaround: Whatever this is, silently keep it in
|
||||||
@@ -446,15 +469,17 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
else if (ih.fh_reloc != 0)
|
else if (ih.fh_reloc != 0)
|
||||||
relocsize = 0;
|
relocsize = 0;
|
||||||
else
|
else {
|
||||||
r = check_relocs(ibuf+t, overlay, t, &nrelocs, &relocsize, &overlay);
|
int r = check_relocs(ibuf+t, overlay, t, &nrelocs, &relocsize, &overlay);
|
||||||
|
if (r != 0)
|
||||||
|
throwCantPack("bad relocation table");
|
||||||
|
symbols.need_reloc = true;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0 || defined(TESTING)
|
#if 0 || (TESTING)
|
||||||
printf("xx2: %d relocs: %d, overlay: %d, t: %d\n", nrelocs, relocsize, overlay, t);
|
printf("xx2: %d relocs: %d, overlay: %d, t: %d\n", nrelocs, relocsize, overlay, t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (r != 0)
|
|
||||||
throwCantPack("bad relocation table");
|
|
||||||
checkOverlay(overlay);
|
checkOverlay(overlay);
|
||||||
|
|
||||||
// Append original fileheader.
|
// Append original fileheader.
|
||||||
@@ -462,7 +487,7 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
ih.fh_sym = 0; // we stripped all symbols
|
ih.fh_sym = 0; // we stripped all symbols
|
||||||
memcpy(ibuf+t, &ih, FH_SIZE);
|
memcpy(ibuf+t, &ih, FH_SIZE);
|
||||||
t += FH_SIZE;
|
t += FH_SIZE;
|
||||||
#if 0 || defined(TESTING)
|
#if 0 || (TESTING)
|
||||||
printf("xx3 reloc: %d, overlay: %d, t: %d\n", relocsize, overlay, t);
|
printf("xx3 reloc: %d, overlay: %d, t: %d\n", relocsize, overlay, t);
|
||||||
#endif
|
#endif
|
||||||
assert(t <= isize);
|
assert(t <= isize);
|
||||||
@@ -472,114 +497,173 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
// After compression this will become the first part of the
|
// After compression this will become the first part of the
|
||||||
// data segement. The second part will be the decompressor.
|
// data segement. The second part will be the decompressor.
|
||||||
|
|
||||||
// alloc buffer (2048 is for decompressor and the various alignments)
|
// alloc buffer (4096 is for decompressor and the various alignments)
|
||||||
obuf.allocForCompression(t, 2048);
|
obuf.allocForCompression(t, 4096);
|
||||||
|
|
||||||
// prepare packheader
|
// prepare packheader
|
||||||
ph.u_len = t;
|
ph.u_len = t;
|
||||||
// prepare filter
|
// prepare filter
|
||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
// compress (max_match = 65535)
|
// compress (max_match = 65535)
|
||||||
compressWithFilters(&ft, 512, 0, NULL, 0, 65535);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
cconf.conf_ucl.max_match = 65535;
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||||
|
compressWithFilters(&ft, 512, &cconf);
|
||||||
|
|
||||||
// get loader
|
//
|
||||||
const unsigned lsize = getLoaderSize();
|
// multipass buildLoader()
|
||||||
const unsigned e_len = get_be16(getLoader()+lsize-6);
|
//
|
||||||
const unsigned d_len = get_be16(getLoader()+lsize-4);
|
|
||||||
const unsigned decomp_offset = get_be16(getLoader()+lsize-2);
|
|
||||||
assert(e_len + d_len == lsize - 6);
|
|
||||||
assert((e_len & 3) == 0 && (d_len & 1) == 0);
|
|
||||||
|
|
||||||
// The decompressed data will now get placed at this offset:
|
// save initial loader
|
||||||
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
|
const unsigned initial_lsize = getLoaderSize();
|
||||||
|
unsigned last_lsize = initial_lsize;
|
||||||
|
MemBuffer last_loader(last_lsize);
|
||||||
|
memcpy(last_loader, getLoader(), last_lsize);
|
||||||
|
|
||||||
// compute addresses
|
|
||||||
unsigned o_text, o_data, o_bss;
|
unsigned o_text, o_data, o_bss;
|
||||||
o_text = e_len;
|
unsigned e_len, d_len, d_off;
|
||||||
o_data = ph.c_len;
|
for (;;)
|
||||||
o_bss = i_bss;
|
|
||||||
|
|
||||||
// word align len of compressed data
|
|
||||||
while (o_data & 1)
|
|
||||||
{
|
{
|
||||||
obuf[o_data++] = 0;
|
// The decompressed data will now get placed at this offset:
|
||||||
offset++;
|
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
|
||||||
}
|
|
||||||
|
|
||||||
// append decompressor (part 2 of loader)
|
// get loader
|
||||||
const unsigned d_off = o_data;
|
const unsigned lsize = getLoaderSize();
|
||||||
memcpy(obuf+d_off, getLoader()+e_len, d_len);
|
e_len = getLoaderSectionStart("CUTPOINT");
|
||||||
o_data += d_len;
|
d_len = lsize - e_len;
|
||||||
|
assert((e_len & 3) == 0 && (d_len & 1) == 0);
|
||||||
|
|
||||||
// dword align the len of the final data segment
|
// compute section sizes
|
||||||
while (o_data & 3)
|
o_text = e_len;
|
||||||
{
|
o_data = ph.c_len;
|
||||||
obuf[o_data++] = 0;
|
o_bss = i_bss;
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
// dword align offset
|
|
||||||
while (offset & 3)
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
// new bss
|
// word align len of compressed data
|
||||||
if (i_text + i_data + i_bss > o_text + o_data + o_bss)
|
while (o_data & 1)
|
||||||
o_bss = (i_text + i_data + i_bss) - (o_text + o_data);
|
|
||||||
|
|
||||||
// dirty bss
|
|
||||||
unsigned dirty_bss = (o_data + offset) - (i_text + i_data);
|
|
||||||
//printf("real dirty_bss: %d\n", dirty_bss);
|
|
||||||
// dword align (or 16 - for speedup when clearing the dirty bss)
|
|
||||||
const unsigned dirty_bss_align = opt->small ? 4 : 16;
|
|
||||||
while (dirty_bss & (dirty_bss_align - 1))
|
|
||||||
dirty_bss++;
|
|
||||||
// adjust bss, assert room for some stack
|
|
||||||
if (dirty_bss + 512 > o_bss)
|
|
||||||
o_bss = dirty_bss + 512;
|
|
||||||
|
|
||||||
// dword align the len of the final bss segment
|
|
||||||
while (o_bss & 3)
|
|
||||||
o_bss++;
|
|
||||||
|
|
||||||
// prepare loader
|
|
||||||
MemBuffer loader(o_text);
|
|
||||||
memcpy(loader, getLoader(), o_text);
|
|
||||||
|
|
||||||
// patch loader
|
|
||||||
int tmp = patchPackHeader(loader, o_text);
|
|
||||||
assert(tmp + 32 == (int)o_text); UNUSED(tmp);
|
|
||||||
patchVersionYear(loader, o_text);
|
|
||||||
if (!opt->small)
|
|
||||||
patchVersion(loader, o_text);
|
|
||||||
// patch "subq.l #1,d6" or "subq.w #1,d6" - see "up41" below
|
|
||||||
const unsigned dirty_bss_d6 =
|
|
||||||
patch_d_subq(loader, o_text, REG_D6, dirty_bss / dirty_bss_align, "u4");
|
|
||||||
patch_be32(loader, o_text, "up31", d_off + offset + decomp_offset);
|
|
||||||
if (opt->small)
|
|
||||||
patch_d_loop(loader, o_text, REG_D0, o_data/4, "up22", "u1");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (o_data <= 160)
|
|
||||||
throwNotCompressible();
|
|
||||||
unsigned loop1 = o_data / 160;
|
|
||||||
unsigned loop2 = o_data % 160;
|
|
||||||
if (loop2 == 0)
|
|
||||||
{
|
{
|
||||||
loop1--;
|
obuf[o_data++] = 0;
|
||||||
loop2 = 160;
|
offset++;
|
||||||
}
|
}
|
||||||
patch_be16(loader, o_text, "u2", OP_MOVEQ(loop2/4-1, REG_D0)); // moveq.l #X,d0
|
|
||||||
patch_d_loop(loader, o_text, REG_D0, loop1, "up22", "u1");
|
|
||||||
}
|
|
||||||
patch_be32(loader,o_text,"up21",o_data + offset);
|
|
||||||
patch_be32(loader,o_text,"up13",i_bss); // p_blen
|
|
||||||
patch_be32(loader,o_text,"up12",i_data); // p_dlen
|
|
||||||
patch_be32(loader,o_text,"up11",i_text); // p_tlen
|
|
||||||
|
|
||||||
// patch decompressor
|
// append decompressor (part 2 of loader)
|
||||||
upx_byte *p = obuf + d_off;
|
d_off = o_data;
|
||||||
// patch "moveq.l #1,d5" or "jmp (ASTACK)"
|
////memcpy(obuf + d_off, getLoader() + e_len, d_len); // must be done after relocation
|
||||||
patch_be16(p, d_len, "u3", (nrelocs > 0) ? OP_MOVEQ(1, REG_D5) : OP_JMP(REG_A7));
|
o_data += d_len;
|
||||||
patch_be32(p, d_len, "up41", dirty_bss_d6);
|
|
||||||
|
// dword align the len of the final data segment
|
||||||
|
while (o_data & 3)
|
||||||
|
{
|
||||||
|
obuf[o_data++] = 0;
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
// dword align offset
|
||||||
|
while (offset & 3)
|
||||||
|
offset++;
|
||||||
|
|
||||||
|
// new bss
|
||||||
|
if (i_text + i_data + i_bss > o_text + o_data + o_bss)
|
||||||
|
o_bss = (i_text + i_data + i_bss) - (o_text + o_data);
|
||||||
|
|
||||||
|
// dirty bss
|
||||||
|
unsigned dirty_bss = (o_data + offset) - (i_text + i_data);
|
||||||
|
//printf("real dirty_bss: %d\n", dirty_bss);
|
||||||
|
// dword align (or 16 - for speedup when clearing the dirty bss)
|
||||||
|
const unsigned dirty_bss_align = opt->small ? 4 : 16;
|
||||||
|
while (dirty_bss & (dirty_bss_align - 1))
|
||||||
|
dirty_bss++;
|
||||||
|
// adjust bss, assert room for some stack
|
||||||
|
unsigned stack = 512 + getDecompressorWrkmemSize();
|
||||||
|
if (dirty_bss + stack > o_bss)
|
||||||
|
o_bss = dirty_bss + stack;
|
||||||
|
|
||||||
|
// dword align the len of the final bss segment
|
||||||
|
while (o_bss & 3)
|
||||||
|
o_bss++;
|
||||||
|
|
||||||
|
// update symbols for buildLoader()
|
||||||
|
if (opt->small)
|
||||||
|
{
|
||||||
|
symbols.loop1.init(o_data / 4);
|
||||||
|
symbols.loop2.init(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
symbols.loop1.init(o_data / 160);
|
||||||
|
symbols.loop2.init((o_data % 160) / 4);
|
||||||
|
}
|
||||||
|
symbols.loop3.init(dirty_bss / dirty_bss_align);
|
||||||
|
|
||||||
|
symbols.up21_d4 = o_data + offset;
|
||||||
|
symbols.up31_base_d4 = d_off + offset;
|
||||||
|
symbols.up21_a6 = symbols.up21_d4 - (i_text + i_data);
|
||||||
|
symbols.up31_base_a6 = symbols.up31_base_d4 - (i_text + i_data);
|
||||||
|
assert((int)symbols.up21_a6 > 0);
|
||||||
|
assert((int)symbols.up31_base_a6 > 0);
|
||||||
|
|
||||||
|
const unsigned c = linker->getSymbolOffset("code_on_stack");
|
||||||
|
unsigned d;
|
||||||
|
d = linker->getSymbolOffset("flush_cache_rts") - c;
|
||||||
|
symbols.flush_cache_rts_offset = d;
|
||||||
|
d = linker->getSymbolOffset("clear_dirty_stack_loop") - c;
|
||||||
|
symbols.clear_dirty_stack_len = (d + 3) / 4 + 32 - 1;
|
||||||
|
d = linker->getSymbolOffset("code_on_stack_end") - c;
|
||||||
|
symbols.copy_to_stack_len = d / 2 - 1;
|
||||||
|
|
||||||
|
// now re-build loader
|
||||||
|
buildLoader(&ft);
|
||||||
|
unsigned new_lsize = getLoaderSize();
|
||||||
|
//printf("buildLoader %d %d\n", new_lsize, initial_lsize);
|
||||||
|
assert(new_lsize <= initial_lsize);
|
||||||
|
if (new_lsize == last_lsize && memcmp(getLoader(), last_loader, last_lsize) == 0)
|
||||||
|
break;
|
||||||
|
last_lsize = new_lsize;
|
||||||
|
memcpy(last_loader, getLoader(), last_lsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// define symbols and reloc
|
||||||
|
//
|
||||||
|
|
||||||
|
defineDecompressorSymbols();
|
||||||
|
|
||||||
|
linker->defineSymbol("loop1_count", symbols.loop1.value);
|
||||||
|
linker->defineSymbol("loop2_count", symbols.loop2.value);
|
||||||
|
linker->defineSymbol("loop3_count", symbols.loop3.value);
|
||||||
|
|
||||||
|
linker->defineSymbol("orig_p_tlen", i_text);
|
||||||
|
linker->defineSymbol("orig_p_dlen", i_data);
|
||||||
|
linker->defineSymbol("orig_p_blen", i_bss);
|
||||||
|
|
||||||
|
if (symbols.up21_a6 <= 32767)
|
||||||
|
linker->defineSymbol("up21_a6", symbols.up21_a6);
|
||||||
|
else
|
||||||
|
linker->defineSymbol("up21_d4", symbols.up21_d4);
|
||||||
|
|
||||||
|
if (symbols.up31_a6 <= 32767)
|
||||||
|
linker->defineSymbol("up31_a6", symbols.up31_a6);
|
||||||
|
else if (symbols.up31_d4 <= 32767)
|
||||||
|
linker->defineSymbol("up31_d4", symbols.up31_d4);
|
||||||
|
else if (symbols.up31_a6 <= 65534)
|
||||||
|
linker->defineSymbol("up31_a6", symbols.up31_a6 - 32767);
|
||||||
|
else
|
||||||
|
linker->defineSymbol("up31_d4", symbols.up31_d4);
|
||||||
|
#if 0
|
||||||
|
printf("relocsize = %d\n", relocsize);
|
||||||
|
printf("upx21(d4) = %d\n", symbols.up21_d4);
|
||||||
|
printf("upx21(a6) = %d\n", symbols.up21_a6);
|
||||||
|
printf("upx31(d4) = %d\n", symbols.up31_d4);
|
||||||
|
printf("upx31(a6) = %d\n", symbols.up31_a6);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
linker->defineSymbol("flush_cache_rts_offset", symbols.flush_cache_rts_offset);
|
||||||
|
linker->defineSymbol("copy_to_stack_len", symbols.copy_to_stack_len);
|
||||||
|
linker->defineSymbol("clear_dirty_stack_len", symbols.clear_dirty_stack_len);
|
||||||
|
|
||||||
|
relocateLoader();
|
||||||
|
|
||||||
|
//
|
||||||
|
// write
|
||||||
|
//
|
||||||
|
|
||||||
// set new file_hdr
|
// set new file_hdr
|
||||||
memcpy(&oh, &ih, FH_SIZE);
|
memcpy(&oh, &ih, FH_SIZE);
|
||||||
@@ -602,20 +686,29 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
// add an empty relocation fixup to workaround a bug in some TOS versions
|
// add an empty relocation fixup to workaround a bug in some TOS versions
|
||||||
oh.fh_reloc = 0;
|
oh.fh_reloc = 0;
|
||||||
|
|
||||||
#if 0 || defined(TESTING)
|
#if 0 || (TESTING)
|
||||||
printf("old text: %6d, data: %6d, bss: %6d, reloc: %d, overlay: %d\n",
|
printf("old text: %6d, data: %6d, bss: %6d, reloc: %d, overlay: %d\n",
|
||||||
i_text, i_data, i_bss, relocsize, overlay);
|
i_text, i_data, i_bss, relocsize, overlay);
|
||||||
printf("new text: %6d, data: %6d, bss: %6d, dirty_bss: %d, flag=0x%x\n",
|
printf("new text: %6d, data: %6d, bss: %6d, flag=0x%x\n",
|
||||||
o_text, o_data, o_bss, dirty_bss, (int)oh.fh_flag);
|
o_text, o_data, o_bss, (int)oh.fh_flag);
|
||||||
|
linker->dumpSymbols();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// prepare loader
|
||||||
|
MemBuffer loader(o_text);
|
||||||
|
memcpy(loader, getLoader(), o_text);
|
||||||
|
patchPackHeader(loader, o_text);
|
||||||
|
|
||||||
// write new file header, loader and compressed file
|
// write new file header, loader and compressed file
|
||||||
fo->write(&oh, FH_SIZE);
|
fo->write(&oh, FH_SIZE);
|
||||||
fo->write(loader, o_text); // entry
|
fo->write(loader, o_text); // entry
|
||||||
|
if (opt->debug.dump_stub_loader)
|
||||||
|
OutputFile::dump(opt->debug.dump_stub_loader, loader, o_text);
|
||||||
|
memcpy(obuf + d_off, getLoader() + e_len, d_len); // copy decompressor
|
||||||
fo->write(obuf, o_data); // compressed + decompressor
|
fo->write(obuf, o_data); // compressed + decompressor
|
||||||
|
|
||||||
// write empty relocation fixup
|
// write empty relocation fixup
|
||||||
fo->write("\x00\x00\x00\x00",4);
|
fo->write("\x00\x00\x00\x00", 4);
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
verifyOverlappingDecompression();
|
verifyOverlappingDecompression();
|
||||||
|
|||||||
+38
-13
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_TOS_H
|
#ifndef __UPX_P_TOS_H
|
||||||
#define __UPX_P_TOS_H
|
#define __UPX_P_TOS_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -42,6 +42,7 @@ public:
|
|||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_ATARI_TOS; }
|
virtual int getFormat() const { return UPX_F_ATARI_TOS; }
|
||||||
virtual const char *getName() const { return "atari/tos"; }
|
virtual const char *getName() const { return "atari/tos"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "m68k-atari.tos"; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
@@ -54,14 +55,14 @@ public:
|
|||||||
virtual void fileInfo();
|
virtual void fileInfo();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual const upx_byte *getLoader() const;
|
virtual Linker* newLinker() const;
|
||||||
virtual int getLoaderSize() const;
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
unsigned getDecomprOffset(int method, int small) const;
|
||||||
|
|
||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
virtual bool checkFileHeader();
|
virtual bool checkFileHeader();
|
||||||
|
|
||||||
struct tos_header_t
|
__packed_struct(tos_header_t)
|
||||||
{
|
|
||||||
BE16 fh_magic;
|
BE16 fh_magic;
|
||||||
BE32 fh_text;
|
BE32 fh_text;
|
||||||
BE32 fh_data;
|
BE32 fh_data;
|
||||||
@@ -70,14 +71,38 @@ protected:
|
|||||||
BE32 fh_reserved;
|
BE32 fh_reserved;
|
||||||
BE32 fh_flag;
|
BE32 fh_flag;
|
||||||
BE16 fh_reloc;
|
BE16 fh_reloc;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
tos_header_t ih, oh;
|
tos_header_t ih, oh;
|
||||||
|
|
||||||
protected:
|
// symbols for buildLoader()
|
||||||
unsigned patch_d_subq(void *l, int llen, int, unsigned, const char*);
|
struct LinkerSymbols
|
||||||
unsigned patch_d_loop(void *l, int llen, int, unsigned, const char*, const char*);
|
{
|
||||||
|
enum { LOOP_NONE, LOOP_SUBQ_L, LOOP_SUBQ_W, LOOP_DBRA };
|
||||||
|
struct LoopInfo {
|
||||||
|
unsigned mode; unsigned count; unsigned value;
|
||||||
|
void init(unsigned count, bool allow_dbra=true);
|
||||||
|
};
|
||||||
|
// buildLoader() input
|
||||||
|
bool need_reloc;
|
||||||
|
LoopInfo loop1;
|
||||||
|
LoopInfo loop2;
|
||||||
|
LoopInfo loop3;
|
||||||
|
unsigned up21_d4;
|
||||||
|
unsigned up21_a6;
|
||||||
|
unsigned up31_base_d4;
|
||||||
|
unsigned up31_base_a6;
|
||||||
|
// buildLoader() output
|
||||||
|
unsigned up31_d4;
|
||||||
|
unsigned up31_a6;
|
||||||
|
// currently not used by buildLoader()
|
||||||
|
unsigned flush_cache_rts_offset;
|
||||||
|
unsigned clear_dirty_stack_len;
|
||||||
|
unsigned copy_to_stack_len;
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
LinkerSymbols symbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+66
-64
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ bool PackUnix::canPack()
|
|||||||
#if defined(__unix__)
|
#if defined(__unix__)
|
||||||
// must be executable by owner
|
// must be executable by owner
|
||||||
if ((fi->st.st_mode & S_IXUSR) == 0)
|
if ((fi->st.st_mode & S_IXUSR) == 0)
|
||||||
throwCantPack("file not executable; try `chmod +x'");
|
throwCantPack("file not executable; try 'chmod +x'");
|
||||||
#endif
|
#endif
|
||||||
if (file_size < 4096)
|
if (file_size < 4096)
|
||||||
throwCantPack("file is too small");
|
throwCantPack("file is too small");
|
||||||
@@ -125,8 +125,8 @@ int PackUnix::getStrategy(Filter &/*ft*/)
|
|||||||
// Called just before reading and compressing each block.
|
// Called just before reading and compressing each block.
|
||||||
// Might want to adjust blocksize, etc.
|
// Might want to adjust blocksize, etc.
|
||||||
|
|
||||||
// If user specified the filter, then use it (-2==strategy).
|
// If user specified the filter, then use it (-2==filter_strategy).
|
||||||
// Else try the first two filters, and pick the better (2==strategy).
|
// Else try the first two filters, and pick the better (2==filter_strategy).
|
||||||
return (opt->no_filter ? -3 : ((opt->filter > 0) ? -2 : 2));
|
return (opt->no_filter ? -3 : ((opt->filter > 0) ? -2 : 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,9 +151,9 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
|
|||||||
// which assumes it has free choice on each call [block].
|
// which assumes it has free choice on each call [block].
|
||||||
// And if the choices aren't the same on each block,
|
// And if the choices aren't the same on each block,
|
||||||
// then un-filtering will give incorrect results.
|
// then un-filtering will give incorrect results.
|
||||||
int strategy = getStrategy(ft);
|
int filter_strategy = getStrategy(ft);
|
||||||
if (file_size > (off_t)blocksize)
|
if (file_size > (off_t)blocksize)
|
||||||
strategy = -3; // no filters
|
filter_strategy = -3; // no filters
|
||||||
|
|
||||||
int l = fi->readx(ibuf, UPX_MIN(blocksize, remaining));
|
int l = fi->readx(ibuf, UPX_MIN(blocksize, remaining));
|
||||||
remaining -= l;
|
remaining -= l;
|
||||||
@@ -170,11 +170,13 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
|
|||||||
// that is, AFTER filtering. We want BEFORE filtering,
|
// that is, AFTER filtering. We want BEFORE filtering,
|
||||||
// so that decompression checks the end-to-end checksum.
|
// so that decompression checks the end-to-end checksum.
|
||||||
unsigned const end_u_adler = upx_adler32(ibuf, ph.u_len, ph.u_adler);
|
unsigned const end_u_adler = upx_adler32(ibuf, ph.u_len, ph.u_adler);
|
||||||
compressWithFilters(&ft, OVERHEAD, strategy);
|
compressWithFilters(&ft, OVERHEAD, NULL_cconf, filter_strategy);
|
||||||
|
|
||||||
if (ph.c_len < ph.u_len) {
|
if (ph.c_len < ph.u_len) {
|
||||||
|
const upx_bytep tbuf = NULL;
|
||||||
|
if (ft.id == 0) tbuf = ibuf;
|
||||||
ph.overlap_overhead = OVERHEAD;
|
ph.overlap_overhead = OVERHEAD;
|
||||||
if (!testOverlappingDecompression(obuf, ph.overlap_overhead)) {
|
if (!testOverlappingDecompression(obuf, tbuf, ph.overlap_overhead)) {
|
||||||
// not in-place compressible
|
// not in-place compressible
|
||||||
ph.c_len = ph.u_len;
|
ph.c_len = ph.u_len;
|
||||||
}
|
}
|
||||||
@@ -189,8 +191,8 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
|
|||||||
// write block header
|
// write block header
|
||||||
b_info blk_info;
|
b_info blk_info;
|
||||||
memset(&blk_info, 0, sizeof(blk_info));
|
memset(&blk_info, 0, sizeof(blk_info));
|
||||||
set_native32(&blk_info.sz_unc, ph.u_len);
|
set_te32(&blk_info.sz_unc, ph.u_len);
|
||||||
set_native32(&blk_info.sz_cpr, ph.c_len);
|
set_te32(&blk_info.sz_cpr, ph.c_len);
|
||||||
if (ph.c_len < ph.u_len) {
|
if (ph.c_len < ph.u_len) {
|
||||||
blk_info.b_method = (unsigned char) ph.method;
|
blk_info.b_method = (unsigned char) ph.method;
|
||||||
blk_info.b_ftid = (unsigned char) ph.filter;
|
blk_info.b_ftid = (unsigned char) ph.filter;
|
||||||
@@ -225,7 +227,7 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
|
|||||||
void
|
void
|
||||||
PackUnix::patchLoaderChecksum()
|
PackUnix::patchLoaderChecksum()
|
||||||
{
|
{
|
||||||
unsigned char *const ptr = const_cast<unsigned char *>(getLoader());
|
unsigned char *const ptr = getLoader();
|
||||||
l_info *const lp = &linfo;
|
l_info *const lp = &linfo;
|
||||||
// checksum for loader; also some PackHeader info
|
// checksum for loader; also some PackHeader info
|
||||||
lp->l_magic = UPX_MAGIC_LE32; // LE32 always
|
lp->l_magic = UPX_MAGIC_LE32; // LE32 always
|
||||||
@@ -236,11 +238,10 @@ PackUnix::patchLoaderChecksum()
|
|||||||
lp->l_checksum = upx_adler32(ptr, lsize);
|
lp->l_checksum = upx_adler32(ptr, lsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackUnix::pack3(OutputFile *fo, Filter &ft)
|
void PackUnix::pack3(OutputFile *fo, Filter &/*ft*/)
|
||||||
{
|
{
|
||||||
upx_byte const *p = getLoader();
|
upx_byte *p = getLoader();
|
||||||
lsize = getLoaderSize();
|
lsize = getLoaderSize();
|
||||||
patchFilter32(const_cast<upx_byte *>(p), lsize, &ft);
|
|
||||||
updateLoader(fo);
|
updateLoader(fo);
|
||||||
patchLoaderChecksum();
|
patchLoaderChecksum();
|
||||||
fo->write(p, lsize);
|
fo->write(p, lsize);
|
||||||
@@ -251,7 +252,7 @@ void PackUnix::pack4(OutputFile *fo, Filter &)
|
|||||||
writePackHeader(fo);
|
writePackHeader(fo);
|
||||||
|
|
||||||
unsigned tmp;
|
unsigned tmp;
|
||||||
set_native32(&tmp, overlay_offset);
|
set_te32(&tmp, overlay_offset);
|
||||||
fo->write(&tmp, sizeof(tmp));
|
fo->write(&tmp, sizeof(tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,9 +278,9 @@ void PackUnix::pack(OutputFile *fo)
|
|||||||
pack1(fo, ft); // generate Elf header, etc.
|
pack1(fo, ft); // generate Elf header, etc.
|
||||||
|
|
||||||
p_info hbuf;
|
p_info hbuf;
|
||||||
set_native32(&hbuf.p_progid, progid);
|
set_te32(&hbuf.p_progid, progid);
|
||||||
set_native32(&hbuf.p_filesize, file_size);
|
set_te32(&hbuf.p_filesize, file_size);
|
||||||
set_native32(&hbuf.p_blocksize, blocksize);
|
set_te32(&hbuf.p_blocksize, blocksize);
|
||||||
fo->write(&hbuf, sizeof(hbuf));
|
fo->write(&hbuf, sizeof(hbuf));
|
||||||
|
|
||||||
pack2(fo, ft); // append the compressed body
|
pack2(fo, ft); // append the compressed body
|
||||||
@@ -305,21 +306,21 @@ void PackUnix::packExtent(
|
|||||||
unsigned &total_out,
|
unsigned &total_out,
|
||||||
Filter *ft,
|
Filter *ft,
|
||||||
OutputFile *fo,
|
OutputFile *fo,
|
||||||
unsigned hdr_ulen
|
unsigned hdr_u_len
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned const init_u_adler = ph.u_adler;
|
unsigned const init_u_adler = ph.u_adler;
|
||||||
unsigned const init_c_adler = ph.c_adler;
|
unsigned const init_c_adler = ph.c_adler;
|
||||||
MemBuffer hdr_ibuf;
|
MemBuffer hdr_ibuf;
|
||||||
if (hdr_ulen) {
|
if (hdr_u_len) {
|
||||||
hdr_ibuf.alloc(hdr_ulen);
|
hdr_ibuf.alloc(hdr_u_len);
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
int l = fi->readx(hdr_ibuf, hdr_ulen);
|
int l = fi->readx(hdr_ibuf, hdr_u_len);
|
||||||
(void)l;
|
(void)l;
|
||||||
}
|
}
|
||||||
fi->seek(x.offset, SEEK_SET);
|
fi->seek(x.offset, SEEK_SET);
|
||||||
for (off_t rest = x.size; 0 != rest; ) {
|
for (off_t rest = x.size; 0 != rest; ) {
|
||||||
int const strategy = getStrategy(*ft);
|
int const filter_strategy = getStrategy(*ft);
|
||||||
int l = fi->readx(ibuf, UPX_MIN(rest, (off_t)blocksize));
|
int l = fi->readx(ibuf, UPX_MIN(rest, (off_t)blocksize));
|
||||||
if (l == 0) {
|
if (l == 0) {
|
||||||
break;
|
break;
|
||||||
@@ -346,17 +347,18 @@ void PackUnix::packExtent(
|
|||||||
ft->id = 0;
|
ft->id = 0;
|
||||||
ft->cto = 0;
|
ft->cto = 0;
|
||||||
|
|
||||||
compressWithFilters(ft, OVERHEAD, strategy,
|
compressWithFilters(ft, OVERHEAD, NULL_cconf, filter_strategy,
|
||||||
NULL, 0, 0, 0, 0, // those 5 args are the defaults
|
0, 0, 0, hdr_ibuf, hdr_u_len);
|
||||||
hdr_ibuf, hdr_ulen);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(void) compress(ibuf, obuf); // ignore return value
|
(void) compress(ibuf, ph.u_len, obuf); // ignore return value
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ph.c_len < ph.u_len) {
|
if (ph.c_len < ph.u_len) {
|
||||||
|
const upx_bytep tbuf = NULL;
|
||||||
|
if (ft == NULL || ft->id == 0) tbuf = ibuf;
|
||||||
ph.overlap_overhead = OVERHEAD;
|
ph.overlap_overhead = OVERHEAD;
|
||||||
if (!testOverlappingDecompression(obuf, ph.overlap_overhead)) {
|
if (!testOverlappingDecompression(obuf, tbuf, ph.overlap_overhead)) {
|
||||||
// not in-place compressible
|
// not in-place compressible
|
||||||
ph.c_len = ph.u_len;
|
ph.c_len = ph.u_len;
|
||||||
}
|
}
|
||||||
@@ -371,35 +373,35 @@ void PackUnix::packExtent(
|
|||||||
|
|
||||||
// write block sizes
|
// write block sizes
|
||||||
b_info tmp;
|
b_info tmp;
|
||||||
if (hdr_ulen) {
|
if (hdr_u_len) {
|
||||||
unsigned hdr_clen;
|
unsigned hdr_c_len = 0;
|
||||||
MemBuffer hdr_obuf;
|
MemBuffer hdr_obuf;
|
||||||
unsigned result[16];
|
hdr_obuf.allocForCompression(hdr_u_len);
|
||||||
upx_compress_config_t conf;
|
int r = upx_compress(hdr_ibuf, hdr_u_len, hdr_obuf, &hdr_c_len, 0,
|
||||||
memset(&conf, 0xff, sizeof(conf));
|
ph.method, 10, NULL, NULL);
|
||||||
hdr_obuf.allocForCompression(hdr_ulen);
|
if (r != UPX_E_OK)
|
||||||
int r = upx_compress(hdr_ibuf, hdr_ulen, hdr_obuf, &hdr_clen, 0,
|
throwInternalError("header compression failed");
|
||||||
ph.method, 10, &conf, result);
|
if (hdr_c_len >= hdr_u_len)
|
||||||
(void)r;
|
throwInternalError("header compression size increase");
|
||||||
ph.saved_u_adler = upx_adler32(hdr_ibuf, hdr_ulen, init_u_adler);
|
ph.saved_u_adler = upx_adler32(hdr_ibuf, hdr_u_len, init_u_adler);
|
||||||
ph.saved_c_adler = upx_adler32(hdr_obuf, hdr_clen, init_c_adler);
|
ph.saved_c_adler = upx_adler32(hdr_obuf, hdr_c_len, init_c_adler);
|
||||||
ph.u_adler = upx_adler32(ibuf, ph.u_len, ph.saved_u_adler);
|
ph.u_adler = upx_adler32(ibuf, ph.u_len, ph.saved_u_adler);
|
||||||
ph.c_adler = upx_adler32(obuf, ph.c_len, ph.saved_c_adler);
|
ph.c_adler = upx_adler32(obuf, ph.c_len, ph.saved_c_adler);
|
||||||
end_u_adler = ph.u_adler;
|
end_u_adler = ph.u_adler;
|
||||||
memset(&tmp, 0, sizeof(tmp));
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
set_native32(&tmp.sz_unc, hdr_ulen);
|
set_te32(&tmp.sz_unc, hdr_u_len);
|
||||||
set_native32(&tmp.sz_cpr, hdr_clen);
|
set_te32(&tmp.sz_cpr, hdr_c_len);
|
||||||
tmp.b_method = (unsigned char) ph.method;
|
tmp.b_method = (unsigned char) ph.method;
|
||||||
fo->write(&tmp, sizeof(tmp));
|
fo->write(&tmp, sizeof(tmp));
|
||||||
b_len += sizeof(b_info);
|
b_len += sizeof(b_info);
|
||||||
fo->write(hdr_obuf, hdr_clen);
|
fo->write(hdr_obuf, hdr_c_len);
|
||||||
total_out += hdr_clen;
|
total_out += hdr_c_len;
|
||||||
total_in += hdr_ulen;
|
total_in += hdr_u_len;
|
||||||
hdr_ulen = 0; // compress hdr one time only
|
hdr_u_len = 0; // compress hdr one time only
|
||||||
}
|
}
|
||||||
memset(&tmp, 0, sizeof(tmp));
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
set_native32(&tmp.sz_unc, ph.u_len);
|
set_te32(&tmp.sz_unc, ph.u_len);
|
||||||
set_native32(&tmp.sz_cpr, ph.c_len);
|
set_te32(&tmp.sz_cpr, ph.c_len);
|
||||||
if (ph.c_len < ph.u_len) {
|
if (ph.c_len < ph.u_len) {
|
||||||
tmp.b_method = (unsigned char) ph.method;
|
tmp.b_method = (unsigned char) ph.method;
|
||||||
if (ft) {
|
if (ft) {
|
||||||
@@ -410,6 +412,9 @@ void PackUnix::packExtent(
|
|||||||
fo->write(&tmp, sizeof(tmp));
|
fo->write(&tmp, sizeof(tmp));
|
||||||
b_len += sizeof(b_info);
|
b_len += sizeof(b_info);
|
||||||
|
|
||||||
|
if (ft) {
|
||||||
|
ph.u_adler = end_u_adler;
|
||||||
|
}
|
||||||
// write compressed data
|
// write compressed data
|
||||||
if (ph.c_len < ph.u_len) {
|
if (ph.c_len < ph.u_len) {
|
||||||
fo->write(obuf, ph.c_len);
|
fo->write(obuf, ph.c_len);
|
||||||
@@ -420,9 +425,6 @@ void PackUnix::packExtent(
|
|||||||
fo->write(ibuf, ph.u_len);
|
fo->write(ibuf, ph.u_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ft) {
|
|
||||||
ph.u_adler = end_u_adler;
|
|
||||||
}
|
|
||||||
total_in += ph.u_len;
|
total_in += ph.u_len;
|
||||||
total_out += ph.c_len;
|
total_out += ph.c_len;
|
||||||
}
|
}
|
||||||
@@ -437,8 +439,8 @@ void PackUnix::unpackExtent(unsigned wanted, OutputFile *fo,
|
|||||||
b_info hdr; memset(&hdr, 0, sizeof(hdr));
|
b_info hdr; memset(&hdr, 0, sizeof(hdr));
|
||||||
while (wanted) {
|
while (wanted) {
|
||||||
fi->readx(&hdr, szb_info);
|
fi->readx(&hdr, szb_info);
|
||||||
int const sz_unc = ph.u_len = get_native32(&hdr.sz_unc);
|
int const sz_unc = ph.u_len = get_te32(&hdr.sz_unc);
|
||||||
int const sz_cpr = ph.c_len = get_native32(&hdr.sz_cpr);
|
int const sz_cpr = ph.c_len = get_te32(&hdr.sz_cpr);
|
||||||
ph.filter_cto = hdr.b_cto8;
|
ph.filter_cto = hdr.b_cto8;
|
||||||
|
|
||||||
if (sz_unc == 0) { // must never happen while 0!=wanted
|
if (sz_unc == 0) { // must never happen while 0!=wanted
|
||||||
@@ -501,13 +503,13 @@ int PackUnix::canUnpack()
|
|||||||
|
|
||||||
fi->seek(-bufsize, SEEK_END);
|
fi->seek(-bufsize, SEEK_END);
|
||||||
fi->readx(buf, bufsize);
|
fi->readx(buf, bufsize);
|
||||||
if (!getPackHeader(buf, bufsize))
|
if (!getPackHeader(buf, bufsize, true)) // allow incompressible extents
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int l = ph.buf_offset + ph.getPackHeaderSize();
|
int l = ph.buf_offset + ph.getPackHeaderSize();
|
||||||
if (l < 0 || l + 4 > bufsize)
|
if (l < 0 || l + 4 > bufsize)
|
||||||
throwCantUnpack("file corrupted");
|
throwCantUnpack("file corrupted");
|
||||||
overlay_offset = get_native32(buf+l);
|
overlay_offset = get_te32(buf+l);
|
||||||
if ((off_t)overlay_offset >= file_size)
|
if ((off_t)overlay_offset >= file_size)
|
||||||
throwCantUnpack("file corrupted");
|
throwCantUnpack("file corrupted");
|
||||||
|
|
||||||
@@ -529,15 +531,15 @@ void PackUnix::unpack(OutputFile *fo)
|
|||||||
Elf32_Ehdr ehdr;
|
Elf32_Ehdr ehdr;
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(&ehdr, sizeof(ehdr));
|
fi->readx(&ehdr, sizeof(ehdr));
|
||||||
unsigned const e_entry = get_native32(&ehdr.e_entry);
|
unsigned const e_entry = get_te32(&ehdr.e_entry);
|
||||||
if (e_entry < 0x401180) { /* old style, 8-byte b_info */
|
if (e_entry < 0x401180) { /* old style, 8-byte b_info */
|
||||||
szb_info = 2*sizeof(unsigned);
|
szb_info = 2*sizeof(unsigned);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Elf32_Phdr phdr;
|
Elf32_Phdr phdr;
|
||||||
fi->seek(get_native32(&ehdr.e_phoff), SEEK_SET);
|
fi->seek(get_te32(&ehdr.e_phoff), SEEK_SET);
|
||||||
fi->readx(&phdr, sizeof(phdr));
|
fi->readx(&phdr, sizeof(phdr));
|
||||||
unsigned const p_vaddr = get_native32(&phdr.p_vaddr);
|
unsigned const p_vaddr = get_te32(&phdr.p_vaddr);
|
||||||
if (0x80==(e_entry - p_vaddr)) { /* 1.22 old style */
|
if (0x80==(e_entry - p_vaddr)) { /* 1.22 old style */
|
||||||
szb_info = 2*sizeof(unsigned);
|
szb_info = 2*sizeof(unsigned);
|
||||||
}
|
}
|
||||||
@@ -556,8 +558,8 @@ void PackUnix::unpack(OutputFile *fo)
|
|||||||
{
|
{
|
||||||
p_info hbuf;
|
p_info hbuf;
|
||||||
fi->readx(&hbuf, sizeof(hbuf));
|
fi->readx(&hbuf, sizeof(hbuf));
|
||||||
orig_file_size = get_native32(&hbuf.p_filesize);
|
orig_file_size = get_te32(&hbuf.p_filesize);
|
||||||
blocksize = get_native32(&hbuf.p_blocksize);
|
blocksize = get_te32(&hbuf.p_blocksize);
|
||||||
|
|
||||||
if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)
|
if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)
|
||||||
throwCantUnpack("file header corrupted");
|
throwCantUnpack("file header corrupted");
|
||||||
@@ -581,8 +583,8 @@ void PackUnix::unpack(OutputFile *fo)
|
|||||||
unsigned sz_unc, sz_cpr;
|
unsigned sz_unc, sz_cpr;
|
||||||
|
|
||||||
fi->readx(&bhdr, szb_info);
|
fi->readx(&bhdr, szb_info);
|
||||||
ph.u_len = sz_unc = get_native32(&bhdr.sz_unc);
|
ph.u_len = sz_unc = get_te32(&bhdr.sz_unc);
|
||||||
ph.c_len = sz_cpr = get_native32(&bhdr.sz_cpr);
|
ph.c_len = sz_cpr = get_te32(&bhdr.sz_cpr);
|
||||||
|
|
||||||
if (sz_unc == 0) // uncompressed size 0 -> EOF
|
if (sz_unc == 0) // uncompressed size 0 -> EOF
|
||||||
{
|
{
|
||||||
|
|||||||
+31
-60
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2010 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2010 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
<markus@oberhumer.com> <ml1050@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_UNIX_H
|
#ifndef __UPX_P_UNIX_H
|
||||||
#define __UPX_P_UNIX_H
|
#define __UPX_P_UNIX_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -64,15 +64,6 @@ protected:
|
|||||||
|
|
||||||
virtual void writePackHeader(OutputFile *fo);
|
virtual void writePackHeader(OutputFile *fo);
|
||||||
|
|
||||||
// in order too share as much code as possible we introduce
|
|
||||||
// an endian abstraction here
|
|
||||||
virtual acc_uint64l_t get_native64(const void *) const = 0;
|
|
||||||
virtual unsigned get_native32(const void *) const = 0;
|
|
||||||
virtual unsigned get_native16(const void *) const = 0;
|
|
||||||
virtual void set_native64(void *, acc_uint64l_t) const = 0;
|
|
||||||
virtual void set_native32(void *, unsigned) const = 0;
|
|
||||||
virtual void set_native16(void *, unsigned) const = 0;
|
|
||||||
|
|
||||||
virtual bool checkCompressionRatio(unsigned, unsigned) const;
|
virtual bool checkCompressionRatio(unsigned, unsigned) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -101,30 +92,28 @@ protected:
|
|||||||
unsigned b_len; // total length of b_info blocks
|
unsigned b_len; // total length of b_info blocks
|
||||||
|
|
||||||
// must agree with stub/linux.hh
|
// must agree with stub/linux.hh
|
||||||
struct b_info { // 12-byte header before each compressed block
|
__packed_struct(b_info) // 12-byte header before each compressed block
|
||||||
unsigned sz_unc; // uncompressed_size
|
unsigned sz_unc; // uncompressed_size
|
||||||
unsigned sz_cpr; // compressed_size
|
unsigned sz_cpr; // compressed_size
|
||||||
unsigned char b_method; // compression algorithm
|
unsigned char b_method; // compression algorithm
|
||||||
unsigned char b_ftid; // filter id
|
unsigned char b_ftid; // filter id
|
||||||
unsigned char b_cto8; // filter parameter
|
unsigned char b_cto8; // filter parameter
|
||||||
unsigned char b_unused;
|
unsigned char b_unused;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
struct l_info { // 12-byte trailer in header for loader
|
__packed_struct(l_info) // 12-byte trailer in header for loader
|
||||||
unsigned l_checksum;
|
LE32 l_checksum;
|
||||||
unsigned l_magic;
|
LE32 l_magic;
|
||||||
unsigned short l_lsize;
|
LE16 l_lsize;
|
||||||
unsigned char l_version;
|
unsigned char l_version;
|
||||||
unsigned char l_format;
|
unsigned char l_format;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct p_info { // 12-byte packed program header
|
__packed_struct(p_info) // 12-byte packed program header
|
||||||
unsigned p_progid;
|
unsigned p_progid;
|
||||||
unsigned p_filesize;
|
unsigned p_filesize;
|
||||||
unsigned p_blocksize;
|
unsigned p_blocksize;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct l_info linfo;
|
struct l_info linfo;
|
||||||
|
|
||||||
@@ -141,40 +130,31 @@ class PackUnixBe32 : public PackUnix
|
|||||||
{
|
{
|
||||||
typedef PackUnix super;
|
typedef PackUnix super;
|
||||||
protected:
|
protected:
|
||||||
PackUnixBe32(InputFile *f) : super(f) { }
|
PackUnixBe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::be_policy; }
|
||||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
|
|
||||||
virtual 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); }
|
|
||||||
|
|
||||||
// must agree with stub/linux.hh
|
// must agree with stub/linux.hh
|
||||||
struct b_info { // 12-byte header before each compressed block
|
__packed_struct(b_info) // 12-byte header before each compressed block
|
||||||
BE32 sz_unc; // uncompressed_size
|
BE32 sz_unc; // uncompressed_size
|
||||||
BE32 sz_cpr; // compressed_size
|
BE32 sz_cpr; // compressed_size
|
||||||
unsigned char b_method; // compression algorithm
|
unsigned char b_method; // compression algorithm
|
||||||
unsigned char b_ftid; // filter id
|
unsigned char b_ftid; // filter id
|
||||||
unsigned char b_cto8; // filter parameter
|
unsigned char b_cto8; // filter parameter
|
||||||
unsigned char b_unused;
|
unsigned char b_unused;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
struct l_info { // 12-byte trailer in header for loader
|
__packed_struct(l_info) // 12-byte trailer in header for loader
|
||||||
BE32 l_checksum;
|
BE32 l_checksum;
|
||||||
BE32 l_magic;
|
BE32 l_magic;
|
||||||
BE16 l_lsize;
|
BE16 l_lsize;
|
||||||
unsigned char l_version;
|
unsigned char l_version;
|
||||||
unsigned char l_format;
|
unsigned char l_format;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct p_info { // 12-byte packed program header
|
__packed_struct(p_info) // 12-byte packed program header
|
||||||
BE32 p_progid;
|
BE32 p_progid;
|
||||||
BE32 p_filesize;
|
BE32 p_filesize;
|
||||||
BE32 p_blocksize;
|
BE32 p_blocksize;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -182,40 +162,31 @@ class PackUnixLe32 : public PackUnix
|
|||||||
{
|
{
|
||||||
typedef PackUnix super;
|
typedef PackUnix super;
|
||||||
protected:
|
protected:
|
||||||
PackUnixLe32(InputFile *f) : super(f) { }
|
PackUnixLe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
|
||||||
virtual 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); }
|
|
||||||
|
|
||||||
// must agree with stub/linux.hh
|
// must agree with stub/linux.hh
|
||||||
struct b_info { // 12-byte header before each compressed block
|
__packed_struct(b_info) // 12-byte header before each compressed block
|
||||||
LE32 sz_unc; // uncompressed_size
|
LE32 sz_unc; // uncompressed_size
|
||||||
LE32 sz_cpr; // compressed_size
|
LE32 sz_cpr; // compressed_size
|
||||||
unsigned char b_method; // compression algorithm
|
unsigned char b_method; // compression algorithm
|
||||||
unsigned char b_ftid; // filter id
|
unsigned char b_ftid; // filter id
|
||||||
unsigned char b_cto8; // filter parameter
|
unsigned char b_cto8; // filter parameter
|
||||||
unsigned char b_unused;
|
unsigned char b_unused;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
struct l_info { // 12-byte trailer in header for loader
|
__packed_struct(l_info) // 12-byte trailer in header for loader
|
||||||
LE32 l_checksum;
|
LE32 l_checksum;
|
||||||
LE32 l_magic;
|
LE32 l_magic;
|
||||||
LE16 l_lsize;
|
LE16 l_lsize;
|
||||||
unsigned char l_version;
|
unsigned char l_version;
|
||||||
unsigned char l_format;
|
unsigned char l_format;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct p_info { // 12-byte packed program header
|
__packed_struct(p_info) // 12-byte packed program header
|
||||||
LE32 p_progid;
|
LE32 p_progid;
|
||||||
LE32 p_filesize;
|
LE32 p_filesize;
|
||||||
LE32 p_blocksize;
|
LE32 p_blocksize;
|
||||||
}
|
__packed_struct_end()
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -235,7 +206,7 @@ public:
|
|||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual const upx_byte *getLoader() const;
|
virtual upx_byte *getLoader() const;
|
||||||
virtual int getLoaderSize() const;
|
virtual int getLoaderSize() const;
|
||||||
|
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
|
|||||||
+1078
-235
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user